GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fCColVector.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1994-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 <istream>
31 #include <ostream>
32 
33 #include "Array-util.h"
34 #include "lo-blas-proto.h"
35 #include "lo-error.h"
36 #include "mx-base.h"
37 #include "mx-inlines.cc"
38 #include "oct-cmplx.h"
39 
40 // FloatComplex Column Vector class
41 
43  : MArray<FloatComplex> (a)
44 { }
45 
46 bool
48 {
50  if (len != a.numel ())
51  return 0;
52  return mx_inline_equal (len, data (), a.data ());
53 }
54 
55 bool
57 {
58  return !(*this == a);
59 }
60 
61 // destructive insert/delete/reorder operations
62 
65 {
66  octave_idx_type a_len = a.numel ();
67 
68  if (r < 0 || r + a_len > numel ())
69  (*current_liboctave_error_handler) ("range error for insert");
70 
71  if (a_len > 0)
72  {
73  make_unique ();
74 
75  for (octave_idx_type i = 0; i < a_len; i++)
76  xelem (r+i) = a.elem (i);
77  }
78 
79  return *this;
80 }
81 
85 {
86  octave_idx_type a_len = a.numel ();
87 
88  if (r < 0 || r + a_len > numel ())
89  (*current_liboctave_error_handler) ("range error for insert");
90 
91  if (a_len > 0)
92  {
93  make_unique ();
94 
95  for (octave_idx_type i = 0; i < a_len; i++)
96  xelem (r+i) = a.elem (i);
97  }
98 
99  return *this;
100 }
101 
104 {
106 
107  if (len > 0)
108  {
109  make_unique ();
110 
111  for (octave_idx_type i = 0; i < len; i++)
112  xelem (i) = val;
113  }
114 
115  return *this;
116 }
117 
120 {
122 
123  if (len > 0)
124  {
125  make_unique ();
126 
127  for (octave_idx_type i = 0; i < len; i++)
128  xelem (i) = val;
129  }
130 
131  return *this;
132 }
133 
137 {
139 
140  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
141  (*current_liboctave_error_handler) ("range error for fill");
142 
143  if (r1 > r2) { std::swap (r1, r2); }
144 
145  if (r2 >= r1)
146  {
147  make_unique ();
148 
149  for (octave_idx_type i = r1; i <= r2; i++)
150  xelem (i) = val;
151  }
152 
153  return *this;
154 }
155 
159 {
161 
162  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
163  (*current_liboctave_error_handler) ("range error for fill");
164 
165  if (r1 > r2) { std::swap (r1, r2); }
166 
167  if (r2 >= r1)
168  {
169  make_unique ();
170 
171  for (octave_idx_type i = r1; i <= r2; i++)
172  xelem (i) = val;
173  }
174 
175  return *this;
176 }
177 
180 {
182  octave_idx_type nr_insert = len;
183  FloatComplexColumnVector retval (len + a.numel ());
184  retval.insert (*this, 0);
185  retval.insert (a, nr_insert);
186  return retval;
187 }
188 
191 {
193  octave_idx_type nr_insert = len;
194  FloatComplexColumnVector retval (len + a.numel ());
195  retval.insert (*this, 0);
196  retval.insert (a, nr_insert);
197  return retval;
198 }
199 
202 {
204 }
205 
208 {
210 }
211 
214 {
215  return do_mx_unary_map<float, FloatComplex, std::abs> (*this);
216 }
217 
220 {
221  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float>> (a);
222 }
223 
224 // resize is the destructive equivalent for this one
225 
228 {
229  if (r1 > r2) { std::swap (r1, r2); }
230 
231  octave_idx_type new_r = r2 - r1 + 1;
232 
233  FloatComplexColumnVector result (new_r);
234 
235  for (octave_idx_type i = 0; i < new_r; i++)
236  result.elem (i) = elem (r1+i);
237 
238  return result;
239 }
240 
243  octave_idx_type n) const
244 {
245  FloatComplexColumnVector result (n);
246 
247  for (octave_idx_type i = 0; i < n; i++)
248  result.elem (i) = elem (r1+i);
249 
250  return result;
251 }
252 
253 // column vector by column vector -> column vector operations
254 
257 {
259 
260  octave_idx_type a_len = a.numel ();
261 
262  if (len != a_len)
263  octave::err_nonconformant ("operator +=", len, a_len);
264 
265  if (len == 0)
266  return *this;
267 
268  FloatComplex *d = fortran_vec (); // Ensures only 1 reference to my privates!
269 
270  mx_inline_add2 (len, d, a.data ());
271  return *this;
272 }
273 
276 {
278 
279  octave_idx_type a_len = a.numel ();
280 
281  if (len != a_len)
282  octave::err_nonconformant ("operator -=", len, a_len);
283 
284  if (len == 0)
285  return *this;
286 
287  FloatComplex *d = fortran_vec (); // Ensures only 1 reference to my privates!
288 
289  mx_inline_sub2 (len, d, a.data ());
290  return *this;
291 }
292 
293 // matrix by column vector -> column vector operations
294 
297 {
298  FloatComplexColumnVector tmp (a);
299  return m * tmp;
300 }
301 
304 {
306 
307  F77_INT nr = octave::to_f77_int (m.rows ());
308  F77_INT nc = octave::to_f77_int (m.cols ());
309 
310  F77_INT a_len = octave::to_f77_int (a.numel ());
311 
312  if (nc != a_len)
313  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
314 
315  retval.clear (nr);
316 
317  if (nr != 0)
318  {
319  if (nc == 0)
320  retval.fill (0.0);
321  else
322  {
323  FloatComplex *y = retval.fortran_vec ();
324 
325  F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
326  nr, nc, 1.0f, F77_CONST_CMPLX_ARG (m.data ()), nr,
327  F77_CONST_CMPLX_ARG (a.data ()), 1, 0.0f, F77_CMPLX_ARG (y), 1
328  F77_CHAR_ARG_LEN (1)));
329  }
330  }
331 
332  return retval;
333 }
334 
335 // matrix by column vector -> column vector operations
336 
339 {
340  FloatComplexMatrix tmp (m);
341  return tmp * a;
342 }
343 
344 // diagonal matrix by column vector -> column vector operations
345 
348 {
349  F77_INT nr = octave::to_f77_int (m.rows ());
350  F77_INT nc = octave::to_f77_int (m.cols ());
351 
352  F77_INT a_len = octave::to_f77_int (a.numel ());
353 
354  if (nc != a_len)
355  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
356 
357  if (nc == 0 || nr == 0)
358  return FloatComplexColumnVector (0);
359 
360  FloatComplexColumnVector result (nr);
361 
362  for (octave_idx_type i = 0; i < a_len; i++)
363  result.elem (i) = a.elem (i) * m.elem (i, i);
364 
365  for (octave_idx_type i = a_len; i < nr; i++)
366  result.elem (i) = 0.0;
367 
368  return result;
369 }
370 
373 {
374  F77_INT nr = octave::to_f77_int (m.rows ());
375  F77_INT nc = octave::to_f77_int (m.cols ());
376 
377  F77_INT a_len = octave::to_f77_int (a.numel ());
378 
379  if (nc != a_len)
380  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
381 
382  if (nc == 0 || nr == 0)
383  return FloatComplexColumnVector (0);
384 
385  FloatComplexColumnVector result (nr);
386 
387  for (octave_idx_type i = 0; i < a_len; i++)
388  result.elem (i) = a.elem (i) * m.elem (i, i);
389 
390  for (octave_idx_type i = a_len; i < nr; i++)
391  result.elem (i) = 0.0;
392 
393  return result;
394 }
395 
398 {
399  F77_INT nr = octave::to_f77_int (m.rows ());
400  F77_INT nc = octave::to_f77_int (m.cols ());
401 
402  F77_INT a_len = octave::to_f77_int (a.numel ());
403 
404  if (nc != a_len)
405  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
406 
407  if (nc == 0 || nr == 0)
408  return FloatComplexColumnVector (0);
409 
410  FloatComplexColumnVector result (nr);
411 
412  for (octave_idx_type i = 0; i < a_len; i++)
413  result.elem (i) = a.elem (i) * m.elem (i, i);
414 
415  for (octave_idx_type i = a_len; i < nr; i++)
416  result.elem (i) = 0.0;
417 
418  return result;
419 }
420 
421 // other operations
422 
425 {
427  if (len == 0)
428  return 0.0;
429 
430  FloatComplex res = elem (0);
431  float absres = std::abs (res);
432 
433  for (octave_idx_type i = 1; i < len; i++)
434  if (std::abs (elem (i)) < absres)
435  {
436  res = elem (i);
437  absres = std::abs (res);
438  }
439 
440  return res;
441 }
442 
445 {
447  if (len == 0)
448  return 0.0;
449 
450  FloatComplex res = elem (0);
451  float absres = std::abs (res);
452 
453  for (octave_idx_type i = 1; i < len; i++)
454  if (std::abs (elem (i)) > absres)
455  {
456  res = elem (i);
457  absres = std::abs (res);
458  }
459 
460  return res;
461 }
462 
463 // i/o
464 
465 std::ostream&
466 operator << (std::ostream& os, const FloatComplexColumnVector& a)
467 {
468 // int field_width = os.precision () + 7;
469  for (octave_idx_type i = 0; i < a.numel (); i++)
470  os << /* setw (field_width) << */ a.elem (i) << "\n";
471  return os;
472 }
473 
474 std::istream&
476 {
477  octave_idx_type len = a.numel ();
478 
479  if (len > 0)
480  {
481  float tmp;
482  for (octave_idx_type i = 0; i < len; i++)
483  {
484  is >> tmp;
485  if (is)
486  a.elem (i) = tmp;
487  else
488  break;
489  }
490  }
491  return is;
492 }
T & elem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:562
T * fortran_vec()
Size of the specified dimension.
Definition: Array-base.cc:1764
const T * data() const
Size of the specified dimension.
Definition: Array.h:663
void make_unique()
Definition: Array.h:216
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:524
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
bool operator==(const FloatComplexColumnVector &a) const
Definition: fCColVector.cc:47
FloatComplexColumnVector extract_n(octave_idx_type r1, octave_idx_type n) const
Definition: fCColVector.cc:242
FloatComplexColumnVector & operator+=(const FloatColumnVector &a)
Definition: fCColVector.cc:256
FloatComplexColumnVector & operator-=(const FloatColumnVector &a)
Definition: fCColVector.cc:275
void clear(octave_idx_type n)
Definition: fCColVector.h:159
bool operator!=(const FloatComplexColumnVector &a) const
Definition: fCColVector.cc:56
FloatComplexRowVector hermitian() const
Definition: fCColVector.cc:201
FloatComplex min() const
Definition: fCColVector.cc:424
FloatComplexColumnVector & insert(const FloatColumnVector &a, octave_idx_type r)
Definition: fCColVector.cc:64
FloatComplex max() const
Definition: fCColVector.cc:444
FloatComplexColumnVector & fill(float val)
Definition: fCColVector.cc:103
FloatComplexColumnVector extract(octave_idx_type r1, octave_idx_type r2) const
Definition: fCColVector.cc:227
FloatComplexRowVector transpose() const
Definition: fCColVector.cc:207
FloatComplexColumnVector stack(const FloatColumnVector &a) const
Definition: fCColVector.cc:179
FloatColumnVector abs() const
Definition: fCColVector.cc:213
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:63
MArray< T > hermitian(T(*fcn)(const T &)=nullptr) const
Definition: MArray.h:102
MArray< T > transpose() const
Definition: MArray.h:99
#define F77_CONST_CMPLX_ARG(x)
Definition: f77-fcn.h:313
#define F77_CMPLX_ARG(x)
Definition: f77-fcn.h:310
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:45
octave_f77_int_type F77_INT
Definition: f77-fcn.h:306
FloatComplexColumnVector conj(const FloatComplexColumnVector &a)
Definition: fCColVector.cc:219
std::istream & operator>>(std::istream &is, FloatComplexColumnVector &a)
Definition: fCColVector.cc:475
std::ostream & operator<<(std::ostream &os, const FloatComplexColumnVector &a)
Definition: fCColVector.cc:466
FloatComplexColumnVector operator*(const FloatComplexMatrix &m, const FloatColumnVector &a)
Definition: fCColVector.cc:296
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
void mx_inline_sub2(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:128
void mx_inline_add2(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:127
bool mx_inline_equal(std::size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:577
T octave_idx_type m
Definition: mx-inlines.cc:781
octave_idx_type n
Definition: mx-inlines.cc:761
T * r
Definition: mx-inlines.cc:781
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
F77_RET_T len
Definition: xerbla.cc:61