// File: /workspace/github_cpp_makefile_star2_O1/yukimasano[P]cpp_matrix/Matrix.cpp
// Function: SOR(Matrix&, Vector&, double, int&)
Vector SOR(Matrix& A, Vector& v, double w, int& count){
	assert(nrows(A) == ncols(A));
	int m =nrows(A);
	// we want a square system

	// INITIALISATION
	Matrix D=diag(A);
	for (int k=1; k<=m; k++){
		if (D(k,k)!= 0) {
		D.set_val(k,k, (1./D(k,k)));
		}
	}
	Matrix U(m,m);
	Matrix L(m,m);
	for (int i=1; i<=m; i++){
		for (int j=1; j<=m; j++){
			if (i>j) {
				L.set_val(i,j, A(i,j));
			}
			if (i<j) {
				U.set_val(i,j, A(i,j));
			}
		}
	}
	Vector temp = ones(m);
	Matrix Lbar= D*L;
	Matrix LL= (diag(temp) + w*Lbar);
	// T = (1+wLbar)**-1 ((1-w)11 - wU)
	// T = LL ((1-w)11 - wU)
	Matrix Ubar=D*U;
	Matrix M = diag(temp);
	M= M*(1.-w) -  w*Ubar;
	Vector c =  (D*v) *w;
	double tol = 1.e-14*v.norm();
	Vector x=c;
	Vector rh(m);
  Vector r = c;
	while (r.norm() >tol){
		count+=1;
		rh = M*x + c;
		//std::cout<<x<<std::endl<<std::flush;
		//forward solve
		for (int k=0; k<m; k++){
			x.set_val(k+1, rh(k+1));
			for(int j = 0; j<k; j++){
				x.set_val(k+1, x(k+1)-(LL(k+1,j+1))*x(j+1));
			}
			x.set_val(k+1, x(k+1)/LL(k+1,k+1));
		}
    r = (A*x -v);
	}
  //	std::cout<<count<<std::endl<<std::flush;
	return x;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rcx, 0xd0(%rsp)
movq %rdx, 0x58(%rsp)
movsd %xmm0, 0x40(%rsp)
movl 0x8(%rsi), %r14d
cmpl 0xc(%rsi), %r14d
jne 0x67b6
movq %rsi, %rbp
movq %rdi, %rbx
leaq 0x80(%rsp), %rdi
callq 0x3c26
movq %r14, (%rsp)
testl %r14d, %r14d
jle 0x6304
leaq 0x80(%rsp), %r14
movq (%r14), %r12
movq (%rsp), %rax
leaq 0x1(%rax), %r13
movl $0x1, %r15d
movq %r14, %rdi
movl %r15d, %esi
movl %r15d, %edx
callq 0x2f92
movsd (%rax), %xmm0
ucomisd 0x3dae(%rip), %xmm0     # 0xa080
jne 0x62d6
jnp 0x62fc
movq %r14, %rdi
movl %r15d, %esi
movl %r15d, %edx
callq 0x2f92
movsd 0x3d2c(%rip), %xmm0     # 0xa018
divsd (%rax), %xmm0
movq -0x8(%r12,%r15,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
incq %r15
cmpq %r15, %r13
jne 0x62b8
leaq 0xc0(%rsp), %rdi
movq (%rsp), %r14
movl %r14d, %esi
movl %r14d, %edx
callq 0x2eb8
movq %rbp, 0x68(%rsp)
leaq 0xb0(%rsp), %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2eb8
testl %r14d, %r14d
jle 0x63c3
movq 0xb0(%rsp), %r12
movq 0xc0(%rsp), %rbp
movq (%rsp), %rax
incq %rax
movq %rax, 0x18(%rsp)
movl %eax, %r13d
movl $0x1, %r14d
movl $0x1, %r15d
cmpq %r15, %r14
jbe 0x638c
movq 0x68(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2f92
movsd (%rax), %xmm0
movq -0x8(%r12,%r14,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
cmpq %r15, %r14
jae 0x63b1
movq 0x68(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2f92
movsd (%rax), %xmm0
movq -0x8(%rbp,%r14,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
incq %r15
cmpq %r15, %r13
jne 0x6367
incq %r14
cmpq 0x18(%rsp), %r14
jne 0x6361
leaq 0xa0(%rsp), %rdi
movq (%rsp), %r14
movl %r14d, %esi
callq 0x8e81
leaq 0xf8(%rsp), %rdi
leaq 0x80(%rsp), %rsi
leaq 0xb0(%rsp), %rdx
callq 0x37d8
leaq 0x70(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x3d37
leaq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x3afa
leaq 0xe8(%rsp), %rdi
leaq 0x70(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x327f
leaq 0x30(%rsp), %rdi
callq 0x2f4c
leaq 0x70(%rsp), %rdi
callq 0x2f4c
leaq 0x70(%rsp), %rdi
leaq 0x80(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
callq 0x37d8
leaq 0x30(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x3d37
movsd 0x3b9c(%rip), %xmm0     # 0xa018
subsd 0x40(%rsp), %xmm0
leaq 0x90(%rsp), %rdx
movsd %xmm0, (%rdx)
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x3a1c
leaq 0x48(%rsp), %rdi
leaq 0x40(%rsp), %rsi
leaq 0x70(%rsp), %rdx
callq 0x3afa
leaq 0x20(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x3480
leaq 0x30(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x35a0
leaq 0x20(%rsp), %rdi
callq 0x2f4c
leaq 0x48(%rsp), %rdi
callq 0x2f4c
leaq 0x8(%rsp), %rdi
callq 0x2f4c
leaq 0x8(%rsp), %rdi
leaq 0x80(%rsp), %rsi
movq 0x58(%rsp), %rdx
callq 0x3941
leaq 0x20(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x86f8
leaq 0x8(%rsp), %rdi
callq 0x8310
movq 0x58(%rsp), %rdi
movl $0x2, %esi
callq 0x8dfc
movsd %xmm0, 0x60(%rsp)
leaq 0x20(%rsp), %rsi
movq %rbx, %rdi
callq 0x82b8
leaq 0x8(%rsp), %rdi
movl %r14d, %esi
callq 0x8268
leaq 0x48(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x82b8
movsd 0x60(%rsp), %xmm0
mulsd 0x3b1d(%rip), %xmm0     # 0xa090
movsd %xmm0, 0x60(%rsp)
xorl %r12d, %r12d
testl %r14d, %r14d
cmovgl %r14d, %r12d
leaq 0x48(%rsp), %r14
leaq 0xd8(%rsp), %r15
leaq 0x90(%rsp), %rbp
leaq 0xe8(%rsp), %r13
movq %r14, %rdi
movl $0x2, %esi
callq 0x8dfc
ucomisd 0x60(%rsp), %xmm0
jbe 0x6721
movq 0xd0(%rsp), %rax
incl (%rax)
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
movq %rbx, %rdx
callq 0x3941
movq %rbp, %rdi
movq %r15, %rsi
leaq 0x20(%rsp), %rdx
callq 0x831d
leaq 0x8(%rsp), %rdi
movq %rbp, %rsi
callq 0x89dc
movq %rbp, %rdi
callq 0x8310
movq %r15, %rdi
callq 0x8310
xorl %r14d, %r14d
xorl %ebp, %ebp
cmpl %r12d, %ebp
je 0x66cc
incl %ebp
leaq 0x8(%rsp), %rdi
movl %ebp, %esi
callq 0x8b5a
movsd (%rax), %xmm0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8ef8
movl $0x1, %r15d
leal (%r14,%r15), %eax
cmpl $0x1, %eax
je 0x6690
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8b5a
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r13, %rdi
movl %ebp, %esi
movl %r15d, %edx
callq 0x2f92
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x8b5a
movsd (%rsp), %xmm1
mulsd (%rax), %xmm1
movsd 0x18(%rsp), %xmm0
subsd %xmm1, %xmm0
incl %r15d
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8ef8
jmp 0x6630
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8b5a
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r13, %rdi
movl %ebp, %esi
movl %ebp, %edx
callq 0x2f92
movsd 0x18(%rsp), %xmm0
divsd (%rax), %xmm0
decl %r14d
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8ef8
jmp 0x6605
leaq 0xd8(%rsp), %r15
movq %r15, %rdi
movq 0x68(%rsp), %rsi
movq %rbx, %rdx
callq 0x3941
leaq 0x90(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
movq 0x58(%rsp), %rdx
callq 0x84c8
leaq 0x48(%rsp), %r14
movq %r14, %rdi
movq %rbp, %rsi
callq 0x89dc
movq %rbp, %rdi
callq 0x8310
movq %r15, %rdi
callq 0x8310
jmp 0x65a0
leaq 0x48(%rsp), %rdi
callq 0x8310
leaq 0x8(%rsp), %rdi
callq 0x8310
leaq 0x20(%rsp), %rdi
callq 0x8310
leaq 0x30(%rsp), %rdi
callq 0x2f4c
leaq 0x70(%rsp), %rdi
callq 0x2f4c
leaq 0xe8(%rsp), %rdi
callq 0x2f4c
leaq 0xf8(%rsp), %rdi
callq 0x2f4c
leaq 0xa0(%rsp), %rdi
callq 0x8310
leaq 0xb0(%rsp), %rdi
callq 0x2f4c
leaq 0xc0(%rsp), %rdi
callq 0x2f4c
leaq 0x80(%rsp), %rdi
callq 0x2f4c
movq %rbx, %rax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3b5d(%rip), %rdi      # 0xa31a
leaq 0x398d(%rip), %rsi      # 0xa151
leaq 0x3c0f(%rip), %rcx      # 0xa3da
movl $0x2b6, %edx            # imm = 0x2B6
callq 0x20b0
movq %rax, %r14
jmp 0x68c3
movq %rax, %r14
jmp 0x68cd
movq %rax, %r14
leaq 0x8(%rsp), %rdi
jmp 0x68da
jmp 0x6824
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x2f4c
jmp 0x6806
movq %rax, %r14
leaq 0x48(%rsp), %rdi
callq 0x2f4c
jmp 0x6815
movq %rax, %r14
leaq 0x8(%rsp), %rdi
callq 0x2f4c
jmp 0x68df
movq %rax, %r14
jmp 0x68df
movq %rax, %r14
jmp 0x68e9
movq %rax, %r14
jmp 0x68f3
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x2f4c
jmp 0x684e
movq %rax, %r14
leaq 0x70(%rsp), %rdi
jmp 0x68fb
movq %rax, %r14
jmp 0x6900
movq %rax, %r14
jmp 0x690d
jmp 0x68af
movq %rax, %r14
jmp 0x6927
jmp 0x68a7
movq %rax, %r14
jmp 0x68d5
jmp 0x687f
jmp 0x6891
jmp 0x68b6
movq %rax, %r14
leaq 0x90(%rsp), %rdi
callq 0x8310
jmp 0x6894
movq %rax, %r14
leaq 0xd8(%rsp), %rdi
callq 0x8310
jmp 0x68b9
jmp 0x68b6
jmp 0x68b6
movq %rax, %r14
jmp 0x6934
movq %rax, %r14
jmp 0x691a
jmp 0x68b6
movq %rax, %r14
leaq 0x48(%rsp), %rdi
callq 0x8310
leaq 0x8(%rsp), %rdi
callq 0x8310
movq %rbx, %rdi
callq 0x8310
leaq 0x20(%rsp), %rdi
callq 0x8310
leaq 0x30(%rsp), %rdi
callq 0x2f4c
leaq 0x70(%rsp), %rdi
callq 0x2f4c
leaq 0xe8(%rsp), %rdi
callq 0x2f4c
leaq 0xf8(%rsp), %rdi
callq 0x2f4c
leaq 0xa0(%rsp), %rdi
callq 0x8310
leaq 0xb0(%rsp), %rdi
callq 0x2f4c
leaq 0xc0(%rsp), %rdi
callq 0x2f4c
leaq 0x80(%rsp), %rdi
callq 0x2f4c
movq %r14, %rdi
callq 0x21f0