GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
CColVector.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2018 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
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License 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 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <iostream>
29 
30 #include "Array-util.h"
31 #include "functor.h"
32 #include "lo-blas-proto.h"
33 #include "lo-error.h"
34 #include "mx-base.h"
35 #include "mx-inlines.cc"
36 #include "oct-cmplx.h"
37 
38 // Complex Column Vector class
39 
41  : MArray<Complex> (a)
42 { }
43 
44 bool
46 {
47  octave_idx_type len = numel ();
48  if (len != a.numel ())
49  return 0;
50  return mx_inline_equal (len, data (), a.data ());
51 }
52 
53 bool
55 {
56  return !(*this == a);
57 }
58 
59 // destructive insert/delete/reorder operations
60 
63 {
64  octave_idx_type a_len = a.numel ();
65 
66  if (r < 0 || r + a_len > numel ())
67  (*current_liboctave_error_handler) ("range error for insert");
68 
69  if (a_len > 0)
70  {
71  make_unique ();
72 
73  for (octave_idx_type i = 0; i < a_len; i++)
74  xelem (r+i) = a.elem (i);
75  }
76 
77  return *this;
78 }
79 
82 {
83  octave_idx_type a_len = a.numel ();
84 
85  if (r < 0 || r + a_len > numel ())
86  (*current_liboctave_error_handler) ("range error for insert");
87 
88  if (a_len > 0)
89  {
90  make_unique ();
91 
92  for (octave_idx_type i = 0; i < a_len; i++)
93  xelem (r+i) = a.elem (i);
94  }
95 
96  return *this;
97 }
98 
101 {
102  octave_idx_type len = numel ();
103 
104  if (len > 0)
105  {
106  make_unique ();
107 
108  for (octave_idx_type i = 0; i < len; i++)
109  xelem (i) = val;
110  }
111 
112  return *this;
113 }
114 
117 {
118  octave_idx_type len = numel ();
119 
120  if (len > 0)
121  {
122  make_unique ();
123 
124  for (octave_idx_type i = 0; i < len; i++)
125  xelem (i) = val;
126  }
127 
128  return *this;
129 }
130 
133 {
134  octave_idx_type len = numel ();
135 
136  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
137  (*current_liboctave_error_handler) ("range error for fill");
138 
139  if (r1 > r2) { std::swap (r1, r2); }
140 
141  if (r2 >= r1)
142  {
143  make_unique ();
144 
145  for (octave_idx_type i = r1; i <= r2; i++)
146  xelem (i) = val;
147  }
148 
149  return *this;
150 }
151 
155 {
156  octave_idx_type len = numel ();
157 
158  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
159  (*current_liboctave_error_handler) ("range error for fill");
160 
161  if (r1 > r2) { std::swap (r1, r2); }
162 
163  if (r2 >= r1)
164  {
165  make_unique ();
166 
167  for (octave_idx_type i = r1; i <= r2; i++)
168  xelem (i) = val;
169  }
170 
171  return *this;
172 }
173 
176 {
177  octave_idx_type len = numel ();
178  octave_idx_type nr_insert = len;
179  ComplexColumnVector retval (len + a.numel ());
180  retval.insert (*this, 0);
181  retval.insert (a, nr_insert);
182  return retval;
183 }
184 
187 {
188  octave_idx_type len = numel ();
189  octave_idx_type nr_insert = len;
190  ComplexColumnVector retval (len + a.numel ());
191  retval.insert (*this, 0);
192  retval.insert (a, nr_insert);
193  return retval;
194 }
195 
198 {
200 }
201 
204 {
205  return MArray<Complex>::transpose ();
206 }
207 
210 {
211  return do_mx_unary_map<double, Complex, std::abs> (*this);
212 }
213 
216 {
217  return do_mx_unary_map<Complex, Complex, std::conj<double>> (a);
218 }
219 
220 // resize is the destructive equivalent for this one
221 
224 {
225  if (r1 > r2) { std::swap (r1, r2); }
226 
227  octave_idx_type new_r = r2 - r1 + 1;
228 
229  ComplexColumnVector result (new_r);
230 
231  for (octave_idx_type i = 0; i < new_r; i++)
232  result.elem (i) = elem (r1+i);
233 
234  return result;
235 }
236 
239 {
241 
242  for (octave_idx_type i = 0; i < n; i++)
243  result.elem (i) = elem (r1+i);
244 
245  return result;
246 }
247 
248 // column vector by column vector -> column vector operations
249 
252 {
253  octave_idx_type len = numel ();
254 
255  octave_idx_type a_len = a.numel ();
256 
257  if (len != a_len)
258  octave::err_nonconformant ("operator +=", len, a_len);
259 
260  if (len == 0)
261  return *this;
262 
263  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
264 
265  mx_inline_add2 (len, d, a.data ());
266  return *this;
267 }
268 
271 {
272  octave_idx_type len = numel ();
273 
274  octave_idx_type a_len = a.numel ();
275 
276  if (len != a_len)
277  octave::err_nonconformant ("operator -=", len, a_len);
278 
279  if (len == 0)
280  return *this;
281 
282  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
283 
284  mx_inline_sub2 (len, d, a.data ());
285  return *this;
286 }
287 
288 // matrix by column vector -> column vector operations
289 
292 {
294  return m * tmp;
295 }
296 
299 {
301 
302  F77_INT nr = octave::to_f77_int (m.rows ());
303  F77_INT nc = octave::to_f77_int (m.cols ());
304 
305  F77_INT a_len = octave::to_f77_int (a.numel ());
306 
307  if (nc != a_len)
308  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
309 
310  retval.clear (nr);
311 
312  if (nr != 0)
313  {
314  if (nc == 0)
315  retval.fill (0.0);
316  else
317  {
318  Complex *y = retval.fortran_vec ();
319 
320  F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
321  nr, nc, 1.0,
322  F77_CONST_DBLE_CMPLX_ARG (m.data ()), nr,
323  F77_CONST_DBLE_CMPLX_ARG (a.data ()), 1, 0.0,
324  F77_DBLE_CMPLX_ARG (y), 1
325  F77_CHAR_ARG_LEN (1)));
326  }
327  }
328 
329  return retval;
330 }
331 
332 // matrix by column vector -> column vector operations
333 
336 {
337  ComplexMatrix tmp (m);
338  return tmp * a;
339 }
340 
341 // diagonal matrix by column vector -> column vector operations
342 
345 {
346  F77_INT nr = octave::to_f77_int (m.rows ());
347  F77_INT nc = octave::to_f77_int (m.cols ());
348 
349  F77_INT a_len = octave::to_f77_int (a.numel ());
350 
351  if (nc != a_len)
352  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
353 
354  if (nc == 0 || nr == 0)
355  return ComplexColumnVector (0);
356 
358 
359  for (octave_idx_type i = 0; i < a_len; i++)
360  result.elem (i) = a.elem (i) * m.elem (i, i);
361 
362  for (octave_idx_type i = a_len; i < nr; i++)
363  result.elem (i) = 0.0;
364 
365  return result;
366 }
367 
370 {
371  F77_INT nr = octave::to_f77_int (m.rows ());
372  F77_INT nc = octave::to_f77_int (m.cols ());
373 
374  F77_INT a_len = octave::to_f77_int (a.numel ());
375 
376  if (nc != a_len)
377  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
378 
379  if (nc == 0 || nr == 0)
380  return ComplexColumnVector (0);
381 
383 
384  for (octave_idx_type i = 0; i < a_len; i++)
385  result.elem (i) = a.elem (i) * m.elem (i, i);
386 
387  for (octave_idx_type i = a_len; i < nr; i++)
388  result.elem (i) = 0.0;
389 
390  return result;
391 }
392 
395 {
396  F77_INT nr = octave::to_f77_int (m.rows ());
397  F77_INT nc = octave::to_f77_int (m.cols ());
398 
399  F77_INT a_len = octave::to_f77_int (a.numel ());
400 
401  if (nc != a_len)
402  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
403 
404  if (nc == 0 || nr == 0)
405  return ComplexColumnVector (0);
406 
408 
409  for (octave_idx_type i = 0; i < a_len; i++)
410  result.elem (i) = a.elem (i) * m.elem (i, i);
411 
412  for (octave_idx_type i = a_len; i < nr; i++)
413  result.elem (i) = 0.0;
414 
415  return result;
416 }
417 
418 // other operations
419 
420 Complex
422 {
423  octave_idx_type len = numel ();
424  if (len == 0)
425  return 0.0;
426 
427  Complex res = elem (0);
428  double absres = std::abs (res);
429 
430  for (octave_idx_type i = 1; i < len; i++)
431  if (std::abs (elem (i)) < absres)
432  {
433  res = elem (i);
434  absres = std::abs (res);
435  }
436 
437  return res;
438 }
439 
440 Complex
442 {
443  octave_idx_type len = numel ();
444  if (len == 0)
445  return 0.0;
446 
447  Complex res = elem (0);
448  double absres = std::abs (res);
449 
450  for (octave_idx_type i = 1; i < len; i++)
451  if (std::abs (elem (i)) > absres)
452  {
453  res = elem (i);
454  absres = std::abs (res);
455  }
456 
457  return res;
458 }
459 
460 // i/o
461 
462 std::ostream&
463 operator << (std::ostream& os, const ComplexColumnVector& a)
464 {
465 // int field_width = os.precision () + 7;
466  for (octave_idx_type i = 0; i < a.numel (); i++)
467  os << /* setw (field_width) << */ a.elem (i) << "\n";
468  return os;
469 }
470 
471 std::istream&
473 {
474  octave_idx_type len = a.numel ();
475 
476  if (len > 0)
477  {
478  double tmp;
479  for (octave_idx_type i = 0; i < len; i++)
480  {
481  is >> tmp;
482  if (is)
483  a.elem (i) = tmp;
484  else
485  break;
486  }
487  }
488  return is;
489 }
octave_idx_type rows(void) const
Definition: Array.h:404
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:125
ComplexColumnVector & insert(const ColumnVector &a, octave_idx_type r)
Definition: CColVector.cc:62
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
void mx_inline_sub2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:126
Complex min(void) const
Definition: CColVector.cc:421
std::ostream & operator<<(std::ostream &os, const ComplexColumnVector &a)
Definition: CColVector.cc:463
const Complex * data(void) const
Definition: Array.h:582
MArray< T > hermitian(T(*fcn)(const T &)=nullptr) const
Definition: MArray.h:106
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
#define F77_DBLE_CMPLX_ARG(x)
Definition: f77-fcn.h:315
Complex max(void) const
Definition: CColVector.cc:441
const Complex * fortran_vec(void) const
Definition: Array.h:584
bool operator==(const ComplexColumnVector &a) const
Definition: CColVector.cc:45
static T abs(T x)
Definition: pr-output.cc:1696
ComplexRowVector hermitian(void) const
Definition: CColVector.cc:197
Complex & elem(octave_idx_type n)
Definition: Array.h:488
ComplexColumnVector stack(const ColumnVector &a) const
Definition: CColVector.cc:175
octave_idx_type rows(void) const
Definition: DiagArray2.h:87
MArray< T > transpose(void) const
Definition: MArray.h:103
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:41
ComplexColumnVector extract_n(octave_idx_type r1, octave_idx_type n) const
Definition: CColVector.cc:238
T elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:115
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
octave_idx_type cols(void) const
Definition: Array.h:412
ComplexColumnVector & operator+=(const ColumnVector &a)
Definition: CColVector.cc:251
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:400
bool swap
Definition: load-save.cc:738
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:215
octave_idx_type cols(void) const
Definition: DiagArray2.h:88
ColumnVector abs(void) const
Definition: CColVector.cc:209
void make_unique(void)
Definition: Array.h:187
bool operator!=(const ComplexColumnVector &a) const
Definition: CColVector.cc:54
ComplexColumnVector operator*(const ComplexMatrix &m, const ColumnVector &a)
Definition: CColVector.cc:291
double tmp
Definition: data.cc:6252
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value retval
Definition: data.cc:6246
Definition: dMatrix.h:36
ComplexColumnVector & operator-=(const ColumnVector &a)
Definition: CColVector.cc:270
With real return the complex result
Definition: data.cc:3260
Complex & xelem(octave_idx_type n)
Definition: Array.h:458
ComplexColumnVector & fill(double val)
Definition: CColVector.cc:100
#define F77_CONST_DBLE_CMPLX_ARG(x)
Definition: f77-fcn.h:318
ComplexColumnVector(void)
Definition: CColVector.h:41
octave_f77_int_type F77_INT
Definition: f77-fcn.h:305
the element is set to zero In other the statement xample y
Definition: data.cc:5264
for i
Definition: data.cc:5264
ComplexRowVector transpose(void) const
Definition: CColVector.cc:203
std::complex< double > Complex
Definition: oct-cmplx.h:31
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
ComplexColumnVector extract(octave_idx_type r1, octave_idx_type r2) const
Definition: CColVector.cc:223
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:569
std::istream & operator>>(std::istream &is, ComplexColumnVector &a)
Definition: CColVector.cc:472
write the output to stdout if nargout is
Definition: load-save.cc:1612
octave::stream os
Definition: file-io.cc:627