00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <iomanip>
00030 #include <iostream>
00031
00032 #include "oct-obj.h"
00033 #include "ov-base.h"
00034 #include "quit.h"
00035 #include "pr-output.h"
00036
00037 #include "byte-swap.h"
00038 #include "ls-oct-ascii.h"
00039 #include "ls-utils.h"
00040 #include "ls-hdf5.h"
00041
00042 #include "boolSparse.h"
00043 #include "ov-base-sparse.h"
00044 #include "pager.h"
00045
00046 template <class T>
00047 octave_value
00048 octave_base_sparse<T>::do_index_op (const octave_value_list& idx,
00049 bool resize_ok)
00050 {
00051 octave_value retval;
00052
00053 octave_idx_type n_idx = idx.length ();
00054
00055 switch (n_idx)
00056 {
00057 case 0:
00058 retval = matrix;
00059 break;
00060
00061 case 1:
00062 {
00063 idx_vector i = idx (0).index_vector ();
00064
00065 if (! error_state)
00066 retval = octave_value (matrix.index (i, resize_ok));
00067 }
00068 break;
00069
00070 case 2:
00071 {
00072 idx_vector i = idx (0).index_vector ();
00073
00074 if (! error_state)
00075 {
00076 idx_vector j = idx (1).index_vector ();
00077
00078 if (! error_state)
00079 retval = octave_value (matrix.index (i, j, resize_ok));
00080 }
00081 }
00082 break;
00083 default:
00084 error ("sparse indexing needs 1 or 2 indices");
00085 }
00086
00087 return retval;
00088 }
00089
00090 template <class T>
00091 octave_value
00092 octave_base_sparse<T>::subsref (const std::string& type,
00093 const std::list<octave_value_list>& idx)
00094 {
00095 octave_value retval;
00096
00097 switch (type[0])
00098 {
00099 case '(':
00100 retval = do_index_op (idx.front ());
00101 break;
00102
00103 case '{':
00104 case '.':
00105 {
00106 std::string nm = type_name ();
00107 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00108 }
00109 break;
00110
00111 default:
00112 panic_impossible ();
00113 }
00114
00115 return retval.next_subsref (type, idx);
00116 }
00117
00118 template <class T>
00119 octave_value
00120 octave_base_sparse<T>::subsasgn (const std::string& type,
00121 const std::list<octave_value_list>& idx,
00122 const octave_value& rhs)
00123 {
00124 octave_value retval;
00125
00126 switch (type[0])
00127 {
00128 case '(':
00129 {
00130 if (type.length () == 1)
00131 retval = numeric_assign (type, idx, rhs);
00132 else
00133 {
00134 std::string nm = type_name ();
00135 error ("in indexed assignment of %s, last lhs index must be ()",
00136 nm.c_str ());
00137 }
00138 }
00139 break;
00140
00141 case '{':
00142 case '.':
00143 {
00144 if (is_empty ())
00145 {
00146 octave_value tmp = octave_value::empty_conv (type, rhs);
00147
00148 retval = tmp.subsasgn (type, idx, rhs);
00149 }
00150 else
00151 {
00152 std::string nm = type_name ();
00153 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00154 }
00155 }
00156 break;
00157
00158 default:
00159 panic_impossible ();
00160 }
00161
00162 return retval;
00163 }
00164
00165 template <class T>
00166 void
00167 octave_base_sparse<T>::assign (const octave_value_list& idx, const T& rhs)
00168 {
00169
00170 octave_idx_type len = idx.length ();
00171
00172 switch (len)
00173 {
00174 case 1:
00175 {
00176 idx_vector i = idx (0).index_vector ();
00177
00178 if (! error_state)
00179 matrix.assign (i, rhs);
00180
00181 break;
00182 }
00183
00184 case 2:
00185 {
00186 idx_vector i = idx (0).index_vector ();
00187
00188 if (! error_state)
00189 {
00190 idx_vector j = idx (1).index_vector ();
00191
00192 if (! error_state)
00193 matrix.assign (i, j, rhs);
00194 }
00195
00196 break;
00197 }
00198
00199 default:
00200 error ("sparse indexing needs 1 or 2 indices");
00201 }
00202
00203
00204
00205 typ.invalidate_type ();
00206 }
00207
00208 template <class MT>
00209 void
00210 octave_base_sparse<MT>::delete_elements (const octave_value_list& idx)
00211 {
00212 octave_idx_type len = idx.length ();
00213
00214 switch (len)
00215 {
00216 case 1:
00217 {
00218 idx_vector i = idx (0).index_vector ();
00219
00220 if (! error_state)
00221 matrix.delete_elements (i);
00222
00223 break;
00224 }
00225
00226 case 2:
00227 {
00228 idx_vector i = idx (0).index_vector ();
00229
00230 if (! error_state)
00231 {
00232 idx_vector j = idx (1).index_vector ();
00233
00234 if (! error_state)
00235 matrix.delete_elements (i, j);
00236 }
00237
00238 break;
00239 }
00240
00241 default:
00242 error ("sparse indexing needs 1 or 2 indices");
00243 }
00244
00245
00246 typ.invalidate_type ();
00247 }
00248
00249 template <class T>
00250 octave_value
00251 octave_base_sparse<T>::resize (const dim_vector& dv, bool) const
00252 {
00253 T retval (matrix);
00254 retval.resize (dv);
00255 return retval;
00256 }
00257
00258 template <class T>
00259 bool
00260 octave_base_sparse<T>::is_true (void) const
00261 {
00262 bool retval = false;
00263 dim_vector dv = matrix.dims ();
00264 octave_idx_type nel = dv.numel ();
00265 octave_idx_type nz = nnz ();
00266
00267 if (nz == nel && nel > 0)
00268 {
00269 T t1 (matrix.reshape (dim_vector (nel, 1)));
00270
00271 SparseBoolMatrix t2 = t1.all ();
00272
00273 retval = t2(0);
00274 }
00275
00276 return retval;
00277 }
00278
00279 template <class T>
00280 bool
00281 octave_base_sparse<T>::print_as_scalar (void) const
00282 {
00283 dim_vector dv = dims ();
00284
00285 return (dv.all_ones () || dv.any_zero ());
00286 }
00287
00288 template <class T>
00289 void
00290 octave_base_sparse<T>::print (std::ostream& os, bool pr_as_read_syntax) const
00291 {
00292 print_raw (os, pr_as_read_syntax);
00293 newline (os);
00294 }
00295
00296 template <class T>
00297 void
00298 octave_base_sparse<T>::print_info (std::ostream& os,
00299 const std::string& prefix) const
00300 {
00301 matrix.print_info (os, prefix);
00302 }
00303
00304 template <class T>
00305 void
00306 octave_base_sparse<T>::print_raw (std::ostream& os,
00307 bool pr_as_read_syntax) const
00308 {
00309 octave_idx_type nr = matrix.rows ();
00310 octave_idx_type nc = matrix.cols ();
00311 octave_idx_type nz = nnz ();
00312
00313
00314
00315
00316
00317 os << "Compressed Column Sparse (rows = " << nr
00318 << ", cols = " << nc
00319 << ", nnz = " << nz;
00320
00321
00322
00323
00324
00325 double dnr = nr;
00326 double dnc = nc;
00327 double dnel = dnr * dnc;
00328
00329 if (dnel > 0)
00330 {
00331 double pct = (nz / dnel * 100);
00332
00333 int prec = 2;
00334
00335
00336
00337
00338
00339
00340 if (pct == 100)
00341 prec = 3;
00342 else
00343 {
00344 if (pct > 99.9)
00345 prec = 4;
00346 else if (pct > 99)
00347 prec = 3;
00348
00349 if (pct > 99.99)
00350 pct = 99.99;
00351 }
00352
00353 os << " [" << std::setprecision (prec) << pct << "%]";
00354 }
00355
00356 os << ")\n";
00357
00358
00359
00360
00361 if (nz != 0)
00362 {
00363 for (octave_idx_type j = 0; j < nc; j++)
00364 {
00365 octave_quit ();
00366
00367
00368
00369
00370
00371
00372
00373 for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++)
00374 {
00375 os << "\n";
00376 os << " (" << matrix.ridx(i)+1 <<
00377 ", " << j+1 << ") -> ";
00378
00379 octave_print_internal (os, matrix.data(i), pr_as_read_syntax);
00380 }
00381 }
00382 }
00383 }
00384
00385 template <class T>
00386 bool
00387 octave_base_sparse<T>::save_ascii (std::ostream& os)
00388 {
00389 dim_vector dv = this->dims ();
00390
00391
00392 matrix.maybe_compress ();
00393
00394 os << "# nnz: " << nnz () << "\n";
00395 os << "# rows: " << dv (0) << "\n";
00396 os << "# columns: " << dv (1) << "\n";
00397
00398 os << this->matrix;
00399
00400 return true;
00401 }
00402
00403 template <class T>
00404 bool
00405 octave_base_sparse<T>::load_ascii (std::istream& is)
00406 {
00407 octave_idx_type nz = 0;
00408 octave_idx_type nr = 0;
00409 octave_idx_type nc = 0;
00410 bool success = true;
00411
00412 if (extract_keyword (is, "nnz", nz, true) &&
00413 extract_keyword (is, "rows", nr, true) &&
00414 extract_keyword (is, "columns", nc, true))
00415 {
00416 T tmp (nr, nc, nz);
00417
00418 is >> tmp;
00419
00420 if (!is)
00421 {
00422 error ("load: failed to load matrix constant");
00423 success = false;
00424 }
00425
00426 matrix = tmp;
00427 }
00428 else
00429 {
00430 error ("load: failed to extract number of rows and columns");
00431 success = false;
00432 }
00433
00434 return success;
00435 }
00436
00437 template <class T>
00438 octave_value
00439 octave_base_sparse<T>::map (octave_base_value::unary_mapper_t umap) const
00440 {
00441
00442 octave_value retval = this->full_value ().map (umap);
00443
00444
00445
00446 if (umap >= umap_xisalnum && umap <= umap_xtoupper)
00447 return retval;
00448
00449 switch (retval.builtin_type ())
00450 {
00451 case btyp_double:
00452 retval = retval.sparse_matrix_value ();
00453 break;
00454 case btyp_complex:
00455 retval = retval.sparse_complex_matrix_value ();
00456 break;
00457 case btyp_bool:
00458 retval = retval.sparse_bool_matrix_value ();
00459 break;
00460 default:
00461 break;
00462 }
00463
00464 return retval;
00465 }