GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-cx-diag.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2008-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "byte-swap.h"
31 
32 #include "ov-cx-diag.h"
33 #include "ov-flt-cx-diag.h"
34 #include "ov-re-diag.h"
35 #include "ov-base-diag.cc"
36 #include "ov-complex.h"
37 #include "ov-cx-mat.h"
38 #include "ls-utils.h"
39 
40 
42 
44  "complex diagonal matrix", "double");
45 
46 static octave_base_value *
47 default_numeric_conversion_function (const octave_base_value& a)
48 {
50  = dynamic_cast<const octave_complex_diag_matrix&> (a);
51 
53 }
54 
57 {
59  (default_numeric_conversion_function,
61 }
62 
63 static octave_base_value *
64 default_numeric_demotion_function (const octave_base_value& a)
65 {
67  = dynamic_cast<const octave_complex_diag_matrix&> (a);
68 
71 }
72 
75 {
76  return
77  octave_base_value::type_conv_info (default_numeric_demotion_function,
79 }
80 
83 {
84  octave_base_value *retval = nullptr;
85 
86  if (m_matrix.nelem () == 1)
87  {
88  retval = new octave_complex (m_matrix (0, 0));
90  if (rv2)
91  {
92  delete retval;
93  retval = rv2;
94  }
95  }
96  else if (m_matrix.all_elements_are_real ())
97  {
98  return new octave_diag_matrix (::real (m_matrix));
99  }
100 
101  return retval;
102 }
103 
106 {
107  DiagMatrix retval;
108 
109  if (! force_conversion)
110  warn_implicit_conversion ("Octave:imag-to-real",
111  type_name (), "real matrix");
112 
113  retval = ::real (m_matrix);
114 
115  return retval;
116 }
117 
120 {
121  DiagMatrix retval;
122 
123  if (! force_conversion)
124  warn_implicit_conversion ("Octave:imag-to-real",
125  type_name (), "real matrix");
126 
127  retval = ::real (m_matrix);
128 
129  return retval;
130 }
131 
134 {
135  return m_matrix;
136 }
137 
140 {
142 }
143 
146 {
147  return m_matrix;
148 }
149 
152 {
154 }
155 
158 {
159  switch (umap)
160  {
161  case umap_abs:
162  return m_matrix.abs ();
163  case umap_real:
165  case umap_conj:
167  case umap_imag:
169  case umap_sqrt:
170  {
172  = m_matrix.extract_diag ().map<Complex> (std::sqrt);
173  ComplexDiagMatrix retval (tmp);
174  retval.resize (m_matrix.rows (), m_matrix.columns ());
175  return retval;
176  }
177  default:
178  return to_dense ().map (umap);
179  }
180 }
181 
182 bool
183 octave_complex_diag_matrix::save_binary (std::ostream& os, bool save_as_floats)
184 {
185 
186  int32_t r = m_matrix.rows ();
187  int32_t c = m_matrix.cols ();
188  os.write (reinterpret_cast<char *> (&r), 4);
189  os.write (reinterpret_cast<char *> (&c), 4);
190 
192  save_type st = LS_DOUBLE;
193  if (save_as_floats)
194  {
195  if (m.too_large_for_float ())
196  {
197  warning ("save: some values too large to save as floats --");
198  warning ("save: saving as doubles instead");
199  }
200  else
201  st = LS_FLOAT;
202  }
203  else if (m_matrix.length () > 4096) // FIXME: make this configurable.
204  {
205  double max_val, min_val;
206  if (m.all_integers (max_val, min_val))
207  st = octave::get_save_type (max_val, min_val);
208  }
209 
210  const Complex *mtmp = m.data ();
211  write_doubles (os, reinterpret_cast<const double *> (mtmp), st,
212  2 * m.numel ());
213 
214  return true;
215 }
216 
217 bool
218 octave_complex_diag_matrix::load_binary (std::istream& is, bool swap,
220 {
221  int32_t r, c;
222  char tmp;
223  if (! (is.read (reinterpret_cast<char *> (&r), 4)
224  && is.read (reinterpret_cast<char *> (&c), 4)
225  && is.read (reinterpret_cast<char *> (&tmp), 1)))
226  return false;
227  if (swap)
228  {
229  swap_bytes<4> (&r);
230  swap_bytes<4> (&c);
231  }
232 
233  ComplexDiagMatrix m (r, c);
234  Complex *im = m.fortran_vec ();
235  octave_idx_type len = m.length ();
236  read_doubles (is, reinterpret_cast<double *> (im),
237  static_cast<save_type> (tmp), 2 * len, swap, fmt);
238 
239  if (! is)
240  return false;
241 
242  m_matrix = m;
243 
244  return true;
245 }
246 
247 bool
248 octave_complex_diag_matrix::chk_valid_scalar (const octave_value& val,
249  Complex& x) const
250 {
251  bool retval = val.is_complex_scalar () || val.is_real_scalar ();
252  if (retval)
253  x = val.complex_value ();
254  return retval;
255 }
256 
257 /*
258 %!assert <*36368> (diag ([1+i, 1-i])^2 , diag ([2i, -2i]), 4*eps)
259 */
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:217
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:63
Array< U, A > map(F fcn) const
Apply function fcn to each element of the Array<T, Alloc>.
Definition: Array.h:859
bool all_elements_are_real() const
Definition: CDiagMatrix.cc:377
DiagMatrix abs() const
Definition: CDiagMatrix.cc:209
ComplexColumnVector extract_diag(octave_idx_type k=0) const
Definition: CDiagMatrix.h:140
octave_idx_type nelem() const
Definition: DiagArray2.h:96
octave_idx_type rows() const
Definition: DiagArray2.h:89
octave_idx_type length() const
Definition: DiagArray2.h:95
octave_idx_type columns() const
Definition: DiagArray2.h:91
octave_idx_type cols() const
Definition: DiagArray2.h:90
ComplexMatrix complex_matrix_value(bool=false) const
virtual octave_base_value * try_narrowing_conversion()
Definition: ov-base.h:323
octave_value as_single() const
Definition: ov-cx-diag.cc:151
DiagMatrix diag_matrix_value(bool=false) const
Definition: ov-cx-diag.cc:105
ComplexDiagMatrix complex_diag_matrix_value(bool=false) const
Definition: ov-cx-diag.cc:133
FloatComplexDiagMatrix float_complex_diag_matrix_value(bool=false) const
Definition: ov-cx-diag.cc:139
octave_value as_double() const
Definition: ov-cx-diag.cc:145
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
Definition: ov-cx-diag.cc:218
FloatDiagMatrix float_diag_matrix_value(bool=false) const
Definition: ov-cx-diag.cc:119
octave_value map(unary_mapper_t umap) const
Definition: ov-cx-diag.cc:157
bool save_binary(std::ostream &os, bool save_as_floats)
Definition: ov-cx-diag.cc:183
std::string type_name() const
Definition: ov-cx-diag.h:101
type_conv_info numeric_demotion_function() const
Definition: ov-cx-diag.cc:74
type_conv_info numeric_conversion_function() const
Definition: ov-cx-diag.cc:56
octave_base_value * try_narrowing_conversion()
Definition: ov-cx-diag.cc:82
static int static_type_id()
Definition: ov-cx-mat.h:184
bool is_real_scalar() const
Definition: ov.h:610
Complex complex_value(bool frc_str_conv=false) const
Definition: ov.h:865
bool is_complex_scalar() const
Definition: ov.h:616
octave_value map(octave_base_value::unary_mapper_t umap) const
Definition: ov.h:1513
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:143
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
Definition: data-conv.cc:776
void write_doubles(std::ostream &os, const double *data, save_type type, octave_idx_type len)
Definition: data-conv.cc:892
save_type
Definition: data-conv.h:87
@ LS_DOUBLE
Definition: data-conv.h:95
@ LS_FLOAT
Definition: data-conv.h:94
void warning(const char *fmt,...)
Definition: error.cc:1063
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:344
F77_RET_T const F77_DBLE * x
save_type get_save_type(double, double)
Definition: ls-utils.cc:40
float_format
Definition: mach-info.h:38
T octave_idx_type m
Definition: mx-inlines.cc:781
T * r
Definition: mx-inlines.cc:781
std::complex< double > Complex
Definition: oct-cmplx.h:33
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:235
F77_RET_T len
Definition: xerbla.cc:61