Mercurial > hg > octave-lyh
annotate liboctave/dDiagMatrix.cc @ 8811:20dfb885f877
int -> octave_idx fixes
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 18 Feb 2009 23:34:03 -0500 |
parents | e3c9102431a9 |
children | c690e3772583 |
rev | line source |
---|---|
1993 | 1 // DiagMatrix manipulations. |
458 | 2 /* |
3 | |
7017 | 4 Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004, |
5 2005, 2007 John W. Eaton | |
458 | 6 |
7 This file is part of Octave. | |
8 | |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
7016 | 11 Free Software Foundation; either version 3 of the License, or (at your |
12 option) any later version. | |
458 | 13 |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
7016 | 20 along with Octave; see the file COPYING. If not, see |
21 <http://www.gnu.org/licenses/>. | |
458 | 22 |
23 */ | |
24 | |
25 #ifdef HAVE_CONFIG_H | |
1192 | 26 #include <config.h> |
458 | 27 #endif |
28 | |
3503 | 29 #include <iostream> |
458 | 30 |
4669 | 31 #include "Array-util.h" |
1368 | 32 #include "lo-error.h" |
458 | 33 #include "mx-base.h" |
34 #include "mx-inlines.cc" | |
1650 | 35 #include "oct-cmplx.h" |
458 | 36 |
1360 | 37 // Diagonal Matrix class. |
458 | 38 |
2385 | 39 bool |
458 | 40 DiagMatrix::operator == (const DiagMatrix& a) const |
41 { | |
42 if (rows () != a.rows () || cols () != a.cols ()) | |
43 return 0; | |
44 | |
3769 | 45 return mx_inline_equal (data (), a.data (), length ()); |
458 | 46 } |
47 | |
2385 | 48 bool |
458 | 49 DiagMatrix::operator != (const DiagMatrix& a) const |
50 { | |
51 return !(*this == a); | |
52 } | |
53 | |
54 DiagMatrix& | |
55 DiagMatrix::fill (double val) | |
56 { | |
5275 | 57 for (octave_idx_type i = 0; i < length (); i++) |
458 | 58 elem (i, i) = val; |
59 return *this; | |
60 } | |
61 | |
62 DiagMatrix& | |
5275 | 63 DiagMatrix::fill (double val, octave_idx_type beg, octave_idx_type end) |
458 | 64 { |
65 if (beg < 0 || end >= length () || end < beg) | |
66 { | |
67 (*current_liboctave_error_handler) ("range error for fill"); | |
68 return *this; | |
69 } | |
70 | |
5275 | 71 for (octave_idx_type i = beg; i <= end; i++) |
458 | 72 elem (i, i) = val; |
73 | |
74 return *this; | |
75 } | |
76 | |
77 DiagMatrix& | |
78 DiagMatrix::fill (const ColumnVector& a) | |
79 { | |
5275 | 80 octave_idx_type len = length (); |
458 | 81 if (a.length () != len) |
82 { | |
83 (*current_liboctave_error_handler) ("range error for fill"); | |
84 return *this; | |
85 } | |
86 | |
5275 | 87 for (octave_idx_type i = 0; i < len; i++) |
458 | 88 elem (i, i) = a.elem (i); |
89 | |
90 return *this; | |
91 } | |
92 | |
93 DiagMatrix& | |
94 DiagMatrix::fill (const RowVector& a) | |
95 { | |
5275 | 96 octave_idx_type len = length (); |
458 | 97 if (a.length () != len) |
98 { | |
99 (*current_liboctave_error_handler) ("range error for fill"); | |
100 return *this; | |
101 } | |
102 | |
5275 | 103 for (octave_idx_type i = 0; i < len; i++) |
458 | 104 elem (i, i) = a.elem (i); |
105 | |
106 return *this; | |
107 } | |
108 | |
109 DiagMatrix& | |
5275 | 110 DiagMatrix::fill (const ColumnVector& a, octave_idx_type beg) |
458 | 111 { |
5275 | 112 octave_idx_type a_len = a.length (); |
458 | 113 if (beg < 0 || beg + a_len >= length ()) |
114 { | |
115 (*current_liboctave_error_handler) ("range error for fill"); | |
116 return *this; | |
117 } | |
118 | |
5275 | 119 for (octave_idx_type i = 0; i < a_len; i++) |
458 | 120 elem (i+beg, i+beg) = a.elem (i); |
121 | |
122 return *this; | |
123 } | |
124 | |
125 DiagMatrix& | |
5275 | 126 DiagMatrix::fill (const RowVector& a, octave_idx_type beg) |
458 | 127 { |
5275 | 128 octave_idx_type a_len = a.length (); |
458 | 129 if (beg < 0 || beg + a_len >= length ()) |
130 { | |
131 (*current_liboctave_error_handler) ("range error for fill"); | |
132 return *this; | |
133 } | |
134 | |
5275 | 135 for (octave_idx_type i = 0; i < a_len; i++) |
458 | 136 elem (i+beg, i+beg) = a.elem (i); |
137 | |
138 return *this; | |
139 } | |
140 | |
141 DiagMatrix | |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
142 DiagMatrix::abs (void) const |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
143 { |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
144 DiagMatrix retval (rows (), cols ()); |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
145 for (octave_idx_type i = 0; i < rows (); i++) |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
146 retval(i, i) = std::abs (elem (i, i)); |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
147 return retval; |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
148 } |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
149 |
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
150 DiagMatrix |
1205 | 151 real (const ComplexDiagMatrix& a) |
152 { | |
153 DiagMatrix retval; | |
5275 | 154 octave_idx_type a_len = a.length (); |
1205 | 155 if (a_len > 0) |
3769 | 156 retval = DiagMatrix (mx_inline_real_dup (a.data (), a_len), a.rows (), |
1205 | 157 a.cols ()); |
158 return retval; | |
159 } | |
160 | |
161 DiagMatrix | |
162 imag (const ComplexDiagMatrix& a) | |
163 { | |
164 DiagMatrix retval; | |
5275 | 165 octave_idx_type a_len = a.length (); |
1205 | 166 if (a_len > 0) |
3769 | 167 retval = DiagMatrix (mx_inline_imag_dup (a.data (), a_len), a.rows (), |
1205 | 168 a.cols ()); |
169 return retval; | |
170 } | |
171 | |
458 | 172 Matrix |
5275 | 173 DiagMatrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const |
458 | 174 { |
5275 | 175 if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; } |
176 if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; } | |
458 | 177 |
5275 | 178 octave_idx_type new_r = r2 - r1 + 1; |
179 octave_idx_type new_c = c2 - c1 + 1; | |
458 | 180 |
181 Matrix result (new_r, new_c); | |
182 | |
5275 | 183 for (octave_idx_type j = 0; j < new_c; j++) |
184 for (octave_idx_type i = 0; i < new_r; i++) | |
458 | 185 result.elem (i, j) = elem (r1+i, c1+j); |
186 | |
187 return result; | |
188 } | |
189 | |
190 // extract row or column i. | |
191 | |
192 RowVector | |
5275 | 193 DiagMatrix::row (octave_idx_type i) const |
458 | 194 { |
5275 | 195 octave_idx_type r = rows (); |
196 octave_idx_type c = cols (); | |
3504 | 197 if (i < 0 || i >= r) |
458 | 198 { |
199 (*current_liboctave_error_handler) ("invalid row selection"); | |
200 return RowVector (); | |
201 } | |
202 | |
3504 | 203 RowVector retval (c, 0.0); |
204 if (r <= c || (r > c && i < c)) | |
458 | 205 retval.elem (i) = elem (i, i); |
206 | |
207 return retval; | |
208 } | |
209 | |
210 RowVector | |
211 DiagMatrix::row (char *s) const | |
212 { | |
533 | 213 if (! s) |
458 | 214 { |
215 (*current_liboctave_error_handler) ("invalid row selection"); | |
216 return RowVector (); | |
217 } | |
218 | |
219 char c = *s; | |
220 if (c == 'f' || c == 'F') | |
5275 | 221 return row (static_cast<octave_idx_type>(0)); |
458 | 222 else if (c == 'l' || c == 'L') |
223 return row (rows () - 1); | |
224 else | |
225 { | |
226 (*current_liboctave_error_handler) ("invalid row selection"); | |
227 return RowVector (); | |
228 } | |
229 } | |
230 | |
231 ColumnVector | |
5275 | 232 DiagMatrix::column (octave_idx_type i) const |
458 | 233 { |
5275 | 234 octave_idx_type r = rows (); |
235 octave_idx_type c = cols (); | |
3504 | 236 if (i < 0 || i >= c) |
458 | 237 { |
238 (*current_liboctave_error_handler) ("invalid column selection"); | |
239 return ColumnVector (); | |
240 } | |
241 | |
3504 | 242 ColumnVector retval (r, 0.0); |
243 if (r >= c || (r < c && i < r)) | |
458 | 244 retval.elem (i) = elem (i, i); |
245 | |
246 return retval; | |
247 } | |
248 | |
249 ColumnVector | |
250 DiagMatrix::column (char *s) const | |
251 { | |
533 | 252 if (! s) |
458 | 253 { |
254 (*current_liboctave_error_handler) ("invalid column selection"); | |
255 return ColumnVector (); | |
256 } | |
257 | |
258 char c = *s; | |
259 if (c == 'f' || c == 'F') | |
5275 | 260 return column (static_cast<octave_idx_type>(0)); |
458 | 261 else if (c == 'l' || c == 'L') |
262 return column (cols () - 1); | |
263 else | |
264 { | |
265 (*current_liboctave_error_handler) ("invalid column selection"); | |
266 return ColumnVector (); | |
267 } | |
268 } | |
269 | |
270 DiagMatrix | |
271 DiagMatrix::inverse (void) const | |
272 { | |
8811 | 273 octave_idx_type info; |
458 | 274 return inverse (info); |
275 } | |
276 | |
277 DiagMatrix | |
8811 | 278 DiagMatrix::inverse (octave_idx_type &info) const |
458 | 279 { |
5275 | 280 octave_idx_type r = rows (); |
281 octave_idx_type c = cols (); | |
282 octave_idx_type len = length (); | |
3504 | 283 if (r != c) |
458 | 284 { |
285 (*current_liboctave_error_handler) ("inverse requires square matrix"); | |
286 return DiagMatrix (); | |
287 } | |
288 | |
3504 | 289 DiagMatrix retval (r, c); |
1627 | 290 |
458 | 291 info = 0; |
5275 | 292 for (octave_idx_type i = 0; i < len; i++) |
458 | 293 { |
294 if (elem (i, i) == 0.0) | |
295 { | |
296 info = -1; | |
1627 | 297 return *this; |
458 | 298 } |
299 else | |
1627 | 300 retval.elem (i, i) = 1.0 / elem (i, i); |
458 | 301 } |
302 | |
1627 | 303 return retval; |
458 | 304 } |
305 | |
306 // diagonal matrix by diagonal matrix -> diagonal matrix operations | |
307 | |
308 // diagonal matrix by diagonal matrix -> diagonal matrix operations | |
309 | |
310 DiagMatrix | |
311 operator * (const DiagMatrix& a, const DiagMatrix& b) | |
312 { | |
5275 | 313 octave_idx_type a_nr = a.rows (); |
314 octave_idx_type a_nc = a.cols (); | |
2385 | 315 |
5275 | 316 octave_idx_type b_nr = b.rows (); |
317 octave_idx_type b_nc = b.cols (); | |
2385 | 318 |
3504 | 319 if (a_nc != b_nr) |
458 | 320 { |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
321 gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc); |
458 | 322 return DiagMatrix (); |
323 } | |
324 | |
3504 | 325 if (a_nr == 0 || a_nc == 0 || b_nc == 0) |
326 return DiagMatrix (a_nr, a_nc, 0.0); | |
458 | 327 |
3504 | 328 DiagMatrix c (a_nr, b_nc); |
458 | 329 |
5275 | 330 octave_idx_type len = a_nr < b_nc ? a_nr : b_nc; |
458 | 331 |
5275 | 332 for (octave_idx_type i = 0; i < len; i++) |
458 | 333 { |
334 double a_element = a.elem (i, i); | |
335 double b_element = b.elem (i, i); | |
336 | |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7924
diff
changeset
|
337 c.elem (i, i) = a_element * b_element; |
458 | 338 } |
339 | |
340 return c; | |
341 } | |
342 | |
343 // other operations | |
344 | |
8371
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
345 DET |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
346 DiagMatrix::determinant (void) const |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
347 { |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
348 DET det (1.0); |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
349 if (rows () != cols ()) |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
350 { |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
351 (*current_liboctave_error_handler) ("determinant requires square matrix"); |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
352 det = 0.0; |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
353 } |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
354 else |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
355 { |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
356 octave_idx_type len = length (); |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
357 for (octave_idx_type i = 0; i < len; i++) |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
358 det *= elem (i, i); |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
359 } |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
360 |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
361 return det; |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
362 } |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
363 |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
364 double |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
365 DiagMatrix::rcond (void) const |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
366 { |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
367 ColumnVector av = diag (0).map (fabs); |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
368 double amx = av.max (), amn = av.min (); |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
369 return amx == 0 ? 0.0 : amn / amx; |
c3f7e2549abb
make det & inv aware of diagonal & permutation matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
370 } |
8367
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
371 |
3504 | 372 std::ostream& |
373 operator << (std::ostream& os, const DiagMatrix& a) | |
458 | 374 { |
375 // int field_width = os.precision () + 7; | |
1360 | 376 |
5275 | 377 for (octave_idx_type i = 0; i < a.rows (); i++) |
458 | 378 { |
5275 | 379 for (octave_idx_type j = 0; j < a.cols (); j++) |
458 | 380 { |
381 if (i == j) | |
382 os << " " /* setw (field_width) */ << a.elem (i, i); | |
383 else | |
384 os << " " /* setw (field_width) */ << 0.0; | |
385 } | |
386 os << "\n"; | |
387 } | |
388 return os; | |
389 } | |
390 | |
391 /* | |
392 ;;; Local Variables: *** | |
393 ;;; mode: C++ *** | |
394 ;;; End: *** | |
395 */ |