dDiagMatrix.cc

Go to the documentation of this file.
00001 // DiagMatrix manipulations.
00002 /*
00003 
00004 Copyright (C) 1994-2012 John W. Eaton
00005 Copyright (C) 2009 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 "lo-error.h"
00033 #include "mx-base.h"
00034 #include "mx-inlines.cc"
00035 #include "oct-cmplx.h"
00036 
00037 // Diagonal Matrix class.
00038 
00039 bool
00040 DiagMatrix::operator == (const DiagMatrix& a) const
00041 {
00042   if (rows () != a.rows () || cols () != a.cols ())
00043     return 0;
00044 
00045   return mx_inline_equal (length (), data (), a.data ());
00046 }
00047 
00048 bool
00049 DiagMatrix::operator != (const DiagMatrix& a) const
00050 {
00051   return !(*this == a);
00052 }
00053 
00054 DiagMatrix&
00055 DiagMatrix::fill (double val)
00056 {
00057   for (octave_idx_type i = 0; i < length (); i++)
00058     elem (i, i) = val;
00059   return *this;
00060 }
00061 
00062 DiagMatrix&
00063 DiagMatrix::fill (double val, octave_idx_type beg, octave_idx_type end)
00064 {
00065   if (beg < 0 || end >= length () || end < beg)
00066     {
00067       (*current_liboctave_error_handler) ("range error for fill");
00068       return *this;
00069     }
00070 
00071   for (octave_idx_type i = beg; i <= end; i++)
00072     elem (i, i) = val;
00073 
00074   return *this;
00075 }
00076 
00077 DiagMatrix&
00078 DiagMatrix::fill (const ColumnVector& a)
00079 {
00080   octave_idx_type len = length ();
00081   if (a.length () != len)
00082     {
00083       (*current_liboctave_error_handler) ("range error for fill");
00084       return *this;
00085     }
00086 
00087   for (octave_idx_type i = 0; i < len; i++)
00088     elem (i, i) = a.elem (i);
00089 
00090   return *this;
00091 }
00092 
00093 DiagMatrix&
00094 DiagMatrix::fill (const RowVector& a)
00095 {
00096   octave_idx_type len = length ();
00097   if (a.length () != len)
00098     {
00099       (*current_liboctave_error_handler) ("range error for fill");
00100       return *this;
00101     }
00102 
00103   for (octave_idx_type i = 0; i < len; i++)
00104     elem (i, i) = a.elem (i);
00105 
00106   return *this;
00107 }
00108 
00109 DiagMatrix&
00110 DiagMatrix::fill (const ColumnVector& a, octave_idx_type beg)
00111 {
00112   octave_idx_type a_len = a.length ();
00113   if (beg < 0 || beg + a_len >= length ())
00114     {
00115       (*current_liboctave_error_handler) ("range error for fill");
00116       return *this;
00117     }
00118 
00119   for (octave_idx_type i = 0; i < a_len; i++)
00120     elem (i+beg, i+beg) = a.elem (i);
00121 
00122   return *this;
00123 }
00124 
00125 DiagMatrix&
00126 DiagMatrix::fill (const RowVector& a, octave_idx_type beg)
00127 {
00128   octave_idx_type a_len = a.length ();
00129   if (beg < 0 || beg + a_len >= length ())
00130     {
00131       (*current_liboctave_error_handler) ("range error for fill");
00132       return *this;
00133     }
00134 
00135   for (octave_idx_type i = 0; i < a_len; i++)
00136     elem (i+beg, i+beg) = a.elem (i);
00137 
00138   return *this;
00139 }
00140 
00141 DiagMatrix
00142 DiagMatrix::abs (void) const
00143 {
00144   return DiagMatrix (diag ().abs (), rows (), columns ());
00145 }
00146 
00147 DiagMatrix
00148 real (const ComplexDiagMatrix& a)
00149 {
00150   return DiagMatrix (real (a.diag ()), a.rows (), a.cols ());
00151 }
00152 
00153 DiagMatrix
00154 imag (const ComplexDiagMatrix& a)
00155 {
00156   return DiagMatrix (imag (a.diag ()), a.rows (), a.cols ());
00157 }
00158 
00159 Matrix
00160 DiagMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
00161 {
00162   if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; }
00163   if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; }
00164 
00165   octave_idx_type new_r = r2 - r1 + 1;
00166   octave_idx_type new_c = c2 - c1 + 1;
00167 
00168   Matrix result (new_r, new_c);
00169 
00170   for (octave_idx_type j = 0; j < new_c; j++)
00171     for (octave_idx_type i = 0; i < new_r; i++)
00172       result.elem (i, j) = elem (r1+i, c1+j);
00173 
00174   return result;
00175 }
00176 
00177 // extract row or column i.
00178 
00179 RowVector
00180 DiagMatrix::row (octave_idx_type i) const
00181 {
00182   octave_idx_type r = rows ();
00183   octave_idx_type c = cols ();
00184   if (i < 0 || i >= r)
00185     {
00186       (*current_liboctave_error_handler) ("invalid row selection");
00187       return RowVector ();
00188     }
00189 
00190   RowVector retval (c, 0.0);
00191   if (r <= c || (r > c && i < c))
00192     retval.elem (i) = elem (i, i);
00193 
00194   return retval;
00195 }
00196 
00197 RowVector
00198 DiagMatrix::row (char *s) const
00199 {
00200   if (! s)
00201     {
00202       (*current_liboctave_error_handler) ("invalid row selection");
00203       return RowVector ();
00204     }
00205 
00206   char c = *s;
00207   if (c == 'f' || c == 'F')
00208     return row (static_cast<octave_idx_type>(0));
00209   else if (c == 'l' || c == 'L')
00210     return row (rows () - 1);
00211   else
00212     {
00213       (*current_liboctave_error_handler) ("invalid row selection");
00214       return RowVector ();
00215     }
00216 }
00217 
00218 ColumnVector
00219 DiagMatrix::column (octave_idx_type i) const
00220 {
00221   octave_idx_type r = rows ();
00222   octave_idx_type c = cols ();
00223   if (i < 0 || i >= c)
00224     {
00225       (*current_liboctave_error_handler) ("invalid column selection");
00226       return ColumnVector ();
00227     }
00228 
00229   ColumnVector retval (r, 0.0);
00230   if (r >= c || (r < c && i < r))
00231     retval.elem (i) = elem (i, i);
00232 
00233   return retval;
00234 }
00235 
00236 ColumnVector
00237 DiagMatrix::column (char *s) const
00238 {
00239   if (! s)
00240     {
00241       (*current_liboctave_error_handler) ("invalid column selection");
00242       return ColumnVector ();
00243     }
00244 
00245   char c = *s;
00246   if (c == 'f' || c == 'F')
00247     return column (static_cast<octave_idx_type>(0));
00248   else if (c == 'l' || c == 'L')
00249     return column (cols () - 1);
00250   else
00251     {
00252       (*current_liboctave_error_handler) ("invalid column selection");
00253       return ColumnVector ();
00254     }
00255 }
00256 
00257 DiagMatrix
00258 DiagMatrix::inverse (void) const
00259 {
00260   octave_idx_type info;
00261   return inverse (info);
00262 }
00263 
00264 DiagMatrix
00265 DiagMatrix::inverse (octave_idx_type &info) const
00266 {
00267   octave_idx_type r = rows ();
00268   octave_idx_type c = cols ();
00269   octave_idx_type len = length ();
00270   if (r != c)
00271     {
00272       (*current_liboctave_error_handler) ("inverse requires square matrix");
00273       return DiagMatrix ();
00274     }
00275 
00276   DiagMatrix retval (r, c);
00277 
00278   info = 0;
00279   for (octave_idx_type i = 0; i < len; i++)
00280     {
00281       if (elem (i, i) == 0.0)
00282         {
00283           info = -1;
00284           return *this;
00285         }
00286       else
00287         retval.elem (i, i) = 1.0 / elem (i, i);
00288     }
00289 
00290   return retval;
00291 }
00292 
00293 DiagMatrix
00294 DiagMatrix::pseudo_inverse (void) const
00295 {
00296   octave_idx_type r = rows ();
00297   octave_idx_type c = cols ();
00298   octave_idx_type len = length ();
00299 
00300   DiagMatrix retval (c, r);
00301 
00302   for (octave_idx_type i = 0; i < len; i++)
00303     {
00304       if (elem (i, i) != 0.0)
00305         retval.elem (i, i) = 1.0 / elem (i, i);
00306       else
00307         retval.elem (i, i) = 0.0;
00308     }
00309 
00310   return retval;
00311 }
00312 
00313 // diagonal matrix by diagonal matrix -> diagonal matrix operations
00314 
00315 // diagonal matrix by diagonal matrix -> diagonal matrix operations
00316 
00317 DiagMatrix
00318 operator * (const DiagMatrix& a, const DiagMatrix& b)
00319 {
00320   octave_idx_type a_nr = a.rows ();
00321   octave_idx_type a_nc = a.cols ();
00322 
00323   octave_idx_type b_nr = b.rows ();
00324   octave_idx_type b_nc = b.cols ();
00325 
00326   if (a_nc != b_nr)
00327     gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
00328 
00329   DiagMatrix c (a_nr, b_nc);
00330 
00331   octave_idx_type len = c.length (), lenm = len < a_nc ? len : a_nc;
00332 
00333   for (octave_idx_type i = 0; i < lenm; i++)
00334     c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
00335   for (octave_idx_type i = lenm; i < len; i++)
00336     c.dgxelem (i) = 0.0;
00337 
00338   return c;
00339 }
00340 
00341 // other operations
00342 
00343 DET
00344 DiagMatrix::determinant (void) const
00345 {
00346   DET det (1.0);
00347   if (rows () != cols ())
00348     {
00349       (*current_liboctave_error_handler) ("determinant requires square matrix");
00350       det = 0.0;
00351     }
00352   else
00353     {
00354       octave_idx_type len = length ();
00355       for (octave_idx_type i = 0; i < len; i++)
00356         det *= elem (i, i);
00357     }
00358 
00359   return det;
00360 }
00361 
00362 double
00363 DiagMatrix::rcond (void) const
00364 {
00365   ColumnVector av  = diag (0).map<double> (fabs);
00366   double amx = av.max (), amn = av.min ();
00367   return amx == 0 ? 0.0 : amn / amx;
00368 }
00369 
00370 std::ostream&
00371 operator << (std::ostream& os, const DiagMatrix& a)
00372 {
00373 //  int field_width = os.precision () + 7;
00374 
00375   for (octave_idx_type i = 0; i < a.rows (); i++)
00376     {
00377       for (octave_idx_type j = 0; j < a.cols (); j++)
00378         {
00379           if (i == j)
00380             os << " " /* setw (field_width) */ << a.elem (i, i);
00381           else
00382             os << " " /* setw (field_width) */ << 0.0;
00383         }
00384       os << "\n";
00385     }
00386   return os;
00387 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines