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 (cgemv, CGEMV) (F77_CONST_CHAR_ARG_DECL,
00045 const octave_idx_type&, const octave_idx_type&,
00046 const FloatComplex&, const FloatComplex*,
00047 const octave_idx_type&, const FloatComplex*,
00048 const octave_idx_type&, const FloatComplex&,
00049 FloatComplex*, const octave_idx_type&
00050 F77_CHAR_ARG_LEN_DECL);
00051 }
00052
00053
00054
00055 FloatComplexColumnVector::FloatComplexColumnVector (const FloatColumnVector& a)
00056 : MArray<FloatComplex> (a)
00057 {
00058 }
00059
00060 bool
00061 FloatComplexColumnVector::operator == (const FloatComplexColumnVector& 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 FloatComplexColumnVector::operator != (const FloatComplexColumnVector& a) const
00071 {
00072 return !(*this == a);
00073 }
00074
00075
00076
00077 FloatComplexColumnVector&
00078 FloatComplexColumnVector::insert (const FloatColumnVector& 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 FloatComplexColumnVector&
00100 FloatComplexColumnVector::insert (const FloatComplexColumnVector& 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 FloatComplexColumnVector&
00122 FloatComplexColumnVector::fill (float 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 FloatComplexColumnVector&
00138 FloatComplexColumnVector::fill (const FloatComplex& 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 FloatComplexColumnVector&
00155 FloatComplexColumnVector::fill (float 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 FloatComplexColumnVector&
00179 FloatComplexColumnVector::fill (const FloatComplex& 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 FloatComplexColumnVector
00203 FloatComplexColumnVector::stack (const FloatColumnVector& a) const
00204 {
00205 octave_idx_type len = length ();
00206 octave_idx_type nr_insert = len;
00207 FloatComplexColumnVector retval (len + a.length ());
00208 retval.insert (*this, 0);
00209 retval.insert (a, nr_insert);
00210 return retval;
00211 }
00212
00213 FloatComplexColumnVector
00214 FloatComplexColumnVector::stack (const FloatComplexColumnVector& a) const
00215 {
00216 octave_idx_type len = length ();
00217 octave_idx_type nr_insert = len;
00218 FloatComplexColumnVector retval (len + a.length ());
00219 retval.insert (*this, 0);
00220 retval.insert (a, nr_insert);
00221 return retval;
00222 }
00223
00224 FloatComplexRowVector
00225 FloatComplexColumnVector::hermitian (void) const
00226 {
00227 return MArray<FloatComplex>::hermitian (std::conj);
00228 }
00229
00230 FloatComplexRowVector
00231 FloatComplexColumnVector::transpose (void) const
00232 {
00233 return MArray<FloatComplex>::transpose ();
00234 }
00235
00236 FloatColumnVector
00237 FloatComplexColumnVector::abs (void) const
00238 {
00239 return do_mx_unary_map<float, FloatComplex, std::abs> (*this);
00240 }
00241
00242 FloatComplexColumnVector
00243 conj (const FloatComplexColumnVector& a)
00244 {
00245 return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float> > (a);
00246 }
00247
00248
00249
00250 FloatComplexColumnVector
00251 FloatComplexColumnVector::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 FloatComplexColumnVector 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 FloatComplexColumnVector
00266 FloatComplexColumnVector::extract_n (octave_idx_type r1, octave_idx_type n) const
00267 {
00268 FloatComplexColumnVector 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 FloatComplexColumnVector&
00279 FloatComplexColumnVector::operator += (const FloatColumnVector& 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 FloatComplex *d = fortran_vec ();
00295
00296 mx_inline_add2 (len, d, a.data ());
00297 return *this;
00298 }
00299
00300 FloatComplexColumnVector&
00301 FloatComplexColumnVector::operator -= (const FloatColumnVector& 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 FloatComplex *d = fortran_vec ();
00317
00318 mx_inline_sub2 (len, d, a.data ());
00319 return *this;
00320 }
00321
00322
00323
00324 FloatComplexColumnVector
00325 operator * (const FloatComplexMatrix& m, const FloatColumnVector& a)
00326 {
00327 FloatComplexColumnVector tmp (a);
00328 return m * tmp;
00329 }
00330
00331 FloatComplexColumnVector
00332 operator * (const FloatComplexMatrix& m, const FloatComplexColumnVector& a)
00333 {
00334 FloatComplexColumnVector 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 FloatComplex *y = retval.fortran_vec ();
00354
00355 F77_XFCN (cgemv, CGEMV, (F77_CONST_CHAR_ARG2 ("N", 1),
00356 nr, nc, 1.0f, m.data (), nr,
00357 a.data (), 1, 0.0f, y, 1
00358 F77_CHAR_ARG_LEN (1)));
00359 }
00360 }
00361 }
00362
00363 return retval;
00364 }
00365
00366
00367
00368 FloatComplexColumnVector
00369 operator * (const FloatMatrix& m, const FloatComplexColumnVector& a)
00370 {
00371 FloatComplexMatrix tmp (m);
00372 return tmp * a;
00373 }
00374
00375
00376
00377 FloatComplexColumnVector
00378 operator * (const FloatDiagMatrix& m, const FloatComplexColumnVector& a)
00379 {
00380 octave_idx_type nr = m.rows ();
00381 octave_idx_type nc = m.cols ();
00382
00383 octave_idx_type a_len = a.length ();
00384
00385 if (nc != a_len)
00386 {
00387 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00388 return FloatComplexColumnVector ();
00389 }
00390
00391 if (nc == 0 || nr == 0)
00392 return FloatComplexColumnVector (0);
00393
00394 FloatComplexColumnVector result (nr);
00395
00396 for (octave_idx_type i = 0; i < a_len; i++)
00397 result.elem (i) = a.elem (i) * m.elem (i, i);
00398
00399 for (octave_idx_type i = a_len; i < nr; i++)
00400 result.elem (i) = 0.0;
00401
00402 return result;
00403 }
00404
00405 FloatComplexColumnVector
00406 operator * (const FloatComplexDiagMatrix& m, const FloatColumnVector& a)
00407 {
00408 octave_idx_type nr = m.rows ();
00409 octave_idx_type nc = m.cols ();
00410
00411 octave_idx_type a_len = a.length ();
00412
00413 if (nc != a_len)
00414 {
00415 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00416 return FloatComplexColumnVector ();
00417 }
00418
00419 if (nc == 0 || nr == 0)
00420 return FloatComplexColumnVector (0);
00421
00422 FloatComplexColumnVector result (nr);
00423
00424 for (octave_idx_type i = 0; i < a_len; i++)
00425 result.elem (i) = a.elem (i) * m.elem (i, i);
00426
00427 for (octave_idx_type i = a_len; i < nr; i++)
00428 result.elem (i) = 0.0;
00429
00430 return result;
00431 }
00432
00433 FloatComplexColumnVector
00434 operator * (const FloatComplexDiagMatrix& m, const FloatComplexColumnVector& a)
00435 {
00436 octave_idx_type nr = m.rows ();
00437 octave_idx_type nc = m.cols ();
00438
00439 octave_idx_type a_len = a.length ();
00440
00441 if (nc != a_len)
00442 {
00443 gripe_nonconformant ("operator *", nr, nc, a_len, 1);
00444 return FloatComplexColumnVector ();
00445 }
00446
00447 if (nc == 0 || nr == 0)
00448 return FloatComplexColumnVector (0);
00449
00450 FloatComplexColumnVector result (nr);
00451
00452 for (octave_idx_type i = 0; i < a_len; i++)
00453 result.elem (i) = a.elem (i) * m.elem (i, i);
00454
00455 for (octave_idx_type i = a_len; i < nr; i++)
00456 result.elem (i) = 0.0;
00457
00458 return result;
00459 }
00460
00461
00462
00463 FloatComplex
00464 FloatComplexColumnVector::min (void) const
00465 {
00466 octave_idx_type len = length ();
00467 if (len == 0)
00468 return 0.0;
00469
00470 FloatComplex res = elem (0);
00471 float absres = std::abs (res);
00472
00473 for (octave_idx_type i = 1; i < len; i++)
00474 if (std::abs (elem (i)) < absres)
00475 {
00476 res = elem (i);
00477 absres = std::abs (res);
00478 }
00479
00480 return res;
00481 }
00482
00483 FloatComplex
00484 FloatComplexColumnVector::max (void) const
00485 {
00486 octave_idx_type len = length ();
00487 if (len == 0)
00488 return 0.0;
00489
00490 FloatComplex res = elem (0);
00491 float absres = std::abs (res);
00492
00493 for (octave_idx_type i = 1; i < len; i++)
00494 if (std::abs (elem (i)) > absres)
00495 {
00496 res = elem (i);
00497 absres = std::abs (res);
00498 }
00499
00500 return res;
00501 }
00502
00503
00504
00505 std::ostream&
00506 operator << (std::ostream& os, const FloatComplexColumnVector& a)
00507 {
00508
00509 for (octave_idx_type i = 0; i < a.length (); i++)
00510 os << a.elem (i) << "\n";
00511 return os;
00512 }
00513
00514 std::istream&
00515 operator >> (std::istream& is, FloatComplexColumnVector& a)
00516 {
00517 octave_idx_type len = a.length();
00518
00519 if (len > 0)
00520 {
00521 float tmp;
00522 for (octave_idx_type i = 0; i < len; i++)
00523 {
00524 is >> tmp;
00525 if (is)
00526 a.elem (i) = tmp;
00527 else
00528 break;
00529 }
00530 }
00531 return is;
00532 }