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 <iostream>
00029 #include <vector>
00030
00031 #include "lo-ieee.h"
00032 #include "mx-base.h"
00033 #include "oct-locbuf.h"
00034
00035 #include "defun.h"
00036 #include "gripes.h"
00037 #include "oct-obj.h"
00038 #include "ops.h"
00039 #include "ov-base.h"
00040 #include "ov-base-mat.h"
00041 #include "ov-base-mat.cc"
00042 #include "ov-bool.h"
00043 #include "ov-bool-mat.h"
00044 #include "ov-re-mat.h"
00045 #include "pr-output.h"
00046
00047 #include "byte-swap.h"
00048 #include "ls-oct-ascii.h"
00049 #include "ls-hdf5.h"
00050 #include "ls-utils.h"
00051
00052 template class octave_base_matrix<boolNDArray>;
00053
00054 DEFINE_OCTAVE_ALLOCATOR (octave_bool_matrix);
00055
00056 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool_matrix,
00057 "bool matrix", "logical");
00058
00059 static octave_base_value *
00060 default_numeric_conversion_function (const octave_base_value& a)
00061 {
00062 CAST_CONV_ARG (const octave_bool_matrix&);
00063
00064 return new octave_matrix (NDArray (v.bool_array_value ()));
00065 }
00066
00067 octave_base_value::type_conv_info
00068 octave_bool_matrix::numeric_conversion_function (void) const
00069 {
00070 return octave_base_value::type_conv_info (default_numeric_conversion_function,
00071 octave_matrix::static_type_id ());
00072 }
00073
00074 octave_base_value *
00075 octave_bool_matrix::try_narrowing_conversion (void)
00076 {
00077 octave_base_value *retval = 0;
00078
00079 if (matrix.ndims () == 2)
00080 {
00081 boolMatrix bm = matrix.matrix_value ();
00082
00083 octave_idx_type nr = bm.rows ();
00084 octave_idx_type nc = bm.cols ();
00085
00086 if (nr == 1 && nc == 1)
00087 retval = new octave_bool (bm (0, 0));
00088 }
00089
00090 return retval;
00091 }
00092
00093 double
00094 octave_bool_matrix::double_value (bool) const
00095 {
00096 double retval = lo_ieee_nan_value ();
00097
00098 if (rows () > 0 && columns () > 0)
00099 {
00100 gripe_implicit_conversion ("Octave:array-as-scalar",
00101 "bool matrix", "real scalar");
00102
00103 retval = matrix (0, 0);
00104 }
00105 else
00106 gripe_invalid_conversion ("bool matrix", "real scalar");
00107
00108 return retval;
00109 }
00110
00111 float
00112 octave_bool_matrix::float_value (bool) const
00113 {
00114 float retval = lo_ieee_float_nan_value ();
00115
00116 if (rows () > 0 && columns () > 0)
00117 {
00118 gripe_implicit_conversion ("Octave:array-as-scalar",
00119 "bool matrix", "real scalar");
00120
00121 retval = matrix (0, 0);
00122 }
00123 else
00124 gripe_invalid_conversion ("bool matrix", "real scalar");
00125
00126 return retval;
00127 }
00128
00129 Complex
00130 octave_bool_matrix::complex_value (bool) const
00131 {
00132 double tmp = lo_ieee_nan_value ();
00133
00134 Complex retval (tmp, tmp);
00135
00136 if (rows () > 0 && columns () > 0)
00137 {
00138 gripe_implicit_conversion ("Octave:array-as-scalar",
00139 "bool matrix", "complex scalar");
00140
00141 retval = matrix (0, 0);
00142 }
00143 else
00144 gripe_invalid_conversion ("bool matrix", "complex scalar");
00145
00146 return retval;
00147 }
00148
00149 FloatComplex
00150 octave_bool_matrix::float_complex_value (bool) const
00151 {
00152 float tmp = lo_ieee_float_nan_value ();
00153
00154 FloatComplex retval (tmp, tmp);
00155
00156 if (rows () > 0 && columns () > 0)
00157 {
00158 gripe_implicit_conversion ("Octave:array-as-scalar",
00159 "bool matrix", "complex scalar");
00160
00161 retval = matrix (0, 0);
00162 }
00163 else
00164 gripe_invalid_conversion ("bool matrix", "complex scalar");
00165
00166 return retval;
00167 }
00168
00169 octave_value
00170 octave_bool_matrix::convert_to_str_internal (bool pad, bool force,
00171 char type) const
00172 {
00173 octave_value tmp = octave_value (array_value ());
00174 return tmp.convert_to_str (pad, force, type);
00175 }
00176
00177 void
00178 octave_bool_matrix::print_raw (std::ostream& os,
00179 bool pr_as_read_syntax) const
00180 {
00181 octave_print_internal (os, matrix, pr_as_read_syntax,
00182 current_print_indent_level ());
00183 }
00184
00185 bool
00186 octave_bool_matrix::save_ascii (std::ostream& os)
00187 {
00188 dim_vector d = dims ();
00189 if (d.length () > 2)
00190 {
00191 NDArray tmp = array_value ();
00192 os << "# ndims: " << d.length () << "\n";
00193
00194 for (int i = 0; i < d.length (); i++)
00195 os << " " << d (i);
00196
00197 os << "\n" << tmp;
00198 }
00199 else
00200 {
00201
00202
00203 os << "# rows: " << rows () << "\n"
00204 << "# columns: " << columns () << "\n";
00205
00206 Matrix tmp = matrix_value ();
00207
00208 os << tmp;
00209 }
00210
00211 return true;
00212 }
00213
00214 bool
00215 octave_bool_matrix::load_ascii (std::istream& is)
00216 {
00217 bool success = true;
00218
00219 string_vector keywords (2);
00220
00221 keywords[0] = "ndims";
00222 keywords[1] = "rows";
00223
00224 std::string kw;
00225 octave_idx_type val = 0;
00226
00227 if (extract_keyword (is, keywords, kw, val, true))
00228 {
00229 if (kw == "ndims")
00230 {
00231 int mdims = static_cast<int> (val);
00232
00233 if (mdims >= 0)
00234 {
00235 dim_vector dv;
00236 dv.resize (mdims);
00237
00238 for (int i = 0; i < mdims; i++)
00239 is >> dv(i);
00240
00241 if (is)
00242 {
00243 boolNDArray btmp (dv);
00244
00245 if (btmp.is_empty ())
00246 matrix = btmp;
00247 else
00248 {
00249 NDArray tmp(dv);
00250 is >> tmp;
00251
00252 if (is)
00253 {
00254 for (octave_idx_type i = 0; i < btmp.nelem (); i++)
00255 btmp.elem (i) = (tmp.elem (i) != 0.);
00256
00257 matrix = btmp;
00258 }
00259 else
00260 {
00261 error ("load: failed to load matrix constant");
00262 success = false;
00263 }
00264 }
00265 }
00266 else
00267 {
00268 error ("load: failed to extract dimensions");
00269 success = false;
00270 }
00271 }
00272 else
00273 {
00274 error ("load: failed to extract number of dimensions");
00275 success = false;
00276 }
00277 }
00278 else if (kw == "rows")
00279 {
00280 octave_idx_type nr = val;
00281 octave_idx_type nc = 0;
00282
00283 if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
00284 {
00285 if (nr > 0 && nc > 0)
00286 {
00287 Matrix tmp (nr, nc);
00288 is >> tmp;
00289 if (is)
00290 {
00291 boolMatrix btmp (nr, nc);
00292 for (octave_idx_type j = 0; j < nc; j++)
00293 for (octave_idx_type i = 0; i < nr; i++)
00294 btmp.elem (i,j) = (tmp.elem (i, j) != 0.);
00295
00296 matrix = btmp;
00297 }
00298 else
00299 {
00300 error ("load: failed to load matrix constant");
00301 success = false;
00302 }
00303 }
00304 else if (nr == 0 || nc == 0)
00305 matrix = boolMatrix (nr, nc);
00306 else
00307 panic_impossible ();
00308 }
00309 else
00310 {
00311 error ("load: failed to extract number of rows and columns");
00312 success = false;
00313 }
00314 }
00315 else
00316 panic_impossible ();
00317 }
00318 else
00319 {
00320 error ("load: failed to extract number of rows and columns");
00321 success = false;
00322 }
00323
00324 return success;
00325 }
00326
00327 bool
00328 octave_bool_matrix::save_binary (std::ostream& os, bool& )
00329 {
00330
00331 dim_vector d = dims ();
00332 if (d.length() < 1)
00333 return false;
00334
00335
00336 int32_t tmp = - d.length();
00337 os.write (reinterpret_cast<char *> (&tmp), 4);
00338 for (int i = 0; i < d.length (); i++)
00339 {
00340 tmp = d(i);
00341 os.write (reinterpret_cast<char *> (&tmp), 4);
00342 }
00343
00344 boolNDArray m = bool_array_value ();
00345 bool *mtmp = m.fortran_vec ();
00346 octave_idx_type nel = m.nelem ();
00347 OCTAVE_LOCAL_BUFFER (char, htmp, nel);
00348
00349 for (octave_idx_type i = 0; i < nel; i++)
00350 htmp[i] = (mtmp[i] ? 1 : 0);
00351
00352 os.write (htmp, nel);
00353
00354 return true;
00355 }
00356
00357 bool
00358 octave_bool_matrix::load_binary (std::istream& is, bool swap,
00359 oct_mach_info::float_format )
00360 {
00361 int32_t mdims;
00362 if (! is.read (reinterpret_cast<char *> (&mdims), 4))
00363 return false;
00364 if (swap)
00365 swap_bytes<4> (&mdims);
00366 if (mdims >= 0)
00367 return false;
00368
00369
00370
00371
00372 mdims = - mdims;
00373 int32_t di;
00374 dim_vector dv;
00375 dv.resize (mdims);
00376
00377 for (int i = 0; i < mdims; i++)
00378 {
00379 if (! is.read (reinterpret_cast<char *> (&di), 4))
00380 return false;
00381 if (swap)
00382 swap_bytes<4> (&di);
00383 dv(i) = di;
00384 }
00385
00386
00387
00388
00389
00390 if (mdims == 1)
00391 {
00392 mdims = 2;
00393 dv.resize (mdims);
00394 dv(1) = dv(0);
00395 dv(0) = 1;
00396 }
00397
00398 octave_idx_type nel = dv.numel ();
00399 OCTAVE_LOCAL_BUFFER (char, htmp, nel);
00400 if (! is.read (htmp, nel))
00401 return false;
00402 boolNDArray m(dv);
00403 bool *mtmp = m.fortran_vec ();
00404 for (octave_idx_type i = 0; i < nel; i++)
00405 mtmp[i] = (htmp[i] ? 1 : 0);
00406 matrix = m;
00407
00408 return true;
00409 }
00410
00411 #if defined (HAVE_HDF5)
00412
00413 bool
00414 octave_bool_matrix::save_hdf5 (hid_t loc_id, const char *name,
00415 bool )
00416 {
00417 dim_vector dv = dims ();
00418 int empty = save_hdf5_empty (loc_id, name, dv);
00419 if (empty)
00420 return (empty > 0);
00421
00422 int rank = dv.length ();
00423 hid_t space_hid = -1, data_hid = -1;
00424 bool retval = true;
00425 boolNDArray m = bool_array_value ();
00426
00427 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
00428
00429
00430 for (int i = 0; i < rank; i++)
00431 hdims[i] = dv (rank-i-1);
00432
00433 space_hid = H5Screate_simple (rank, hdims, 0);
00434 if (space_hid < 0) return false;
00435 #if HAVE_HDF5_18
00436 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_HBOOL, space_hid,
00437 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00438 #else
00439 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_HBOOL, space_hid,
00440 H5P_DEFAULT);
00441 #endif
00442 if (data_hid < 0)
00443 {
00444 H5Sclose (space_hid);
00445 return false;
00446 }
00447
00448 octave_idx_type nel = m.nelem ();
00449 bool *mtmp = m.fortran_vec ();
00450 OCTAVE_LOCAL_BUFFER (hbool_t, htmp, nel);
00451
00452 for (octave_idx_type i = 0; i < nel; i++)
00453 htmp[i] = mtmp[i];
00454
00455 retval = H5Dwrite (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL,
00456 H5P_DEFAULT, htmp) >= 0;
00457
00458 H5Dclose (data_hid);
00459 H5Sclose (space_hid);
00460
00461 return retval;
00462 }
00463
00464 bool
00465 octave_bool_matrix::load_hdf5 (hid_t loc_id, const char *name)
00466 {
00467 bool retval = false;
00468
00469 dim_vector dv;
00470 int empty = load_hdf5_empty (loc_id, name, dv);
00471 if (empty > 0)
00472 matrix.resize(dv);
00473 if (empty)
00474 return (empty > 0);
00475
00476 #if HAVE_HDF5_18
00477 hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
00478 #else
00479 hid_t data_hid = H5Dopen (loc_id, name);
00480 #endif
00481 hid_t space_id = H5Dget_space (data_hid);
00482
00483 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
00484
00485 if (rank < 1)
00486 {
00487 H5Dclose (data_hid);
00488 return false;
00489 }
00490
00491 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
00492 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
00493
00494 H5Sget_simple_extent_dims (space_id, hdims, maxdims);
00495
00496
00497 if (rank == 1)
00498 {
00499 dv.resize (2);
00500 dv(0) = 1;
00501 dv(1) = hdims[0];
00502 }
00503 else
00504 {
00505 dv.resize (rank);
00506 for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
00507 dv(j) = hdims[i];
00508 }
00509
00510 octave_idx_type nel = dv.numel ();
00511 OCTAVE_LOCAL_BUFFER (hbool_t, htmp, nel);
00512 if (H5Dread (data_hid, H5T_NATIVE_HBOOL, H5S_ALL, H5S_ALL, H5P_DEFAULT, htmp) >= 0)
00513 {
00514 retval = true;
00515
00516 boolNDArray btmp (dv);
00517 for (octave_idx_type i = 0; i < nel; i++)
00518 btmp.elem (i) = htmp[i];
00519
00520 matrix = btmp;
00521 }
00522
00523 H5Dclose (data_hid);
00524
00525 return retval;
00526 }
00527
00528 #endif
00529
00530 mxArray *
00531 octave_bool_matrix::as_mxArray (void) const
00532 {
00533 mxArray *retval = new mxArray (mxLOGICAL_CLASS, dims (), mxREAL);
00534
00535 bool *pr = static_cast<bool *> (retval->get_data ());
00536
00537 mwSize nel = numel ();
00538
00539 const bool *p = matrix.data ();
00540
00541 for (mwIndex i = 0; i < nel; i++)
00542 pr[i] = p[i];
00543
00544 return retval;
00545 }
00546
00547 DEFUN (logical, args, ,
00548 "-*- texinfo -*-\n\
00549 @deftypefn {Built-in Function} {} logical (@var{x})\n\
00550 Convert @var{x} to logical type.\n\
00551 @seealso{double, single, char}\n\
00552 @end deftypefn")
00553 {
00554 octave_value retval;
00555
00556 if (args.length () == 1)
00557 {
00558 octave_value arg = args(0);
00559 if (arg.is_bool_type ())
00560 retval = arg;
00561 else if (arg.is_numeric_type ())
00562 {
00563 if (arg.is_sparse_type ())
00564 retval = arg.sparse_bool_matrix_value ();
00565 else if (arg.is_scalar_type ())
00566 retval = arg.bool_value ();
00567 else
00568 retval = arg.bool_array_value ();
00569 }
00570 else
00571 gripe_wrong_type_arg ("logical", arg);
00572 }
00573 else
00574 print_usage ();
00575
00576 return retval;
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589