GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ov-perm.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2008-2017 Jaroslav Hajek
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include "byte-swap.h"
28 #include "dim-vector.h"
29 
30 #include "mxarray.h"
31 #include "ov-perm.h"
32 #include "ov-re-mat.h"
33 #include "ov-scalar.h"
34 #include "error.h"
35 #include "errwarn.h"
36 #include "ops.h"
37 #include "pr-output.h"
38 
39 #include "ls-oct-text.h"
40 
43  const std::list<octave_value_list>& idx)
44 {
46 
47  switch (type[0])
48  {
49  case '(':
50  retval = do_index_op (idx.front ());
51  break;
52 
53  case '{':
54  case '.':
55  {
57  error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
58  }
59  break;
60 
61  default:
63  }
64 
65  return retval.next_subsref (type, idx);
66 }
67 
70  bool resize_ok)
71 {
73  octave_idx_type nidx = idx.length ();
74  idx_vector idx0, idx1;
75  if (nidx == 2)
76  {
77  int k = 0; // index we're processing when index_vector throws
78  try
79  {
80  idx0 = idx(0).index_vector ();
81  k = 1;
82  idx1 = idx(1).index_vector ();
83  }
84  catch (octave::index_exception& e)
85  {
86  // Rethrow to allow more info to be reported later.
87  e.set_pos_if_unset (2, k+1);
88  throw;
89  }
90  }
91 
92  // This hack is to allow constructing permutation matrices using
93  // eye(n)(p,:), eye(n)(:,q) && eye(n)(p,q) where p & q are permutation
94  // vectors.
95  // Note that, for better consistency, eye(n)(:,:) still converts to a full
96  // matrix.
97  if (nidx == 2)
98  {
99  bool left = idx0.is_permutation (matrix.rows ());
100  bool right = idx1.is_permutation (matrix.cols ());
101 
102  if (left && right)
103  {
104  if (idx0.is_colon ()) left = false;
105  if (idx1.is_colon ()) right = false;
106  if (left || right)
107  {
108  PermMatrix p = matrix;
109  if (left)
110  p = PermMatrix (idx0, false) * p;
111  if (right)
112  p = p * PermMatrix (idx1, true);
113  retval = p;
114  }
115  else
116  {
117  retval = this;
118  this->count++;
119  }
120  }
121  }
122 
123  if (! retval.is_defined ())
124  {
125  if (nidx == 2 && ! resize_ok && idx0.is_scalar () && idx1.is_scalar ())
126  retval = matrix.checkelem (idx0(0), idx1(0));
127  else
128  retval = to_dense ().do_index_op (idx, resize_ok);
129  }
130 
131  return retval;
132 }
133 
134 // Return true if this matrix has all true elements (non-zero, not NaN/NA).
135 // A permutation cannot have NaN/NA.
136 bool
138 {
139  if (dims ().numel () > 1)
140  {
142  return false; // > 1x1 permutation always has zeros, and no NaN.
143  }
144  else
145  return dims ().numel (); // 1x1 is [1] == true, 0x0 == false.
146 }
147 
148 double
150 {
151  if (is_empty ())
152  err_invalid_conversion (type_name (), "real scalar");
153 
154  warn_implicit_conversion ("Octave:array-to-scalar",
155  type_name (), "real scalar");
156 
157  return matrix(0, 0);
158 }
159 
160 float
162 {
163  if (is_empty ())
164  err_invalid_conversion (type_name (), "real scalar");
165 
166  warn_implicit_conversion ("Octave:array-to-scalar",
167  type_name (), "real scalar");
168 
169  return matrix(0, 0);
170 }
171 
172 Complex
174 {
175  if (rows () == 0 || columns () == 0)
176  err_invalid_conversion (type_name (), "complex scalar");
177 
178  warn_implicit_conversion ("Octave:array-to-scalar",
179  type_name (), "complex scalar");
180 
181  return Complex (matrix(0, 0), 0);
182 }
183 
186 {
187  float tmp = lo_ieee_float_nan_value ();
188 
189  FloatComplex retval (tmp, tmp);
190 
191  if (rows () == 0 || columns () == 0)
192  err_invalid_conversion (type_name (), "complex scalar");
193 
194  warn_implicit_conversion ("Octave:array-to-scalar",
195  type_name (), "complex scalar");
196 
197  retval = matrix(0, 0);
198 
199  return retval;
200 }
201 
202 #define FORWARD_MATRIX_VALUE(TYPE, PREFIX) \
203  TYPE \
204  octave_perm_matrix::PREFIX ## _value (bool frc_str_conv) const \
205  { \
206  return to_dense ().PREFIX ## _value (frc_str_conv); \
207  }
208 
211 {
212  return SparseMatrix (matrix);
213 }
214 
217 {
218  return SparseBoolMatrix (matrix);
219 }
220 
223 {
225 }
226 
231 
236 
239 
241 octave_perm_matrix::index_vector (bool require_integers) const
242 {
243  return to_dense ().index_vector (require_integers);
244 }
245 
248  char type) const
249 {
250  return to_dense ().convert_to_str_internal (pad, force, type);
251 }
252 
255 {
256  return matrix;
257 }
258 
261 {
262  return float_array_value ();
263 }
264 
267 {
268  return int8_array_value ();
269 }
270 
273 {
274  return int16_array_value ();
275 }
276 
279 {
280  return int32_array_value ();
281 }
282 
285 {
286  return int64_array_value ();
287 }
288 
291 {
292  return uint8_array_value ();
293 }
294 
297 {
298  return uint16_array_value ();
299 }
300 
303 {
304  return uint32_array_value ();
305 }
306 
309 {
310  return uint64_array_value ();
311 }
312 
313 bool
315 {
316  os << "# size: " << matrix.rows () << "\n";
317  os << "# orient: c\n";
318 
320  octave_idx_type n = pvec.numel ();
321  ColumnVector tmp (n);
322  for (octave_idx_type i = 0; i < n; i++) tmp(i) = pvec(i) + 1;
323  os << tmp;
324 
325  return true;
326 }
327 
328 bool
330 {
331  octave_idx_type n;
332  char orient;
333 
334  if (! extract_keyword (is, "size", n, true)
335  || ! extract_keyword (is, "orient", orient, true))
336  error ("load: failed to extract size & orientation");
337 
338  bool colp = orient == 'c';
339  ColumnVector tmp (n);
340  is >> tmp;
341  if (! is)
342  error ("load: failed to load permutation matrix constant");
343 
344  Array<octave_idx_type> pvec (dim_vector (n, 1));
345  for (octave_idx_type i = 0; i < n; i++) pvec(i) = tmp(i) - 1;
346  matrix = PermMatrix (pvec, colp);
347 
348  // Invalidate cache. Probably not necessary, but safe.
350 
351  return true;
352 }
353 
354 bool
355 octave_perm_matrix::save_binary (std::ostream& os, bool&)
356 {
357 
358  int32_t sz = matrix.rows ();
359  bool colp = true;
360  os.write (reinterpret_cast<char *> (&sz), 4);
361  os.write (reinterpret_cast<char *> (&colp), 1);
362  const Array<octave_idx_type>& col_perm = matrix.col_perm_vec ();
363  os.write (reinterpret_cast<const char *> (col_perm.data ()),
364  col_perm.byte_size ());
365 
366  return true;
367 }
368 
369 bool
372 {
373  int32_t sz;
374  bool colp;
375  if (! (is.read (reinterpret_cast<char *> (&sz), 4)
376  && is.read (reinterpret_cast<char *> (&colp), 1)))
377  return false;
378 
380 
381  if (! is.read (reinterpret_cast<char *> (m.fortran_vec ()), m.byte_size ()))
382  return false;
383 
384  if (swap)
385  {
386  int nel = m.numel ();
387  for (int i = 0; i < nel; i++)
388  switch (sizeof (octave_idx_type))
389  {
390  case 8:
391  swap_bytes<8> (&m(i));
392  break;
393  case 4:
394  swap_bytes<4> (&m(i));
395  break;
396  case 2:
397  swap_bytes<2> (&m(i));
398  break;
399  case 1:
400  default:
401  break;
402  }
403  }
404 
405  matrix = PermMatrix (m, colp);
406  return true;
407 }
408 
409 void
411  bool pr_as_read_syntax) const
412 {
413  return octave_print_internal (os, matrix, pr_as_read_syntax,
415 }
416 
417 mxArray *
419 {
420  return to_dense ().as_mxArray ();
421 }
422 
423 bool
425 {
426  dim_vector dv = dims ();
427 
428  return (dv.all_ones () || dv.any_zero ());
429 }
430 
431 void
432 octave_perm_matrix::print (std::ostream& os, bool pr_as_read_syntax)
433 {
434  print_raw (os, pr_as_read_syntax);
435  newline (os);
436 }
437 
438 int
440  oct_data_conv::data_type output_type, int skip,
442 {
443  return to_dense ().write (os, block_size, output_type, skip, flt_fmt);
444 }
445 
446 void
448  const std::string& prefix) const
449 {
450  matrix.print_info (os, prefix);
451 }
452 
455 {
456  if (! dense_cache.is_defined ())
458 
459  return dense_cache;
460 }
461 
463  "permutation matrix", "double");
464 
465 static octave_base_value *
467 {
468  const octave_perm_matrix& v = dynamic_cast<const octave_perm_matrix&> (a);
469 
470  return new octave_matrix (v.matrix_value ());
471 }
472 
475 {
478 }
479 
482 {
484 
485  if (matrix.numel () == 1)
486  retval = new octave_scalar (matrix (0, 0));
487 
488  return retval;
489 }
490 
493 {
494  if (n < matrix.numel ())
495  {
496  octave_idx_type nr = matrix.rows ();
497 
498  octave_idx_type r = n % nr;
499  octave_idx_type c = n / nr;
500 
501  return octave_value (matrix.elem (r, c));
502  }
503  else
504  return octave_value ();
505 }
std::string type_name(void) const
Definition: ov-perm.h:248
static int left
Definition: randmtzig.cc:185
octave_refcount< octave_idx_type > count
Definition: ov-base.h:843
octave_value as_single(void) const
Definition: ov-perm.cc:260
int8NDArray int8_array_value(void) const
Definition: ov-perm.h:172
octave_value as_int32(void) const
Definition: ov-perm.cc:278
octave_idx_type rows(void) const
Definition: PermMatrix.h:59
octave_idx_type columns(void) const
Definition: ov-base.h:319
mxArray * as_mxArray(void) const
Definition: ov.h:1309
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
octave_value as_uint32(void) const
Definition: ov-perm.cc:302
void set_pos_if_unset(octave_idx_type nd_arg, octave_idx_type dim_arg)
octave_idx_type length(void) const
Definition: ovl.h:96
octave_idx_type cols(void) const
Definition: PermMatrix.h:60
bool is_defined(void) const
Definition: ov.h:536
for large enough k
Definition: lu.cc:606
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the then the first element defines the pivoting tolerance for the unsymmetric the values defined such that for full matrix
Definition: lu.cc:138
void swap_bytes< 8 >(void *ptr)
Definition: byte-swap.h:68
void error(const char *fmt,...)
Definition: error.cc:570
void swap_bytes< 2 >(void *ptr)
Definition: byte-swap.h:53
void print_info(std::ostream &os, const std::string &prefix) const
Definition: ov-perm.cc:447
octave_value as_uint64(void) const
Definition: ov-perm.cc:308
int32NDArray int32_array_value(void) const
Definition: ov-perm.h:178
virtual octave_value to_dense(void) const
Definition: ov-perm.cc:454
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:169
octave::mach_info::float_format flt_fmt
Definition: load-save.cc:723
Matrix matrix_value(bool=false) const
Definition: ov-perm.cc:227
octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition: ov.h:1207
bool is_true(void) const
Definition: ov-perm.cc:137
octave_idx_type checkelem(octave_idx_type i, octave_idx_type j) const
Definition: PermMatrix.cc:100
bool all_ones(void) const
Definition: dim-vector.h:377
void print_info(std::ostream &os, const std::string &prefix) const
Definition: PermMatrix.h:114
in this the arguments are accumulated from left to right
Definition: data.cc:393
octave_base_value * try_narrowing_conversion(void)
Definition: ov-perm.cc:481
i e
Definition: data.cc:2724
void newline(std::ostream &os) const
Definition: ov-base.cc:1381
SparseBoolMatrix sparse_bool_matrix_value(bool=false) const
Definition: ov-perm.cc:216
bool save_binary(std::ostream &os, bool &save_as_floats)
Definition: ov-perm.cc:355
bool is_empty(void) const
Definition: ov-base.h:355
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:389
int64NDArray int64_array_value(void) const
Definition: ov-perm.h:181
virtual octave_idx_type numel(void) const
Definition: ov-base.h:329
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov-perm.cc:69
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
Definition: ov-perm.cc:370
octave_value as_uint16(void) const
Definition: ov-perm.cc:296
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
bool swap
Definition: load-save.cc:725
double double_value(bool=false) const
Definition: ov-perm.cc:149
size_t byte_size(void) const
Definition: Array.h:435
bool print_as_scalar(void) const
Definition: ov-perm.cc:424
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:941
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:60
octave_value as_uint8(void) const
Definition: ov-perm.cc:290
uint64NDArray uint64_array_value(void) const
Definition: ov-perm.h:193
int write(octave_stream &os, int block_size, oct_data_conv::data_type output_type, int skip, octave::mach_info::float_format flt_fmt) const
Definition: ov.cc:2192
static octave_base_value * default_numeric_conversion_function(const octave_base_value &a)
Definition: ov-perm.cc:466
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
Definition: ls-oct-text.cc:80
const Array< octave_idx_type > & col_perm_vec(void) const
Definition: PermMatrix.h:79
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
then the function must return scalars which will be concatenated into the return array(s).If code
Definition: cellfun.cc:398
static int static_type_id(void)
Definition: ov-re-mat.h:250
uint8NDArray uint8_array_value(void) const
Definition: ov-perm.h:184
const T * data(void) const
Definition: Array.h:582
double tmp
Definition: data.cc:6300
octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition: ov-perm.cc:247
octave_value retval
Definition: data.cc:6294
#define panic_impossible()
Definition: error.h:40
FloatComplex float_complex_value(bool=false) const
Definition: ov-perm.cc:185
octave_idx_type elem(octave_idx_type i, octave_idx_type j) const
Definition: PermMatrix.h:83
idx type
Definition: ov.cc:3129
Definition: dMatrix.h:37
sz
Definition: data.cc:5342
void print(std::ostream &os, bool pr_as_read_syntax=false)
Definition: ov-perm.cc:432
bool any_zero(void) const
Definition: dim-vector.h:359
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
bool is_permutation(octave_idx_type n) const
Definition: idx-vector.cc:1135
PermMatrix matrix
Definition: ov-perm.h:240
uint16NDArray uint16_array_value(void) const
Definition: ov-perm.h:187
float lo_ieee_float_nan_value(void)
Definition: lo-ieee.cc:202
friend class octave_value
Definition: ov-base.h:211
bool load_ascii(std::istream &is)
Definition: ov-perm.cc:329
octave_value as_double(void) const
Definition: ov-perm.cc:254
octave_value dense_cache
Definition: ov-perm.h:244
void err_invalid_conversion(const std::string &from, const std::string &to)
Definition: errwarn.cc:68
bool save_ascii(std::ostream &os)
Definition: ov-perm.cc:314
octave_value as_int8(void) const
Definition: ov-perm.cc:266
octave_value as_int64(void) const
Definition: ov-perm.cc:284
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
int current_print_indent_level(void) const
Definition: ov-base.h:830
p
Definition: lu.cc:138
void octave_print_internal(std::ostream &, char, bool)
Definition: pr-output.cc:1722
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:332
int16NDArray int16_array_value(void) const
Definition: ov-perm.h:175
bool is_scalar(void) const
Definition: idx-vector.h:568
type_conv_info numeric_conversion_function(void) const
Definition: ov-perm.cc:474
SparseComplexMatrix sparse_complex_matrix_value(bool=false) const
Definition: ov-perm.cc:222
octave_value fast_elem_extract(octave_idx_type n) const
Definition: ov-perm.cc:492
octave_value as_int16(void) const
Definition: ov-perm.cc:272
void warn_array_as_logical(const dim_vector &dv)
Definition: errwarn.cc:276
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov-perm.cc:42
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
uint32NDArray uint32_array_value(void) const
Definition: ov-perm.h:190
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition: ov-perm.cc:410
Complex complex_value(bool=false) const
Definition: ov-perm.cc:173
FloatNDArray float_array_value(bool=false) const
Definition: ov-perm.cc:233
std::complex< double > Complex
Definition: oct-cmplx.h:31
const T * fortran_vec(void) const
Definition: Array.h:584
write the output to stdout if nargout is
Definition: load-save.cc:1576
#define FORWARD_MATRIX_VALUE(TYPE, PREFIX)
Definition: ov-perm.cc:202
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
idx_vector index_vector(bool require_integers=false) const
Definition: ov-perm.cc:241
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
int write(octave_stream &os, int block_size, oct_data_conv::data_type output_type, int skip, octave::mach_info::float_format flt_fmt) const
Definition: ov-perm.cc:439
dim_vector dv
Definition: sub2ind.cc:263
float float_value(bool=false) const
Definition: ov-perm.cc:161
octave_idx_type numel(void) const
Definition: PermMatrix.h:72
octave_value next_subsref(const std::string &type, const std::list< octave_value_list > &idx, size_t skip=1)
Definition: ov.cc:1462
octave_idx_type rows(void) const
Definition: ov-base.h:312
bool is_colon(void) const
Definition: idx-vector.h:565
SparseMatrix sparse_matrix_value(bool=false) const
Definition: ov-perm.cc:210
dim_vector dims(void) const
Definition: ov-perm.h:69
mxArray * as_mxArray(void) const
Definition: ov-perm.cc:418
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov.h:454