# 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