GNU Octave  4.2.1
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
CColVector.cc
Go to the documentation of this file.
1 // ColumnVector manipulations.
2 /*
3 
4 Copyright (C) 1994-2017 John W. Eaton
5 Copyright (C) 2010 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include <iostream>
30 
31 #include "Array-util.h"
32 #include "functor.h"
33 #include "lo-blas-proto.h"
34 #include "lo-error.h"
35 #include "mx-base.h"
36 #include "mx-inlines.cc"
37 #include "oct-cmplx.h"
38 
39 // Complex Column Vector class
40 
42  : MArray<Complex> (a)
43 { }
44 
45 bool
47 {
48  octave_idx_type len = numel ();
49  if (len != a.numel ())
50  return 0;
51  return mx_inline_equal (len, data (), a.data ());
52 }
53 
54 bool
56 {
57  return !(*this == a);
58 }
59 
60 // destructive insert/delete/reorder operations
61 
64 {
65  octave_idx_type a_len = a.numel ();
66 
67  if (r < 0 || r + a_len > numel ())
68  (*current_liboctave_error_handler) ("range error for insert");
69 
70  if (a_len > 0)
71  {
72  make_unique ();
73 
74  for (octave_idx_type i = 0; i < a_len; i++)
75  xelem (r+i) = a.elem (i);
76  }
77 
78  return *this;
79 }
80 
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 
134 {
135  octave_idx_type len = numel ();
136 
137  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
138  (*current_liboctave_error_handler) ("range error for fill");
139 
140  if (r1 > r2) { std::swap (r1, r2); }
141 
142  if (r2 >= r1)
143  {
144  make_unique ();
145 
146  for (octave_idx_type i = r1; i <= r2; i++)
147  xelem (i) = val;
148  }
149 
150  return *this;
151 }
152 
156 {
157  octave_idx_type len = numel ();
158 
159  if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
160  (*current_liboctave_error_handler) ("range error for fill");
161 
162  if (r1 > r2) { std::swap (r1, r2); }
163 
164  if (r2 >= r1)
165  {
166  make_unique ();
167 
168  for (octave_idx_type i = r1; i <= r2; i++)
169  xelem (i) = val;
170  }
171 
172  return *this;
173 }
174 
177 {
178  octave_idx_type len = numel ();
179  octave_idx_type nr_insert = len;
180  ComplexColumnVector retval (len + a.numel ());
181  retval.insert (*this, 0);
182  retval.insert (a, nr_insert);
183  return retval;
184 }
185 
188 {
189  octave_idx_type len = numel ();
190  octave_idx_type nr_insert = len;
191  ComplexColumnVector retval (len + a.numel ());
192  retval.insert (*this, 0);
193  retval.insert (a, nr_insert);
194  return retval;
195 }
196 
199 {
201 }
202 
205 {
206  return MArray<Complex>::transpose ();
207 }
208 
211 {
212  return do_mx_unary_map<double, Complex, std::abs> (*this);
213 }
214 
217 {
218  return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
219 }
220 
221 // resize is the destructive equivalent for this one
222 
225 {
226  if (r1 > r2) { std::swap (r1, r2); }
227 
228  octave_idx_type new_r = r2 - r1 + 1;
229 
230  ComplexColumnVector result (new_r);
231 
232  for (octave_idx_type i = 0; i < new_r; i++)
233  result.elem (i) = elem (r1+i);
234 
235  return result;
236 }
237 
240 {
242 
243  for (octave_idx_type i = 0; i < n; i++)
244  result.elem (i) = elem (r1+i);
245 
246  return result;
247 }
248 
249 // column vector by column vector -> column vector operations
250 
253 {
254  octave_idx_type len = numel ();
255 
256  octave_idx_type a_len = a.numel ();
257 
258  if (len != a_len)
259  octave::err_nonconformant ("operator +=", len, a_len);
260 
261  if (len == 0)
262  return *this;
263 
264  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
265 
266  mx_inline_add2 (len, d, a.data ());
267  return *this;
268 }
269 
272 {
273  octave_idx_type len = numel ();
274 
275  octave_idx_type a_len = a.numel ();
276 
277  if (len != a_len)
278  octave::err_nonconformant ("operator -=", len, a_len);
279 
280  if (len == 0)
281  return *this;
282 
283  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
284 
285  mx_inline_sub2 (len, d, a.data ());
286  return *this;
287 }
288 
289 // matrix by column vector -> column vector operations
290 
293 {
295  return m * tmp;
296 }
297 
300 {
302 
303  octave_idx_type nr = m.rows ();
304  octave_idx_type nc = m.cols ();
305 
306  octave_idx_type a_len = a.numel ();
307 
308  if (nc != a_len)
309  octave::err_nonconformant ("operator *", nr, nc, a_len, 1);
310 
311  retval.clear (nr);
312 
313  if (nr != 0)
314  {
315  if (nc == 0)
316  retval.fill (0.0);
317  else
318  {
319  Complex *y = retval.fortran_vec ();
320 
321  F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
322  nr, nc, 1.0,
323  F77_CONST_DBLE_CMPLX_ARG (m.data ()), nr,
324  F77_CONST_DBLE_CMPLX_ARG (a.data ()), 1, 0.0,
325  F77_DBLE_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 {
338  ComplexMatrix tmp (m);
339  return tmp * a;
340 }
341 
342 // diagonal matrix by column vector -> column vector operations
343 
346 {
347  octave_idx_type nr = m.rows ();
348  octave_idx_type nc = m.cols ();
349 
350  octave_idx_type a_len = 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 ComplexColumnVector (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  octave_idx_type nr = m.rows ();
373  octave_idx_type nc = m.cols ();
374 
375  octave_idx_type a_len = 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 ComplexColumnVector (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  octave_idx_type nr = m.rows ();
398  octave_idx_type nc = m.cols ();
399 
400  octave_idx_type a_len = 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 ComplexColumnVector (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 
421 Complex
423 {
424  octave_idx_type len = numel ();
425  if (len == 0)
426  return 0.0;
427 
428  Complex res = elem (0);
429  double 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 
441 Complex
443 {
444  octave_idx_type len = numel ();
445  if (len == 0)
446  return 0.0;
447 
448  Complex res = elem (0);
449  double 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&
464 operator << (std::ostream& os, const ComplexColumnVector& a)
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  double 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 }
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:127
ComplexColumnVector & insert(const ColumnVector &a, octave_idx_type r)
Definition: CColVector.cc:63
void mx_inline_sub2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:128
ComplexRowVector transpose(void) const
Definition: CColVector.cc:204
T elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:114
std::ostream & operator<<(std::ostream &os, const ComplexColumnVector &a)
Definition: CColVector.cc:464
ColumnVector abs(void) const
Definition: CColVector.cc:210
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
bool operator==(const ComplexColumnVector &a) const
Definition: CColVector.cc:46
#define F77_DBLE_CMPLX_ARG(x)
Definition: f77-fcn.h:345
octave_idx_type rows(void) const
Definition: DiagArray2.h:88
MArray< T > transpose(void) const
Definition: MArray.h:103
T & elem(octave_idx_type n)
Definition: Array.h:482
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:52
octave_idx_type rows(void) const
Definition: Array.h:401
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &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 F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
ComplexColumnVector & operator+=(const ColumnVector &a)
Definition: CColVector.cc:252
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:398
bool swap
Definition: load-save.cc:725
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:216
ComplexColumnVector extract_n(octave_idx_type r1, octave_idx_type n) const
Definition: CColVector.cc:239
Complex max(void) const
Definition: CColVector.cc:442
ComplexColumnVector extract(octave_idx_type r1, octave_idx_type r2) const
Definition: CColVector.cc:224
void make_unique(void)
Definition: Array.h:185
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
bool operator!=(const ComplexColumnVector &a) const
Definition: CColVector.cc:55
const Complex * data(void) const
Definition: Array.h:582
ComplexColumnVector operator*(const ComplexMatrix &m, const ColumnVector &a)
Definition: CColVector.cc:292
double tmp
Definition: data.cc:6300
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value retval
Definition: data.cc:6294
void clear(octave_idx_type n)
Definition: CColVector.h:146
Definition: dMatrix.h:37
ComplexColumnVector & operator-=(const ColumnVector &a)
Definition: CColVector.cc:271
MArray< T > hermitian(T(*fcn)(const T &)=0) const
Definition: MArray.h:106
With real return the complex result
Definition: data.cc:3375
ComplexRowVector hermitian(void) const
Definition: CColVector.cc:198
Complex & xelem(octave_idx_type n)
Definition: Array.h:455
octave_idx_type cols(void) const
Definition: DiagArray2.h:89
ComplexColumnVector & fill(double val)
Definition: CColVector.cc:101
#define F77_CONST_DBLE_CMPLX_ARG(x)
Definition: f77-fcn.h:348
Complex min(void) const
Definition: CColVector.cc:422
ComplexColumnVector(void)
Definition: CColVector.h:42
ComplexColumnVector stack(const ColumnVector &a) const
Definition: CColVector.cc:176
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup abs(local error in x(i))<
the element is set to zero In other the statement xample y
Definition: data.cc:5342
std::complex< double > Complex
Definition: oct-cmplx.h:31
const Complex * fortran_vec(void) const
Definition: Array.h:584
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:532
octave_idx_type cols(void) const
Definition: Array.h:409
std::istream & operator>>(std::istream &is, ComplexColumnVector &a)
Definition: CColVector.cc:473
write the output to stdout if nargout is
Definition: load-save.cc:1576