fCColVector.cc

Go to the documentation of this file.
00001 // ColumnVector manipulations.
00002 /*
00003 
00004 Copyright (C) 1994-2012 John W. Eaton
00005 Copyright (C) 2010 VZLU Prague
00006 
00007 This file is part of Octave.
00008 
00009 Octave is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as published by the
00011 Free Software Foundation; either version 3 of the License, or (at your
00012 option) any later version.
00013 
00014 Octave is distributed in the hope that it will be useful, but WITHOUT
00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017 for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with Octave; see the file COPYING.  If not, see
00021 <http://www.gnu.org/licenses/>.
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 // Fortran functions we call.
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 // FloatComplex Column Vector class
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 // destructive insert/delete/reorder operations
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 // resize is the destructive equivalent for this one
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 // column vector by column vector -> column vector operations
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 (); // Ensures only one reference to my privates!
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 (); // Ensures only one reference to my privates!
00317 
00318   mx_inline_sub2 (len, d, a.data ());
00319   return *this;
00320 }
00321 
00322 // matrix by column vector -> column vector operations
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 // matrix by column vector -> column vector operations
00367 
00368 FloatComplexColumnVector
00369 operator * (const FloatMatrix& m, const FloatComplexColumnVector& a)
00370 {
00371   FloatComplexMatrix tmp (m);
00372   return tmp * a;
00373 }
00374 
00375 // diagonal matrix by column vector -> column vector operations
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 // other operations
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 // i/o
00504 
00505 std::ostream&
00506 operator << (std::ostream& os, const FloatComplexColumnVector& a)
00507 {
00508 //  int field_width = os.precision () + 7;
00509   for (octave_idx_type i = 0; i < a.length (); i++)
00510     os << /* setw (field_width) << */ 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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines