00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <climits>
00029
00030 #include <iostream>
00031 #include <vector>
00032
00033 #include "lo-specfun.h"
00034 #include "lo-mappers.h"
00035 #include "oct-locbuf.h"
00036
00037 #include "ov-base.h"
00038 #include "ov-scalar.h"
00039 #include "gripes.h"
00040
00041 #include "ls-hdf5.h"
00042
00043 #include "ov-re-sparse.h"
00044
00045 #include "ov-base-sparse.h"
00046 #include "ov-base-sparse.cc"
00047
00048 #include "ov-bool-sparse.h"
00049
00050 template class OCTINTERP_API octave_base_sparse<SparseMatrix>;
00051
00052 DEFINE_OCTAVE_ALLOCATOR (octave_sparse_matrix);
00053
00054 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_matrix, "sparse matrix", "double");
00055
00056 idx_vector
00057 octave_sparse_matrix::index_vector (void) const
00058 {
00059 if (matrix.numel () == matrix.nnz ())
00060 return idx_vector (array_value ());
00061 else
00062 {
00063 std::string nm = type_name ();
00064 error ("%s type invalid as index value", nm.c_str ());
00065 return idx_vector ();
00066 }
00067 }
00068
00069 octave_base_value *
00070 octave_sparse_matrix::try_narrowing_conversion (void)
00071 {
00072 octave_base_value *retval = 0;
00073
00074 if (Vsparse_auto_mutate)
00075 {
00076
00077
00078
00079 if (matrix.rows () == 1 && matrix.cols () == 1)
00080 {
00081
00082 const SparseMatrix tmp (matrix);
00083
00084 retval = new octave_scalar (tmp (0));
00085 }
00086 else if (matrix.cols () > 0 && matrix.rows () > 0
00087 && (double (matrix.byte_size ()) > double (matrix.rows ())
00088 * double (matrix.cols ()) * sizeof (double)))
00089 retval = new octave_matrix (matrix.matrix_value ());
00090 }
00091
00092 return retval;
00093 }
00094
00095 double
00096 octave_sparse_matrix::double_value (bool) const
00097 {
00098 double retval = lo_ieee_nan_value ();
00099
00100 if (numel () > 0)
00101 {
00102 if (numel () > 1)
00103 gripe_implicit_conversion ("Octave:array-as-scalar",
00104 "real sparse matrix", "real scalar");
00105
00106 retval = matrix (0, 0);
00107 }
00108 else
00109 gripe_invalid_conversion ("real sparse matrix", "real scalar");
00110
00111 return retval;
00112 }
00113
00114 Complex
00115 octave_sparse_matrix::complex_value (bool) const
00116 {
00117 double tmp = lo_ieee_nan_value ();
00118
00119 Complex retval (tmp, tmp);
00120
00121
00122 if (rows () > 0 && columns () > 0)
00123 {
00124 if (numel () > 1)
00125 gripe_implicit_conversion ("Octave:array-as-scalar",
00126 "real sparse matrix", "complex scalar");
00127
00128 retval = matrix (0, 0);
00129 }
00130 else
00131 gripe_invalid_conversion ("real sparse matrix", "complex scalar");
00132
00133 return retval;
00134 }
00135
00136 Matrix
00137 octave_sparse_matrix::matrix_value (bool) const
00138 {
00139 return matrix.matrix_value ();
00140 }
00141
00142 boolNDArray
00143 octave_sparse_matrix::bool_array_value (bool warn) const
00144 {
00145 NDArray m = matrix.matrix_value ();
00146
00147 if (m.any_element_is_nan ())
00148 gripe_nan_to_logical_conversion ();
00149 else if (warn && m.any_element_not_one_or_zero ())
00150 gripe_logical_conversion ();
00151
00152 return boolNDArray (m);
00153 }
00154
00155 charNDArray
00156 octave_sparse_matrix::char_array_value (bool) const
00157 {
00158 charNDArray retval (dims (), 0);
00159 octave_idx_type nc = matrix.cols ();
00160 octave_idx_type nr = matrix.rows ();
00161
00162 for (octave_idx_type j = 0; j < nc; j++)
00163 for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++)
00164 retval(matrix.ridx(i) + nr * j) = static_cast<char>(matrix.data (i));
00165
00166 return retval;
00167 }
00168
00169 ComplexMatrix
00170 octave_sparse_matrix::complex_matrix_value (bool) const
00171 {
00172 return ComplexMatrix (matrix.matrix_value ());
00173 }
00174
00175 ComplexNDArray
00176 octave_sparse_matrix::complex_array_value (bool) const
00177 {
00178 return ComplexNDArray (ComplexMatrix (matrix.matrix_value ()));
00179 }
00180
00181 NDArray
00182 octave_sparse_matrix::array_value (bool) const
00183 {
00184 return NDArray (matrix.matrix_value ());
00185 }
00186
00187 SparseBoolMatrix
00188 octave_sparse_matrix::sparse_bool_matrix_value (bool warn) const
00189 {
00190 if (matrix.any_element_is_nan ())
00191 gripe_nan_to_logical_conversion ();
00192 else if (warn && matrix.any_element_not_one_or_zero ())
00193 gripe_logical_conversion ();
00194
00195 return mx_el_ne (matrix, 0.0);
00196 }
00197
00198 octave_value
00199 octave_sparse_matrix::convert_to_str_internal (bool, bool, char type) const
00200 {
00201 octave_value retval;
00202 dim_vector dv = dims ();
00203 octave_idx_type nel = dv.numel ();
00204
00205 if (nel == 0)
00206 {
00207 char s = '\0';
00208 retval = octave_value (&s, type);
00209 }
00210 else
00211 {
00212 octave_idx_type nr = matrix.rows ();
00213 octave_idx_type nc = matrix.cols ();
00214 charNDArray chm (dv, static_cast<char> (0));
00215
00216 bool warned = false;
00217
00218 for (octave_idx_type j = 0; j < nc; j++)
00219 for (octave_idx_type i = matrix.cidx(j);
00220 i < matrix.cidx(j+1); i++)
00221 {
00222 octave_quit ();
00223
00224 double d = matrix.data (i);
00225
00226 if (xisnan (d))
00227 {
00228 gripe_nan_to_character_conversion ();
00229 return retval;
00230 }
00231 else
00232 {
00233 int ival = NINT (d);
00234
00235 if (ival < 0 || ival > UCHAR_MAX)
00236 {
00237
00238
00239
00240 ival = 0;
00241
00242 if (! warned)
00243 {
00244 ::warning ("range error for conversion to character value");
00245 warned = true;
00246 }
00247 }
00248
00249 chm (matrix.ridx(i) + j * nr) =
00250 static_cast<char> (ival);
00251 }
00252 }
00253
00254 retval = octave_value (chm, type);
00255 }
00256
00257 return retval;
00258 }
00259
00260 bool
00261 octave_sparse_matrix::save_binary (std::ostream& os, bool&save_as_floats)
00262 {
00263 dim_vector d = this->dims ();
00264 if (d.length() < 1)
00265 return false;
00266
00267
00268 matrix.maybe_compress ();
00269
00270 int nr = d(0);
00271 int nc = d(1);
00272 int nz = nnz ();
00273
00274 int32_t itmp;
00275
00276 itmp= -2;
00277 os.write (reinterpret_cast<char *> (&itmp), 4);
00278
00279 itmp= nr;
00280 os.write (reinterpret_cast<char *> (&itmp), 4);
00281
00282 itmp= nc;
00283 os.write (reinterpret_cast<char *> (&itmp), 4);
00284
00285 itmp= nz;
00286 os.write (reinterpret_cast<char *> (&itmp), 4);
00287
00288 save_type st = LS_DOUBLE;
00289 if (save_as_floats)
00290 {
00291 if (matrix.too_large_for_float ())
00292 {
00293 warning ("save: some values too large to save as floats --");
00294 warning ("save: saving as doubles instead");
00295 }
00296 else
00297 st = LS_FLOAT;
00298 }
00299 else if (matrix.nnz () > 8192)
00300 {
00301 double max_val, min_val;
00302 if (matrix.all_integers (max_val, min_val))
00303 st = get_save_type (max_val, min_val);
00304 }
00305
00306
00307
00308 for (int i = 0; i < nc+1; i++)
00309 {
00310 octave_quit ();
00311 itmp = matrix.cidx(i);
00312 os.write (reinterpret_cast<char *> (&itmp), 4);
00313 }
00314
00315 for (int i = 0; i < nz; i++)
00316 {
00317 octave_quit ();
00318 itmp = matrix.ridx(i);
00319 os.write (reinterpret_cast<char *> (&itmp), 4);
00320 }
00321
00322 write_doubles (os, matrix.data(), st, nz);
00323
00324 return true;
00325 }
00326
00327 bool
00328 octave_sparse_matrix::load_binary (std::istream& is, bool swap,
00329 oct_mach_info::float_format fmt)
00330 {
00331 int32_t nz, nc, nr, tmp;
00332 char ctmp;
00333
00334 if (! is.read (reinterpret_cast<char *> (&tmp), 4))
00335 return false;
00336
00337 if (swap)
00338 swap_bytes<4> (&tmp);
00339
00340 if (tmp != -2) {
00341 error ("load: only 2D sparse matrices are supported");
00342 return false;
00343 }
00344
00345 if (! is.read (reinterpret_cast<char *> (&nr), 4))
00346 return false;
00347 if (! is.read (reinterpret_cast<char *> (&nc), 4))
00348 return false;
00349 if (! is.read (reinterpret_cast<char *> (&nz), 4))
00350 return false;
00351
00352 if (swap)
00353 {
00354 swap_bytes<4> (&nr);
00355 swap_bytes<4> (&nc);
00356 swap_bytes<4> (&nz);
00357 }
00358
00359 SparseMatrix m (static_cast<octave_idx_type> (nr),
00360 static_cast<octave_idx_type> (nc),
00361 static_cast<octave_idx_type> (nz));
00362
00363 for (int i = 0; i < nc+1; i++)
00364 {
00365 octave_quit ();
00366 if (! is.read (reinterpret_cast<char *> (&tmp), 4))
00367 return false;
00368 if (swap)
00369 swap_bytes<4> (&tmp);
00370 m.xcidx(i) = tmp;
00371 }
00372
00373 for (int i = 0; i < nz; i++)
00374 {
00375 octave_quit ();
00376 if (! is.read (reinterpret_cast<char *> (&tmp), 4))
00377 return false;
00378 if (swap)
00379 swap_bytes<4> (&tmp);
00380 m.xridx(i) = tmp;
00381 }
00382
00383 if (! is.read (reinterpret_cast<char *> (&ctmp), 1))
00384 return false;
00385
00386 read_doubles (is, m.xdata (), static_cast<save_type> (ctmp), nz, swap, fmt);
00387
00388 if (error_state || ! is)
00389 return false;
00390
00391 if (! m.indices_ok ())
00392 return false;
00393
00394 matrix = m;
00395
00396 return true;
00397 }
00398
00399 #if defined (HAVE_HDF5)
00400
00401 bool
00402 octave_sparse_matrix::save_hdf5 (hid_t loc_id, const char *name,
00403 bool save_as_floats)
00404 {
00405 dim_vector dv = dims ();
00406 int empty = save_hdf5_empty (loc_id, name, dv);
00407 if (empty)
00408 return (empty > 0);
00409
00410
00411 matrix.maybe_compress ();
00412
00413 #if HAVE_HDF5_18
00414 hid_t group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00415 #else
00416 hid_t group_hid = H5Gcreate (loc_id, name, 0);
00417 #endif
00418 if (group_hid < 0)
00419 return false;
00420
00421 hid_t space_hid = -1, data_hid = -1;
00422 bool retval = true;
00423 SparseMatrix m = sparse_matrix_value ();
00424 octave_idx_type tmp;
00425 hsize_t hdims[2];
00426
00427 space_hid = H5Screate_simple (0, hdims, 0);
00428 if (space_hid < 0)
00429 {
00430 H5Gclose (group_hid);
00431 return false;
00432 }
00433 #if HAVE_HDF5_18
00434 data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
00435 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00436 #else
00437 data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
00438 H5P_DEFAULT);
00439 #endif
00440 if (data_hid < 0)
00441 {
00442 H5Sclose (space_hid);
00443 H5Gclose (group_hid);
00444 return false;
00445 }
00446
00447 tmp = m.rows ();
00448 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00449 &tmp) >= 0;
00450 H5Dclose (data_hid);
00451 if (!retval)
00452 {
00453 H5Sclose (space_hid);
00454 H5Gclose (group_hid);
00455 return false;
00456 }
00457 #if HAVE_HDF5_18
00458 data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
00459 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00460 #else
00461 data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
00462 H5P_DEFAULT);
00463 #endif
00464 if (data_hid < 0)
00465 {
00466 H5Sclose (space_hid);
00467 H5Gclose (group_hid);
00468 return false;
00469 }
00470
00471 tmp = m.cols ();
00472 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00473 &tmp) >= 0;
00474 H5Dclose (data_hid);
00475 if (!retval)
00476 {
00477 H5Sclose (space_hid);
00478 H5Gclose (group_hid);
00479 return false;
00480 }
00481
00482 #if HAVE_HDF5_18
00483 data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
00484 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00485 #else
00486 data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
00487 H5P_DEFAULT);
00488 #endif
00489 if (data_hid < 0)
00490 {
00491 H5Sclose (space_hid);
00492 H5Gclose (group_hid);
00493 return false;
00494 }
00495
00496 tmp = m.nnz ();
00497 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00498 &tmp) >= 0;
00499 H5Dclose (data_hid);
00500 if (!retval)
00501 {
00502 H5Sclose (space_hid);
00503 H5Gclose (group_hid);
00504 return false;
00505 }
00506
00507 H5Sclose (space_hid);
00508
00509 hdims[0] = m.cols() + 1;
00510 hdims[1] = 1;
00511
00512 space_hid = H5Screate_simple (2, hdims, 0);
00513
00514 if (space_hid < 0)
00515 {
00516 H5Gclose (group_hid);
00517 return false;
00518 }
00519
00520 #if HAVE_HDF5_18
00521 data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
00522 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00523 #else
00524 data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
00525 H5P_DEFAULT);
00526 #endif
00527 if (data_hid < 0)
00528 {
00529 H5Sclose (space_hid);
00530 H5Gclose (group_hid);
00531 return false;
00532 }
00533
00534 octave_idx_type * itmp = m.xcidx ();
00535 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00536 itmp) >= 0;
00537 H5Dclose (data_hid);
00538 if (!retval)
00539 {
00540 H5Sclose (space_hid);
00541 H5Gclose (group_hid);
00542 return false;
00543 }
00544
00545 H5Sclose (space_hid);
00546
00547 hdims[0] = m.nnz ();
00548 hdims[1] = 1;
00549
00550 space_hid = H5Screate_simple (2, hdims, 0);
00551
00552 if (space_hid < 0)
00553 {
00554 H5Gclose (group_hid);
00555 return false;
00556 }
00557 #if HAVE_HDF5_18
00558 data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
00559 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00560 #else
00561 data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
00562 H5P_DEFAULT);
00563 #endif
00564 if (data_hid < 0)
00565 {
00566 H5Sclose (space_hid);
00567 H5Gclose (group_hid);
00568 return false;
00569 }
00570
00571 itmp = m.xridx ();
00572 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00573 itmp) >= 0;
00574 H5Dclose (data_hid);
00575 if (!retval)
00576 {
00577 H5Sclose (space_hid);
00578 H5Gclose (group_hid);
00579 return false;
00580 }
00581
00582 hid_t save_type_hid = H5T_NATIVE_DOUBLE;
00583
00584 if (save_as_floats)
00585 {
00586 if (m.too_large_for_float ())
00587 {
00588 warning ("save: some values too large to save as floats --");
00589 warning ("save: saving as doubles instead");
00590 }
00591 else
00592 save_type_hid = H5T_NATIVE_FLOAT;
00593 }
00594 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS
00595
00596 else
00597 {
00598 double max_val, min_val;
00599
00600 if (m.all_integers (max_val, min_val))
00601 save_type_hid
00602 = save_type_to_hdf5 (get_save_type (max_val, min_val));
00603 }
00604 #endif
00605
00606 #if HAVE_HDF5_18
00607 data_hid = H5Dcreate (group_hid, "data", save_type_hid, space_hid,
00608 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00609 #else
00610 data_hid = H5Dcreate (group_hid, "data", save_type_hid, space_hid,
00611 H5P_DEFAULT);
00612 #endif
00613 if (data_hid < 0)
00614 {
00615 H5Sclose (space_hid);
00616 H5Gclose (group_hid);
00617 return false;
00618 }
00619
00620 double * dtmp = m.xdata ();
00621 retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
00622 H5P_DEFAULT, dtmp) >= 0;
00623 H5Dclose (data_hid);
00624 H5Sclose (space_hid);
00625 H5Gclose (group_hid);
00626
00627 return retval;
00628 }
00629
00630 bool
00631 octave_sparse_matrix::load_hdf5 (hid_t loc_id, const char *name)
00632 {
00633 octave_idx_type nr, nc, nz;
00634 hid_t group_hid, data_hid, space_hid;
00635 hsize_t rank;
00636
00637 dim_vector dv;
00638 int empty = load_hdf5_empty (loc_id, name, dv);
00639 if (empty > 0)
00640 matrix.resize(dv);
00641 if (empty)
00642 return (empty > 0);
00643
00644 #if HAVE_HDF5_18
00645 group_hid = H5Gopen (loc_id, name, H5P_DEFAULT);
00646 #else
00647 group_hid = H5Gopen (loc_id, name);
00648 #endif
00649 if (group_hid < 0) return false;
00650
00651 #if HAVE_HDF5_18
00652 data_hid = H5Dopen (group_hid, "nr", H5P_DEFAULT);
00653 #else
00654 data_hid = H5Dopen (group_hid, "nr");
00655 #endif
00656 space_hid = H5Dget_space (data_hid);
00657 rank = H5Sget_simple_extent_ndims (space_hid);
00658
00659 if (rank != 0)
00660 {
00661 H5Dclose (data_hid);
00662 H5Gclose (group_hid);
00663 return false;
00664 }
00665
00666 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
00667 H5P_DEFAULT, &nr) < 0)
00668 {
00669 H5Dclose (data_hid);
00670 H5Gclose (group_hid);
00671 return false;
00672 }
00673
00674 H5Dclose (data_hid);
00675
00676 #if HAVE_HDF5_18
00677 data_hid = H5Dopen (group_hid, "nc", H5P_DEFAULT);
00678 #else
00679 data_hid = H5Dopen (group_hid, "nc");
00680 #endif
00681 space_hid = H5Dget_space (data_hid);
00682 rank = H5Sget_simple_extent_ndims (space_hid);
00683
00684 if (rank != 0)
00685 {
00686 H5Dclose (data_hid);
00687 H5Gclose (group_hid);
00688 return false;
00689 }
00690
00691 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
00692 H5P_DEFAULT, &nc) < 0)
00693 {
00694 H5Dclose (data_hid);
00695 H5Gclose (group_hid);
00696 return false;
00697 }
00698
00699 H5Dclose (data_hid);
00700
00701 #if HAVE_HDF5_18
00702 data_hid = H5Dopen (group_hid, "nz", H5P_DEFAULT);
00703 #else
00704 data_hid = H5Dopen (group_hid, "nz");
00705 #endif
00706 space_hid = H5Dget_space (data_hid);
00707 rank = H5Sget_simple_extent_ndims (space_hid);
00708
00709 if (rank != 0)
00710 {
00711 H5Dclose (data_hid);
00712 H5Gclose (group_hid);
00713 return false;
00714 }
00715
00716 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
00717 H5P_DEFAULT, &nz) < 0)
00718 {
00719 H5Dclose (data_hid);
00720 H5Gclose (group_hid);
00721 return false;
00722 }
00723
00724 H5Dclose (data_hid);
00725
00726 SparseMatrix m (static_cast<octave_idx_type> (nr),
00727 static_cast<octave_idx_type> (nc),
00728 static_cast<octave_idx_type> (nz));
00729
00730 #if HAVE_HDF5_18
00731 data_hid = H5Dopen (group_hid, "cidx", H5P_DEFAULT);
00732 #else
00733 data_hid = H5Dopen (group_hid, "cidx");
00734 #endif
00735 space_hid = H5Dget_space (data_hid);
00736 rank = H5Sget_simple_extent_ndims (space_hid);
00737
00738 if (rank != 2)
00739 {
00740 H5Sclose (space_hid);
00741 H5Dclose (data_hid);
00742 H5Gclose (group_hid);
00743 return false;
00744 }
00745
00746 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
00747 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
00748
00749 H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
00750
00751 if (static_cast<int> (hdims[0]) != nc + 1
00752 || static_cast<int> (hdims[1]) != 1)
00753 {
00754 H5Sclose (space_hid);
00755 H5Dclose (data_hid);
00756 H5Gclose (group_hid);
00757 return false;
00758 }
00759
00760 octave_idx_type *itmp = m.xcidx ();
00761 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
00762 H5P_DEFAULT, itmp) < 0)
00763 {
00764 H5Sclose (space_hid);
00765 H5Dclose (data_hid);
00766 H5Gclose (group_hid);
00767 return false;
00768 }
00769
00770 H5Sclose (space_hid);
00771 H5Dclose (data_hid);
00772
00773 #if HAVE_HDF5_18
00774 data_hid = H5Dopen (group_hid, "ridx", H5P_DEFAULT);
00775 #else
00776 data_hid = H5Dopen (group_hid, "ridx");
00777 #endif
00778 space_hid = H5Dget_space (data_hid);
00779 rank = H5Sget_simple_extent_ndims (space_hid);
00780
00781 if (rank != 2)
00782 {
00783 H5Sclose (space_hid);
00784 H5Dclose (data_hid);
00785 H5Gclose (group_hid);
00786 return false;
00787 }
00788
00789 H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
00790
00791 if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1)
00792 {
00793 H5Sclose (space_hid);
00794 H5Dclose (data_hid);
00795 H5Gclose (group_hid);
00796 return false;
00797 }
00798
00799 itmp = m.xridx ();
00800 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
00801 H5P_DEFAULT, itmp) < 0)
00802 {
00803 H5Sclose (space_hid);
00804 H5Dclose (data_hid);
00805 H5Gclose (group_hid);
00806 return false;
00807 }
00808
00809 H5Sclose (space_hid);
00810 H5Dclose (data_hid);
00811
00812 #if HAVE_HDF5_18
00813 data_hid = H5Dopen (group_hid, "data", H5P_DEFAULT);
00814 #else
00815 data_hid = H5Dopen (group_hid, "data");
00816 #endif
00817 space_hid = H5Dget_space (data_hid);
00818 rank = H5Sget_simple_extent_ndims (space_hid);
00819
00820 if (rank != 2)
00821 {
00822 H5Sclose (space_hid);
00823 H5Dclose (data_hid);
00824 H5Gclose (group_hid);
00825 return false;
00826 }
00827
00828 H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
00829
00830 if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1)
00831 {
00832 H5Sclose (space_hid);
00833 H5Dclose (data_hid);
00834 H5Gclose (group_hid);
00835 return false;
00836 }
00837
00838 double *dtmp = m.xdata ();
00839 bool retval = false;
00840 if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
00841 H5P_DEFAULT, dtmp) >= 0
00842 && m.indices_ok ())
00843 {
00844 retval = true;
00845 matrix = m;
00846 }
00847
00848 H5Sclose (space_hid);
00849 H5Dclose (data_hid);
00850 H5Gclose (group_hid);
00851
00852 return retval;
00853 }
00854
00855 #endif
00856
00857 mxArray *
00858 octave_sparse_matrix::as_mxArray (void) const
00859 {
00860 mwSize nz = nzmax();
00861 mwSize nr = rows();
00862 mwSize nc = columns();
00863 mxArray *retval = new mxArray (mxDOUBLE_CLASS, nr, nc, nz, mxREAL);
00864 double *pr = static_cast<double *> (retval->get_data ());
00865 mwIndex *ir = retval->get_ir();
00866 mwIndex *jc = retval->get_jc();
00867
00868 for (mwIndex i = 0; i < nz; i++)
00869 {
00870 pr[i] = matrix.data(i);
00871 ir[i] = matrix.ridx(i);
00872 }
00873
00874 for (mwIndex i = 0; i < nc + 1; i++)
00875 jc[i] = matrix.cidx(i);
00876
00877 return retval;
00878 }
00879
00880 octave_value
00881 octave_sparse_matrix::map (unary_mapper_t umap) const
00882 {
00883 switch (umap)
00884 {
00885 case umap_imag:
00886 return SparseMatrix (matrix.rows (), matrix.cols (), 0.0);
00887
00888 case umap_real:
00889 case umap_conj:
00890 return matrix;
00891
00892
00893 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \
00894 case umap_ ## UMAP: \
00895 return octave_value (matrix.FCN ())
00896
00897 ARRAY_METHOD_MAPPER (abs, abs);
00898
00899 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \
00900 case umap_ ## UMAP: \
00901 return octave_value (matrix.map<TYPE> (FCN))
00902
00903 ARRAY_MAPPER (acos, Complex, rc_acos);
00904 ARRAY_MAPPER (acosh, Complex, rc_acosh);
00905 ARRAY_MAPPER (angle, double, ::arg);
00906 ARRAY_MAPPER (arg, double, ::arg);
00907 ARRAY_MAPPER (asin, Complex, rc_asin);
00908 ARRAY_MAPPER (asinh, double, ::asinh);
00909 ARRAY_MAPPER (atan, double, ::atan);
00910 ARRAY_MAPPER (atanh, Complex, rc_atanh);
00911 ARRAY_MAPPER (erf, double, ::erf);
00912 ARRAY_MAPPER (erfinv, double, ::erfinv);
00913 ARRAY_MAPPER (erfc, double, ::erfc);
00914 ARRAY_MAPPER (gamma, double, xgamma);
00915 ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
00916 ARRAY_MAPPER (cbrt, double, ::cbrt);
00917 ARRAY_MAPPER (ceil, double, ::ceil);
00918 ARRAY_MAPPER (cos, double, ::cos);
00919 ARRAY_MAPPER (cosh, double, ::cosh);
00920 ARRAY_MAPPER (exp, double, ::exp);
00921 ARRAY_MAPPER (expm1, double, ::expm1);
00922 ARRAY_MAPPER (fix, double, ::fix);
00923 ARRAY_MAPPER (floor, double, ::floor);
00924 ARRAY_MAPPER (log, Complex, rc_log);
00925 ARRAY_MAPPER (log2, Complex, rc_log2);
00926 ARRAY_MAPPER (log10, Complex, rc_log10);
00927 ARRAY_MAPPER (log1p, Complex, rc_log1p);
00928 ARRAY_MAPPER (round, double, xround);
00929 ARRAY_MAPPER (roundb, double, xroundb);
00930 ARRAY_MAPPER (signum, double, ::signum);
00931 ARRAY_MAPPER (sin, double, ::sin);
00932 ARRAY_MAPPER (sinh, double, ::sinh);
00933 ARRAY_MAPPER (sqrt, Complex, rc_sqrt);
00934 ARRAY_MAPPER (tan, double, ::tan);
00935 ARRAY_MAPPER (tanh, double, ::tanh);
00936 ARRAY_MAPPER (isnan, bool, xisnan);
00937 ARRAY_MAPPER (isna, bool, octave_is_NA);
00938 ARRAY_MAPPER (isinf, bool, xisinf);
00939 ARRAY_MAPPER (finite, bool, xfinite);
00940
00941 default:
00942 return octave_base_sparse<SparseMatrix>::map (umap);
00943 }
00944 }