00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <iostream>
00030
00031 #include "Array-util.h"
00032 #include "f77-fcn.h"
00033 #include "functor.h"
00034 #include "lo-error.h"
00035 #include "mx-base.h"
00036 #include "mx-inlines.cc"
00037 #include "oct-cmplx.h"
00038
00039
00040
00041 extern "C"
00042 {
00043 F77_RET_T
00044 F77_FUNC (zgemv, ZGEMV) (F77_CONST_CHAR_ARG_DECL,
00045 const octave_idx_type&, const octave_idx_type&,
00046 const Complex&, const Complex*,
00047 const octave_idx_type&, const Complex*,
00048 const octave_idx_type&, const Complex&,
00049 Complex*, const octave_idx_type&
00050 F77_CHAR_ARG_LEN_DECL);
00051 }
00052
00053
00054
00055 ComplexColumnVector::ComplexColumnVector (const ColumnVector& a)
00056 : MArray<Complex> (a)
00057 {
00058 }
00059
00060 bool
00061 ComplexColumnVector::operator == (const ComplexColumnVector& a) const
00062 {
00063 octave_idx_type len = length ();
00064 if (len != a.length ())
00065 return 0;
00066 return mx_inline_equal (len, data (), a.data ());
00067 }
00068
00069 bool
00070 ComplexColumnVector::operator != (const ComplexColumnVector& a) const
00071 {
00072 return !(*this == a);
00073 }
00074
00075
00076
00077 ComplexColumnVector&
00078 ComplexColumnVector::insert (const ColumnVector& a, octave_idx_type r)
00079 {
00080 octave_idx_type a_len = a.length ();
00081
00082 if (r < 0 || r + a_len > length ())
00083 {
00084 (*current_liboctave_error_handler) ("range error for insert");
00085 return *this;
00086 }
00087
00088 if (a_len > 0)
00089 {
00090 make_unique ();
00091
00092 for (octave_idx_type i = 0; i < a_len; i++)
00093 xelem (r+i) = a.elem (i);
00094 }
00095
00096 return *this;
00097 }
00098
00099 ComplexColumnVector&
00100 ComplexColumnVector::insert (const ComplexColumnVector& a, octave_idx_type r)
00101 {
00102 octave_idx_type a_len = a.length ();
00103
00104 if (r < 0 || r + a_len > length ())
00105 {
00106 (*current_liboctave_error_handler) ("range error for insert");
00107 return *this;
00108 }
00109
00110 if (a_len > 0)
00111 {
00112 make_unique ();
00113
00114 for (octave_idx_type i = 0; i < a_len; i++)
00115 xelem (r+i) = a.elem (i);
00116 }
00117
00118 return *this;
00119 }
00120
00121 ComplexColumnVector&
00122 ComplexColumnVector::fill (double val)
00123 {
00124 octave_idx_type len = length ();
00125
00126 if (len > 0)
00127 {
00128 make_unique ();
00129
00130 for (octave_idx_type i = 0; i < len; i++)
00131 xelem (i) = val;
00132 }
00133
00134 return *this;
00135 }
00136
00137 ComplexColumnVector&
00138 ComplexColumnVector::fill (const Complex& val)
00139 {
00140 octave_idx_type len = length ();
00141
00142 if (len > 0)
00143 {
00144 make_unique ();
00145
00146 for (octave_idx_type i = 0; i < len; i++)
00147 xelem (i) = val;
00148 }
00149
00150
00151 return *this;
00152 }
00153
00154 ComplexColumnVector&
00155 ComplexColumnVector::fill (double val, octave_idx_type r1, octave_idx_type r2)
00156 {
00157 octave_idx_type len = length ();
00158
00159 if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
00160 {
00161 (*current_liboctave_error_handler) ("range error for fill");
00162 return *this;
00163 }
00164
00165 if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
00166
00167 if (r2 >= r1)
00168 {
00169 make_unique ();
00170
00171 for (octave_idx_type i = r1; i <= r2; i++)
00172 xelem (i) = val;
00173 }
00174
00175 return *this;
00176 }
00177
00178 ComplexColumnVector&
00179 ComplexColumnVector::fill (const Complex& val, octave_idx_type r1, octave_idx_type r2)
00180 {
00181 octave_idx_type len = length ();
00182
00183 if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
00184 {
00185 (*current_liboctave_error_handler) ("range error for fill");
00186 return *this;
00187 }
00188
00189 if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
00190
00191 if (r2 >= r1)
00192 {
00193 make_unique ();
00194
00195 for (octave_idx_type i = r1; i <= r2; i++)
00196 xelem (i) = val;
00197 }
00198
00199 return *this;
00200 }
00201
00202 ComplexColumnVector
00203 ComplexColumnVector::stack (const ColumnVector& a) const
00204 {
00205 octave_idx_type len = length ();
00206 octave_idx_type nr_insert = len;
00207 ComplexColumnVector retval (len + a.length ());
00208 retval.insert (*this, 0);
00209 retval.insert (a, nr_insert);
00210 return retval;
00211 }
00212
00213 ComplexColumnVector
00214 ComplexColumnVector::stack (const ComplexColumnVector& a) const
00215 {
00216 octave_idx_type len = length ();
00217 octave_idx_type nr_insert = len;
00218 ComplexColumnVector retval (len + a.length ());
00219 retval.insert (*this, 0);
00220 retval.insert (a, nr_insert);
00221 return retval;
00222 }
00223
00224 ComplexRowVector
00225 ComplexColumnVector::hermitian (void) const
00226 {
00227 return MArray<Complex>::hermitian (std::conj);
00228 }
00229
00230 ComplexRowVector
00231 ComplexColumnVector::transpose (void) const
00232 {
00233 return MArray<Complex>::transpose ();
00234 }
00235
00236 ColumnVector
00237 ComplexColumnVector::abs (void) const
00238 {
00239 return do_mx_unary_map<double, Complex, std::abs> (*this);
00240 }
00241
00242 ComplexColumnVector
00243 conj (const ComplexColumnVector& a)
00244 {
00245 return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
00246 }
00247
00248
00249
00250 ComplexColumnVector
00251 ComplexColumnVector::extract (octave_idx_type r1, octave_idx_type r2) const
00252 {
00253 if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
00254
00255 octave_idx_type new_r = r2 - r1 + 1;
00256
00257 ComplexColumnVector result (new_r);
00258
00259 for (octave_idx_type i = 0; i < new_r; i++)
00260 result.elem (i) = elem (r1+i);
00261
00262 return result;
00263 }
00264
00265 ComplexColumnVector
00266 ComplexColumnVector::extract_n (octave_idx_type r1, octave_idx_type n) const
00267 {
00268 ComplexColumnVector result (n);
00269
00270 for (octave_idx_type i = 0; i < n; i++)
00271 result.elem (i) = elem (r1+i);
00272
00273 return result;
00274 }
00275
00276
00277
00278 ComplexColumnVector&
00279 ComplexColumnVector::operator += (const ColumnVector& a)
00280 {
00281 octave_idx_type len = length ();
00282
00283 octave_idx_type a_len = a.length ();
00284
00285 if (len != a_len)
00286 {
00287 gripe_nonconformant ("operator +=", len, a_len);
00288 return *this;
00289 }
00290
00291 if (len == 0)
00292 return *this;
00293
00294 Complex *d = fortran_vec ();
00295
00296 mx_inline_add2 (len, d, a.data ());
00297 return *this;
00298 }
00299
00300 ComplexColumnVector&
00301 ComplexColumnVector::operator -= (const ColumnVector& a)
00302 {
00303 octave_idx_type len = length ();
00304
00305 octave_idx_type a_len = a.length ();
00306
00307 if (len != a_len)
00308 {
00309 gripe_nonconformant ("operator -=", len, a_len);
00310 return *this;
00311 }
00312
00313 if (len == 0)
00314 return *this;
00315
00316 Complex *d = fortran_vec ();
00317
00318 mx_inline_sub2 (len, d, a.data ());
00319 return *this;
00320 }
00321
00322
00323
00324 ComplexColumnVector
00325 operator * (const ComplexMatrix& m, const ColumnVector& a)
00326 {
00327 ComplexColumnVector tmp (a);
00328 return m * tmp;
00329 }
00330
00331 ComplexColumnVector
00332 operator * (const ComplexMatrix& m, const ComplexColumnVector& a)
00333 {
00334 ComplexColumnVector retval;
00335
00336 octave_idx_type nr = m.rows ();
00337 octave_idx_type nc = m.cols ();
00338
00339 octave_idx_type a_len = a.length ();
00340
00341 if (nc != a_len)
00342 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00343 else
00344 {
00345 retval.clear (nr);
00346
00347 if (nr != 0)
00348 {
00349 if (nc == 0)
00350 retval.fill (0.0);
00351 else
00352 {
00353 Complex *y = retval.fortran_vec ();
00354
00355 F77_XFCN (zgemv, ZGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
00356 nr, nc, 1.0, m.data (), nr,
00357 a.data (), 1, 0.0, y, 1
00358 F77_CHAR_ARG_LEN (1)));
00359 }
00360 }
00361
00362 }
00363
00364 return retval;
00365 }
00366
00367
00368
00369 ComplexColumnVector
00370 operator * (const Matrix& m, const ComplexColumnVector& a)
00371 {
00372 ComplexMatrix tmp (m);
00373 return tmp * a;
00374 }
00375
00376
00377
00378 ComplexColumnVector
00379 operator * (const DiagMatrix& m, const ComplexColumnVector& a)
00380 {
00381 octave_idx_type nr = m.rows ();
00382 octave_idx_type nc = m.cols ();
00383
00384 octave_idx_type a_len = a.length ();
00385
00386 if (nc != a_len)
00387 {
00388 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00389 return ComplexColumnVector ();
00390 }
00391
00392 if (nc == 0 || nr == 0)
00393 return ComplexColumnVector (0);
00394
00395 ComplexColumnVector result (nr);
00396
00397 for (octave_idx_type i = 0; i < a_len; i++)
00398 result.elem (i) = a.elem (i) * m.elem (i, i);
00399
00400 for (octave_idx_type i = a_len; i < nr; i++)
00401 result.elem (i) = 0.0;
00402
00403 return result;
00404 }
00405
00406 ComplexColumnVector
00407 operator * (const ComplexDiagMatrix& m, const ColumnVector& a)
00408 {
00409 octave_idx_type nr = m.rows ();
00410 octave_idx_type nc = m.cols ();
00411
00412 octave_idx_type a_len = a.length ();
00413
00414 if (nc != a_len)
00415 {
00416 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00417 return ComplexColumnVector ();
00418 }
00419
00420 if (nc == 0 || nr == 0)
00421 return ComplexColumnVector (0);
00422
00423 ComplexColumnVector result (nr);
00424
00425 for (octave_idx_type i = 0; i < a_len; i++)
00426 result.elem (i) = a.elem (i) * m.elem (i, i);
00427
00428 for (octave_idx_type i = a_len; i < nr; i++)
00429 result.elem (i) = 0.0;
00430
00431 return result;
00432 }
00433
00434 ComplexColumnVector
00435 operator * (const ComplexDiagMatrix& m, const ComplexColumnVector& a)
00436 {
00437 octave_idx_type nr = m.rows ();
00438 octave_idx_type nc = m.cols ();
00439
00440 octave_idx_type a_len = a.length ();
00441
00442 if (nc != a_len)
00443 {
00444 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00445 return ComplexColumnVector ();
00446 }
00447
00448 if (nc == 0 || nr == 0)
00449 return ComplexColumnVector (0);
00450
00451 ComplexColumnVector result (nr);
00452
00453 for (octave_idx_type i = 0; i < a_len; i++)
00454 result.elem (i) = a.elem (i) * m.elem (i, i);
00455
00456 for (octave_idx_type i = a_len; i < nr; i++)
00457 result.elem (i) = 0.0;
00458
00459 return result;
00460 }
00461
00462
00463
00464 Complex
00465 ComplexColumnVector::min (void) const
00466 {
00467 octave_idx_type len = length ();
00468 if (len == 0)
00469 return 0.0;
00470
00471 Complex res = elem (0);
00472 double absres = std::abs (res);
00473
00474 for (octave_idx_type i = 1; i < len; i++)
00475 if (std::abs (elem (i)) < absres)
00476 {
00477 res = elem (i);
00478 absres = std::abs (res);
00479 }
00480
00481 return res;
00482 }
00483
00484 Complex
00485 ComplexColumnVector::max (void) const
00486 {
00487 octave_idx_type len = length ();
00488 if (len == 0)
00489 return 0.0;
00490
00491 Complex res = elem (0);
00492 double absres = std::abs (res);
00493
00494 for (octave_idx_type i = 1; i < len; i++)
00495 if (std::abs (elem (i)) > absres)
00496 {
00497 res = elem (i);
00498 absres = std::abs (res);
00499 }
00500
00501 return res;
00502 }
00503
00504
00505
00506 std::ostream&
00507 operator << (std::ostream& os, const ComplexColumnVector& a)
00508 {
00509
00510 for (octave_idx_type i = 0; i < a.length (); i++)
00511 os << a.elem (i) << "\n";
00512 return os;
00513 }
00514
00515 std::istream&
00516 operator >> (std::istream& is, ComplexColumnVector& a)
00517 {
00518 octave_idx_type len = a.length();
00519
00520 if (len > 0)
00521 {
00522 double tmp;
00523 for (octave_idx_type i = 0; i < len; i++)
00524 {
00525 is >> tmp;
00526 if (is)
00527 a.elem (i) = tmp;
00528 else
00529 break;
00530 }
00531 }
00532 return is;
00533 }