1
// RowVector manipulations.
4
Copyright (C) 1994-2013 John W. Eaton
6
This file is part of Octave.
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 the
10
Free Software Foundation; either version 3 of the License, or (at your
11
option) any later version.
13
Octave is distributed in the hope that it will be useful, but WITHOUT
14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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
<http://www.gnu.org/licenses/>.
30
#include "Array-util.h"
35
#include "mx-inlines.cc"
36
#include "oct-cmplx.h"
38
// Fortran functions we call.
43
F77_FUNC (zgemv, ZGEMV) (F77_CONST_CHAR_ARG_DECL,
44
const octave_idx_type&, const octave_idx_type&,
45
const Complex&, const Complex*,
46
const octave_idx_type&, const Complex*,
47
const octave_idx_type&, const Complex&, Complex*,
48
const octave_idx_type&
49
F77_CHAR_ARG_LEN_DECL);
52
F77_FUNC (xzdotu, XZDOTU) (const octave_idx_type&, const Complex*,
53
const octave_idx_type&, const Complex*,
54
const octave_idx_type&, Complex&);
57
// Complex Row Vector class
60
ComplexRowVector::operator == (const ComplexRowVector& a) const
62
octave_idx_type len = length ();
63
if (len != a.length ())
65
return mx_inline_equal (len, data (), a.data ());
69
ComplexRowVector::operator != (const ComplexRowVector& a) const
74
// destructive insert/delete/reorder operations
77
ComplexRowVector::insert (const RowVector& a, octave_idx_type c)
79
octave_idx_type a_len = a.length ();
81
if (c < 0 || c + a_len > length ())
83
(*current_liboctave_error_handler) ("range error for insert");
91
for (octave_idx_type i = 0; i < a_len; i++)
92
xelem (c+i) = a.elem (i);
99
ComplexRowVector::insert (const ComplexRowVector& a, octave_idx_type c)
101
octave_idx_type a_len = a.length ();
103
if (c < 0 || c + a_len > length ())
105
(*current_liboctave_error_handler) ("range error for insert");
113
for (octave_idx_type i = 0; i < a_len; i++)
114
xelem (c+i) = a.elem (i);
121
ComplexRowVector::fill (double val)
123
octave_idx_type len = length ();
129
for (octave_idx_type i = 0; i < len; i++)
137
ComplexRowVector::fill (const Complex& val)
139
octave_idx_type len = length ();
145
for (octave_idx_type i = 0; i < len; i++)
153
ComplexRowVector::fill (double val, octave_idx_type c1, octave_idx_type c2)
155
octave_idx_type len = length ();
157
if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
159
(*current_liboctave_error_handler) ("range error for fill");
163
if (c1 > c2) { std::swap (c1, c2); }
169
for (octave_idx_type i = c1; i <= c2; i++)
177
ComplexRowVector::fill (const Complex& val,
178
octave_idx_type c1, octave_idx_type c2)
180
octave_idx_type len = length ();
182
if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
184
(*current_liboctave_error_handler) ("range error for fill");
188
if (c1 > c2) { std::swap (c1, c2); }
194
for (octave_idx_type i = c1; i <= c2; i++)
202
ComplexRowVector::append (const RowVector& a) const
204
octave_idx_type len = length ();
205
octave_idx_type nc_insert = len;
206
ComplexRowVector retval (len + a.length ());
207
retval.insert (*this, 0);
208
retval.insert (a, nc_insert);
213
ComplexRowVector::append (const ComplexRowVector& a) const
215
octave_idx_type len = length ();
216
octave_idx_type nc_insert = len;
217
ComplexRowVector retval (len + a.length ());
218
retval.insert (*this, 0);
219
retval.insert (a, nc_insert);
224
ComplexRowVector::hermitian (void) const
226
return MArray<Complex>::hermitian (std::conj);
230
ComplexRowVector::transpose (void) const
232
return MArray<Complex>::transpose ();
236
conj (const ComplexRowVector& a)
238
return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
241
// resize is the destructive equivalent for this one
244
ComplexRowVector::extract (octave_idx_type c1, octave_idx_type c2) const
246
if (c1 > c2) { std::swap (c1, c2); }
248
octave_idx_type new_c = c2 - c1 + 1;
250
ComplexRowVector result (new_c);
252
for (octave_idx_type i = 0; i < new_c; i++)
253
result.elem (i) = elem (c1+i);
259
ComplexRowVector::extract_n (octave_idx_type r1, octave_idx_type n) const
261
ComplexRowVector result (n);
263
for (octave_idx_type i = 0; i < n; i++)
264
result.elem (i) = elem (r1+i);
269
// row vector by row vector -> row vector operations
272
ComplexRowVector::operator += (const RowVector& a)
274
octave_idx_type len = length ();
276
octave_idx_type a_len = a.length ();
280
gripe_nonconformant ("operator +=", len, a_len);
287
Complex *d = fortran_vec (); // Ensures only one reference to my privates!
289
mx_inline_add2 (len, d, a.data ());
294
ComplexRowVector::operator -= (const RowVector& a)
296
octave_idx_type len = length ();
298
octave_idx_type a_len = a.length ();
302
gripe_nonconformant ("operator -=", len, a_len);
309
Complex *d = fortran_vec (); // Ensures only one reference to my privates!
311
mx_inline_sub2 (len, d, a.data ());
315
// row vector by matrix -> row vector
318
operator * (const ComplexRowVector& v, const ComplexMatrix& a)
320
ComplexRowVector retval;
322
octave_idx_type len = v.length ();
324
octave_idx_type a_nr = a.rows ();
325
octave_idx_type a_nc = a.cols ();
328
gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
332
retval.resize (a_nc, 0.0);
335
// Transpose A to form A'*x == (x'*A)'
337
octave_idx_type ld = a_nr;
339
retval.resize (a_nc);
340
Complex *y = retval.fortran_vec ();
342
F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
343
a_nr, a_nc, 1.0, a.data (),
344
ld, v.data (), 1, 0.0, y, 1
345
F77_CHAR_ARG_LEN (1)));
353
operator * (const RowVector& v, const ComplexMatrix& a)
355
ComplexRowVector tmp (v);
362
ComplexRowVector::min (void) const
364
octave_idx_type len = length ();
366
return Complex (0.0);
368
Complex res = elem (0);
369
double absres = std::abs (res);
371
for (octave_idx_type i = 1; i < len; i++)
372
if (std::abs (elem (i)) < absres)
375
absres = std::abs (res);
382
ComplexRowVector::max (void) const
384
octave_idx_type len = length ();
386
return Complex (0.0);
388
Complex res = elem (0);
389
double absres = std::abs (res);
391
for (octave_idx_type i = 1; i < len; i++)
392
if (std::abs (elem (i)) > absres)
395
absres = std::abs (res);
404
operator << (std::ostream& os, const ComplexRowVector& a)
406
// int field_width = os.precision () + 7;
407
for (octave_idx_type i = 0; i < a.length (); i++)
408
os << " " /* setw (field_width) */ << a.elem (i);
413
operator >> (std::istream& is, ComplexRowVector& a)
415
octave_idx_type len = a.length ();
420
for (octave_idx_type i = 0; i < len; i++)
432
// row vector by column vector -> scalar
434
// row vector by column vector -> scalar
437
operator * (const ComplexRowVector& v, const ColumnVector& a)
439
ComplexColumnVector tmp (a);
444
operator * (const ComplexRowVector& v, const ComplexColumnVector& a)
446
Complex retval (0.0, 0.0);
448
octave_idx_type len = v.length ();
450
octave_idx_type a_len = a.length ();
453
gripe_nonconformant ("operator *", len, a_len);
455
F77_FUNC (xzdotu, XZDOTU) (len, v.data (), 1, a.data (), 1, retval);
463
linspace (const Complex& x1, const Complex& x2, octave_idx_type n)
467
NoAlias<ComplexRowVector> retval (n);
469
Complex delta = (x2 - x1) / (n - 1.0);
471
for (octave_idx_type i = 1; i < n-1; i++)
472
retval(i) = x1 + static_cast<double> (i)*delta;