#### 22.1.4.2 Return Types of Operators and Functions ¶

The two basic reasons to use sparse matrices are to reduce the memory
usage and to not have to do calculations on zero elements. The two are
closely related in that the computation time on a sparse matrix operator
or function is roughly linear with the number of nonzero elements.

Therefore, there is a certain density of nonzero elements of a matrix
where it no longer makes sense to store it as a sparse matrix, but rather
as a full matrix. For this reason operators and functions that have a
high probability of returning a full matrix will always return one. For
example adding a scalar constant to a sparse matrix will almost always
make it a full matrix, and so the example,

speye (3) + 0
⇒ 1 0 0
0 1 0
0 0 1

returns a full matrix as can be seen.

As all of the mixed operators and functions between full and sparse
matrices exist, in general this does not cause any problems. However,
one area where it does cause a problem is where a sparse matrix is
promoted to a full matrix, where subsequent operations would resparsify
the matrix. Such cases are rare, but can be artificially created, for
example `(fliplr (speye (3)) + speye (3)) - speye (3)`

gives a full
matrix when it should give a sparse one. In general, where such cases
occur, they impose only a small memory penalty.

There is however one known case where this behavior of Octave’s
sparse matrices will cause a problem. That is in the handling of the
*diag* function. Whether *diag* returns a sparse or full matrix
depending on the type of its input arguments. So

a = diag (sparse ([1,2,3]), -1);

should return a sparse matrix. To ensure this actually happens, the
*sparse* function, and other functions based on it like *speye*,
always returns a sparse matrix, even if the memory used will be larger
than its full representation.