GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
fCColVector.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 // FloatComplex Column Vector class
39 
41  : MArray<FloatComplex> (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 
83 {
84  octave_idx_type a_len = a.numel ();
85 
86  if (r < 0 || r + a_len > numel ())
87  (*current_liboctave_error_handler) ("range error for insert");
88 
89  if (a_len > 0)
90  {
91  make_unique ();
92 
93  for (octave_idx_type i = 0; i < a_len; i++)
94  xelem (r+i) = a.elem (i);
95  }
96 
97  return *this;
98 }
99 
102 {
103  octave_idx_type len = numel ();
104 
105  if (len > 0)
106  {
107  make_unique ();
108 
109  for (octave_idx_type i = 0; i < len; i++)
110  xelem (i) = val;
111  }
112 
113  return *this;
114 }
115 
118 {
119  octave_idx_type len = numel ();
120 
121  if (len > 0)
122  {
123  make_unique ();
124 
125  for (octave_idx_type i = 0; i < len; i++)
126  xelem (i) = val;
127  }
128 
129  return *this;
130 }
131 
135 {
136  octave_idx_type len = numel ();
137 
138  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
139  (*current_liboctave_error_handler) ("range error for fill");
140 
141  if (r1 > r2) { std::swap (r1, r2); }
142 
143  if (r2 >= r1)
144  {
145  make_unique ();
146 
147  for (octave_idx_type i = r1; i <= r2; i++)
148  xelem (i) = val;
149  }
150 
151  return *this;
152 }
153 
157 {
158  octave_idx_type len = numel ();
159 
160  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
161  (*current_liboctave_error_handler) ("range error for fill");
162 
163  if (r1 > r2) { std::swap (r1, r2); }
164 
165  if (r2 >= r1)
166  {
167  make_unique ();
168 
169  for (octave_idx_type i = r1; i <= r2; i++)
170  xelem (i) = val;
171  }
172 
173  return *this;
174 }
175 
178 {
179  octave_idx_type len = numel ();
180  octave_idx_type nr_insert = len;
181  FloatComplexColumnVector retval (len + a.numel ());
182  retval.insert (*this, 0);
183  retval.insert (a, nr_insert);
184  return retval;
185 }
186 
189 {
190  octave_idx_type len = numel ();
191  octave_idx_type nr_insert = len;
192  FloatComplexColumnVector retval (len + a.numel ());
193  retval.insert (*this, 0);
194  retval.insert (a, nr_insert);
195  return retval;
196 }
197 
200 {
202 }
203 
206 {
208 }
209 
212 {
213  return do_mx_unary_map<float, FloatComplex, std::abs> (*this);
214 }
215 
218 {
219  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float>> (a);
220 }
221 
222 // resize is the destructive equivalent for this one
223 
226 {
227  if (r1 > r2) { std::swap (r1, r2); }
228 
229  octave_idx_type new_r = r2 - r1 + 1;
230 
232 
233  for (octave_idx_type i = 0; i < new_r; i++)
234  result.elem (i) = elem (r1+i);
235 
236  return result;
237 }
238 
241  octave_idx_type n) const
242 {
244 
245  for (octave_idx_type i = 0; i < n; i++)
246  result.elem (i) = elem (r1+i);
247 
248  return result;
249 }
250 
251 // column vector by column vector -> column vector operations
252 
255 {
256  octave_idx_type len = numel ();
257 
258  octave_idx_type a_len = a.numel ();
259 
260  if (len != a_len)
261  octave::err_nonconformant ("operator +=", len, a_len);
262 
263  if (len == 0)
264  return *this;
265 
266  FloatComplex *d = fortran_vec (); // Ensures only 1 reference to my privates!
267 
268  mx_inline_add2 (len, d, a.data ());
269  return *this;
270 }
271 
274 {
275  octave_idx_type len = numel ();
276 
277  octave_idx_type a_len = a.numel ();
278 
279  if (len != a_len)
280  octave::err_nonconformant ("operator -=", len, a_len);
281 
282  if (len == 0)
283  return *this;
284 
285  FloatComplex *d = fortran_vec (); // Ensures only 1 reference to my privates!
286 
287  mx_inline_sub2 (len, d, a.data ());
288  return *this;
289 }
290 
291 // matrix by column vector -> column vector operations
292 
295 {
297  return m * tmp;
298 }
299 
302 {
304 
305  F77_INT nr = octave::to_f77_int (m.rows ());
306  F77_INT nc = octave::to_f77_int (m.cols ());
307 
308  F77_INT a_len = octave::to_f77_int (a.numel ());
309 
310  if (nc != a_len)
311  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
312 
313  retval.clear (nr);
314 
315  if (nr != 0)
316  {
317  if (nc == 0)
318  retval.fill (0.0);
319  else
320  {
321  FloatComplex *y = retval.fortran_vec ();
322 
323  F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
324  nr, nc, 1.0f, F77_CONST_CMPLX_ARG (m.data ()), nr,
325  F77_CONST_CMPLX_ARG (a.data ()), 1, 0.0f, F77_CMPLX_ARG (y), 1
326  F77_CHAR_ARG_LEN (1)));
327  }
328  }
329 
330  return retval;
331 }
332 
333 // matrix by column vector -> column vector operations
334 
337 {
339  return tmp * a;
340 }
341 
342 // diagonal matrix by column vector -> column vector operations
343 
346 {
347  F77_INT nr = octave::to_f77_int (m.rows ());
348  F77_INT nc = octave::to_f77_int (m.cols ());
349 
350  F77_INT a_len = octave::to_f77_int (a.numel ());
351 
352  if (nc != a_len)
353  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
354 
355  if (nc == 0 || nr == 0)
356  return FloatComplexColumnVector (0);
357 
359 
360  for (octave_idx_type i = 0; i < a_len; i++)
361  result.elem (i) = a.elem (i) * m.elem (i, i);
362 
363  for (octave_idx_type i = a_len; i < nr; i++)
364  result.elem (i) = 0.0;
365 
366  return result;
367 }
368 
371 {
372  F77_INT nr = octave::to_f77_int (m.rows ());
373  F77_INT nc = octave::to_f77_int (m.cols ());
374 
375  F77_INT a_len = octave::to_f77_int (a.numel ());
376 
377  if (nc != a_len)
378  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
379 
380  if (nc == 0 || nr == 0)
381  return FloatComplexColumnVector (0);
382 
384 
385  for (octave_idx_type i = 0; i < a_len; i++)
386  result.elem (i) = a.elem (i) * m.elem (i, i);
387 
388  for (octave_idx_type i = a_len; i < nr; i++)
389  result.elem (i) = 0.0;
390 
391  return result;
392 }
393 
396 {
397  F77_INT nr = octave::to_f77_int (m.rows ());
398  F77_INT nc = octave::to_f77_int (m.cols ());
399 
400  F77_INT a_len = octave::to_f77_int (a.numel ());
401 
402  if (nc != a_len)
403  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
404 
405  if (nc == 0 || nr == 0)
406  return FloatComplexColumnVector (0);
407 
409 
410  for (octave_idx_type i = 0; i < a_len; i++)
411  result.elem (i) = a.elem (i) * m.elem (i, i);
412 
413  for (octave_idx_type i = a_len; i < nr; i++)
414  result.elem (i) = 0.0;
415 
416  return result;
417 }
418 
419 // other operations
420 
423 {
424  octave_idx_type len = numel ();
425  if (len == 0)
426  return 0.0;
427 
428  FloatComplex res = elem (0);
429  float absres = std::abs (res);
430 
431  for (octave_idx_type i = 1; i < len; i++)
432  if (std::abs (elem (i)) < absres)
433  {
434  res = elem (i);
435  absres = std::abs (res);
436  }
437 
438  return res;
439 }
440 
443 {
444  octave_idx_type len = numel ();
445  if (len == 0)
446  return 0.0;
447 
448  FloatComplex res = elem (0);
449  float absres = std::abs (res);
450 
451  for (octave_idx_type i = 1; i < len; i++)
452  if (std::abs (elem (i)) > absres)
453  {
454  res = elem (i);
455  absres = std::abs (res);
456  }
457 
458  return res;
459 }
460 
461 // i/o
462 
463 std::ostream&
465 {
466 // int field_width = os.precision () + 7;
467  for (octave_idx_type i = 0; i < a.numel (); i++)
468  os << /* setw (field_width) << */ a.elem (i) << "\n";
469  return os;
470 }
471 
472 std::istream&
474 {
475  octave_idx_type len = a.numel ();
476 
477  if (len > 0)
478  {
479  float tmp;
480  for (octave_idx_type i = 0; i < len; i++)
481  {
482  is >> tmp;
483  if (is)
484  a.elem (i) = tmp;
485  else
486  break;
487  }
488  }
489  return is;
490 }
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
FloatComplexColumnVector operator*(const FloatComplexMatrix &m, const FloatColumnVector &a)
Definition: fCColVector.cc:294
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
bool operator==(const FloatComplexColumnVector &a) const
Definition: fCColVector.cc:45
FloatComplexColumnVector stack(const FloatColumnVector &a) const
Definition: fCColVector.cc:177
const FloatComplex * data(void) const
Definition: Array.h:582
FloatComplexColumnVector & operator-=(const FloatColumnVector &a)
Definition: fCColVector.cc:273
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
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 * f
FloatComplexColumnVector extract(octave_idx_type r1, octave_idx_type r2) const
Definition: fCColVector.cc:225
const FloatComplex * fortran_vec(void) const
Definition: Array.h:584
static T abs(T x)
Definition: pr-output.cc:1696
std::istream & operator>>(std::istream &is, FloatComplexColumnVector &a)
Definition: fCColVector.cc:473
FloatComplex & elem(octave_idx_type n)
Definition: Array.h:488
FloatComplexColumnVector conj(const FloatComplexColumnVector &a)
Definition: fCColVector.cc:217
bool operator!=(const FloatComplexColumnVector &a) const
Definition: fCColVector.cc:54
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
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
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
FloatComplexColumnVector & operator+=(const FloatColumnVector &a)
Definition: fCColVector.cc:254
FloatComplex max(void) const
Definition: fCColVector.cc:442
octave_idx_type cols(void) const
Definition: DiagArray2.h:88
FloatComplexColumnVector extract_n(octave_idx_type r1, octave_idx_type n) const
Definition: fCColVector.cc:240
void make_unique(void)
Definition: Array.h:187
FloatComplex min(void) const
Definition: fCColVector.cc:422
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
With real return the complex result
Definition: data.cc:3260
FloatComplex & xelem(octave_idx_type n)
Definition: Array.h:458
FloatComplexRowVector transpose(void) const
Definition: fCColVector.cc:205
#define F77_CMPLX_ARG(x)
Definition: f77-fcn.h:309
FloatComplexRowVector hermitian(void) const
Definition: fCColVector.cc:199
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
#define F77_CONST_CMPLX_ARG(x)
Definition: f77-fcn.h:312
FloatComplexColumnVector & fill(float val)
Definition: fCColVector.cc:101
std::ostream & operator<<(std::ostream &os, const FloatComplexColumnVector &a)
Definition: fCColVector.cc:464
for i
Definition: data.cc:5264
FloatComplexColumnVector & insert(const FloatColumnVector &a, octave_idx_type r)
Definition: fCColVector.cc:62
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:569
write the output to stdout if nargout is
Definition: load-save.cc:1612
FloatColumnVector abs(void) const
Definition: fCColVector.cc:211
octave::stream os
Definition: file-io.cc:627