// File: /workspace/github_cpp_makefile_star2_O2/toxaart[P]hierarchical_block_sparse_lib/source/HierarchicalBlockSparseMatrix.h
// Function: hbsm::HierarchicalBlockSparseMatrix<double>::assign_from_vectors_general(std::vector<int, std::allocator<int>> const&, std::vector<int, std::allocator<int>> const&, std::vector<double, std::allocator<double>> const&, bool, bool)
void HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors_general(const std::vector<int> & rows,
				     const std::vector<int> & cols,
				     const std::vector<Treal> & values,
				     bool useMax,
					 bool boundaries_checked) {


			assert(blocksize > 0);
			if(rows.size() != values.size() || cols.size() != values.size())
				throw std::runtime_error("Error in HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors: bad sizes.");

			if(rows.size() == 0) return;

			// this will be done only at the top level, later it is not necessary
			if(!boundaries_checked){
				for(int i = 0; i < values.size(); ++i){
					if( rows[i] < 0 ||  rows[i] > nRows_orig-1 || cols[i] < 0 || cols[i] > nCols_orig - 1)
						throw std::runtime_error("Error in HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors: index outside matrix boundaries.");

				}
			}

			if(lowest_level()){

        int max_row_num = nRows;
        if(on_bottom_boundary()) max_row_num = get_n_rows() % blocksize;

        int max_col_num = nCols;
        if(on_right_boundary()) max_col_num = get_n_cols() % blocksize;

        if(get_first_row_position() >= get_n_rows() || get_first_col_position() >= get_n_cols()){ // block to skip
            return;
        }


				for(size_t i = 0; i < values.size(); ++i){

          int row = rows[i];
					int col = cols[i];

          if(row >= max_row_num || col >= max_col_num){
						continue;
					}

					Treal val = values[i];

          if(useMax){
              submatrix[col * nRows + row] = (val > submatrix[col * nRows + row]) ? val : submatrix[col * nRows + row];
          }
          else{
              submatrix[col * nRows + row] += val; // Note: we use += here, so if an element appears several times, the result becomes the sum of those contributions.
          }

				}





				return;
			}

			// now we have to split arrays into 4 parts and recursively apply the same procedure on children
			std::vector<int> rows0, cols0, rows1, cols1, rows2, cols2, rows3, cols3;
            std::vector<Treal> vals0,vals1,vals2,vals3;

			int n_elements = rows.size();

            rows0.reserve(n_elements);
            cols0.reserve(n_elements);
            vals0.reserve(n_elements);

            rows1.reserve(n_elements);
            cols1.reserve(n_elements);
            vals1.reserve(n_elements);

            rows2.reserve(n_elements);
            cols2.reserve(n_elements);
            vals2.reserve(n_elements);

            rows3.reserve(n_elements);
            cols3.reserve(n_elements);
            vals3.reserve(n_elements);

			// the offset, when providing parts of vectors to the next level their "coordinates" will be shifted
			int offset = nRows/2;

			for(size_t i = 0; i < n_elements; ++i){

				int row = rows[i];
				int col = cols[i];
				Treal val = values[i];

				// this part goes to child0
				if(row < offset && col < offset){
					rows0.push_back(row);
					cols0.push_back(col);
					vals0.push_back(val);
				}

				// this part goes to child1
				if(offset <= row && row < nRows && col < offset){
					rows1.push_back(row-offset);
					cols1.push_back(col);
					vals1.push_back(val);
				}

				// this part goes to child2
				if(row < offset && offset <= col && col < nCols){
					rows2.push_back(row);
					cols2.push_back(col-offset);
					vals2.push_back(val);
				}

				// this part goes to child3
				if(offset <= row && row < nRows && offset <= col && col < nCols){
					rows3.push_back(row-offset);
					cols3.push_back(col-offset);
					vals3.push_back(val);
				}

			}

			if(vals0.size() > 0){
				if(children[0] != NULL){
					throw std::runtime_error("Error in HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors: non-null child0 matrix occured.");
				}
				children[0] = std::make_shared<HierarchicalBlockSparseMatrix<Treal> >();
		    children[0]->set_params(get_params());
				children[0]->resize(nRows / 2, nCols / 2);
				children[0]->parent = this;
                children[0]->assign_from_vectors_general(rows0, cols0, vals0, useMax,true);
			}

			if(vals1.size() > 0){
				if(children[1] != NULL){
					throw std::runtime_error("Error in HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors: non-null child1 matrix occured.");
				}
				children[1] = std::make_shared<HierarchicalBlockSparseMatrix<Treal> >();
		    children[1]->set_params(get_params());
				children[1]->resize(nRows / 2, nCols / 2);
				children[1]->parent = this;
                children[1]->assign_from_vectors_general(rows1, cols1, vals1, useMax,true);
			}

			if(vals2.size() > 0){
				if(children[2] != NULL){
					throw std::runtime_error("Error in HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors: non-null child2 matrix occured.");
				}
				children[2] = std::make_shared<HierarchicalBlockSparseMatrix<Treal> >();
		    children[2]->set_params(get_params());
				children[2]->resize(nRows / 2, nCols / 2);
				children[2]->parent = this;
                children[2]->assign_from_vectors_general(rows2, cols2, vals2, useMax,true);
			}

			if(vals3.size() > 0){
				if(children[3] != NULL){
					throw std::runtime_error("Error in HierarchicalBlockSparseMatrix<Treal>::assign_from_vectors: non-null child3 matrix occured.");
				}
				children[3] = std::make_shared<HierarchicalBlockSparseMatrix<Treal> >();
		    children[3]->set_params(get_params());
				children[3]->resize(nRows / 2, nCols / 2);
				children[3]->parent = this;
                children[3]->assign_from_vectors_general(rows3, cols3, vals3, useMax,true);
			}
		}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rdx, 0x20(%rsp)
cmpl $0x0, 0x10(%rdi)
jle 0x64a9
movq %rsi, %r13
movq %rdi, %rbx
movq (%rsi), %rax
movq 0x8(%rsi), %rsi
movq %rsi, %rdi
subq %rax, %rdi
movq %rdi, %r10
sarq $0x2, %r10
movq 0x8(%rcx), %rdx
movq %rcx, 0xa8(%rsp)
subq (%rcx), %rdx
sarq $0x3, %rdx
cmpq %rdx, %r10
jne 0x648a
movl %r8d, %r15d
movq 0x20(%rsp), %r8
movq (%r8), %rdx
movq 0x8(%r8), %r8
subq %rdx, %r8
cmpq %rdi, %r8
jne 0x648a
cmpq %rax, %rsi
je 0x6478
testb %r9b, %r9b
je 0x5dc0
movq %rbx, %rdi
callq 0x5a0a
testb %al, %al
je 0x5e21
movl (%rbx), %ebp
movq %rbx, %rdi
callq 0x662c
testb %al, %al
je 0x5cf3
movq %rbx, %rdi
callq 0x3a98
cltd
idivl 0x10(%rbx)
movl %edx, %ebp
movl 0x4(%rbx), %r14d
movq %rbx, %rdi
callq 0x666a
testb %al, %al
je 0x5d12
movq %rbx, %rdi
callq 0x3ab4
cltd
idivl 0x10(%rbx)
movl %edx, %r14d
movq %rbx, %rdi
callq 0x66aa
movl %eax, %r12d
movq %rbx, %rdi
callq 0x3a98
cmpl %eax, %r12d
jge 0x6478
movq %rbx, %rdi
callq 0x671c
movl %eax, %r12d
movq %rbx, %rdi
callq 0x3ab4
cmpl %eax, %r12d
jge 0x6478
movq 0xa8(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
movq (%r13), %rdx
movq 0x20(%rsp), %rsi
movq (%rsi), %rsi
movl (%rbx), %edi
movq 0x70(%rbx), %r8
xorl %r9d, %r9d
cmpq %r9, %rcx
je 0x6478
movl (%rdx,%r9,4), %r10d
cmpl %ebp, %r10d
jge 0x5dbb
movl (%rsi,%r9,4), %r11d
cmpl %r14d, %r11d
jge 0x5dbb
movsd (%rax,%r9,8), %xmm0
imull %edi, %r11d
addl %r10d, %r11d
movslq %r11d, %r10
movsd (%r8,%r10,8), %xmm1
testb %r15b, %r15b
je 0x5db1
maxsd %xmm1, %xmm0
jmp 0x5db5
addsd %xmm1, %xmm0
movsd %xmm0, (%r8,%r10,8)
incq %r9
jmp 0x5d75
movl 0x8(%rbx), %esi
movl 0xc(%rbx), %edi
xorl %r8d, %r8d
cmpq %r8, %r10
je 0x5cc7
movl (%rax,%r8,4), %r9d
testl %r9d, %r9d
js 0x5df1
cmpl %esi, %r9d
jge 0x5df1
movl (%rdx,%r8,4), %r9d
testl %r9d, %r9d
js 0x5df1
incq %r8
cmpl %edi, %r9d
jl 0x5dc9
pushq $0x10
popq %rdi
callq 0x20a0
movq %rax, %r14
leaq 0x2a5f(%rip), %rsi      # 0x8862
movq %rax, %rdi
callq 0x2050
movq 0x71de(%rip), %rsi      # 0xcff0
movq 0x71a7(%rip), %rdx      # 0xcfc0
movq %r14, %rdi
callq 0x21d0
movl %r15d, 0x2c(%rsp)
xorpd %xmm0, %xmm0
leaq 0x1a0(%rsp), %rdi
movapd %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
movapd %xmm0, 0x170(%rsp)
andq $0x0, 0x180(%rsp)
movapd %xmm0, 0x150(%rsp)
andq $0x0, 0x160(%rsp)
movapd %xmm0, 0x130(%rsp)
andq $0x0, 0x140(%rsp)
movapd %xmm0, 0x110(%rsp)
andq $0x0, 0x120(%rsp)
movapd %xmm0, 0xf0(%rsp)
andq $0x0, 0x100(%rsp)
movapd %xmm0, 0xd0(%rsp)
andq $0x0, 0xe0(%rsp)
movapd %xmm0, 0xb0(%rsp)
andq $0x0, 0xc0(%rsp)
movapd %xmm0, 0x90(%rsp)
andq $0x0, 0xa0(%rsp)
movapd %xmm0, 0x70(%rsp)
andq $0x0, 0x80(%rsp)
movapd %xmm0, 0x50(%rsp)
andq $0x0, 0x60(%rsp)
movapd %xmm0, 0x30(%rsp)
andq $0x0, 0x40(%rsp)
movq 0x8(%r13), %rax
movq %r13, 0x190(%rsp)
subq (%r13), %rax
shrq $0x2, %rax
movslq %eax, %r14
movq %r14, %rsi
callq 0x6790
leaq 0x170(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0x90(%rsp), %rdi
movq %r14, %rsi
callq 0x6826
leaq 0x150(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0x130(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0x70(%rsp), %rdi
movq %r14, %rsi
callq 0x6826
leaq 0x110(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0xf0(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0x50(%rsp), %rdi
movq %r14, %rsi
callq 0x6826
leaq 0xd0(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0xb0(%rsp), %rdi
movq %r14, %rsi
callq 0x6790
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
callq 0x6826
movq %r14, 0x198(%rsp)
movl (%rbx), %eax
pushq $0x2
popq %rcx
cltd
idivl %ecx
movl %eax, %ebp
xorl %r15d, %r15d
leaq 0x10(%rsp), %r14
leaq 0x130(%rsp), %r13
cmpq %r15, 0x198(%rsp)
je 0x6163
movq 0x190(%rsp), %rax
movq (%rax), %rax
movl (%rax,%r15,4), %eax
movl %eax, 0xc(%rsp)
movq 0x20(%rsp), %rcx
movq (%rcx), %rcx
movl (%rcx,%r15,4), %ecx
movl %ecx, 0x4(%rsp)
movq 0xa8(%rsp), %rdx
movq (%rdx), %rdx
movsd (%rdx,%r15,8), %xmm0
movsd %xmm0, 0x10(%rsp)
cmpl %ebp, %eax
setl %dl
cmpl %ebp, %ecx
setl %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x6072
leaq 0x1a0(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0x52ae
leaq 0x170(%rsp), %rdi
leaq 0x4(%rsp), %rsi
callq 0x52ae
leaq 0x90(%rsp), %rdi
movq %r14, %rsi
callq 0x68bc
movl 0xc(%rsp), %eax
movl 0x4(%rsp), %ecx
movl %eax, %edx
subl %ebp, %edx
jl 0x60b4
cmpl (%rbx), %eax
jge 0x60b4
cmpl %ebp, %ecx
jge 0x60b4
movl %edx, 0x8(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x71b4
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
callq 0x52ae
leaq 0x70(%rsp), %rdi
movq %r14, %rsi
callq 0x68bc
movl 0xc(%rsp), %eax
cmpl %ebp, %eax
jge 0x6104
movl 0x4(%rsp), %ecx
cmpl %ecx, %ebp
jg 0x6104
cmpl 0x4(%rbx), %ecx
jge 0x6104
leaq 0x110(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0x52ae
movl 0x4(%rsp), %eax
subl %ebp, %eax
movl %eax, 0x8(%rsp)
leaq 0xf0(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x71b4
leaq 0x50(%rsp), %rdi
movq %r14, %rsi
callq 0x68bc
movl 0xc(%rsp), %eax
movl %eax, %ecx
subl %ebp, %ecx
jl 0x615b
cmpl (%rbx), %eax
jge 0x615b
movl 0x4(%rsp), %eax
cmpl %eax, %ebp
jg 0x615b
cmpl 0x4(%rbx), %eax
jge 0x615b
movl %ecx, 0x8(%rsp)
leaq 0xd0(%rsp), %rdi
leaq 0x8(%rsp), %r12
movq %r12, %rsi
callq 0x71b4
movl 0x4(%rsp), %eax
subl %ebp, %eax
movl %eax, 0x8(%rsp)
leaq 0xb0(%rsp), %rdi
movq %r12, %rsi
callq 0x71b4
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
callq 0x68bc
incq %r15
jmp 0x5fda
movq 0x98(%rsp), %rax
movzbl 0x2c(%rsp), %ebp
cmpq 0x90(%rsp), %rax
pushq $0x2
popq %r15
je 0x6211
cmpq $0x0, 0x28(%rbx)
jne 0x64c8
leaq 0x10(%rsp), %rdi
callq 0x68de
leaq 0x28(%rbx), %rdi
leaq 0x10(%rsp), %rsi
callq 0x5a26
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x5a54
movq 0x28(%rbx), %rdi
movl 0x10(%rbx), %eax
movl %eax, -0x8(%r14)
leaq 0x10(%rsp), %rsi
callq 0x3958
movq 0x28(%rbx), %rdi
movl (%rbx), %eax
movl 0x4(%rbx), %ecx
cltd
idivl %r15d
movl %eax, %esi
movl %ecx, %eax
cltd
idivl %r15d
movl %eax, %edx
xorl %ecx, %ecx
callq 0x39e4
movq 0x28(%rbx), %rdi
movq %rbx, 0x68(%rdi)
leaq 0x1a0(%rsp), %rsi
leaq 0x170(%rsp), %rdx
leaq 0x90(%rsp), %rcx
pushq $0x1
popq %r9
movl %ebp, %r8d
callq 0x5c44
movq 0x78(%rsp), %rax
cmpq 0x70(%rsp), %rax
je 0x62ad
cmpq $0x0, 0x38(%rbx)
jne 0x64e4
leaq 0x10(%rsp), %rdi
callq 0x68de
leaq 0x38(%rbx), %rdi
leaq 0x10(%rsp), %rsi
callq 0x5a26
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x5a54
movq 0x38(%rbx), %rdi
movl 0x10(%rbx), %eax
movl %eax, -0x8(%r14)
leaq 0x10(%rsp), %rsi
callq 0x3958
movq 0x38(%rbx), %rdi
movl (%rbx), %eax
movl 0x4(%rbx), %ecx
cltd
idivl %r15d
movl %eax, %esi
movl %ecx, %eax
cltd
idivl %r15d
movl %eax, %edx
xorl %ecx, %ecx
callq 0x39e4
movq 0x38(%rbx), %rdi
movq %rbx, 0x68(%rdi)
leaq 0x150(%rsp), %rsi
leaq 0x130(%rsp), %rdx
leaq 0x70(%rsp), %rcx
pushq $0x1
popq %r9
movl %ebp, %r8d
callq 0x5c44
movq 0x58(%rsp), %rax
cmpq 0x50(%rsp), %rax
je 0x6349
cmpq $0x0, 0x48(%rbx)
jne 0x6500
leaq 0x10(%rsp), %rdi
callq 0x68de
leaq 0x48(%rbx), %rdi
leaq 0x10(%rsp), %rsi
callq 0x5a26
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x5a54
movq 0x48(%rbx), %rdi
movl 0x10(%rbx), %eax
movl %eax, -0x8(%r14)
leaq 0x10(%rsp), %rsi
callq 0x3958
movq 0x48(%rbx), %rdi
movl (%rbx), %eax
movl 0x4(%rbx), %ecx
cltd
idivl %r15d
movl %eax, %esi
movl %ecx, %eax
cltd
idivl %r15d
movl %eax, %edx
xorl %ecx, %ecx
callq 0x39e4
movq 0x48(%rbx), %rdi
movq %rbx, 0x68(%rdi)
leaq 0x110(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
leaq 0x50(%rsp), %rcx
pushq $0x1
popq %r9
movl %ebp, %r8d
callq 0x5c44
movq 0x38(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x63e5
cmpq $0x0, 0x58(%rbx)
jne 0x651c
leaq 0x10(%rsp), %rdi
callq 0x68de
leaq 0x58(%rbx), %rdi
leaq 0x10(%rsp), %rsi
callq 0x5a26
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x5a54
movq 0x58(%rbx), %rdi
movl 0x10(%rbx), %eax
movl %eax, -0x8(%r14)
leaq 0x10(%rsp), %rsi
callq 0x3958
movq 0x58(%rbx), %rdi
movl (%rbx), %eax
movl 0x4(%rbx), %ecx
cltd
idivl %r15d
movl %eax, %esi
movl %ecx, %eax
cltd
idivl %r15d
movl %eax, %edx
xorl %ecx, %ecx
callq 0x39e4
movq 0x58(%rbx), %rdi
movq %rbx, 0x68(%rdi)
leaq 0xd0(%rsp), %rsi
leaq 0xb0(%rsp), %rdx
leaq 0x30(%rsp), %rcx
pushq $0x1
popq %r9
movl %ebp, %r8d
callq 0x5c44
leaq 0x30(%rsp), %rdi
callq 0x5c00
leaq 0x50(%rsp), %rdi
callq 0x5c00
leaq 0x70(%rsp), %rdi
callq 0x5c00
leaq 0x90(%rsp), %rdi
callq 0x5c00
leaq 0xb0(%rsp), %rdi
callq 0x5afc
leaq 0xd0(%rsp), %rdi
callq 0x5afc
leaq 0xf0(%rsp), %rdi
callq 0x5afc
leaq 0x110(%rsp), %rdi
callq 0x5afc
leaq 0x130(%rsp), %rdi
callq 0x5afc
leaq 0x150(%rsp), %rdi
callq 0x5afc
leaq 0x170(%rsp), %rdi
callq 0x5afc
leaq 0x1a0(%rsp), %rdi
callq 0x5afc
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x20a0
movq %rax, %r14
leaq 0x2377(%rip), %rsi      # 0x8813
movq %rax, %rdi
callq 0x2050
jmp 0x5e0b
leaq 0x20cf(%rip), %rdi      # 0x857f
leaq 0x20d6(%rip), %rsi      # 0x858d
leaq 0x229a(%rip), %rcx      # 0x8758
movl $0x2a3, %edx            # imm = 0x2A3
callq 0x20d0
pushq $0x10
popq %rdi
callq 0x20a0
movq %rax, %r14
leaq 0x23ed(%rip), %rsi      # 0x88c7
movq %rax, %rdi
callq 0x2050
jmp 0x6536
pushq $0x10
popq %rdi
callq 0x20a0
movq %rax, %r14
leaq 0x2435(%rip), %rsi      # 0x892b
movq %rax, %rdi
callq 0x2050
jmp 0x6536
pushq $0x10
popq %rdi
callq 0x20a0
movq %rax, %r14
leaq 0x247d(%rip), %rsi      # 0x898f
movq %rax, %rdi
callq 0x2050
jmp 0x6536
pushq $0x10
popq %rdi
callq 0x20a0
movq %rax, %r14
leaq 0x24c5(%rip), %rsi      # 0x89f3
movq %rax, %rdi
callq 0x2050
movq 0x6ab3(%rip), %rsi      # 0xcff0
movq 0x6a7c(%rip), %rdx      # 0xcfc0
movq %r14, %rdi
callq 0x21d0
jmp 0x6552
jmp 0x6552
jmp 0x6552
movq %rax, %rbx
movq %r14, %rdi
callq 0x2100
jmp 0x6590
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x657d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
jmp 0x658d
movq %rax, %rbx
movq %r14, %rdi
callq 0x2100
jmp 0x6623
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x5c00
leaq 0x50(%rsp), %rdi
callq 0x5c00
leaq 0x70(%rsp), %rdi
callq 0x5c00
leaq 0x90(%rsp), %rdi
callq 0x5c00
leaq 0xb0(%rsp), %rdi
callq 0x5afc
leaq 0xd0(%rsp), %rdi
callq 0x5afc
leaq 0xf0(%rsp), %rdi
callq 0x5afc
leaq 0x110(%rsp), %rdi
callq 0x5afc
leaq 0x130(%rsp), %rdi
callq 0x5afc
leaq 0x150(%rsp), %rdi
callq 0x5afc
leaq 0x170(%rsp), %rdi
callq 0x5afc
leaq 0x1a0(%rsp), %rdi
callq 0x5afc
movq %rbx, %rdi
callq 0x21f0
nop