Fill!() vs for loop

Technically there shouldnt be a difference between using fill! to make every element of a matrix a SMCSC and using a for loop to do so.
But using fill!() messes up code. As in it seems like two copies are being made somewhere?

Can you show an example to demonstrate what the problem is?

I can tell you that fill will create a new array, while fill! will not. For example, fill!(A, 3) will replace every element in the array A with the value 3. Another, equally fast, option is A .= 3.

Suppose I do:

A= Matrix{Vector{SparseMatrixCSC{Int8}}}(10,10)

fill!(A, [sparse(zeros(Int8, 10, 10))])
A[1,1][1][1,1] = 30
#gives A[1,1][1][1,1] equal to 60

# ||

for i in eachindex(A)
A[i] = [sparse(zeros(Int8, 10, 10))]
end
A[1,1][1][1,1] = 30
#gives A[1,1][1][1,1] equal to 30

After executing with fill() and then the for loop, the fill method adds almost two times the result of the actual assignment.

That code doesn’t work. Are you sure you run exactly that?

FWIW, fill will use the same object for all entries, but the loop will create a new matrix on each call. So that gives very different results.

This doesn’t work. What should this do?

An array of vectors of sparse matrices!? That is quite mind bending. Is that really what you want?

Also fill(A, ...) doesn’t work, it just gives an error. You have to use fill! here. And after you have done that, A[1,1] = 30 also fails, and raises an error.

Did you try run the code before you posted it? What version of Julia are you using?

I am sorry, I did use fill!().
It still doesn’t execute as expected.

Yes; 0.6.2

This should make every element of A a single element Vector of SparseMatrixCSCs of all zeros.

OK. So what is it that you want A to be? Should really it be a matrix of vectors of sparse matrices, or something else?

I’m getting confused because you first make this very complicated array, and then try to do A[1, 1] = 30, which cannot work, because A is expecting elements to be vectors of sparse matrices, not just a number.

OK, got it. But then what are you trying to achieve by A[1, 1] = 30?

Again, sorry. It should be A[1,1][1][1,1]
It gives incorrect answers using this

Actually, I set multiple elements of A like that using a conditioned loop but the results are incorrect using fill!() at the start

For me the result of this code is that A[1,1][1][1,1] equals 30, not 60.

1 Like

Okay then I’ll check the code logic again.

fill (and fill!) set every element of their first argument to be the second argument, which is really not what you’d want in this case (I don’t think you want all of the elements of the “filled” vector to all point to the exact same vector of sparse matrices).

In this case, I think array comprehension is your friend.
[Vector{SparseMatrixCSC{Int8}}() for i=1:10, j=1:10]
should do the trick for you.

BTW, take a look at the help section of fill! by typing ?fill! in the Julia REPL. You are probably running into problems with all elements of A holding the same identical array.

1 Like