Mercurial > octave
changeset 32312:66a8907102c5 stable
correctly load all-zero sparse matrices from text files (bug #64696)
Since changeset c0d8ce61c1c9, sparse arrays have reserved at least one
element of storage so nzmax is always greater than 0. That causes
trouble for the read_sparse_matrix function which only reads a set of
triplets (ROW, COL, VAL) from the input stream and assumes that the
sparse array that it receives and fills with values has been
initialized with exactly the correct amount of storage to hold all the
values in the file (it assumes that nnz is the same as nzmax). But
that's not the case for sparse arrays created with nnz equal to 0 and
read_sparse_matrix attempts to read an element when it should not. We
can't avoid the problem by calling Sparse<T>::nnz in
read_sparse_matrix because it returns zero for a newly allocated
sparse array and won't be correct until the values are stored in the
array. Instead, we have to skip reading array elements in the
load_ascii function if NZ is zero.
* ov-base-sparse.cc (octave_base_sparse<T>::load_ascii): Skip input of
matrix elements if NNZ is zero. New test.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 19 Sep 2023 14:00:19 -0400 |
parents | 68f3ec939f92 |
children | 091d5c1ec4ef ccca7e42adcb |
files | libinterp/octave-value/ov-base-sparse.cc |
diffstat | 1 files changed, 22 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-base-sparse.cc Thu Sep 14 14:13:10 2023 -0400 +++ b/libinterp/octave-value/ov-base-sparse.cc Tue Sep 19 14:00:19 2023 -0400 @@ -429,16 +429,35 @@ T tmp (nr, nc, nz); - is >> tmp; + if (nz > 0) + { + is >> tmp; - if (! is) - error ("load: failed to load matrix constant"); + if (! is) + error ("load: failed to load matrix constant"); + } matrix = tmp; return true; } +/* +%!test <64696> +%! A = B = sparse (1, 2); +%! assert (nnz (A), 0); +%! assert (nnz (B), 0); +%! txt_file = [tempname(), ".dat"]; +%! unwind_protect +%! save (txt_file, "A", "B"); +%! s = load (txt_file); +%! unwind_protect_cleanup +%! unlink (txt_file); +%! end_unwind_protect +%! assert (s.A, A); +%! assert (s.B, B); +*/ + template <typename T> octave_value octave_base_sparse<T>::fast_elem_extract (octave_idx_type n) const