// File: /workspace/github_cpp_makefile_star2_O2/IlanPrice[P]Linear-Algebra-Library-in-Cplusplus/Matrix.cpp
// Function: LU(Matrix const&)
boost::tuple< Matrix, Matrix, Matrix> LU(const Matrix& A)
	{
		Vector dim = size(A);
		int m = dim(1);
		int n = dim(2);
		Matrix U(A);
		Matrix pivot(m,m);
		Matrix P = eye(m);
		Matrix L = eye(m);

		for (int k=1;k<m;k++)
		{
			// partial pivoting
			double max = U(k,k);
			int index = k;
			pivot = eye(m);
			for (int i = k; i<=m; i++)
			{
				if (std::abs(U(i,k)) > std::abs(max))
				{
					index = i;
					max = U(i,k);
				}
			}
			if (index != k)
			{

				Vector temp = U.getElements(k,k,1,n,"vector");
				U.setElements(k,k,1,n,U.getElements(index,index,1,n,"Vector"));
				U.setElements(index,index,1,n,temp);
				Vector temp2 = L.getElements(k,k,1,m,"vector");

				L.setElements(k,k,1,m,L.getElements(index,index,1,m,"Vector"));
				L.setElements(index,index,1,m,temp2);
				pivot(index,index)=0; pivot(k,k) = 0;
				pivot(index,k) = 1; pivot(k,index) = 1;
				P = pivot*P;
			}
			// variant of Gaussian elimination
			Matrix Lk = eye(m);
			for (int i = k+1; i<=m;i++)
			{
				Lk(i,k) = U(i,k)/U(k,k);
				for (int j=k+1;j<=n;j++)
				{
					U(i,j) = U(i,j) - Lk(i,k)*U(k,j);
				}
				U(i,k) = 0;
			}
			L = L*pivot*Lk;
		}
		boost::tuple<Matrix,Matrix,Matrix> LUP = boost::make_tuple(L, U, P);
		return LUP;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
movq %rsi, %rbx
movq %rdi, 0x90(%rsp)
leaq 0xa8(%rsp), %r14
movq %r14, %rdi
callq 0x506c
pushq $0x1
popq %rbp
movq %r14, %rdi
movl %ebp, %esi
callq 0x2030
cvttsd2si (%rax), %r14d
leaq 0xa8(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0x2030
cvttsd2si (%rax), %r15d
leaq 0x80(%rsp), %rdi
movq %rbx, %rsi
callq 0x29b2
leaq 0x50(%rsp), %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x285c
leaq 0x70(%rsp), %rdi
movl %r14d, %esi
callq 0x50c7
leaq 0x18(%rsp), %rdi
movl %r14d, %esi
callq 0x50c7
movl %r14d, 0x10(%rsp)
movl %r14d, %eax
negl %eax
movq %rax, 0x98(%rsp)
leaq 0x80(%rsp), %r12
leaq 0xe8(%rsp), %r13
cmpl 0x10(%rsp), %ebp
jge 0x430c
movq %r12, %rdi
movl %ebp, %esi
movl %ebp, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movapd %xmm0, 0x30(%rsp)
movq %r13, %rdi
movl 0x10(%rsp), %esi
callq 0x50c7
leaq 0x50(%rsp), %rdi
movq %r13, %rsi
callq 0x4c1c
movq %r13, %rdi
callq 0x2a78
movl %ebp, %ebx
movl %ebp, %r14d
movq 0x98(%rsp), %rax
addl %r14d, %eax
cmpl $0x1, %eax
je 0x3f56
movq %r12, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movapd 0x512d(%rip), %xmm2     # 0x9050
andpd %xmm2, %xmm0
movapd 0x30(%rsp), %xmm1
andpd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x3f51
movq %r12, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movapd %xmm0, 0x30(%rsp)
movl %r14d, %ebx
incl %r14d
jmp 0x3efa
cmpl %ebp, %ebx
je 0x41b6
leaq 0x168(%rsp), %rdi
leaq 0x53f4(%rip), %rsi      # 0x9361
leaq 0x40(%rsp), %rdx
callq 0x1060
movq %r13, %rdi
movq %r12, %rsi
movl %ebp, %edx
movl %ebp, %ecx
pushq $0x1
popq %r8
movl %r15d, %r9d
callq 0x2d9e
leaq 0x168(%rsp), %rdi
callq 0x1070
leaq 0x148(%rsp), %rdi
leaq 0x5615(%rip), %rsi      # 0x95be
leaq 0x40(%rsp), %rdx
callq 0x1060
leaq 0xd8(%rsp), %rdi
movq %r12, %rsi
movl %ebx, %edx
movl %ebx, %ecx
pushq $0x1
popq %r14
movl %r14d, %r8d
movl %r15d, %r9d
callq 0x2d9e
movq %r12, %rdi
movl %ebp, %esi
movl %ebp, %edx
movl %r14d, %ecx
movl %r15d, %r8d
leaq 0xd8(%rsp), %r14
movq %r14, %r9
callq 0x32d6
movq %r14, %rdi
callq 0x1908
leaq 0x148(%rsp), %rdi
callq 0x1070
leaq 0xf8(%rsp), %r14
movq %r14, %rdi
movq %r13, %rsi
callq 0x18bc
movq %r12, %rdi
movl %ebx, %esi
movl %ebx, %edx
pushq $0x1
popq %rcx
movl %r15d, %r8d
movq %r14, %r9
callq 0x32d6
movq %r14, %rdi
callq 0x1908
leaq 0x128(%rsp), %rdi
leaq 0x531f(%rip), %rsi      # 0x9361
leaq 0x60(%rsp), %rdx
callq 0x1060
leaq 0x40(%rsp), %rdi
leaq 0x18(%rsp), %rsi
movl %ebp, %edx
movl %ebp, %ecx
pushq $0x1
popq %r8
movl 0x10(%rsp), %r9d
callq 0x2d9e
leaq 0xc8(%rsp), %r14
leaq 0x128(%rsp), %rdi
callq 0x1070
leaq 0x108(%rsp), %rdi
leaq 0x5532(%rip), %rsi      # 0x95be
leaq 0x60(%rsp), %rdx
callq 0x1060
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
movl %ebx, %edx
movl %ebx, %ecx
pushq $0x1
popq %r8
movl 0x10(%rsp), %r14d
movl %r14d, %r9d
callq 0x2d9e
leaq 0x18(%rsp), %rdi
movl %ebp, %esi
movl %ebp, %edx
pushq $0x1
popq %rcx
movl %r14d, %r8d
leaq 0xc8(%rsp), %r14
movq %r14, %r9
callq 0x32d6
movq %r14, %rdi
callq 0x1908
leaq 0x108(%rsp), %rdi
callq 0x1070
leaq 0xb8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x18bc
leaq 0x18(%rsp), %rdi
movl %ebx, %esi
movl %ebx, %edx
pushq $0x1
popq %rcx
movl 0x10(%rsp), %r8d
leaq 0xb8(%rsp), %r14
movq %r14, %r9
callq 0x32d6
movq %r14, %rdi
callq 0x1908
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movl %ebx, %esi
movl %ebx, %edx
callq 0x3a1a
andq $0x0, (%rax)
movq %r14, %rdi
movl %ebp, %esi
movl %ebp, %edx
callq 0x3a1a
andq $0x0, (%rax)
movq %r14, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3a1a
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, (%rax)
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
callq 0x3a1a
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, (%rax)
leaq 0x60(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
leaq 0x70(%rsp), %r14
movq %r14, %rdx
callq 0x376b
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4c1c
movq %rbx, %rdi
callq 0x2a78
leaq 0x40(%rsp), %rdi
callq 0x1908
movq %r13, %rdi
callq 0x1908
movq %r13, %rdi
movl 0x10(%rsp), %esi
callq 0x50c7
leal 0x1(%rbp), %ebx
movl %ebx, 0x14(%rsp)
cmpl 0x10(%rsp), %ebx
jg 0x42b2
movq %r12, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq %r12, %rdi
movl %ebp, %esi
movl %ebp, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movq %r13, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3a1a
movsd 0x30(%rsp), %xmm0
divsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x14(%rsp), %r14d
cmpl %r15d, %r14d
jg 0x429b
movq %r12, %rdi
movl %ebx, %esi
movl %r14d, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq %r13, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movq %r12, %rdi
movl %ebp, %esi
movl %r14d, %edx
callq 0x3a1a
movsd (%rax), %xmm0
movsd %xmm0, 0xa0(%rsp)
movq %r12, %rdi
movl %ebx, %esi
movl %r14d, %edx
callq 0x3a1a
movsd 0x28(%rsp), %xmm1
mulsd 0xa0(%rsp), %xmm1
movsd 0x30(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
incl %r14d
jmp 0x4220
movq %r12, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3a1a
andq $0x0, (%rax)
incl %ebx
jmp 0x41c9
leaq 0x60(%rsp), %rbx
movq %rbx, %rdi
leaq 0x18(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x376b
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x376b
leaq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x4c1c
movq %r14, %rdi
callq 0x2a78
movq %rbx, %rdi
callq 0x2a78
movq %r13, %rdi
callq 0x2a78
movl 0x14(%rsp), %eax
movl %eax, %ebp
jmp 0x3eb4
leaq 0x18(%rsp), %rsi
leaq 0x80(%rsp), %rdx
leaq 0x70(%rsp), %rcx
movq 0x90(%rsp), %rbx
movq %rbx, %rdi
callq 0x8c9e
leaq 0x18(%rsp), %rdi
callq 0x2a78
leaq 0x70(%rsp), %rdi
callq 0x2a78
leaq 0x50(%rsp), %rdi
callq 0x2a78
leaq 0x80(%rsp), %rdi
callq 0x2a78
leaq 0xa8(%rsp), %rdi
callq 0x1908
movq %rbx, %rax
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x446f
movq %rax, %rbx
jmp 0x4490
movq %rax, %rbx
jmp 0x449a
movq %rax, %rbx
jmp 0x44a4
jmp 0x439c
jmp 0x439c
movq %rax, %rbx
jmp 0x44b1
movq %rax, %rbx
jmp 0x440a
jmp 0x43f5
jmp 0x4453
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x1908
jmp 0x43d2
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
jmp 0x43da
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x1070
jmp 0x4460
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x1908
jmp 0x4456
jmp 0x43f5
movq %rax, %rbx
jmp 0x4460
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x1908
leaq 0x108(%rsp), %rdi
callq 0x1070
jmp 0x4456
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0x1070
jmp 0x4486
jmp 0x4453
movq %rax, %rbx
leaq 0xf8(%rsp), %rdi
jmp 0x445b
jmp 0x446f
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x2a78
jmp 0x4479
jmp 0x4476
jmp 0x446f
jmp 0x446f
jmp 0x446f
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x1908
leaq 0xe8(%rsp), %rdi
callq 0x1908
jmp 0x4486
movq %rax, %rbx
jmp 0x4486
jmp 0x4476
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x2a78
leaq 0x18(%rsp), %rdi
callq 0x2a78
leaq 0x70(%rsp), %rdi
callq 0x2a78
leaq 0x50(%rsp), %rdi
callq 0x2a78
leaq 0x80(%rsp), %rdi
callq 0x2a78
leaq 0xa8(%rsp), %rdi
callq 0x1908
movq %rbx, %rdi
callq 0x1180