// File: /workspace/github_cpp_makefile_star2_O3/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, 0xc8(%rsp)
movq %rdx, 0x50(%rsp)
movsd %xmm0, 0x38(%rsp)
movl 0x8(%rsi), %r14d
cmpl 0xc(%rsi), %r14d
jne 0x676a
movq %rsi, %rbp
movq %rdi, %rbx
leaq 0x78(%rsp), %rdi
callq 0x3bfa
movq %r14, (%rsp)
testl %r14d, %r14d
jle 0x62cd
leaq 0x78(%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 0x2f5c
movsd (%rax), %xmm0
ucomisd 0x2de5(%rip), %xmm0     # 0x9080
jne 0x629f
jnp 0x62c5
movq %r14, %rdi
movl %r15d, %esi
movl %r15d, %edx
callq 0x2f5c
movsd 0x2d63(%rip), %xmm0     # 0x9018
divsd (%rax), %xmm0
movq -0x8(%r12,%r15,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
incq %r15
cmpq %r15, %r13
jne 0x6281
leaq 0xb8(%rsp), %rdi
movq (%rsp), %r14
movl %r14d, %esi
movl %r14d, %edx
callq 0x2e94
movq %rbp, 0x60(%rsp)
leaq 0xa8(%rsp), %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2e94
testl %r14d, %r14d
jle 0x637f
movq 0xa8(%rsp), %r12
movq 0xb8(%rsp), %rbp
movq (%rsp), %rax
leaq 0x1(%rax), %r13
movl $0x1, %r14d
movl $0x1, %r15d
cmpq %r15, %r14
jbe 0x634a
movq 0x60(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2f5c
movsd (%rax), %xmm0
movq -0x8(%r12,%r14,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
cmpq %r15, %r14
jae 0x636f
movq 0x60(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x2f5c
movsd (%rax), %xmm0
movq -0x8(%rbp,%r14,8), %rax
movsd %xmm0, -0x8(%rax,%r15,8)
incq %r15
cmpq %r15, %r13
jne 0x6325
incq %r14
cmpq %r13, %r14
jne 0x631f
leaq 0x98(%rsp), %rdi
movq (%rsp), %r14
movl %r14d, %esi
callq 0x8ded
leaq 0xf8(%rsp), %rdi
leaq 0x78(%rsp), %rsi
leaq 0xa8(%rsp), %rdx
callq 0x37a8
leaq 0x68(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x3d0b
leaq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x3ace
leaq 0xe8(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x28(%rsp), %rdx
callq 0x3253
leaq 0x28(%rsp), %rdi
callq 0x2f1c
leaq 0x68(%rsp), %rdi
callq 0x2f1c
leaq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0x37a8
leaq 0x28(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x3d0b
movsd 0x2be6(%rip), %xmm0     # 0x9018
subsd 0x38(%rsp), %xmm0
leaq 0x88(%rsp), %rdx
movsd %xmm0, (%rdx)
leaq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x39f0
leaq 0x40(%rsp), %rdi
leaq 0x38(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0x3ace
leaq 0x18(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x3454
leaq 0x28(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x3574
leaq 0x18(%rsp), %rdi
callq 0x2f1c
leaq 0x40(%rsp), %rdi
callq 0x2f1c
leaq 0x8(%rsp), %rdi
callq 0x2f1c
leaq 0x8(%rsp), %rdi
leaq 0x78(%rsp), %rsi
movq 0x50(%rsp), %rdx
callq 0x3915
leaq 0x18(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x38(%rsp), %rdx
callq 0x864a
leaq 0x8(%rsp), %rdi
callq 0x827e
movq 0x50(%rsp), %rdi
movl $0x2, %esi
callq 0x8d68
movsd %xmm0, 0x58(%rsp)
leaq 0x18(%rsp), %rsi
movq %rbx, %rdi
callq 0x822a
leaq 0x8(%rsp), %rdi
movl %r14d, %esi
callq 0x81e8
leaq 0x40(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x822a
movsd 0x58(%rsp), %xmm0
mulsd 0x2b6a(%rip), %xmm0     # 0x9090
movsd %xmm0, 0x58(%rsp)
xorl %r12d, %r12d
testl %r14d, %r14d
cmovgl %r14d, %r12d
leaq 0x40(%rsp), %r14
leaq 0xd8(%rsp), %r15
leaq 0x88(%rsp), %rbp
leaq 0xe8(%rsp), %r13
movq %r14, %rdi
movl $0x2, %esi
callq 0x8d68
ucomisd 0x58(%rsp), %xmm0
jbe 0x66d8
movq 0xc8(%rsp), %rax
incl (%rax)
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
movq %rbx, %rdx
callq 0x3915
movq %rbp, %rdi
movq %r15, %rsi
leaq 0x18(%rsp), %rdx
callq 0x828b
leaq 0x8(%rsp), %rdi
movq %rbp, %rsi
callq 0x893a
movq %rbp, %rdi
callq 0x827e
movq %r15, %rdi
callq 0x827e
xorl %r14d, %r14d
xorl %ebp, %ebp
cmpl %r12d, %ebp
je 0x6683
incl %ebp
leaq 0x8(%rsp), %rdi
movl %ebp, %esi
callq 0x8abc
movsd (%rax), %xmm0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8e60
movl $0x1, %r15d
leal (%r14,%r15), %eax
cmpl $0x1, %eax
je 0x6649
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8abc
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
movq %r13, %rdi
movl %ebp, %esi
movl %r15d, %edx
callq 0x2f5c
movsd (%rax), %xmm0
movsd %xmm0, 0xd0(%rsp)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x8abc
movsd 0xd0(%rsp), %xmm1
mulsd (%rax), %xmm1
movsd (%rsp), %xmm0
subsd %xmm1, %xmm0
incl %r15d
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8e60
jmp 0x65e3
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8abc
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
movq %r13, %rdi
movl %ebp, %esi
movl %ebp, %edx
callq 0x2f5c
movsd (%rsp), %xmm0
divsd (%rax), %xmm0
decl %r14d
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8e60
jmp 0x65b8
leaq 0xd8(%rsp), %r15
movq %r15, %rdi
movq 0x60(%rsp), %rsi
movq %rbx, %rdx
callq 0x3915
leaq 0x88(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
movq 0x50(%rsp), %rdx
callq 0x8428
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movq %rbp, %rsi
callq 0x893a
movq %rbp, %rdi
callq 0x827e
movq %r15, %rdi
callq 0x827e
jmp 0x6553
leaq 0x40(%rsp), %rdi
callq 0x827e
leaq 0x8(%rsp), %rdi
callq 0x827e
leaq 0x18(%rsp), %rdi
callq 0x827e
leaq 0x28(%rsp), %rdi
callq 0x2f1c
leaq 0x68(%rsp), %rdi
callq 0x2f1c
leaq 0xe8(%rsp), %rdi
callq 0x2f1c
leaq 0xf8(%rsp), %rdi
callq 0x2f1c
leaq 0x98(%rsp), %rdi
callq 0x827e
leaq 0xa8(%rsp), %rdi
callq 0x2f1c
leaq 0xb8(%rsp), %rdi
callq 0x2f1c
leaq 0x78(%rsp), %rdi
callq 0x2f1c
movq %rbx, %rax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2ba9(%rip), %rdi      # 0x931a
leaq 0x29d9(%rip), %rsi      # 0x9151
leaq 0x2c5b(%rip), %rcx      # 0x93da
movl $0x2b6, %edx            # imm = 0x2B6
callq 0x20b0
movq %rax, %r14
jmp 0x6877
movq %rax, %r14
jmp 0x6881
movq %rax, %r14
leaq 0x8(%rsp), %rdi
jmp 0x688e
jmp 0x67d8
movq %rax, %r14
leaq 0x18(%rsp), %rdi
callq 0x2f1c
jmp 0x67ba
movq %rax, %r14
leaq 0x40(%rsp), %rdi
callq 0x2f1c
jmp 0x67c9
movq %rax, %r14
leaq 0x8(%rsp), %rdi
callq 0x2f1c
jmp 0x6893
movq %rax, %r14
jmp 0x6893
movq %rax, %r14
jmp 0x689d
movq %rax, %r14
jmp 0x68a7
movq %rax, %r14
leaq 0x28(%rsp), %rdi
callq 0x2f1c
jmp 0x6802
movq %rax, %r14
leaq 0x68(%rsp), %rdi
jmp 0x68af
movq %rax, %r14
jmp 0x68b4
movq %rax, %r14
jmp 0x68c1
jmp 0x6863
movq %rax, %r14
jmp 0x68db
jmp 0x685b
movq %rax, %r14
jmp 0x6889
jmp 0x6833
jmp 0x6845
jmp 0x686a
movq %rax, %r14
leaq 0x88(%rsp), %rdi
callq 0x827e
jmp 0x6848
movq %rax, %r14
leaq 0xd8(%rsp), %rdi
callq 0x827e
jmp 0x686d
jmp 0x686a
jmp 0x686a
movq %rax, %r14
jmp 0x68e8
movq %rax, %r14
jmp 0x68ce
jmp 0x686a
movq %rax, %r14
leaq 0x40(%rsp), %rdi
callq 0x827e
leaq 0x8(%rsp), %rdi
callq 0x827e
movq %rbx, %rdi
callq 0x827e
leaq 0x18(%rsp), %rdi
callq 0x827e
leaq 0x28(%rsp), %rdi
callq 0x2f1c
leaq 0x68(%rsp), %rdi
callq 0x2f1c
leaq 0xe8(%rsp), %rdi
callq 0x2f1c
leaq 0xf8(%rsp), %rdi
callq 0x2f1c
leaq 0x98(%rsp), %rdi
callq 0x827e
leaq 0xa8(%rsp), %rdi
callq 0x2f1c
leaq 0xb8(%rsp), %rdi
callq 0x2f1c
leaq 0x78(%rsp), %rdi
callq 0x2f1c
movq %r14, %rdi
callq 0x21f0