GNU Octave  3.8.0
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-intx.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2013 John W. Eaton
4 Copyright (C) 2010 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #include <cstdlib>
25 
26 #include <iosfwd>
27 #include <string>
28 
29 #include "mx-base.h"
30 #include "oct-alloc.h"
31 #include "str-vec.h"
32 
33 #include "error.h"
34 #include "mxarray.h"
35 #include "oct-stream.h"
36 #include "ov-base.h"
37 #include "ov-base-int.h"
38 #include "ov-typeinfo.h"
39 #include "gripes.h"
40 
41 #include "ov-re-mat.h"
42 #include "ov-scalar.h"
43 
44 class
48 {
49 public:
50 
53 
56 
59  (intNDArray<OCTAVE_INT_T> (nda)) { }
60 
62 
63  octave_base_value *clone (void) const
64  { return new OCTAVE_VALUE_INT_MATRIX_T (*this); }
65 
66  octave_base_value *empty_clone (void) const
67  { return new OCTAVE_VALUE_INT_MATRIX_T (); }
68 
69  bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
70 
71  bool is_integer_type (void) const { return true; }
72 
73  builtin_type_t builtin_type (void) const { return OCTAVE_INT_BTYP; }
74 
75 public:
76 
78  int8_array_value (void) const { return int8NDArray (matrix); }
79 
81  int16_array_value (void) const { return int16NDArray (matrix); }
82 
84  int32_array_value (void) const { return int32NDArray (matrix); }
85 
87  int64_array_value (void) const { return int64NDArray (matrix); }
88 
90  uint8_array_value (void) const { return uint8NDArray (matrix); }
91 
93  uint16_array_value (void) const { return uint16NDArray (matrix); }
94 
96  uint32_array_value (void) const { return uint32NDArray (matrix); }
97 
99  uint64_array_value (void) const { return uint64NDArray (matrix); }
100 
101  double
102  double_value (bool = false) const
103  {
104  double retval = lo_ieee_nan_value ();
105 
106  if (numel () > 0)
107  {
108  gripe_implicit_conversion ("Octave:array-to-scalar",
109  type_name (), "real scalar");
110 
111  retval = matrix(0).double_value ();
112  }
113  else
114  gripe_invalid_conversion (type_name (), "real scalar");
115 
116  return retval;
117 
118  }
119 
120  float
121  float_value (bool = false) const
122  {
123  float retval = lo_ieee_float_nan_value ();
124 
125  if (numel () > 0)
126  {
127  gripe_implicit_conversion ("Octave:array-to-scalar",
128  type_name (), "real scalar");
129 
130  retval = matrix(0).float_value ();
131  }
132  else
133  gripe_invalid_conversion (type_name (), "real scalar");
134 
135  return retval;
136 
137  }
138 
139  double scalar_value (bool = false) const { return double_value (); }
140 
141  float float_scalar_value (bool = false) const { return float_value (); }
142 
143  Matrix
144  matrix_value (bool = false) const
145  {
146  Matrix retval;
147  dim_vector dv = dims ();
148  if (dv.length () > 2)
149  error ("invalid conversion of %s to Matrix", type_name ().c_str ());
150  else
151  {
152  retval = Matrix (dv(0), dv(1));
153  double *vec = retval.fortran_vec ();
154  octave_idx_type nel = matrix.numel ();
155  for (octave_idx_type i = 0; i < nel; i++)
156  vec[i] = matrix(i).double_value ();
157  }
158  return retval;
159  }
160 
162  float_matrix_value (bool = false) const
163  {
164  FloatMatrix retval;
165  dim_vector dv = dims ();
166  if (dv.length () > 2)
167  error ("invalid conversion of %s to FloatMatrix", type_name ().c_str ());
168  else
169  {
170  retval = FloatMatrix (dv(0), dv(1));
171  float *vec = retval.fortran_vec ();
172  octave_idx_type nel = matrix.numel ();
173  for (octave_idx_type i = 0; i < nel; i++)
174  vec[i] = matrix(i).float_value ();
175  }
176  return retval;
177  }
178 
180  complex_matrix_value (bool = false) const
181  {
182  ComplexMatrix retval;
183  dim_vector dv = dims ();
184  if (dv.length () > 2)
185  error ("invalid conversion of %s to Matrix", type_name ().c_str ());
186  else
187  {
188  retval = ComplexMatrix (dv(0), dv(1));
189  Complex *vec = retval.fortran_vec ();
190  octave_idx_type nel = matrix.numel ();
191  for (octave_idx_type i = 0; i < nel; i++)
192  vec[i] = Complex (matrix(i).double_value ());
193  }
194  return retval;
195  }
196 
198  float_complex_matrix_value (bool = false) const
199  {
200  FloatComplexMatrix retval;
201  dim_vector dv = dims ();
202  if (dv.length () > 2)
203  error ("invalid conversion of %s to FloatMatrix", type_name ().c_str ());
204  else
205  {
206  retval = FloatComplexMatrix (dv(0), dv(1));
207  FloatComplex *vec = retval.fortran_vec ();
208  octave_idx_type nel = matrix.numel ();
209  for (octave_idx_type i = 0; i < nel; i++)
210  vec[i] = FloatComplex (matrix(i).float_value ());
211  }
212  return retval;
213  }
214 
215  NDArray
216  array_value (bool = false) const
217  {
218  NDArray retval (matrix.dims ());
219  double *vec = retval.fortran_vec ();
220  octave_idx_type nel = matrix.numel ();
221  for (octave_idx_type i = 0; i < nel; i++)
222  vec[i] = matrix(i).double_value ();
223  return retval;
224  }
225 
227  float_array_value (bool = false) const
228  {
229  FloatNDArray retval (matrix.dims ());
230  float *vec = retval.fortran_vec ();
231  octave_idx_type nel = matrix.numel ();
232  for (octave_idx_type i = 0; i < nel; i++)
233  vec[i] = matrix(i).float_value ();
234  return retval;
235  }
236 
238  complex_array_value (bool = false) const
239  {
240  ComplexNDArray retval (matrix.dims ());
241  Complex *vec = retval.fortran_vec ();
242  octave_idx_type nel = matrix.numel ();
243  for (octave_idx_type i = 0; i < nel; i++)
244  vec[i] = Complex (matrix(i).double_value ());
245  return retval;
246  }
247 
249  float_complex_array_value (bool = false) const
250  {
251  FloatComplexNDArray retval (matrix.dims ());
252  FloatComplex *vec = retval.fortran_vec ();
253  octave_idx_type nel = matrix.numel ();
254  for (octave_idx_type i = 0; i < nel; i++)
255  vec[i] = FloatComplex (matrix(i).float_value ());
256  return retval;
257  }
258 
260  bool_array_value (bool warn = false) const
261  {
262  boolNDArray retval (dims ());
263 
264  octave_idx_type nel = numel ();
265 
266  if (warn && matrix.any_element_not_one_or_zero ())
268 
269  bool *vec = retval.fortran_vec ();
270  for (octave_idx_type i = 0; i < nel; i++)
271  vec[i] = matrix(i).bool_value ();
272 
273  return retval;
274  }
275 
277  char_array_value (bool = false) const
278  {
279  charNDArray retval (dims ());
280 
281  octave_idx_type nel = numel ();
282 
283  char *vec = retval.fortran_vec ();
284  for (octave_idx_type i = 0; i < nel; i++)
285  vec[i] = matrix(i).char_value ();
286 
287  return retval;
288  }
289 
290  // Use matrix_ref here to clear index cache.
291  void increment (void)
292  {
293  matrix_ref () += OCTAVE_INT_T (1);
294  }
295 
296  void decrement (void)
297  {
298  matrix_ref () -= OCTAVE_INT_T (1);
299  }
300 
301  void changesign (void)
302  {
303  matrix_ref ().changesign ();
304  }
305 
306  idx_vector index_vector (void) const
307  { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
308 
309  int write (octave_stream& os, int block_size,
310  oct_data_conv::data_type output_type, int skip,
311  oct_mach_info::float_format flt_fmt) const
312  { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
313 
314  // Unsafe. This function exists to support the MEX interface.
315  // You should not use it anywhere else.
316  void *mex_get_data (void) const { return matrix.mex_get_data (); }
317 
318  mxArray *as_mxArray (void) const
319  {
320  mxArray *retval = new mxArray (OCTAVE_INT_MX_CLASS, dims (), mxREAL);
321 
322  OCTAVE_INT_T::val_type *pr = static_cast<OCTAVE_INT_T::val_type *>
323  (retval->get_data ());
324 
325  mwSize nel = numel ();
326 
327  const OCTAVE_INT_T *p = matrix.data ();
328 
329  for (mwIndex i = 0; i < nel; i++)
330  pr[i] = p[i].value ();
331 
332  return retval;
333  }
334 
335  octave_value map (unary_mapper_t umap) const
336  {
337  switch (umap)
338  {
339  case umap_abs:
340  return matrix.abs ();
341  case umap_signum:
342  return matrix.signum ();
343  case umap_ceil:
344  case umap_conj:
345  case umap_fix:
346  case umap_floor:
347  case umap_real:
348  case umap_round:
349  return matrix;
350  case umap_imag:
351  return intNDArray<OCTAVE_INT_T> (matrix.dims (), OCTAVE_INT_T ());
352  case umap_isnan:
353  case umap_isna:
354  case umap_isinf:
355  return boolNDArray (matrix.dims (), false);
356  case umap_finite:
357  return boolNDArray (matrix.dims (), true);
358 
359  default:
360  {
361  octave_matrix m (array_value ());
362  return m.map (umap);
363  }
364  }
365  }
366 
367 private:
368 
370 
372 };
373 
374 class
378 {
379 public:
380 
383 
386 
388 
389  octave_base_value *clone (void) const
390  { return new OCTAVE_VALUE_INT_SCALAR_T (*this); }
391 
392  octave_base_value *empty_clone (void) const
393  { return new OCTAVE_VALUE_INT_MATRIX_T (); }
394 
395  octave_value do_index_op (const octave_value_list& idx,
396  bool resize_ok = false)
397  {
398  // FIXME: this doesn't solve the problem of
399  //
400  // a = 1; a([1,1], [1,1], [1,1])
401  //
402  // and similar constructions. Hmm...
403 
404  // FIXME: using this constructor avoids narrowing the
405  // 1x1 matrix back to a scalar value. Need a better solution
406  // to this problem.
407 
408  octave_value tmp
411 
412  return tmp.do_index_op (idx, resize_ok);
413  }
414 
415  bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
416 
417  bool is_integer_type (void) const { return true; }
418 
419  builtin_type_t builtin_type (void) const { return OCTAVE_INT_BTYP; }
420 
421 public:
422 
424  int8_scalar_value (void) const { return octave_int8 (scalar); }
425 
427  int16_scalar_value (void) const { return octave_int16 (scalar); }
428 
430  int32_scalar_value (void) const { return octave_int32 (scalar); }
431 
433  int64_scalar_value (void) const { return octave_int64 (scalar); }
434 
436  uint8_scalar_value (void) const { return octave_uint8 (scalar); }
437 
439  uint16_scalar_value (void) const { return octave_uint16 (scalar); }
440 
442  uint32_scalar_value (void) const { return octave_uint32 (scalar); }
443 
445  uint64_scalar_value (void) const { return octave_uint64 (scalar); }
446 
448  int8_array_value (void) const
449  { return int8NDArray (dim_vector (1, 1), int8_scalar_value ()); }
450 
452  int16_array_value (void) const
453  { return int16NDArray (dim_vector (1, 1), int16_scalar_value ()); }
454 
456  int32_array_value (void) const
457  { return int32NDArray (dim_vector (1, 1), int32_scalar_value ()); }
458 
460  int64_array_value (void) const
461  { return int64NDArray (dim_vector (1, 1), int64_scalar_value ()); }
462 
464  uint8_array_value (void) const
465  { return uint8NDArray (dim_vector (1, 1), uint8_scalar_value ()); }
466 
468  uint16_array_value (void) const
469  { return uint16NDArray (dim_vector (1, 1), uint16_scalar_value ()); }
470 
472  uint32_array_value (void) const
473  { return uint32NDArray (dim_vector (1, 1), uint32_scalar_value ()); }
474 
476  uint64_array_value (void) const
477  { return uint64NDArray (dim_vector (1, 1), uint64_scalar_value ()); }
478 
479  octave_value resize (const dim_vector& dv, bool fill = false) const
480  {
481  if (fill)
482  {
483  intNDArray<OCTAVE_INT_T> retval (dv, 0);
484  if (dv.numel ())
485  retval(0) = scalar;
486  return retval;
487  }
488  else
489  {
490  intNDArray<OCTAVE_INT_T> retval (dv);
491  if (dv.numel ())
492  retval(0) = scalar;
493  return retval;
494  }
495  }
496 
497  double double_value (bool = false) const { return scalar.double_value (); }
498 
499  float float_value (bool = false) const { return scalar.float_value (); }
500 
501  double scalar_value (bool = false) const { return scalar.double_value (); }
502 
503  float float_scalar_value (bool = false) const
504  { return scalar.float_value (); }
505 
506  Matrix
507  matrix_value (bool = false) const
508  {
509  Matrix retval (1, 1);
510  retval(0,0) = scalar.double_value ();
511  return retval;
512  }
513 
515  float_matrix_value (bool = false) const
516  {
517  FloatMatrix retval (1, 1);
518  retval(0,0) = scalar.float_value ();
519  return retval;
520  }
521 
523  complex_matrix_value (bool = false) const
524  {
525  ComplexMatrix retval (1, 1);
526  retval(0,0) = Complex (scalar.double_value ());
527  return retval;
528  }
529 
531  float_complex_matrix_value (bool = false) const
532  {
533  FloatComplexMatrix retval (1, 1);
534  retval(0,0) = FloatComplex (scalar.float_value ());
535  return retval;
536  }
537 
538  NDArray
539  array_value (bool = false) const
540  {
541  NDArray retval (dim_vector (1, 1));
542  retval(0) = scalar.double_value ();
543  return retval;
544  }
545 
547  float_array_value (bool = false) const
548  {
549  FloatNDArray retval (dim_vector (1, 1));
550  retval(0) = scalar.float_value ();
551  return retval;
552  }
553 
555  complex_array_value (bool = false) const
556  {
557  ComplexNDArray retval (dim_vector (1, 1));
558  retval(0) = FloatComplex (scalar.double_value ());
559  return retval;
560  }
561 
563  float_complex_array_value (bool = false) const
564  {
565  FloatComplexNDArray retval (dim_vector (1, 1));
566  retval(0) = FloatComplex (scalar.float_value ());
567  return retval;
568  }
569 
570  bool bool_value (bool warn = false) const
571  {
572  if (warn && scalar != 0.0 && scalar != 1.0)
574 
575  return scalar.bool_value ();
576  }
577 
579  bool_array_value (bool warn = false) const
580  {
581  boolNDArray retval (dim_vector (1, 1));
582 
583  if (warn && scalar != 0.0 && scalar != 1.0)
585 
586  retval(0) = scalar.bool_value ();
587 
588  return retval;
589  }
590 
592  char_array_value (bool = false) const
593  {
594  charNDArray retval (dim_vector (1, 1));
595  retval(0) = scalar.char_value ();
596  return retval;
597  }
598 
599  void increment (void)
600  {
601  scalar += OCTAVE_INT_T (1);
602  }
603 
604  void decrement (void)
605  {
606  scalar -= OCTAVE_INT_T (1);
607  }
608 
609  idx_vector index_vector (void) const { return idx_vector (scalar); }
610 
611  int write (octave_stream& os, int block_size,
612  oct_data_conv::data_type output_type, octave_idx_type skip,
613  oct_mach_info::float_format flt_fmt) const
614  {
616  block_size, output_type, skip, flt_fmt);
617  }
618 
619  // Unsafe. This function exists to support the MEX interface.
620  // You should not use it anywhere else.
621  void *mex_get_data (void) const { return scalar.mex_get_data (); }
622 
623  mxArray *as_mxArray (void) const
624  {
625  mxArray *retval = new mxArray (OCTAVE_INT_MX_CLASS, 1, 1, mxREAL);
626 
627  OCTAVE_INT_T::val_type *pr = static_cast<OCTAVE_INT_T::val_type *>
628  (retval->get_data ());
629 
630  pr[0] = scalar.value ();
631 
632  return retval;
633  }
634 
635  octave_value map (unary_mapper_t umap) const
636  {
637  switch (umap)
638  {
639  case umap_abs:
640  return scalar.abs ();
641  case umap_signum:
642  return scalar.signum ();
643  case umap_ceil:
644  case umap_conj:
645  case umap_fix:
646  case umap_floor:
647  case umap_real:
648  case umap_round:
649  return scalar;
650  case umap_imag:
651  return OCTAVE_INT_T ();
652  case umap_isnan:
653  case umap_isna:
654  case umap_isinf:
655  return false;
656  case umap_finite:
657  return true;
658 
659  default:
660  {
661  octave_scalar m (scalar_value ());
662  return m.map (umap);
663  }
664  }
665  }
666 
667 private:
668 
670 
672 };