// File: toxaart[P]hierarchical_block_sparse_lib/source/HierarchicalBlockSparseMatrix.h
// Function: hbsm::HierarchicalBlockSparseMatrix<double>::random_blocks(unsigned long)
void HierarchicalBlockSparseMatrix<Treal>::random_blocks(size_t nnz_blocks){

            // assume matrix is resized and we are at the top level;

            int M = nRows_orig;
            int N = nCols_orig;

            int n_block_dim1 = M / blocksize;
            if(M % blocksize > 0) n_block_dim1 += 1;

            int n_block_dim2 = N / blocksize;
            if(N % blocksize > 0) n_block_dim2 += 1;

            int total_number_of_blocks = n_block_dim1 * n_block_dim2;

            if(nnz_blocks > total_number_of_blocks) throw std::runtime_error("Error in HierarchicalBlockSparseMatrix::random_blocks():too many blocks!");

            std::vector<int> v;
            v.resize(total_number_of_blocks);
            for(int i = 0; i < total_number_of_blocks; ++i) v[i] = i;

            std::random_device rd;
            std::mt19937 g(rd());
            std::shuffle(v.begin(), v.end(), g);

            std::vector<int> row_indices, col_indices;
            std::vector<Treal> values;

            row_indices.resize(nnz_blocks * blocksize * blocksize);
            col_indices.resize(nnz_blocks * blocksize * blocksize);
            values.resize(nnz_blocks * blocksize * blocksize);

            size_t element_counter = 0;

            double lower_bound = -1.0;
            double upper_bound = 1.0;
            std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
            std::default_random_engine re;

            for(int k = 0; k < nnz_blocks; ++k){

                int block_row_pos = blocksize * (v[k] / n_block_dim1);
                int block_col_pos = blocksize * (v[k] % n_block_dim1);

                for(int i = 0; i < blocksize*blocksize; ++i){

                    int element_row_pos = block_row_pos + i / blocksize;
                    int element_col_pos = block_col_pos + i % blocksize;

                    if(element_row_pos > get_n_rows()-1 || element_col_pos > get_n_cols()-1) continue;

                    values[element_counter] = unif(re);
                    row_indices[element_counter] = element_row_pos;
                    col_indices[element_counter] = element_col_pos;

                    element_counter++;
                }

            }

            row_indices.resize(element_counter);
            col_indices.resize(element_counter);
            values.resize(element_counter);



            assign_from_vectors(row_indices, col_indices, values);



        }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2860, %rsp           # imm = 0x2860
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x2810(%rbp)
movl 0x8(%rcx), %eax
movl %eax, -0x14(%rbp)
movl 0xc(%rcx), %eax
movl %eax, -0x18(%rbp)
movl -0x14(%rbp), %eax
cltd
idivl 0x10(%rcx)
movl %eax, -0x1c(%rbp)
movl -0x14(%rbp), %eax
cltd
idivl 0x10(%rcx)
cmpl $0x0, %edx
jle 0x14009
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
movq -0x2810(%rbp), %rcx
movl -0x18(%rbp), %eax
cltd
idivl 0x10(%rcx)
movl %eax, -0x20(%rbp)
movl -0x18(%rbp), %eax
cltd
idivl 0x10(%rcx)
cmpl $0x0, %edx
jle 0x1402f
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
imull -0x20(%rbp), %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
cmpq %rcx, %rax
jbe 0x140a2
movl $0x10, %edi
callq 0x20d0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x2818(%rbp)
leaq 0x23960(%rip), %rsi     # 0x379c4
callq 0x20a0
jmp 0x1406b
movq -0x2818(%rbp), %rdi
movq 0x2cf77(%rip), %rsi     # 0x40ff0
movq 0x2cf40(%rip), %rdx     # 0x40fc0
callq 0x2320
movq -0x2818(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x2150
jmp 0x1458f
leaq -0x50(%rbp), %rdi
movq %rdi, -0x2820(%rbp)
callq 0x10e60
movq -0x2820(%rbp), %rdi
movslq -0x24(%rbp), %rsi
callq 0x2d250
jmp 0x140c4
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x1410d
movl -0x54(%rbp), %eax
movl %eax, -0x2824(%rbp)
movslq -0x54(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x26720
movl -0x2824(%rbp), %ecx
movl %ecx, (%rax)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x140cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x14586
leaq -0x13e0(%rbp), %rdi
callq 0x2d2e0
jmp 0x1411b
leaq -0x13e0(%rbp), %rdi
callq 0x2d380
movl %eax, -0x2828(%rbp)
jmp 0x1412f
movl -0x2828(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x2768(%rbp), %rdi
callq 0x2d3a0
jmp 0x14147
leaq -0x50(%rbp), %rdi
movq %rdi, -0x2830(%rbp)
callq 0x27020
movq -0x2830(%rbp), %rdi
movq %rax, -0x2770(%rbp)
callq 0x26eb0
movq %rax, -0x2778(%rbp)
movq -0x2770(%rbp), %rdi
movq -0x2778(%rbp), %rsi
leaq -0x2768(%rbp), %rdx
callq 0x2d3d0
jmp 0x1418d
leaq -0x2790(%rbp), %rdi
movq %rdi, -0x2838(%rbp)
callq 0x10e60
leaq -0x27a8(%rbp), %rdi
callq 0x10e60
leaq -0x27c0(%rbp), %rdi
callq 0x10e80
movq -0x2810(%rbp), %rax
movq -0x2838(%rbp), %rdi
movq -0x10(%rbp), %rsi
movslq 0x10(%rax), %rax
imulq %rax, %rsi
imulq %rax, %rsi
callq 0x2d250
jmp 0x141dd
movq -0x2810(%rbp), %rax
movq -0x10(%rbp), %rsi
movslq 0x10(%rax), %rax
imulq %rax, %rsi
imulq %rax, %rsi
leaq -0x27a8(%rbp), %rdi
callq 0x2d250
jmp 0x14202
movq -0x2810(%rbp), %rax
movq -0x10(%rbp), %rsi
movslq 0x10(%rax), %rax
imulq %rax, %rsi
imulq %rax, %rsi
leaq -0x27c0(%rbp), %rdi
callq 0x23470
jmp 0x14227
movq $0x0, -0x27c8(%rbp)
movabsq $-0x4010000000000000, %rax # imm = 0xBFF0000000000000
movq %rax, -0x27d0(%rbp)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0x27d8(%rbp)
movsd -0x27d0(%rbp), %xmm0
movsd -0x27d8(%rbp), %xmm1
leaq -0x27e8(%rbp), %rdi
callq 0x2d640
jmp 0x14272
leaq -0x27f0(%rbp), %rdi
callq 0x2d670
jmp 0x14280
movl $0x0, -0x27f4(%rbp)
movslq -0x27f4(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x144d6
movq -0x2810(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x2840(%rbp)
movslq -0x27f4(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x26720
movl -0x2840(%rbp), %ecx
movl (%rax), %eax
cltd
idivl -0x1c(%rbp)
movl %eax, %edx
movq -0x2810(%rbp), %rax
imull %edx, %ecx
movl %ecx, -0x27f8(%rbp)
movl 0x10(%rax), %eax
movl %eax, -0x283c(%rbp)
movslq -0x27f4(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x26720
movl (%rax), %eax
cltd
idivl -0x1c(%rbp)
movl -0x283c(%rbp), %eax
imull %edx, %eax
movl %eax, -0x27fc(%rbp)
movl $0x0, -0x2800(%rbp)
movq -0x2810(%rbp), %rdx
movl -0x2800(%rbp), %eax
movl 0x10(%rdx), %ecx
imull 0x10(%rdx), %ecx
cmpl %ecx, %eax
jge 0x144c0
movq -0x2810(%rbp), %rdi
movl -0x27f8(%rbp), %eax
movl %eax, -0x284c(%rbp)
movl -0x2800(%rbp), %eax
cltd
idivl 0x10(%rdi)
movl %eax, %ecx
movl -0x284c(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x2804(%rbp)
movl -0x27fc(%rbp), %eax
movl %eax, -0x2848(%rbp)
movl -0x2800(%rbp), %eax
cltd
idivl 0x10(%rdi)
movl -0x2848(%rbp), %eax
addl %edx, %eax
movl %eax, -0x2808(%rbp)
movl -0x2804(%rbp), %eax
movl %eax, -0x2844(%rbp)
callq 0x24470
movl %eax, %ecx
movl -0x2844(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jg 0x143c5
movq -0x2810(%rbp), %rdi
movl -0x2808(%rbp), %eax
movl %eax, -0x2850(%rbp)
callq 0x24540
movl %eax, %ecx
movl -0x2850(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jle 0x14410
jmp 0x144ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x1457a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x27c0(%rbp), %rdi
callq 0x112e0
leaq -0x27a8(%rbp), %rdi
callq 0x11340
leaq -0x2790(%rbp), %rdi
callq 0x11340
jmp 0x1457a
leaq -0x27e8(%rbp), %rdi
leaq -0x27f0(%rbp), %rsi
callq 0x2d690
movsd %xmm0, -0x2858(%rbp)
jmp 0x1442d
movq -0x27c8(%rbp), %rsi
leaq -0x27c0(%rbp), %rdi
callq 0x22b60
movsd -0x2858(%rbp), %xmm0
movsd %xmm0, (%rax)
movl -0x2804(%rbp), %eax
movl %eax, -0x2860(%rbp)
movq -0x27c8(%rbp), %rsi
leaq -0x2790(%rbp), %rdi
callq 0x26720
movl -0x2860(%rbp), %ecx
movl %ecx, (%rax)
movl -0x2808(%rbp), %eax
movl %eax, -0x285c(%rbp)
movq -0x27c8(%rbp), %rsi
leaq -0x27a8(%rbp), %rdi
callq 0x26720
movl -0x285c(%rbp), %ecx
movl %ecx, (%rax)
movq -0x27c8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x27c8(%rbp)
movl -0x2800(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2800(%rbp)
jmp 0x14311
jmp 0x144c2
movl -0x27f4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27f4(%rbp)
jmp 0x1428a
movq -0x27c8(%rbp), %rsi
leaq -0x2790(%rbp), %rdi
callq 0x2d250
jmp 0x144eb
movq -0x27c8(%rbp), %rsi
leaq -0x27a8(%rbp), %rdi
callq 0x2d250
jmp 0x14500
movq -0x27c8(%rbp), %rsi
leaq -0x27c0(%rbp), %rdi
callq 0x23470
jmp 0x14515
movq -0x2810(%rbp), %rdi
leaq -0x2790(%rbp), %rsi
leaq -0x27a8(%rbp), %rdx
leaq -0x27c0(%rbp), %rcx
callq 0x10f00
jmp 0x14538
leaq -0x27c0(%rbp), %rdi
callq 0x112e0
leaq -0x27a8(%rbp), %rdi
callq 0x11340
leaq -0x2790(%rbp), %rdi
callq 0x11340
leaq -0x13e0(%rbp), %rdi
callq 0x2d6c0
leaq -0x50(%rbp), %rdi
callq 0x11340
addq $0x2860, %rsp           # imm = 0x2860
popq %rbp
retq
leaq -0x13e0(%rbp), %rdi
callq 0x2d6c0
leaq -0x50(%rbp), %rdi
callq 0x11340
movq -0x30(%rbp), %rdi
callq 0x2340
nopl (%rax,%rax)