On Thursday, February 12, 2015 at 10:03:04 PM UTC-6, Zouhair Mahboubi wrote:
>
>
>
> I'm trying to find the column indices of non-zero elements of a given row 
> in a sparse matrix A
>
> I figured using findn would be a fast way to do that, but I was curious to 
> see how the implementation was done since all I cared about were the 
> columns for a given row and I thought I could have my own version that only 
> checked for a given row.
>
> But when I took a peek in 
> https://github.com/JuliaLang/julia/blob/master/base/sparse/sparsematrix.jl#L310
> I was surprised to see this in findn (and findnz)
>
> S.nzval[k] != 0
>
>
>
> I would have expected nzval to always be != 0 by construction?
>
> Then I had a look at nnz and countnz, and I was again surprised to see 
> that they have slightly different implementations!
> Especially given the help for the two functions (which makes sense since 
> one expects all stored elements in the sparse matrix to be non-zero)
>
> help?> nnz
>> Base.nnz(A)
>>    Returns the number of stored (filled) elements in a sparse matrix.
>> help?> countnz
>> Base.countnz(A)
>>    Counts the number of nonzero values in array A (dense or sparse).
>>    Note that this is not a constant-time operation. For sparse
>>    matrices, one should usually use "nnz", which returns the number
>>    of stored values.
>
>
>
> The only way I can see that happening, is if the user manually modifies 
> nzval? i.e.
> A = spdiagm(ones(5));
> println(nnz(A), countnz(A)) #prints 55
> A[1,1] = 0
> println(nnz(A), countnz(A)) #prints 44
> A.nzval[1] = 0
> println(nnz(A), countnz(A)) #prints 43
>
>
> So few questions:
>
>
>    - what is the fastet way to do what I was initially trying to 
>    accomplish: find the column indices and values of a given row in a sparse 
>    matrix A 
>    - why the checking of nzval?
>    - is that because it's ok to change nzval manually? if not, why is 
>       nzval not "protected" ?
>    
>
Regarding the question of changing elements of nzval, yes, there can be 
occasions when one wants to do this.  

Remember that it only makes sense to use a sparse representation when 
working with large matrices - in my case sparse symmetric matrices with 
potentially millions of columns.  Frequently these structures are 
associated with optimization problems in which the criterion to be 
optimized is repeatedly evaluated at different parameter values.  In such 
cases you don't want to take copies unnecessarily so you may cheat a bit 
and rely on the structure staying the same even when the values of 
individual elements change.  In my case some elements can become zero 
transiently but I don't want the structure to change when a potential 
non-zero happens to take on a value of zero.

There isn't a concept of a protected value in Julia.  Most things are 
pretty open to changes by the programmer, according to the "consenting 
adults" approach of the language developers.   In other languages the 
inherent restrictions on what can be changed can lead to inefficiencies. 
 For about the last decade that I was developing software in R I found 
myself bashing my head against the restriction that modifications to 
arguments within a function are not visible outside the function.  That is, 
copy-on-write is enforced for arguments.  That is wonderful until you want 
to modify a large structure in place and you can't.

There are several functions that can modify the nzval member of a sparse 
matrix in place.  According to convention the names of such functions 
usually end in '!', as in "scale!", "A_mul_B!", etc.  You can cause 
yourself a lot of grief with these functions, which is why the names end in 
'!', but you can also do things that would otherwise be very difficult to 
achieve without creating many copies.  And economizing on storage is the 
reason for sparse matrices in the first place.
 

>
>
> Thanks,
> -z
>

Reply via email to