How to build this sparsematrix in Julia

@acxz

I got lost here :slight_smile:

For t in 0:25e-6:2

In may real code, R is 33x33 and F is 102x33. O is 102x33.

F_density = 0.2935234699940582
R_density = 0.02938475665748393
O_density = 0.030303030303030304

The time difference I was referring to here was the time it takes for your program to run with the for loop using nzrange. Can you give us the timings without using nzrange and after using nzrange? I won’t believe

using this iteration in my time-domain for-loop is expensive

until I see what the times were.

Thank you for these values! Although no need to put the density of R since we know it is a structured matrix. These are really helpful in terms of creating a “minimal working example” (MWE) can you update your example with this information similar to how I used these pieces of information in an above post: How to build this sparsematrix in Julia - #37 by acxz

Just tested these dimensions and densities and using sparse matrices wile result in faster code, but slightly larger memory usage. Generally speed matters more for us tho, as I’m is the case for your problem as well.

I got lost here :slight_smile:

Let’s have you implement your code with nzrange and see if the time difference is worth it for us to go deeper. baby steps right?

1 Like

Thanks!
Actually, I tried to implement nzrange in the MWE (before going to my real code), but looks like I made mistake somewhere. Could you please help me to correct it?


function update!(SparseMat, val)
       rows = rowvals(SparseMat)
       vals = nonzeros(SparseMat)
       n = size(SparseMat,2)
       iter = 0;
       for j = 1:n
              for i in nzrange(SparseMat, j)
                 #row = rows[i]
                 #val = vals[i]
                 iter += 1;
                 O[rows[i],j] = Ik[iter];
                 s=0;
              end
       end
end

R = sparse([zeros(1,8); Matrix(1.0I, 8-1, 8-1) zeros(8-1,1)]);
Nh = [6, 6, 6, 8, 7, 7]; # fixed
Ik = [7, 1, -4, 8, 4, 1];
F = sparse([3 3 3 4 4 4 0.0 0.0;
            1 2 1 7 9 3 0.0 0.0; 
            7 8 1 4 8 8 0.0 0.0;
            1 1 2 8 5 1 0.0 0.0;
            5 6 1 4 2 5 4.6 0.0;
            1 6 8 1 1 4 6.8 0.0]);

F1 = copy(F);
F2 = copy(F);
K = F * R;
O = sparse(1:6, Nh, Ik)
Ik = [10, 20, 30, 40, 50, 60];
update!(O, Ik) # This works as as O.nzval .= Ik;
S = sparse(1:6, Nh, Ik);
julia> O == S
false

I think using nzrange as you have defined your problem in the MWE will not work (or at least you’ll have to do more manipulation)

With how you have currently defined your problem, this is probably the best you can do:

col_vec = [6, 6, 6, 8, 7, 7];
row_vec = [1, 2, 3, 4, 5, 6];
val_vec = [7, 1, -4, 8, 4, 1];

O = sparse(row_vec, col_vec, val_vec)

new_val_vec = 10:10:60;

for idx in 1:length(val_vec)
    O[row_vec[idx], col_vec[idx]] = new_val_vec[idx]
end

S = sparse(row_vec, col_vec, new_val_vec)

O == S

Print out O right after you create it. println(O) Do you notice how the row_vec and the col_vec are stored in the sparse matrix type? That is the ordering you need your new values in to use .nzval. In CSC, the sort is by columns first and then the rows are sorted for each column. The values of the matrix need to be in that order.

2 Likes