Wed 21 Feb 2018 09:25:54 PM UTC, comment #3:
I've applied a second test with
And I don't see any consequence of the patch
I take it that in this scenario:
the matrix representation is some other class that has a fast implementation of nnz(). So that's good.
One other note: be sure to check changesets for any dangling whitespace. If you are running linux, type "hg diff" at a bash shell and you are likely to see highlighted red blocks wherever there is whitespace after the last character.

Wed 21 Feb 2018 08:01:14 PM UTC, comment #2:
I've looked at the patch. The conditional test
if (is_diag_matrix ())
in the patch appears to be superfluous. Isn't the class, by definition, diagonal? Wouldn't simply extracting the diagonal, i.e., collapsing to a vector, be sufficient? I.e.,
However, there is some special code in the ::diag() method:
Is that special case something to be concerned about? I think that would arise for the following sort of construct:
(Note how the application of diag() with k=0, the default in calling the ::diag() member function, expands the matrix in this case, not contracts it.)
Also, throughout ovbasediag.h are several to_dense() calls. Maybe they all could be addressed with one patch here. For example, there is the method "sort" that uses to_dense() first, but that too could be improved speedwise noting that the operation boils down to pushing the diagonal value either to the first or last row, WLOG, e.g.,
(if it is sortbyrow, then change the rule for the other direction). One would just start with the appropriately sized zeros matrix and then index through the diagonal vector sending the values to the top or bottom row based on one lessthanzero comparison.

Wed 21 Feb 2018 06:03:05 PM UTC, comment #1:
Indeed the time difference is huge.
I tried the following test script:
Got a total time of 0.0039184 seconds with the patch applied and 11.160 seconds without the patch.
Hope this helps :)
(file #43379, file #43380)

Wed 21 Feb 2018 06:11:33 AM UTC, original submission:
nnz for diagonal matrices is implemented in libinterp/octavevalue/ovbasediag.h. The code is simple
However, this isn't very efficient. It converts and then caches the full version of the matrix and then calls nnz on that full matrix. Besides the conversion, nnz on a full matrix means looking at every element. For a diagonal matrix nnz should just need to look at the elements on the diagonal.
For a square matrix the difference is O(N^2) for full matrix versus O(N) for just the diagonal.
