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