dRowVector.cc

Go to the documentation of this file.
00001 // RowVector manipulations.
00002 /*
00003 
00004 Copyright (C) 1994-2012 John W. Eaton
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
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 // Fortran functions we call.
00039 
00040 extern "C"
00041 {
00042   F77_RET_T
00043   F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL,
00044                            const octave_idx_type&, const octave_idx_type&,
00045                            const double&, const double*,
00046                            const octave_idx_type&, const double*,
00047                            const octave_idx_type&, const double&,
00048                            double*, const octave_idx_type&
00049                            F77_CHAR_ARG_LEN_DECL);
00050   F77_RET_T
00051   F77_FUNC (xddot, XDDOT) (const octave_idx_type&, const double*,
00052                            const octave_idx_type&, const double*,
00053                            const octave_idx_type&, double&);
00054 }
00055 
00056 // Row Vector class.
00057 
00058 bool
00059 RowVector::operator == (const RowVector& a) const
00060 {
00061   octave_idx_type len = length ();
00062   if (len != a.length ())
00063     return 0;
00064   return mx_inline_equal (len, data (), a.data ());
00065 }
00066 
00067 bool
00068 RowVector::operator != (const RowVector& a) const
00069 {
00070   return !(*this == a);
00071 }
00072 
00073 RowVector&
00074 RowVector::insert (const RowVector& a, octave_idx_type c)
00075 {
00076   octave_idx_type a_len = a.length ();
00077 
00078   if (c < 0 || c + a_len > length ())
00079     {
00080       (*current_liboctave_error_handler) ("range error for insert");
00081       return *this;
00082     }
00083 
00084   if (a_len > 0)
00085     {
00086       make_unique ();
00087 
00088       for (octave_idx_type i = 0; i < a_len; i++)
00089         xelem (c+i) = a.elem (i);
00090     }
00091 
00092   return *this;
00093 }
00094 
00095 RowVector&
00096 RowVector::fill (double val)
00097 {
00098   octave_idx_type len = length ();
00099 
00100   if (len > 0)
00101     {
00102       make_unique ();
00103 
00104       for (octave_idx_type i = 0; i < len; i++)
00105         xelem (i) = val;
00106     }
00107 
00108   return *this;
00109 }
00110 
00111 RowVector&
00112 RowVector::fill (double val, octave_idx_type c1, octave_idx_type c2)
00113 {
00114   octave_idx_type len = length ();
00115 
00116   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
00117     {
00118       (*current_liboctave_error_handler) ("range error for fill");
00119       return *this;
00120     }
00121 
00122   if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
00123 
00124   if (c2 >= c1)
00125     {
00126       make_unique ();
00127 
00128       for (octave_idx_type i = c1; i <= c2; i++)
00129         xelem (i) = val;
00130     }
00131 
00132   return *this;
00133 }
00134 
00135 RowVector
00136 RowVector::append (const RowVector& a) const
00137 {
00138   octave_idx_type len = length ();
00139   octave_idx_type nc_insert = len;
00140   RowVector retval (len + a.length ());
00141   retval.insert (*this, 0);
00142   retval.insert (a, nc_insert);
00143   return retval;
00144 }
00145 
00146 ColumnVector
00147 RowVector::transpose (void) const
00148 {
00149   return MArray<double>::transpose();
00150 }
00151 
00152 RowVector
00153 real (const ComplexRowVector& a)
00154 {
00155   return do_mx_unary_op<double, Complex> (a, mx_inline_real);
00156 }
00157 
00158 RowVector
00159 imag (const ComplexRowVector& a)
00160 {
00161   return do_mx_unary_op<double, Complex> (a, mx_inline_imag);
00162 }
00163 
00164 RowVector
00165 RowVector::extract (octave_idx_type c1, octave_idx_type c2) const
00166 {
00167   if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
00168 
00169   octave_idx_type new_c = c2 - c1 + 1;
00170 
00171   RowVector result (new_c);
00172 
00173   for (octave_idx_type i = 0; i < new_c; i++)
00174     result.xelem (i) = elem (c1+i);
00175 
00176   return result;
00177 }
00178 
00179 RowVector
00180 RowVector::extract_n (octave_idx_type r1, octave_idx_type n) const
00181 {
00182   RowVector result (n);
00183 
00184   for (octave_idx_type i = 0; i < n; i++)
00185     result.xelem (i) = elem (r1+i);
00186 
00187   return result;
00188 }
00189 
00190 // row vector by matrix -> row vector
00191 
00192 RowVector
00193 operator * (const RowVector& v, const Matrix& a)
00194 {
00195   RowVector retval;
00196 
00197   octave_idx_type len = v.length ();
00198 
00199   octave_idx_type a_nr = a.rows ();
00200   octave_idx_type a_nc = a.cols ();
00201 
00202   if (a_nr != len)
00203     gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
00204   else
00205     {
00206       if (len == 0)
00207         retval.resize (a_nc, 0.0);
00208       else
00209         {
00210           // Transpose A to form A'*x == (x'*A)'
00211 
00212           octave_idx_type ld = a_nr;
00213 
00214           retval.resize (a_nc);
00215           double *y = retval.fortran_vec ();
00216 
00217           F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
00218                                    a_nr, a_nc, 1.0, a.data (),
00219                                    ld, v.data (), 1, 0.0, y, 1
00220                                    F77_CHAR_ARG_LEN (1)));
00221         }
00222     }
00223 
00224   return retval;
00225 }
00226 
00227 // other operations
00228 
00229 double
00230 RowVector::min (void) const
00231 {
00232   octave_idx_type len = length ();
00233   if (len == 0)
00234     return 0;
00235 
00236   double res = elem (0);
00237 
00238   for (octave_idx_type i = 1; i < len; i++)
00239     if (elem (i) < res)
00240       res = elem (i);
00241 
00242   return res;
00243 }
00244 
00245 double
00246 RowVector::max (void) const
00247 {
00248   octave_idx_type len = length ();
00249   if (len == 0)
00250     return 0;
00251 
00252   double res = elem (0);
00253 
00254   for (octave_idx_type i = 1; i < len; i++)
00255     if (elem (i) > res)
00256       res = elem (i);
00257 
00258   return res;
00259 }
00260 
00261 std::ostream&
00262 operator << (std::ostream& os, const RowVector& a)
00263 {
00264 //  int field_width = os.precision () + 7;
00265 
00266   for (octave_idx_type i = 0; i < a.length (); i++)
00267     os << " " /* setw (field_width) */ << a.elem (i);
00268   return os;
00269 }
00270 
00271 std::istream&
00272 operator >> (std::istream& is, RowVector& a)
00273 {
00274   octave_idx_type len = a.length();
00275 
00276   if (len > 0)
00277     {
00278       double tmp;
00279       for (octave_idx_type i = 0; i < len; i++)
00280         {
00281           is >> tmp;
00282           if (is)
00283             a.elem (i) = tmp;
00284           else
00285             break;
00286         }
00287     }
00288   return is;
00289 }
00290 
00291 // other operations
00292 
00293 RowVector
00294 linspace (double x1, double x2, octave_idx_type n)
00295 {
00296   if (n < 1) n = 1;
00297 
00298   NoAlias<RowVector> retval (n);
00299 
00300   double delta = (x2 - x1) / (n - 1);
00301   retval(0) = x1;
00302   for (octave_idx_type i = 1; i < n-1; i++)
00303     retval(i) = x1 + i*delta;
00304   retval(n-1) = x2;
00305 
00306   return retval;
00307 }
00308 
00309 // row vector by column vector -> scalar
00310 
00311 double
00312 operator * (const RowVector& v, const ColumnVector& a)
00313 {
00314   double retval = 0.0;
00315 
00316   octave_idx_type len = v.length ();
00317 
00318   octave_idx_type a_len = a.length ();
00319 
00320   if (len != a_len)
00321     gripe_nonconformant ("operator *", len, a_len);
00322   else if (len != 0)
00323     F77_FUNC (xddot, XDDOT) (len, v.data (), 1, a.data (), 1, retval);
00324 
00325   return retval;
00326 }
00327 
00328 Complex
00329 operator * (const RowVector& v, const ComplexColumnVector& a)
00330 {
00331   ComplexRowVector tmp (v);
00332   return tmp * a;
00333 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines