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 "lo-error.h"
00033 #include "mx-base.h"
00034 #include "mx-inlines.cc"
00035 #include "oct-cmplx.h"
00036
00037
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
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
00314
00315
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
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
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 << " " << a.elem (i, i);
00381 else
00382 os << " " << 0.0;
00383 }
00384 os << "\n";
00385 }
00386 return os;
00387 }