Mercurial > hg > octave-lyh
diff liboctave/Sparse.h @ 9469:c6edba80dfae
sanity checks for loading sparse matrices
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 29 Jul 2009 12:15:27 -0400 |
parents | d865363208d6 |
children | f80c566bc751 |
line wrap: on
line diff
--- a/liboctave/Sparse.h +++ b/liboctave/Sparse.h @@ -33,6 +33,7 @@ #include "Array.h" #include "Array2.h" #include "dim-vector.h" +#include "lo-error.h" #include "lo-utils.h" #include "oct-sort.h" @@ -131,6 +132,8 @@ void change_length (octave_idx_type nz); + bool indices_ok (void) const; + private: // No assignment! @@ -565,6 +568,8 @@ return result; } + + bool indices_ok (void) const { return rep->indices_ok (); } }; // NOTE: these functions should be friends of the Sparse<T> class and @@ -579,6 +584,98 @@ /* friend */ int assign1 (Sparse<LT>& lhs, const Sparse<RT>& rhs); +template<typename T> +std::istream& +read_sparse_matrix (std::istream& is, Sparse<T>& a, + T (*read_fcn) (std::istream&)) +{ + octave_idx_type nr = a.rows (); + octave_idx_type nc = a.cols (); + octave_idx_type nz = a.nzmax (); + + if (nr > 0 && nc > 0) + { + octave_idx_type itmp; + octave_idx_type jtmp; + octave_idx_type iold = 0; + octave_idx_type jold = 0; + octave_idx_type ii = 0; + T tmp; + + a.cidx (0) = 0; + for (octave_idx_type i = 0; i < nz; i++) + { + is >> itmp; + itmp--; + + if (itmp < iold) + { + (*current_liboctave_error_handler) + ("invalid sparse matrix: row indices must appear in ascending order in each column"); + is.setstate (std::ios::failbit); + goto done; + } + + if (itmp < 0 || itmp >= nr) + { + (*current_liboctave_error_handler) + ("invalid sparse matrix: row index = %d out of range", + itmp + 1); + is.setstate (std::ios::failbit); + goto done; + } + + + iold = itmp; + + is >> jtmp; + jtmp--; + + if (jtmp < jold) + { + (*current_liboctave_error_handler) + ("invalid sparse matrix: column indices must appear in ascending order"); + is.setstate (std::ios::failbit); + goto done; + } + + if (jtmp < 0 || jtmp >= nc) + { + (*current_liboctave_error_handler) + ("invalid sparse matrix: column index = %d out of range", + jtmp + 1); + is.setstate (std::ios::failbit); + goto done; + } + + tmp = read_fcn (is); + + if (is) + { + if (jold != jtmp) + { + for (octave_idx_type j = jold; j < jtmp; j++) + a.cidx(j+1) = ii; + + jold = jtmp; + iold = 0; + } + a.data (ii) = tmp; + a.ridx (ii++) = itmp; + } + else + goto done; + } + + for (octave_idx_type j = jold; j < nc; j++) + a.cidx(j+1) = ii; + } + + done: + + return is; +} + #define INSTANTIATE_SPARSE_ASSIGN(LT, RT, API) \ template API int assign (Sparse<LT>&, const Sparse<RT>&); \ template API int assign1 (Sparse<LT>&, const Sparse<RT>&);