// File: 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:
subq $0x288, %rsp            # imm = 0x288
movq %rdi, 0xb0(%rsp)
movq %rdi, %rax
movq %rax, 0xb8(%rsp)
movq %rdi, 0x280(%rsp)
movq %rsi, 0x278(%rsp)
movq %rdx, 0x270(%rsp)
movsd %xmm0, 0x268(%rsp)
movq %rcx, 0x260(%rsp)
movq 0x278(%rsp), %rdi
callq 0x3ac0
movl %eax, 0xc4(%rsp)
movq 0x278(%rsp), %rdi
callq 0x3ad0
movl %eax, %ecx
movl 0xc4(%rsp), %eax
cmpl %ecx, %eax
jne 0x9543
jmp 0x9562
leaq 0x5dc8(%rip), %rdi      # 0xf312
leaq 0x5bf8(%rip), %rsi      # 0xf149
movl $0x2b6, %edx            # imm = 0x2B6
leaq 0x5e75(%rip), %rcx      # 0xf3d2
callq 0x2090
movq 0x278(%rsp), %rdi
callq 0x3ac0
movl %eax, 0x25c(%rsp)
movq 0x278(%rsp), %rsi
leaq 0x248(%rsp), %rdi
callq 0x4d20
movl $0x1, 0x244(%rsp)
movl 0x244(%rsp), %eax
cmpl 0x25c(%rsp), %eax
jg 0x9675
movl 0x244(%rsp), %edx
leaq 0x248(%rsp), %rdi
movl %edx, %esi
callq 0x36e0
movq %rax, 0xa8(%rsp)
jmp 0x95ca
movq 0xa8(%rsp), %rax
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x95e3
jp 0x95e3
jmp 0x965d
movl 0x244(%rsp), %edx
movl %edx, 0x98(%rsp)
movl %edx, %eax
movl %eax, 0x9c(%rsp)
leaq 0x248(%rsp), %rdi
movl %edx, %esi
callq 0x36e0
movq %rax, 0xa0(%rsp)
jmp 0x9613
movl 0x98(%rsp), %edx
movl 0x9c(%rsp), %esi
movq 0xa0(%rsp), %rax
movsd 0x59ff(%rip), %xmm0     # 0xf030
divsd (%rax), %xmm0
leaq 0x248(%rsp), %rdi
callq 0x47c0
jmp 0x965d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa105
jmp 0x965f
movl 0x244(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x244(%rsp)
jmp 0x9596
movl 0x25c(%rsp), %edx
leaq 0x220(%rsp), %rdi
movl %edx, %esi
callq 0x3560
jmp 0x968d
movl 0x25c(%rsp), %edx
leaq 0x210(%rsp), %rdi
movl %edx, %esi
callq 0x3560
jmp 0x96a5
movl $0x1, 0x20c(%rsp)
movl 0x20c(%rsp), %eax
cmpl 0x25c(%rsp), %eax
jg 0x9813
movl $0x1, 0x208(%rsp)
movl 0x208(%rsp), %eax
cmpl 0x25c(%rsp), %eax
jg 0x97fb
movl 0x20c(%rsp), %eax
cmpl 0x208(%rsp), %eax
jle 0x9785
movl 0x20c(%rsp), %esi
movl %esi, 0x88(%rsp)
movl 0x208(%rsp), %edx
movl %edx, 0x8c(%rsp)
movq 0x278(%rsp), %rdi
callq 0x36e0
movq %rax, 0x90(%rsp)
jmp 0x972a
movl 0x8c(%rsp), %edx
movl 0x88(%rsp), %esi
movq 0x90(%rsp), %rax
movsd (%rax), %xmm0
leaq 0x210(%rsp), %rdi
callq 0x47c0
jmp 0x9785
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0f8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0eb
movl 0x20c(%rsp), %eax
cmpl 0x208(%rsp), %eax
jge 0x97e3
movl 0x20c(%rsp), %esi
movl %esi, 0x78(%rsp)
movl 0x208(%rsp), %edx
movl %edx, 0x7c(%rsp)
movq 0x278(%rsp), %rdi
callq 0x36e0
movq %rax, 0x80(%rsp)
jmp 0x97c2
movl 0x7c(%rsp), %edx
movl 0x78(%rsp), %esi
movq 0x80(%rsp), %rax
movsd (%rax), %xmm0
leaq 0x220(%rsp), %rdi
callq 0x47c0
jmp 0x97e5
movl 0x208(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x208(%rsp)
jmp 0x96cf
jmp 0x97fd
movl 0x20c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20c(%rsp)
jmp 0x96b0
movl 0x25c(%rsp), %esi
leaq 0x1f8(%rsp), %rdi
callq 0xe3d0
jmp 0x9829
leaq 0x1e8(%rsp), %rdi
leaq 0x248(%rsp), %rsi
leaq 0x210(%rsp), %rdx
callq 0x45b0
jmp 0x9848
leaq 0x1c8(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x4f30
jmp 0x985f
leaq 0x1b8(%rsp), %rdi
leaq 0x268(%rsp), %rsi
leaq 0x1e8(%rsp), %rdx
callq 0x4b60
jmp 0x987e
leaq 0x1d8(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
leaq 0x1b8(%rsp), %rdx
callq 0x3c80
jmp 0x989d
leaq 0x1b8(%rsp), %rdi
callq 0x3660
leaq 0x1c8(%rsp), %rdi
callq 0x3660
leaq 0x1a8(%rsp), %rdi
leaq 0x248(%rsp), %rsi
leaq 0x220(%rsp), %rdx
callq 0x45b0
jmp 0x98d6
leaq 0x198(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x4f30
jmp 0x98ed
movsd 0x268(%rsp), %xmm1
movsd 0x5732(%rip), %xmm0     # 0xf030
subsd %xmm1, %xmm0
movsd %xmm0, 0x170(%rsp)
leaq 0x178(%rsp), %rdi
leaq 0x198(%rsp), %rsi
leaq 0x170(%rsp), %rdx
callq 0x4960
jmp 0x992a
leaq 0x160(%rsp), %rdi
leaq 0x268(%rsp), %rsi
leaq 0x1a8(%rsp), %rdx
callq 0x4b60
jmp 0x9949
leaq 0x188(%rsp), %rdi
leaq 0x178(%rsp), %rsi
leaq 0x160(%rsp), %rdx
callq 0x3ff0
jmp 0x9968
leaq 0x198(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x41e0
jmp 0x997f
leaq 0x188(%rsp), %rdi
callq 0x3660
leaq 0x160(%rsp), %rdi
callq 0x3660
leaq 0x178(%rsp), %rdi
callq 0x3660
movq 0x270(%rsp), %rdx
leaq 0x140(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x4800
jmp 0x99c5
leaq 0x150(%rsp), %rdi
leaq 0x140(%rsp), %rsi
leaq 0x268(%rsp), %rdx
callq 0xd860
jmp 0x99e4
leaq 0x140(%rsp), %rdi
callq 0xd170
movq 0x270(%rsp), %rdi
movl $0x2, %esi
callq 0xe320
movsd %xmm0, 0x70(%rsp)
jmp 0x9a0b
movq 0xb0(%rsp), %rdi
movsd 0x70(%rsp), %xmm0
movsd 0x566f(%rip), %xmm1     # 0xf090
mulsd %xmm1, %xmm0
movsd %xmm0, 0x138(%rsp)
movb $0x0, 0x137(%rsp)
leaq 0x150(%rsp), %rsi
callq 0xd0d0
jmp 0x9a45
movl 0x25c(%rsp), %esi
leaq 0x120(%rsp), %rdi
callq 0xd040
jmp 0x9a5b
leaq 0x110(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0xd0d0
jmp 0x9a72
jmp 0x9a74
leaq 0x110(%rsp), %rdi
movl $0x2, %esi
callq 0xe320
movsd %xmm0, 0x68(%rsp)
jmp 0x9a8e
movsd 0x68(%rsp), %xmm0
ucomisd 0x138(%rsp), %xmm0
jbe 0x9fb1
movq 0xb0(%rsp), %rdx
movq 0x260(%rsp), %rax
movl (%rax), %ecx
incl %ecx
movl %ecx, (%rax)
leaq 0xf0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x4800
jmp 0x9ad0
leaq 0x100(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
leaq 0x150(%rsp), %rdx
callq 0xd1a0
jmp 0x9aef
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0xdc70
jmp 0x9b06
leaq 0x100(%rsp), %rdi
callq 0xd170
leaq 0xf0(%rsp), %rdi
callq 0xd170
movl $0x0, 0xec(%rsp)
movl 0xec(%rsp), %eax
cmpl 0x25c(%rsp), %eax
jge 0x9ef7
movl 0xec(%rsp), %esi
incl %esi
movl %esi, 0x5c(%rsp)
leaq 0x120(%rsp), %rdi
callq 0xdee0
movq %rax, 0x60(%rsp)
jmp 0x9b60
movl 0x5c(%rsp), %esi
movq 0xb0(%rsp), %rdi
movq 0x60(%rsp), %rax
movsd (%rax), %xmm0
callq 0xe480
jmp 0x9b7c
movl $0x0, 0xe8(%rsp)
movl 0xe8(%rsp), %eax
cmpl 0xec(%rsp), %eax
jge 0x9e6a
movq 0xb0(%rsp), %rdi
movl 0xec(%rsp), %esi
incl %esi
movl %esi, 0x4c(%rsp)
callq 0xdee0
movq %rax, 0x50(%rsp)
jmp 0x9bbc
movq 0x50(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movl 0xec(%rsp), %esi
incl %esi
movl 0xe8(%rsp), %edx
incl %edx
leaq 0x1d8(%rsp), %rdi
callq 0x36e0
movq %rax, 0x40(%rsp)
jmp 0x9bf1
movq 0xb0(%rsp), %rdi
movq 0x40(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movl 0xe8(%rsp), %esi
incl %esi
callq 0xdee0
movq %rax, 0x30(%rsp)
jmp 0x9c1d
movl 0x4c(%rsp), %esi
movq 0xb0(%rsp), %rdi
movsd 0x38(%rsp), %xmm0
movsd 0x28(%rsp), %xmm1
movq 0x30(%rsp), %rax
movsd (%rax), %xmm2
mulsd %xmm2, %xmm1
subsd %xmm1, %xmm0
callq 0xe480
jmp 0x9c4d
jmp 0x9c4f
movl 0xe8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe8(%rsp)
jmp 0x9b87
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9cce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x1b8(%rsp), %rdi
callq 0x3660
leaq 0x1c8(%rsp), %rdi
callq 0x3660
jmp 0xa0d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0c4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa0aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9d85
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9d78
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x188(%rsp), %rdi
callq 0x3660
leaq 0x160(%rsp), %rdi
callq 0x3660
leaq 0x178(%rsp), %rdi
callq 0x3660
jmp 0xa0aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x140(%rsp), %rdi
callq 0xd170
jmp 0xa0aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa09d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0xa090
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9fec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9fdf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9e58
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0x100(%rsp), %rdi
callq 0xd170
leaq 0xf0(%rsp), %rdi
callq 0xd170
jmp 0x9fdf
movq 0xb0(%rsp), %rdi
movl 0xec(%rsp), %esi
incl %esi
movl %esi, 0x1c(%rsp)
callq 0xdee0
movq %rax, 0x20(%rsp)
jmp 0x9e8b
movq 0x20(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0xec(%rsp), %edx
incl %edx
leaq 0x1d8(%rsp), %rdi
movl %edx, %esi
callq 0x36e0
movq %rax, 0x10(%rsp)
jmp 0x9eb9
movl 0x1c(%rsp), %esi
movq 0xb0(%rsp), %rdi
movsd 0x8(%rsp), %xmm0
movq 0x10(%rsp), %rax
movsd (%rax), %xmm1
divsd %xmm1, %xmm0
callq 0xe480
jmp 0x9edf
jmp 0x9ee1
movl 0xec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xec(%rsp)
jmp 0x9b2b
movq 0xb0(%rsp), %rdx
movq 0x278(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x4800
jmp 0x9f16
movq 0x270(%rsp), %rdx
leaq 0xd8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xd470
jmp 0x9f35
leaq 0x110(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0xdc70
jmp 0x9f4c
leaq 0xd8(%rsp), %rdi
callq 0xd170
leaq 0xc8(%rsp), %rdi
callq 0xd170
jmp 0x9a74
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
jmp 0x9fa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x238(%rsp)
movl %eax, 0x234(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0xd170
leaq 0xc8(%rsp), %rdi
callq 0xd170
jmp 0x9fdf
movb $0x1, 0x137(%rsp)
leaq 0x110(%rsp), %rdi
callq 0xd170
leaq 0x120(%rsp), %rdi
callq 0xd170
testb $0x1, 0x137(%rsp)
jne 0xa00b
jmp 0x9ffe
leaq 0x110(%rsp), %rdi
callq 0xd170
leaq 0x120(%rsp), %rdi
callq 0xd170
jmp 0xa090
movq 0xb0(%rsp), %rdi
callq 0xd170
leaq 0x150(%rsp), %rdi
callq 0xd170
leaq 0x198(%rsp), %rdi
callq 0x3660
leaq 0x1a8(%rsp), %rdi
callq 0x3660
leaq 0x1d8(%rsp), %rdi
callq 0x3660
leaq 0x1e8(%rsp), %rdi
callq 0x3660
leaq 0x1f8(%rsp), %rdi
callq 0xd170
leaq 0x210(%rsp), %rdi
callq 0x3660
leaq 0x220(%rsp), %rdi
callq 0x3660
leaq 0x248(%rsp), %rdi
callq 0x3660
movq 0xb8(%rsp), %rax
addq $0x288, %rsp            # imm = 0x288
retq
movq 0xb0(%rsp), %rdi
callq 0xd170
leaq 0x150(%rsp), %rdi
callq 0xd170
leaq 0x198(%rsp), %rdi
callq 0x3660
leaq 0x1a8(%rsp), %rdi
callq 0x3660
leaq 0x1d8(%rsp), %rdi
callq 0x3660
leaq 0x1e8(%rsp), %rdi
callq 0x3660
leaq 0x1f8(%rsp), %rdi
callq 0xd170
leaq 0x210(%rsp), %rdi
callq 0x3660
leaq 0x220(%rsp), %rdi
callq 0x3660
leaq 0x248(%rsp), %rdi
callq 0x3660
movq 0x238(%rsp), %rdi
callq 0x21e0
nop