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