// File: /workspace/github_cpp_makefile_star2_O2/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 $0x118, %rsp            # imm = 0x118
movq %rcx, 0xe0(%rsp)
movq %rdx, 0x60(%rsp)
movsd %xmm0, 0x48(%rsp)
movl 0x8(%rsi), %r15d
cmpl 0xc(%rsi), %r15d
jne 0x661b
movq %rsi, %rbp
movq %rdi, %rbx
leaq 0x90(%rsp), %r14
movq %r14, %rdi
callq 0x39fa
xorl %r12d, %r12d
testl %r15d, %r15d
movl $0x0, %eax
movq %r15, 0x20(%rsp)
cmovgl %r15d, %eax
movq (%r14), %r13
movq %rax, 0x88(%rsp)
incl %eax
movq %rax, 0x8(%rsp)
cmpq %r12, 0x88(%rsp)
je 0x6176
leaq 0x1(%r12), %r15
movq %r14, %rdi
movl %r15d, %esi
movl %r15d, %edx
callq 0x2e20
movsd (%rax), %xmm0
ucomisd 0x2f38(%rip), %xmm0     # 0x9080
jne 0x614c
jnp 0x6171
movq %r14, %rdi
movl %r15d, %esi
movl %r15d, %edx
callq 0x2e20
movsd 0x2eb6(%rip), %xmm0     # 0x9018
divsd (%rax), %xmm0
movq (%r13,%r12,8), %rax
movsd %xmm0, (%rax,%r12,8)
movq %r15, %r12
jmp 0x611f
leaq 0xd0(%rsp), %rdi
movq 0x20(%rsp), %r14
movl %r14d, %esi
movl %r14d, %edx
callq 0x2d58
movq %rbp, 0x70(%rsp)
leaq 0xc0(%rsp), %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2d58
movq 0xc0(%rsp), %rbp
movq 0xd0(%rsp), %r13
leal 0x1(%r14), %r12d
pushq $0x1
popq %r14
cmpq 0x8(%rsp), %r14
je 0x6222
pushq $0x1
popq %r15
cmpq %r15, %r12
je 0x621d
cmpq %r15, %r14
jbe 0x61f3
movq 0x70(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2e20
movsd (%rax), %xmm0
movq -0x8(%rbp,%r14,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
cmpq %r15, %r14
jae 0x6218
movq 0x70(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2e20
movsd (%rax), %xmm0
movq -0x8(%r13,%r14,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
incq %r15
jmp 0x61c9
incq %r14
jmp 0x61be
leaq 0xb0(%rsp), %rdi
movq 0x20(%rsp), %r14
movl %r14d, %esi
callq 0x8995
leaq 0x108(%rsp), %rdi
leaq 0x90(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
callq 0x35d4
leaq 0x78(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x3b09
leaq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x38f1
leaq 0xf8(%rsp), %rdi
leaq 0x78(%rsp), %rsi
leaq 0x38(%rsp), %rdx
callq 0x30c0
leaq 0x38(%rsp), %rdi
callq 0x2dea
leaq 0x78(%rsp), %rdi
callq 0x2dea
leaq 0x78(%rsp), %rdi
leaq 0x90(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
callq 0x35d4
leaq 0x38(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x3b09
movsd 0x2d3c(%rip), %xmm0     # 0x9018
subsd 0x48(%rsp), %xmm0
leaq 0xa0(%rsp), %rdx
movsd %xmm0, (%rdx)
leaq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x380b
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rsi
leaq 0x78(%rsp), %rdx
callq 0x38f1
leaq 0x28(%rsp), %rdi
leaq 0x10(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x32b3
leaq 0x38(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x33ce
leaq 0x28(%rsp), %rdi
callq 0x2dea
leaq 0x50(%rsp), %rdi
callq 0x2dea
leaq 0x10(%rsp), %rdi
callq 0x2dea
leaq 0x10(%rsp), %rdi
leaq 0x90(%rsp), %rsi
movq 0x60(%rsp), %rdx
callq 0x372f
leaq 0x28(%rsp), %rdi
leaq 0x10(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x83d5
leaq 0x10(%rsp), %rdi
callq 0x8104
pushq $0x2
popq %rsi
movq 0x60(%rsp), %rdi
callq 0x891a
movsd %xmm0, 0x68(%rsp)
leaq 0x28(%rsp), %rsi
movq %rbx, %rdi
callq 0x80b8
leaq 0x10(%rsp), %rdi
movl %r14d, %esi
callq 0x8068
leaq 0x50(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x80b8
movsd 0x68(%rsp), %xmm0
mulsd 0x2cbf(%rip), %xmm0     # 0x9090
movsd %xmm0, 0x68(%rsp)
leaq 0x50(%rsp), %r14
leaq 0xe8(%rsp), %r15
leaq 0xa0(%rsp), %r12
leaq 0x10(%rsp), %rbp
leaq 0xf8(%rsp), %r13
movq %r14, %rdi
pushq $0x2
popq %rsi
callq 0x891a
ucomisd 0x68(%rsp), %xmm0
jbe 0x6586
movq 0xe0(%rsp), %rax
incl (%rax)
movq %r15, %rdi
leaq 0x38(%rsp), %rsi
movq %rbx, %rdx
callq 0x372f
movq %r12, %rdi
movq %r15, %rsi
leaq 0x28(%rsp), %rdx
callq 0x8111
movq %rbp, %rdi
movq %r12, %rsi
callq 0x859c
movq %r12, %rdi
callq 0x8104
movq %r15, %rdi
callq 0x8104
xorl %r12d, %r12d
xorl %r14d, %r14d
cmpl 0x88(%rsp), %r14d
je 0x6531
incl %r14d
movq %rbp, %rdi
movl %r14d, %esi
callq 0x86de
movsd (%rax), %xmm0
movq %rbx, %rdi
movl %r14d, %esi
callq 0x89d4
pushq $0x1
popq %rax
movl %eax, %r15d
leal (%r12,%r15), %eax
cmpl $0x1, %eax
je 0x64f1
movq %rbx, %rdi
movl %r14d, %esi
callq 0x86de
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %r13, %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2e20
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x86de
movsd 0x20(%rsp), %xmm1
mulsd (%rax), %xmm1
movsd 0x8(%rsp), %xmm0
subsd %xmm1, %xmm0
incl %r15d
movq %rbx, %rdi
movl %r14d, %esi
callq 0x89d4
jmp 0x648c
movq %rbx, %rdi
movl %r14d, %esi
callq 0x86de
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %r13, %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2e20
movsd 0x8(%rsp), %xmm0
divsd (%rax), %xmm0
decl %r12d
movq %rbx, %rdi
movl %r14d, %esi
callq 0x89d4
jmp 0x645b
leaq 0xe8(%rsp), %r15
movq %r15, %rdi
movq 0x70(%rsp), %rsi
movq %rbx, %rdx
callq 0x372f
leaq 0xa0(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
movq 0x60(%rsp), %rdx
callq 0x8238
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq %r12, %rsi
callq 0x859c
movq %r12, %rdi
callq 0x8104
movq %r15, %rdi
callq 0x8104
jmp 0x63f9
leaq 0x50(%rsp), %rdi
callq 0x8104
leaq 0x10(%rsp), %rdi
callq 0x8104
leaq 0x28(%rsp), %rdi
callq 0x8104
leaq 0x38(%rsp), %rdi
callq 0x2dea
leaq 0x78(%rsp), %rdi
callq 0x2dea
leaq 0xf8(%rsp), %rdi
callq 0x2dea
leaq 0x108(%rsp), %rdi
callq 0x2dea
leaq 0xb0(%rsp), %rdi
callq 0x8104
leaq 0xc0(%rsp), %rdi
callq 0x2dea
leaq 0xd0(%rsp), %rdi
callq 0x2dea
leaq 0x90(%rsp), %rdi
callq 0x2dea
movq %rbx, %rax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2cf8(%rip), %rdi      # 0x931a
leaq 0x2b28(%rip), %rsi      # 0x9151
leaq 0x2daa(%rip), %rcx      # 0x93da
movl $0x2b6, %edx            # imm = 0x2B6
callq 0x20b0
movq %rax, %r14
jmp 0x6728
movq %rax, %r14
jmp 0x6732
movq %rax, %r14
leaq 0x10(%rsp), %rdi
jmp 0x673f
jmp 0x6689
movq %rax, %r14
leaq 0x28(%rsp), %rdi
callq 0x2dea
jmp 0x666b
movq %rax, %r14
leaq 0x50(%rsp), %rdi
callq 0x2dea
jmp 0x667a
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x2dea
jmp 0x6744
movq %rax, %r14
jmp 0x6744
movq %rax, %r14
jmp 0x674e
movq %rax, %r14
jmp 0x6758
movq %rax, %r14
leaq 0x38(%rsp), %rdi
callq 0x2dea
jmp 0x66b3
movq %rax, %r14
leaq 0x78(%rsp), %rdi
jmp 0x6760
movq %rax, %r14
jmp 0x6765
movq %rax, %r14
jmp 0x6772
jmp 0x6714
movq %rax, %r14
jmp 0x678c
jmp 0x670c
movq %rax, %r14
jmp 0x673a
jmp 0x66e4
jmp 0x66f6
jmp 0x671b
movq %rax, %r14
leaq 0xa0(%rsp), %rdi
callq 0x8104
jmp 0x66f9
movq %rax, %r14
leaq 0xe8(%rsp), %rdi
callq 0x8104
jmp 0x671e
jmp 0x671b
jmp 0x671b
movq %rax, %r14
jmp 0x6799
movq %rax, %r14
jmp 0x677f
jmp 0x671b
movq %rax, %r14
leaq 0x50(%rsp), %rdi
callq 0x8104
leaq 0x10(%rsp), %rdi
callq 0x8104
movq %rbx, %rdi
callq 0x8104
leaq 0x28(%rsp), %rdi
callq 0x8104
leaq 0x38(%rsp), %rdi
callq 0x2dea
leaq 0x78(%rsp), %rdi
callq 0x2dea
leaq 0xf8(%rsp), %rdi
callq 0x2dea
leaq 0x108(%rsp), %rdi
callq 0x2dea
leaq 0xb0(%rsp), %rdi
callq 0x8104
leaq 0xc0(%rsp), %rdi
callq 0x2dea
leaq 0xd0(%rsp), %rdi
callq 0x2dea
leaq 0x90(%rsp), %rdi
callq 0x2dea
movq %r14, %rdi
callq 0x21d0