Mercurial > hg > octave-lyh
diff src/ls-mat5.cc @ 5164:57077d0ddc8e
[project @ 2005-02-25 19:55:24 by jwe]
author | jwe |
---|---|
date | Fri, 25 Feb 2005 19:55:28 +0000 |
parents | 3db2b2762491 |
children | 90a9058de7e8 |
line wrap: on
line diff
--- a/src/ls-mat5.cc +++ b/src/ls-mat5.cc @@ -164,7 +164,7 @@ template <class T> void -read_mat5_integer_data (std::istream& is, T &m, int count, bool swap, +read_mat5_integer_data (std::istream& is, T *m, int count, bool swap, mat5_data_type type) { @@ -188,33 +188,27 @@ switch (type) { case miINT8: - READ_INTEGER_DATA (signed char, swap, m.fortran_vec (), 1, - count, is); + READ_INTEGER_DATA (signed char, swap, m, 1, count, is); break; case miUINT8: - READ_INTEGER_DATA (unsigned char, swap, m.fortran_vec (), 1, - count, is); + READ_INTEGER_DATA (unsigned char, swap, m, 1, count, is); break; case miINT16: - READ_INTEGER_DATA (signed TWO_BYTE_INT, swap, m.fortran_vec (), 2, - count, is); + READ_INTEGER_DATA (signed TWO_BYTE_INT, swap, m, 2, count, is); break; case miUINT16: - READ_INTEGER_DATA (unsigned TWO_BYTE_INT, swap, m.fortran_vec (), 2, - count, is); + READ_INTEGER_DATA (unsigned TWO_BYTE_INT, swap, m, 2, count, is); break; case miINT32: - READ_INTEGER_DATA (signed FOUR_BYTE_INT, swap, m.fortran_vec (), 4, - count, is); + READ_INTEGER_DATA (signed FOUR_BYTE_INT, swap, m, 4, count, is); break; case miUINT32: - READ_INTEGER_DATA (unsigned FOUR_BYTE_INT, swap, m.fortran_vec (), 4, - count, is); + READ_INTEGER_DATA (unsigned FOUR_BYTE_INT, swap, m, 4, count, is); break; case miSINGLE: @@ -226,15 +220,13 @@ case miINT64: #ifdef EIGHT_BYTE_INT - READ_INTEGER_DATA (signed EIGHT_BYTE_INT, swap, m.fortran_vec (), 8, - count, is); + READ_INTEGER_DATA (signed EIGHT_BYTE_INT, swap, m, 8, count, is); #endif break; case miUINT64: #ifdef EIGHT_BYTE_INT - READ_INTEGER_DATA (unsigned EIGHT_BYTE_INT, swap, m.fortran_vec (), 8, - count, is); + READ_INTEGER_DATA (unsigned EIGHT_BYTE_INT, swap, m, 8, count, is); #endif break; @@ -247,28 +239,32 @@ } -template void read_mat5_integer_data (std::istream& is, int8NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_int8 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, int16NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_int16 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, int32NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_int32 *m, + int count, bool swap, + mat5_data_type type); +template void read_mat5_integer_data (std::istream& is, octave_int64 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, int64NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_uint8 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, uint8NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_uint16 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, uint16NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_uint32 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, uint32NDArray &m, +template void read_mat5_integer_data (std::istream& is, octave_uint64 *m, int count, bool swap, mat5_data_type type); -template void read_mat5_integer_data (std::istream& is, uint64NDArray &m, + +template void read_mat5_integer_data (std::istream& is, int *m, int count, bool swap, mat5_data_type type); @@ -286,7 +282,7 @@ \ int n = re.length (); \ tmp_pos = is.tellg (); \ - read_mat5_integer_data (is, re, n, swap, \ + read_mat5_integer_data (is, re.fortran_vec (), n, swap, \ (enum mat5_data_type) type); \ \ if (! is || error_state) \ @@ -401,7 +397,7 @@ bool imag; bool logicalvar; enum arrayclasstype arrayclass; - FOUR_BYTE_INT junk; + FOUR_BYTE_INT nnz; FOUR_BYTE_INT flags; dim_vector dims; int len; @@ -448,7 +444,7 @@ global = (flags & 0x0400) != 0; // global variable? logicalvar = (flags & 0x0200) != 0; // we don't use this yet arrayclass = (arrayclasstype)(flags & 0xff); - read_int (is, swap, junk); // an "undefined" entry + read_int (is, swap, nnz); // number of non-zero in sparse // dimensions array subelement { @@ -531,8 +527,124 @@ goto skip_ahead; case mxSPARSE_CLASS: - warning ("load: sparse arrays are not implemented"); - goto skip_ahead; + { + int nr = dims(0); + int nc = dims(1); + SparseMatrix sm; + SparseComplexMatrix scm; + NDArray re; + int *ridx; + int *cidx; + double *data; + + // Setup return value + if (imag) + { + scm = SparseComplexMatrix (nr, nc, nnz); + ridx = scm.ridx (); + cidx = scm.cidx (); + re = NDArray (dim_vector (static_cast<int> (nnz))); + data = re.fortran_vec (); + } + else + { + sm = SparseMatrix (nr, nc, nnz); + ridx = sm.ridx (); + cidx = sm.cidx (); + data = sm.data (); + } + + // row indices + std::streampos tmp_pos; + + if (read_mat5_tag (is, swap, type, len)) + { + error ("load: reading sparse row data for `%s'", retval.c_str ()); + goto data_read_error; + } + + tmp_pos = is.tellg (); + + read_mat5_integer_data (is, ridx, nnz, swap, + (enum mat5_data_type) type); + + if (! is || error_state) + { + error ("load: reading sparse row data for `%s'", retval.c_str ()); + goto data_read_error; + } + + is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len))); + + // col indices + if (read_mat5_tag (is, swap, type, len)) + { + error ("load: reading sparse column data for `%s'", retval.c_str ()); + goto data_read_error; + } + + tmp_pos = is.tellg (); + + read_mat5_integer_data (is, cidx, nc + 1, swap, + (enum mat5_data_type) type); + + if (! is || error_state) + { + error ("load: reading sparse column data for `%s'", retval.c_str ()); + goto data_read_error; + } + + is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len))); + + // real data subelement + if (read_mat5_tag (is, swap, type, len)) + { + error ("load: reading sparse matrix data for `%s'", retval.c_str ()); + goto data_read_error; + } + + tmp_pos = is.tellg (); + read_mat5_binary_data (is, data, nnz, swap, + (enum mat5_data_type) type, flt_fmt); + + if (! is || error_state) + { + error ("load: reading sparse matrix data for `%s'", retval.c_str ()); + goto data_read_error; + } + + is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len))); + + // imaginary data subelement + if (imag) + { + NDArray im (dim_vector (static_cast<int> (nnz))); + + if (read_mat5_tag (is, swap, type, len)) + { + error ("load: reading sparse matrix data for `%s'", retval.c_str ()); + goto data_read_error; + } + + read_mat5_binary_data (is, im.fortran_vec (), nnz, swap, + (enum mat5_data_type) type, flt_fmt); + + if (! is || error_state) + { + error ("load: reading imaginary sparse matrix data for `%s'", + retval.c_str ()); + goto data_read_error; + } + + for (int i = 0; i < nnz; i++) + scm.xdata (i) = Complex (re (i), im (i)); + + tc = scm; + } + else + tc = sm; + } + break; case mxFUNCTION_CLASS: warning ("load: function handles are not implemented"); @@ -913,9 +1025,8 @@ template <class T> void -write_mat5_integer_data (std::ostream& os, const T& m, int size) +write_mat5_integer_data (std::ostream& os, const T *m, int size, int nel) { - int nel = m.nelem (); mat5_data_type mst; unsigned len; @@ -927,10 +1038,10 @@ case 2: mst = miUINT16; break; - case 3: + case 4: mst = miUINT32; break; - case 4: + case 8: mst = miUINT64; break; case -1: @@ -941,11 +1052,11 @@ mst = miINT16; size = - size; break; - case -3: + case -4: mst = miINT32; size = - size; break; - case -4: + case -8: default: mst = miINT64; size = - size; @@ -955,7 +1066,7 @@ len = nel*size; write_mat5_tag (os, mst, len); - os.write (X_CAST(char *, m.data ()), len); + os.write (X_CAST(char *, m), len); if (PAD (len) > len) { @@ -964,22 +1075,24 @@ } } -template void write_mat5_integer_data (std::ostream& os, - const int8NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const int16NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const int32NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const int64NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const uint8NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const uint16NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const uint32NDArray &m, int size); -template void write_mat5_integer_data (std::ostream& os, - const uint64NDArray &m, int size); +template void write_mat5_integer_data (std::ostream& os, const octave_int8 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_int16 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_int32 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_int64 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_uint8 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_uint16 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_uint32 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const octave_uint64 *m, + int size, int nel); +template void write_mat5_integer_data (std::ostream& os, const int *m, + int size, int nel); // Write out cell element values in the cell array to OS, preceded by // the appropriate tag. @@ -1011,7 +1124,7 @@ bool mark_as_global, bool save_as_floats) { FOUR_BYTE_INT flags=0; - FOUR_BYTE_INT junk=0; + FOUR_BYTE_INT nnz=0; std::streampos fixup, contin; std::string cname = tc.class_name (); @@ -1046,6 +1159,20 @@ flags |= mxUINT32_CLASS; else if (cname == "uint64") flags |= mxUINT64_CLASS; + else if (cname == "sparse") + { + flags |= mxSPARSE_CLASS; + if (tc.is_complex_type ()) + { + SparseComplexMatrix scm = tc.sparse_complex_matrix_value (); + nnz = scm.nnz (); + } + else + { + SparseMatrix sm = tc.sparse_matrix_value (); + nnz = sm.nnz (); + } + } else if (tc.is_real_scalar ()) flags |= mxDOUBLE_CLASS; else if (tc.is_real_matrix () || tc.is_range ()) @@ -1065,7 +1192,7 @@ } os.write ((char *)&flags, 4); - os.write ((char *)&junk, 4); + os.write ((char *)&nnz, 4); { dim_vector dv = tc.dims (); @@ -1128,53 +1255,93 @@ if (paddedlength > len) os.write ((char *)buf, paddedlength - len); } + else if (cname == "sparse") + { + if (tc.is_complex_type ()) + { + SparseComplexMatrix m = tc.sparse_complex_matrix_value (); + int nc = m.cols (); + + write_mat5_integer_data (os, m.ridx (), - sizeof(int), nnz); + write_mat5_integer_data (os, m.cidx (), - sizeof(int), nc + 1); + + NDArray buf (dim_vector (nnz, 1)); + + for (int i = 0; i < nnz; i++) + buf (i) = ::real (m.data (i)); + + write_mat5_array (os, buf, save_as_floats); + + for (int i = 0; i < nnz; i++) + buf (i) = ::imag (m.data (i)); + + write_mat5_array (os, buf, save_as_floats); + } + else + { + SparseMatrix m = tc.sparse_matrix_value (); + int nc = m.cols (); + + write_mat5_integer_data (os, m.ridx (), - sizeof(int), nnz); + write_mat5_integer_data (os, m.cidx (), - sizeof(int), nc + 1); + + // XXX FIXME XXX + // Is there a way to easily do without this buffer + NDArray buf (dim_vector (nnz, 1)); + + for (int i = 0; i < nnz; i++) + buf (i) = m.data (i); + + write_mat5_array (os, buf, save_as_floats); + } + } else if (cname == "int8") { int8NDArray m = tc.int8_array_value (); - write_mat5_integer_data (os, m, -1); + write_mat5_integer_data (os, m.fortran_vec (), -1, m.nelem ()); } else if (cname == "int16") { int16NDArray m = tc.int16_array_value (); - write_mat5_integer_data (os, m, -2); + write_mat5_integer_data (os, m.fortran_vec (), -2, m.nelem ()); } else if (cname == "int32") { int32NDArray m = tc.int32_array_value (); - write_mat5_integer_data (os, m, -4); + write_mat5_integer_data (os, m.fortran_vec (), -4, m.nelem ()); } else if (cname == "int64") { int64NDArray m = tc.int64_array_value (); - write_mat5_integer_data (os, m, -8); + write_mat5_integer_data (os, m.fortran_vec (), -8, m.nelem ()); } else if (cname == "uint8") { uint8NDArray m = tc.uint8_array_value (); - write_mat5_integer_data (os, m, 1); + write_mat5_integer_data (os, m.fortran_vec (), 1, m.nelem ()); } else if (cname == "uint16") { uint16NDArray m = tc.uint16_array_value (); - write_mat5_integer_data (os, m, 2); + write_mat5_integer_data (os, m.fortran_vec (), 2, m.nelem ()); } else if (cname == "uint32") { uint32NDArray m = tc.uint32_array_value (); - write_mat5_integer_data (os, m, 4); + write_mat5_integer_data (os, m.fortran_vec (), 4, m.nelem ()); } else if (cname == "uint64") { uint64NDArray m = tc.uint64_array_value (); - write_mat5_integer_data (os, m, 8); + write_mat5_integer_data (os, m.fortran_vec (), 8, m.nelem ()); } else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ()) {