Mercurial > hg > octave-nkf
annotate liboctave/dMatrix.cc @ 9661:afcf852256d2
optimize / and '\ for triangular matrices
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 23 Sep 2009 10:00:16 +0200 |
parents | 3429c956de6f |
children | 0d3b248f4ab6 |
rev | line source |
---|---|
1993 | 1 // Matrix manipulations. |
458 | 2 /* |
3 | |
7017 | 4 Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
8920 | 5 2003, 2004, 2005, 2006, 2007, 2009 John W. Eaton |
7803 | 6 Copyright (C) 2008 Jaroslav Hajek |
9601
a9b37bae1802
add a couple of missing copyright statements
Jaroslav Hajek <highegg@gmail.com>
parents:
9578
diff
changeset
|
7 Copyright (C) 2009 VZLU Prague, a.s. |
458 | 8 |
9 This file is part of Octave. | |
10 | |
11 Octave is free software; you can redistribute it and/or modify it | |
12 under the terms of the GNU General Public License as published by the | |
7016 | 13 Free Software Foundation; either version 3 of the License, or (at your |
14 option) any later version. | |
458 | 15 |
16 Octave is distributed in the hope that it will be useful, but WITHOUT | |
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
19 for more details. | |
20 | |
21 You should have received a copy of the GNU General Public License | |
7016 | 22 along with Octave; see the file COPYING. If not, see |
23 <http://www.gnu.org/licenses/>. | |
458 | 24 |
25 */ | |
26 | |
27 #ifdef HAVE_CONFIG_H | |
1192 | 28 #include <config.h> |
458 | 29 #endif |
30 | |
1367 | 31 #include <cfloat> |
32 | |
3503 | 33 #include <iostream> |
6209 | 34 #include <vector> |
1367 | 35 |
4669 | 36 #include "Array-util.h" |
2317 | 37 #include "byte-swap.h" |
2828 | 38 #include "dMatrix.h" |
1819 | 39 #include "dbleAEPBAL.h" |
8335 | 40 #include "DET.h" |
1819 | 41 #include "dbleSCHUR.h" |
740 | 42 #include "dbleSVD.h" |
6207 | 43 #include "dbleCHOL.h" |
1847 | 44 #include "f77-fcn.h" |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
45 #include "functor.h" |
458 | 46 #include "lo-error.h" |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
8375
diff
changeset
|
47 #include "oct-locbuf.h" |
2354 | 48 #include "lo-ieee.h" |
49 #include "lo-mappers.h" | |
1968 | 50 #include "lo-utils.h" |
1367 | 51 #include "mx-base.h" |
2828 | 52 #include "mx-m-dm.h" |
3176 | 53 #include "mx-dm-m.h" |
1367 | 54 #include "mx-inlines.cc" |
8774
b756ce0002db
split implementation and interface in mx-op-defs and MArray-defs
Jaroslav Hajek <highegg@gmail.com>
parents:
8743
diff
changeset
|
55 #include "mx-op-defs.h" |
1650 | 56 #include "oct-cmplx.h" |
9523
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
57 #include "oct-fftw.h" |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
58 #include "oct-norm.h" |
4153 | 59 #include "quit.h" |
458 | 60 |
61 // Fortran functions we call. | |
62 | |
63 extern "C" | |
64 { | |
7478 | 65 F77_RET_T |
7477 | 66 F77_FUNC (xilaenv, XILAENV) (const octave_idx_type&, F77_CONST_CHAR_ARG_DECL, |
67 F77_CONST_CHAR_ARG_DECL, | |
68 const octave_idx_type&, const octave_idx_type&, | |
7478 | 69 const octave_idx_type&, const octave_idx_type&, |
70 octave_idx_type& | |
71 F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL); | |
7476 | 72 |
4552 | 73 F77_RET_T |
74 F77_FUNC (dgebal, DGEBAL) (F77_CONST_CHAR_ARG_DECL, | |
5275 | 75 const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type&, |
76 octave_idx_type&, double*, octave_idx_type& | |
4552 | 77 F77_CHAR_ARG_LEN_DECL); |
78 | |
79 F77_RET_T | |
80 F77_FUNC (dgebak, DGEBAK) (F77_CONST_CHAR_ARG_DECL, | |
81 F77_CONST_CHAR_ARG_DECL, | |
5275 | 82 const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*, |
83 const octave_idx_type&, double*, const octave_idx_type&, octave_idx_type& | |
4552 | 84 F77_CHAR_ARG_LEN_DECL |
85 F77_CHAR_ARG_LEN_DECL); | |
86 | |
87 | |
88 F77_RET_T | |
89 F77_FUNC (dgemm, DGEMM) (F77_CONST_CHAR_ARG_DECL, | |
90 F77_CONST_CHAR_ARG_DECL, | |
5275 | 91 const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, |
92 const double&, const double*, const octave_idx_type&, | |
93 const double*, const octave_idx_type&, const double&, | |
94 double*, const octave_idx_type& | |
4552 | 95 F77_CHAR_ARG_LEN_DECL |
96 F77_CHAR_ARG_LEN_DECL); | |
97 | |
98 F77_RET_T | |
5983 | 99 F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL, |
100 const octave_idx_type&, const octave_idx_type&, const double&, | |
101 const double*, const octave_idx_type&, const double*, | |
102 const octave_idx_type&, const double&, double*, | |
103 const octave_idx_type& | |
104 F77_CHAR_ARG_LEN_DECL); | |
105 | |
106 F77_RET_T | |
107 F77_FUNC (xddot, XDDOT) (const octave_idx_type&, const double*, const octave_idx_type&, | |
108 const double*, const octave_idx_type&, double&); | |
109 | |
110 F77_RET_T | |
7801
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
111 F77_FUNC (dsyrk, DSYRK) (F77_CONST_CHAR_ARG_DECL, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
112 F77_CONST_CHAR_ARG_DECL, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
113 const octave_idx_type&, const octave_idx_type&, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
114 const double&, const double*, const octave_idx_type&, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
115 const double&, double*, const octave_idx_type& |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
116 F77_CHAR_ARG_LEN_DECL |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
117 F77_CHAR_ARG_LEN_DECL); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
118 |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
119 F77_RET_T |
5275 | 120 F77_FUNC (dgetrf, DGETRF) (const octave_idx_type&, const octave_idx_type&, double*, const octave_idx_type&, |
121 octave_idx_type*, octave_idx_type&); | |
4329 | 122 |
4552 | 123 F77_RET_T |
5275 | 124 F77_FUNC (dgetrs, DGETRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, const octave_idx_type&, |
125 const double*, const octave_idx_type&, | |
126 const octave_idx_type*, double*, const octave_idx_type&, octave_idx_type& | |
4552 | 127 F77_CHAR_ARG_LEN_DECL); |
128 | |
129 F77_RET_T | |
5275 | 130 F77_FUNC (dgetri, DGETRI) (const octave_idx_type&, double*, const octave_idx_type&, const octave_idx_type*, |
131 double*, const octave_idx_type&, octave_idx_type&); | |
4552 | 132 |
133 F77_RET_T | |
5275 | 134 F77_FUNC (dgecon, DGECON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, double*, |
135 const octave_idx_type&, const double&, double&, | |
136 double*, octave_idx_type*, octave_idx_type& | |
4552 | 137 F77_CHAR_ARG_LEN_DECL); |
138 | |
139 F77_RET_T | |
7072 | 140 F77_FUNC (dgelsy, DGELSY) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, |
141 double*, const octave_idx_type&, double*, | |
142 const octave_idx_type&, octave_idx_type*, double&, octave_idx_type&, | |
143 double*, const octave_idx_type&, octave_idx_type&); | |
144 | |
145 F77_RET_T | |
146 F77_FUNC (dgelsd, DGELSD) (const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, | |
5275 | 147 double*, const octave_idx_type&, double*, |
7071 | 148 const octave_idx_type&, double*, double&, octave_idx_type&, |
7072 | 149 double*, const octave_idx_type&, octave_idx_type*, |
150 octave_idx_type&); | |
458 | 151 |
5785 | 152 F77_RET_T |
153 F77_FUNC (dpotrf, DPOTRF) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
154 double *, const octave_idx_type&, | |
155 octave_idx_type& F77_CHAR_ARG_LEN_DECL); | |
156 | |
157 F77_RET_T | |
158 F77_FUNC (dpocon, DPOCON) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
159 double*, const octave_idx_type&, const double&, | |
160 double&, double*, octave_idx_type*, | |
161 octave_idx_type& F77_CHAR_ARG_LEN_DECL); | |
162 F77_RET_T | |
163 F77_FUNC (dpotrs, DPOTRS) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
164 const octave_idx_type&, const double*, | |
165 const octave_idx_type&, double*, | |
166 const octave_idx_type&, octave_idx_type& | |
167 F77_CHAR_ARG_LEN_DECL); | |
168 | |
169 F77_RET_T | |
6207 | 170 F77_FUNC (dtrtri, DTRTRI) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, |
171 const octave_idx_type&, const double*, | |
172 const octave_idx_type&, octave_idx_type& | |
173 F77_CHAR_ARG_LEN_DECL | |
174 F77_CHAR_ARG_LEN_DECL); | |
175 F77_RET_T | |
5785 | 176 F77_FUNC (dtrcon, DTRCON) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, |
177 F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
178 const double*, const octave_idx_type&, double&, | |
179 double*, octave_idx_type*, octave_idx_type& | |
180 F77_CHAR_ARG_LEN_DECL | |
181 F77_CHAR_ARG_LEN_DECL | |
182 F77_CHAR_ARG_LEN_DECL); | |
183 F77_RET_T | |
184 F77_FUNC (dtrtrs, DTRTRS) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, | |
185 F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, | |
186 const octave_idx_type&, const double*, | |
187 const octave_idx_type&, double*, | |
188 const octave_idx_type&, octave_idx_type& | |
189 F77_CHAR_ARG_LEN_DECL | |
190 F77_CHAR_ARG_LEN_DECL | |
191 F77_CHAR_ARG_LEN_DECL); | |
192 | |
4552 | 193 F77_RET_T |
194 F77_FUNC (dlartg, DLARTG) (const double&, const double&, double&, | |
195 double&, double&); | |
196 | |
197 F77_RET_T | |
198 F77_FUNC (dtrsyl, DTRSYL) (F77_CONST_CHAR_ARG_DECL, | |
199 F77_CONST_CHAR_ARG_DECL, | |
5275 | 200 const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, |
201 const double*, const octave_idx_type&, const double*, | |
202 const octave_idx_type&, const double*, const octave_idx_type&, | |
203 double&, octave_idx_type& | |
4552 | 204 F77_CHAR_ARG_LEN_DECL |
205 F77_CHAR_ARG_LEN_DECL); | |
206 | |
207 F77_RET_T | |
5275 | 208 F77_FUNC (xdlange, XDLANGE) (F77_CONST_CHAR_ARG_DECL, const octave_idx_type&, |
209 const octave_idx_type&, const double*, | |
210 const octave_idx_type&, double*, double& | |
4552 | 211 F77_CHAR_ARG_LEN_DECL); |
458 | 212 } |
213 | |
1360 | 214 // Matrix class. |
458 | 215 |
2349 | 216 Matrix::Matrix (const RowVector& rv) |
8614
5114ea5a41b5
use shallow copying in Matrix/RowVector/ColumnVector conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8392
diff
changeset
|
217 : MArray2<double> (Array2<double> (rv, 1, rv.length ())) |
2349 | 218 { |
219 } | |
220 | |
221 Matrix::Matrix (const ColumnVector& cv) | |
8614
5114ea5a41b5
use shallow copying in Matrix/RowVector/ColumnVector conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8392
diff
changeset
|
222 : MArray2<double> (Array2<double> (cv, cv.length (), 1)) |
2349 | 223 { |
224 } | |
225 | |
458 | 226 Matrix::Matrix (const DiagMatrix& a) |
1214 | 227 : MArray2<double> (a.rows (), a.cols (), 0.0) |
458 | 228 { |
5275 | 229 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 230 elem (i, i) = a.elem (i, i); |
231 } | |
232 | |
8367
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
233 Matrix::Matrix (const PermMatrix& a) |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
234 : MArray2<double> (a.rows (), a.cols (), 0.0) |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
235 { |
8375
e3c9102431a9
fix design problems of diag & perm matrix classes
Jaroslav Hajek <highegg@gmail.com>
parents:
8367
diff
changeset
|
236 const Array<octave_idx_type> ia (a.pvec ()); |
8367
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
237 octave_idx_type len = a.rows (); |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
238 if (a.is_col_perm ()) |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
239 for (octave_idx_type i = 0; i < len; i++) |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
240 elem (ia(i), i) = 1.0; |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
241 else |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
242 for (octave_idx_type i = 0; i < len; i++) |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
243 elem (i, ia(i)) = 1.0; |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
244 } |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8337
diff
changeset
|
245 |
5775 | 246 // FIXME -- could we use a templated mixed-type copy function |
1574 | 247 // here? |
248 | |
2828 | 249 Matrix::Matrix (const boolMatrix& a) |
250 : MArray2<double> (a.rows (), a.cols ()) | |
251 { | |
5275 | 252 for (octave_idx_type i = 0; i < a.rows (); i++) |
253 for (octave_idx_type j = 0; j < a.cols (); j++) | |
2828 | 254 elem (i, j) = a.elem (i, j); |
255 } | |
256 | |
1574 | 257 Matrix::Matrix (const charMatrix& a) |
258 : MArray2<double> (a.rows (), a.cols ()) | |
259 { | |
5275 | 260 for (octave_idx_type i = 0; i < a.rows (); i++) |
261 for (octave_idx_type j = 0; j < a.cols (); j++) | |
8956
d91fa4b20bbb
ensure nonnegative char -> real conversion
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
262 elem (i, j) = static_cast<unsigned char> (a.elem (i, j)); |
1574 | 263 } |
264 | |
2385 | 265 bool |
458 | 266 Matrix::operator == (const Matrix& a) const |
267 { | |
268 if (rows () != a.rows () || cols () != a.cols ()) | |
2385 | 269 return false; |
458 | 270 |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
271 return mx_inline_equal (length (), data (), a.data ()); |
458 | 272 } |
273 | |
2385 | 274 bool |
458 | 275 Matrix::operator != (const Matrix& a) const |
276 { | |
277 return !(*this == a); | |
278 } | |
279 | |
3354 | 280 bool |
281 Matrix::is_symmetric (void) const | |
282 { | |
283 if (is_square () && rows () > 0) | |
284 { | |
5275 | 285 for (octave_idx_type i = 0; i < rows (); i++) |
286 for (octave_idx_type j = i+1; j < cols (); j++) | |
3354 | 287 if (elem (i, j) != elem (j, i)) |
288 return false; | |
289 | |
290 return true; | |
291 } | |
292 | |
293 return false; | |
294 } | |
295 | |
458 | 296 Matrix& |
5275 | 297 Matrix::insert (const Matrix& a, octave_idx_type r, octave_idx_type c) |
458 | 298 { |
1561 | 299 Array2<double>::insert (a, r, c); |
458 | 300 return *this; |
301 } | |
302 | |
303 Matrix& | |
5275 | 304 Matrix::insert (const RowVector& a, octave_idx_type r, octave_idx_type c) |
458 | 305 { |
5275 | 306 octave_idx_type a_len = a.length (); |
4316 | 307 |
1698 | 308 if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ()) |
458 | 309 { |
310 (*current_liboctave_error_handler) ("range error for insert"); | |
311 return *this; | |
312 } | |
313 | |
4316 | 314 if (a_len > 0) |
315 { | |
316 make_unique (); | |
317 | |
5275 | 318 for (octave_idx_type i = 0; i < a_len; i++) |
4316 | 319 xelem (r, c+i) = a.elem (i); |
320 } | |
458 | 321 |
322 return *this; | |
323 } | |
324 | |
325 Matrix& | |
5275 | 326 Matrix::insert (const ColumnVector& a, octave_idx_type r, octave_idx_type c) |
458 | 327 { |
5275 | 328 octave_idx_type a_len = a.length (); |
4316 | 329 |
1698 | 330 if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ()) |
458 | 331 { |
332 (*current_liboctave_error_handler) ("range error for insert"); | |
333 return *this; | |
334 } | |
335 | |
4316 | 336 if (a_len > 0) |
337 { | |
338 make_unique (); | |
339 | |
5275 | 340 for (octave_idx_type i = 0; i < a_len; i++) |
4316 | 341 xelem (r+i, c) = a.elem (i); |
342 } | |
458 | 343 |
344 return *this; | |
345 } | |
346 | |
347 Matrix& | |
5275 | 348 Matrix::insert (const DiagMatrix& a, octave_idx_type r, octave_idx_type c) |
458 | 349 { |
5275 | 350 octave_idx_type a_nr = a.rows (); |
351 octave_idx_type a_nc = a.cols (); | |
1697 | 352 |
1698 | 353 if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ()) |
458 | 354 { |
355 (*current_liboctave_error_handler) ("range error for insert"); | |
356 return *this; | |
357 } | |
358 | |
1697 | 359 fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1); |
360 | |
5275 | 361 octave_idx_type a_len = a.length (); |
4316 | 362 |
363 if (a_len > 0) | |
364 { | |
365 make_unique (); | |
366 | |
5275 | 367 for (octave_idx_type i = 0; i < a_len; i++) |
4316 | 368 xelem (r+i, c+i) = a.elem (i, i); |
369 } | |
458 | 370 |
371 return *this; | |
372 } | |
373 | |
374 Matrix& | |
375 Matrix::fill (double val) | |
376 { | |
5275 | 377 octave_idx_type nr = rows (); |
378 octave_idx_type nc = cols (); | |
4316 | 379 |
458 | 380 if (nr > 0 && nc > 0) |
4316 | 381 { |
382 make_unique (); | |
383 | |
5275 | 384 for (octave_idx_type j = 0; j < nc; j++) |
385 for (octave_idx_type i = 0; i < nr; i++) | |
4316 | 386 xelem (i, j) = val; |
387 } | |
458 | 388 |
389 return *this; | |
390 } | |
391 | |
392 Matrix& | |
5275 | 393 Matrix::fill (double val, octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) |
458 | 394 { |
5275 | 395 octave_idx_type nr = rows (); |
396 octave_idx_type nc = cols (); | |
4316 | 397 |
458 | 398 if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0 |
399 || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc) | |
400 { | |
401 (*current_liboctave_error_handler) ("range error for fill"); | |
402 return *this; | |
403 } | |
404 | |
5275 | 405 if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; } |
406 if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; } | |
458 | 407 |
4316 | 408 if (r2 >= r1 && c2 >= c1) |
409 { | |
410 make_unique (); | |
411 | |
5275 | 412 for (octave_idx_type j = c1; j <= c2; j++) |
413 for (octave_idx_type i = r1; i <= r2; i++) | |
4316 | 414 xelem (i, j) = val; |
415 } | |
458 | 416 |
417 return *this; | |
418 } | |
419 | |
420 Matrix | |
421 Matrix::append (const Matrix& a) const | |
422 { | |
5275 | 423 octave_idx_type nr = rows (); |
424 octave_idx_type nc = cols (); | |
458 | 425 if (nr != a.rows ()) |
426 { | |
427 (*current_liboctave_error_handler) ("row dimension mismatch for append"); | |
428 return Matrix (); | |
429 } | |
430 | |
5275 | 431 octave_idx_type nc_insert = nc; |
458 | 432 Matrix retval (nr, nc + a.cols ()); |
433 retval.insert (*this, 0, 0); | |
434 retval.insert (a, 0, nc_insert); | |
435 return retval; | |
436 } | |
437 | |
438 Matrix | |
439 Matrix::append (const RowVector& a) const | |
440 { | |
5275 | 441 octave_idx_type nr = rows (); |
442 octave_idx_type nc = cols (); | |
458 | 443 if (nr != 1) |
444 { | |
445 (*current_liboctave_error_handler) ("row dimension mismatch for append"); | |
446 return Matrix (); | |
447 } | |
448 | |
5275 | 449 octave_idx_type nc_insert = nc; |
458 | 450 Matrix retval (nr, nc + a.length ()); |
451 retval.insert (*this, 0, 0); | |
452 retval.insert (a, 0, nc_insert); | |
453 return retval; | |
454 } | |
455 | |
456 Matrix | |
457 Matrix::append (const ColumnVector& a) const | |
458 { | |
5275 | 459 octave_idx_type nr = rows (); |
460 octave_idx_type nc = cols (); | |
458 | 461 if (nr != a.length ()) |
462 { | |
463 (*current_liboctave_error_handler) ("row dimension mismatch for append"); | |
464 return Matrix (); | |
465 } | |
466 | |
5275 | 467 octave_idx_type nc_insert = nc; |
458 | 468 Matrix retval (nr, nc + 1); |
469 retval.insert (*this, 0, 0); | |
470 retval.insert (a, 0, nc_insert); | |
471 return retval; | |
472 } | |
473 | |
474 Matrix | |
475 Matrix::append (const DiagMatrix& a) const | |
476 { | |
5275 | 477 octave_idx_type nr = rows (); |
478 octave_idx_type nc = cols (); | |
458 | 479 if (nr != a.rows ()) |
480 { | |
481 (*current_liboctave_error_handler) ("row dimension mismatch for append"); | |
482 return *this; | |
483 } | |
484 | |
5275 | 485 octave_idx_type nc_insert = nc; |
458 | 486 Matrix retval (nr, nc + a.cols ()); |
487 retval.insert (*this, 0, 0); | |
488 retval.insert (a, 0, nc_insert); | |
489 return retval; | |
490 } | |
491 | |
492 Matrix | |
493 Matrix::stack (const Matrix& a) const | |
494 { | |
5275 | 495 octave_idx_type nr = rows (); |
496 octave_idx_type nc = cols (); | |
458 | 497 if (nc != a.cols ()) |
498 { | |
499 (*current_liboctave_error_handler) | |
500 ("column dimension mismatch for stack"); | |
501 return Matrix (); | |
502 } | |
503 | |
5275 | 504 octave_idx_type nr_insert = nr; |
458 | 505 Matrix retval (nr + a.rows (), nc); |
506 retval.insert (*this, 0, 0); | |
507 retval.insert (a, nr_insert, 0); | |
508 return retval; | |
509 } | |
510 | |
511 Matrix | |
512 Matrix::stack (const RowVector& a) const | |
513 { | |
5275 | 514 octave_idx_type nr = rows (); |
515 octave_idx_type nc = cols (); | |
458 | 516 if (nc != a.length ()) |
517 { | |
518 (*current_liboctave_error_handler) | |
519 ("column dimension mismatch for stack"); | |
520 return Matrix (); | |
521 } | |
522 | |
5275 | 523 octave_idx_type nr_insert = nr; |
458 | 524 Matrix retval (nr + 1, nc); |
525 retval.insert (*this, 0, 0); | |
526 retval.insert (a, nr_insert, 0); | |
527 return retval; | |
528 } | |
529 | |
530 Matrix | |
531 Matrix::stack (const ColumnVector& a) const | |
532 { | |
5275 | 533 octave_idx_type nr = rows (); |
534 octave_idx_type nc = cols (); | |
458 | 535 if (nc != 1) |
536 { | |
537 (*current_liboctave_error_handler) | |
538 ("column dimension mismatch for stack"); | |
539 return Matrix (); | |
540 } | |
541 | |
5275 | 542 octave_idx_type nr_insert = nr; |
458 | 543 Matrix retval (nr + a.length (), nc); |
544 retval.insert (*this, 0, 0); | |
545 retval.insert (a, nr_insert, 0); | |
546 return retval; | |
547 } | |
548 | |
549 Matrix | |
550 Matrix::stack (const DiagMatrix& a) const | |
551 { | |
5275 | 552 octave_idx_type nr = rows (); |
553 octave_idx_type nc = cols (); | |
458 | 554 if (nc != a.cols ()) |
555 { | |
556 (*current_liboctave_error_handler) | |
557 ("column dimension mismatch for stack"); | |
558 return Matrix (); | |
559 } | |
560 | |
5275 | 561 octave_idx_type nr_insert = nr; |
458 | 562 Matrix retval (nr + a.rows (), nc); |
563 retval.insert (*this, 0, 0); | |
564 retval.insert (a, nr_insert, 0); | |
565 return retval; | |
566 } | |
567 | |
568 Matrix | |
1205 | 569 real (const ComplexMatrix& a) |
570 { | |
8650
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8614
diff
changeset
|
571 return Matrix (mx_inline_real_dup (a.data (), a.length ()), |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8614
diff
changeset
|
572 a.rows (), a.cols ()); |
1205 | 573 } |
574 | |
575 Matrix | |
576 imag (const ComplexMatrix& a) | |
577 { | |
8650
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8614
diff
changeset
|
578 return Matrix (mx_inline_imag_dup (a.data (), a.length ()), |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8614
diff
changeset
|
579 a.rows (), a.cols ()); |
1205 | 580 } |
581 | |
582 Matrix | |
5275 | 583 Matrix::extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const |
458 | 584 { |
5275 | 585 if (r1 > r2) { octave_idx_type tmp = r1; r1 = r2; r2 = tmp; } |
586 if (c1 > c2) { octave_idx_type tmp = c1; c1 = c2; c2 = tmp; } | |
587 | |
588 octave_idx_type new_r = r2 - r1 + 1; | |
589 octave_idx_type new_c = c2 - c1 + 1; | |
458 | 590 |
591 Matrix result (new_r, new_c); | |
592 | |
5275 | 593 for (octave_idx_type j = 0; j < new_c; j++) |
594 for (octave_idx_type i = 0; i < new_r; i++) | |
4316 | 595 result.xelem (i, j) = elem (r1+i, c1+j); |
596 | |
597 return result; | |
598 } | |
599 | |
600 Matrix | |
5275 | 601 Matrix::extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const |
4316 | 602 { |
603 Matrix result (nr, nc); | |
604 | |
5275 | 605 for (octave_idx_type j = 0; j < nc; j++) |
606 for (octave_idx_type i = 0; i < nr; i++) | |
4316 | 607 result.xelem (i, j) = elem (r1+i, c1+j); |
458 | 608 |
609 return result; | |
610 } | |
611 | |
612 // extract row or column i. | |
613 | |
614 RowVector | |
5275 | 615 Matrix::row (octave_idx_type i) const |
458 | 616 { |
8614
5114ea5a41b5
use shallow copying in Matrix/RowVector/ColumnVector conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8392
diff
changeset
|
617 return MArray<double> (index (idx_vector (i), idx_vector::colon)); |
458 | 618 } |
619 | |
620 ColumnVector | |
5275 | 621 Matrix::column (octave_idx_type i) const |
458 | 622 { |
8614
5114ea5a41b5
use shallow copying in Matrix/RowVector/ColumnVector conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8392
diff
changeset
|
623 return MArray<double> (index (idx_vector::colon, idx_vector (i))); |
458 | 624 } |
625 | |
626 Matrix | |
627 Matrix::inverse (void) const | |
628 { | |
5275 | 629 octave_idx_type info; |
7788 | 630 double rcon; |
6207 | 631 MatrixType mattype (*this); |
7788 | 632 return inverse (mattype, info, rcon, 0, 0); |
6207 | 633 } |
634 | |
635 Matrix | |
6479 | 636 Matrix::inverse (octave_idx_type& info) const |
637 { | |
7788 | 638 double rcon; |
6479 | 639 MatrixType mattype (*this); |
7788 | 640 return inverse (mattype, info, rcon, 0, 0); |
6479 | 641 } |
642 | |
643 Matrix | |
7788 | 644 Matrix::inverse (octave_idx_type& info, double& rcon, int force, |
6479 | 645 int calc_cond) const |
646 { | |
647 MatrixType mattype (*this); | |
7788 | 648 return inverse (mattype, info, rcon, force, calc_cond); |
6479 | 649 } |
650 | |
651 Matrix | |
6207 | 652 Matrix::inverse (MatrixType& mattype) const |
653 { | |
654 octave_idx_type info; | |
7788 | 655 double rcon; |
656 return inverse (mattype, info, rcon, 0, 0); | |
6207 | 657 } |
658 | |
659 Matrix | |
660 Matrix::inverse (MatrixType &mattype, octave_idx_type& info) const | |
661 { | |
7788 | 662 double rcon; |
663 return inverse (mattype, info, rcon, 0, 0); | |
458 | 664 } |
665 | |
666 Matrix | |
7788 | 667 Matrix::tinverse (MatrixType &mattype, octave_idx_type& info, double& rcon, |
6207 | 668 int force, int calc_cond) const |
458 | 669 { |
6207 | 670 Matrix retval; |
671 | |
672 octave_idx_type nr = rows (); | |
673 octave_idx_type nc = cols (); | |
674 | |
675 if (nr != nc || nr == 0 || nc == 0) | |
676 (*current_liboctave_error_handler) ("inverse requires square matrix"); | |
677 else | |
678 { | |
679 int typ = mattype.type (); | |
680 char uplo = (typ == MatrixType::Lower ? 'L' : 'U'); | |
681 char udiag = 'N'; | |
682 retval = *this; | |
683 double *tmp_data = retval.fortran_vec (); | |
684 | |
685 F77_XFCN (dtrtri, DTRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1), | |
686 F77_CONST_CHAR_ARG2 (&udiag, 1), | |
687 nr, tmp_data, nr, info | |
688 F77_CHAR_ARG_LEN (1) | |
689 F77_CHAR_ARG_LEN (1))); | |
690 | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
691 // Throw-away extra info LAPACK gives so as to not change output. |
7788 | 692 rcon = 0.0; |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
693 if (info != 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
694 info = -1; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
695 else if (calc_cond) |
6207 | 696 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
697 octave_idx_type dtrcon_info = 0; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
698 char job = '1'; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
699 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
700 OCTAVE_LOCAL_BUFFER (double, work, 3 * nr); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
701 OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, nr); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
702 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
703 F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&job, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
704 F77_CONST_CHAR_ARG2 (&uplo, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
705 F77_CONST_CHAR_ARG2 (&udiag, 1), |
7788 | 706 nr, tmp_data, nr, rcon, |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
707 work, iwork, dtrcon_info |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
708 F77_CHAR_ARG_LEN (1) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
709 F77_CHAR_ARG_LEN (1) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
710 F77_CHAR_ARG_LEN (1))); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
711 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
712 if (dtrcon_info != 0) |
6207 | 713 info = -1; |
714 } | |
715 | |
716 if (info == -1 && ! force) | |
717 retval = *this; // Restore matrix contents. | |
718 } | |
719 | |
720 return retval; | |
458 | 721 } |
722 | |
6207 | 723 |
458 | 724 Matrix |
7788 | 725 Matrix::finverse (MatrixType &mattype, octave_idx_type& info, double& rcon, |
6207 | 726 int force, int calc_cond) const |
458 | 727 { |
1948 | 728 Matrix retval; |
729 | |
5275 | 730 octave_idx_type nr = rows (); |
731 octave_idx_type nc = cols (); | |
1948 | 732 |
458 | 733 if (nr != nc || nr == 0 || nc == 0) |
1948 | 734 (*current_liboctave_error_handler) ("inverse requires square matrix"); |
458 | 735 else |
736 { | |
5275 | 737 Array<octave_idx_type> ipvt (nr); |
738 octave_idx_type *pipvt = ipvt.fortran_vec (); | |
1948 | 739 |
740 retval = *this; | |
741 double *tmp_data = retval.fortran_vec (); | |
742 | |
4329 | 743 Array<double> z(1); |
5275 | 744 octave_idx_type lwork = -1; |
4329 | 745 |
4330 | 746 // Query the optimum work array size. |
4329 | 747 F77_XFCN (dgetri, DGETRI, (nc, tmp_data, nr, pipvt, |
748 z.fortran_vec (), lwork, info)); | |
749 | |
5275 | 750 lwork = static_cast<octave_idx_type> (z(0)); |
4329 | 751 lwork = (lwork < 2 *nc ? 2*nc : lwork); |
752 z.resize (lwork); | |
753 double *pz = z.fortran_vec (); | |
754 | |
755 info = 0; | |
756 | |
4330 | 757 // Calculate the norm of the matrix, for later use. |
4329 | 758 double anorm = 0; |
759 if (calc_cond) | |
5275 | 760 anorm = retval.abs().sum().row(static_cast<octave_idx_type>(0)).max(); |
4329 | 761 |
762 F77_XFCN (dgetrf, DGETRF, (nc, nc, tmp_data, nr, pipvt, info)); | |
1948 | 763 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
764 // Throw-away extra info LAPACK gives so as to not change output. |
7788 | 765 rcon = 0.0; |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
766 if (info != 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
767 info = -1; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
768 else if (calc_cond) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
769 { |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
770 octave_idx_type dgecon_info = 0; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
771 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
772 // Now calculate the condition number for non-singular matrix. |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
773 char job = '1'; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
774 Array<octave_idx_type> iz (nc); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
775 octave_idx_type *piz = iz.fortran_vec (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
776 F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
777 nc, tmp_data, nr, anorm, |
7788 | 778 rcon, pz, piz, dgecon_info |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
779 F77_CHAR_ARG_LEN (1))); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
780 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
781 if (dgecon_info != 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
782 info = -1; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
783 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
784 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
785 if (info == -1 && ! force) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
786 retval = *this; // Restore matrix contents. |
1948 | 787 else |
788 { | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
789 octave_idx_type dgetri_info = 0; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
790 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
791 F77_XFCN (dgetri, DGETRI, (nc, tmp_data, nr, pipvt, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
792 pz, lwork, dgetri_info)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
793 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
794 if (dgetri_info != 0) |
1948 | 795 info = -1; |
796 } | |
6207 | 797 |
798 if (info != 0) | |
799 mattype.mark_as_rectangular(); | |
458 | 800 } |
801 | |
1948 | 802 return retval; |
458 | 803 } |
804 | |
740 | 805 Matrix |
7788 | 806 Matrix::inverse (MatrixType &mattype, octave_idx_type& info, double& rcon, |
6207 | 807 int force, int calc_cond) const |
808 { | |
809 int typ = mattype.type (false); | |
810 Matrix ret; | |
811 | |
812 if (typ == MatrixType::Unknown) | |
813 typ = mattype.type (*this); | |
814 | |
815 if (typ == MatrixType::Upper || typ == MatrixType::Lower) | |
7788 | 816 ret = tinverse (mattype, info, rcon, force, calc_cond); |
6840 | 817 else |
6207 | 818 { |
819 if (mattype.is_hermitian ()) | |
820 { | |
6486 | 821 CHOL chol (*this, info, calc_cond); |
6207 | 822 if (info == 0) |
6486 | 823 { |
824 if (calc_cond) | |
7788 | 825 rcon = chol.rcond (); |
6486 | 826 else |
7788 | 827 rcon = 1.0; |
6486 | 828 ret = chol.inverse (); |
829 } | |
6207 | 830 else |
831 mattype.mark_as_unsymmetric (); | |
832 } | |
833 | |
834 if (!mattype.is_hermitian ()) | |
7788 | 835 ret = finverse(mattype, info, rcon, force, calc_cond); |
836 | |
837 if ((mattype.is_hermitian () || calc_cond) && rcon == 0.) | |
6840 | 838 ret = Matrix (rows (), columns (), octave_Inf); |
6207 | 839 } |
840 | |
841 return ret; | |
842 } | |
843 | |
844 Matrix | |
4384 | 845 Matrix::pseudo_inverse (double tol) const |
740 | 846 { |
3480 | 847 SVD result (*this, SVD::economy); |
740 | 848 |
849 DiagMatrix S = result.singular_values (); | |
850 Matrix U = result.left_singular_matrix (); | |
851 Matrix V = result.right_singular_matrix (); | |
852 | |
853 ColumnVector sigma = S.diag (); | |
854 | |
5275 | 855 octave_idx_type r = sigma.length () - 1; |
856 octave_idx_type nr = rows (); | |
857 octave_idx_type nc = cols (); | |
740 | 858 |
859 if (tol <= 0.0) | |
860 { | |
861 if (nr > nc) | |
862 tol = nr * sigma.elem (0) * DBL_EPSILON; | |
863 else | |
864 tol = nc * sigma.elem (0) * DBL_EPSILON; | |
865 } | |
866 | |
867 while (r >= 0 && sigma.elem (r) < tol) | |
868 r--; | |
869 | |
870 if (r < 0) | |
871 return Matrix (nc, nr, 0.0); | |
872 else | |
873 { | |
874 Matrix Ur = U.extract (0, 0, nr-1, r); | |
875 DiagMatrix D = DiagMatrix (sigma.extract (0, r)) . inverse (); | |
876 Matrix Vr = V.extract (0, 0, nc-1, r); | |
877 return Vr * D * Ur.transpose (); | |
878 } | |
879 } | |
880 | |
9523
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
881 #if defined (HAVE_FFTW) |
3827 | 882 |
883 ComplexMatrix | |
884 Matrix::fourier (void) const | |
885 { | |
886 size_t nr = rows (); | |
887 size_t nc = cols (); | |
888 | |
889 ComplexMatrix retval (nr, nc); | |
890 | |
891 size_t npts, nsamples; | |
892 | |
893 if (nr == 1 || nc == 1) | |
894 { | |
895 npts = nr > nc ? nr : nc; | |
896 nsamples = 1; | |
897 } | |
898 else | |
899 { | |
900 npts = nr; | |
901 nsamples = nc; | |
902 } | |
903 | |
4773 | 904 const double *in (fortran_vec ()); |
3827 | 905 Complex *out (retval.fortran_vec ()); |
906 | |
4773 | 907 octave_fftw::fft (in, out, npts, nsamples); |
3827 | 908 |
909 return retval; | |
910 } | |
911 | |
912 ComplexMatrix | |
913 Matrix::ifourier (void) const | |
914 { | |
915 size_t nr = rows (); | |
916 size_t nc = cols (); | |
917 | |
918 ComplexMatrix retval (nr, nc); | |
919 | |
920 size_t npts, nsamples; | |
921 | |
922 if (nr == 1 || nc == 1) | |
923 { | |
924 npts = nr > nc ? nr : nc; | |
925 nsamples = 1; | |
926 } | |
927 else | |
928 { | |
929 npts = nr; | |
930 nsamples = nc; | |
931 } | |
932 | |
933 ComplexMatrix tmp (*this); | |
934 Complex *in (tmp.fortran_vec ()); | |
935 Complex *out (retval.fortran_vec ()); | |
936 | |
4773 | 937 octave_fftw::ifft (in, out, npts, nsamples); |
3827 | 938 |
939 return retval; | |
940 } | |
941 | |
942 ComplexMatrix | |
943 Matrix::fourier2d (void) const | |
944 { | |
4773 | 945 dim_vector dv(rows (), cols ()); |
946 | |
947 const double *in = fortran_vec (); | |
948 ComplexMatrix retval (rows (), cols ()); | |
949 octave_fftw::fftNd (in, retval.fortran_vec (), 2, dv); | |
3827 | 950 |
951 return retval; | |
952 } | |
953 | |
954 ComplexMatrix | |
955 Matrix::ifourier2d (void) const | |
956 { | |
4773 | 957 dim_vector dv(rows (), cols ()); |
3827 | 958 |
959 ComplexMatrix retval (*this); | |
4773 | 960 Complex *out (retval.fortran_vec ()); |
961 | |
962 octave_fftw::ifftNd (out, out, 2, dv); | |
3827 | 963 |
964 return retval; | |
965 } | |
966 | |
967 #else | |
968 | |
9523
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
969 extern "C" |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
970 { |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
971 // Note that the original complex fft routines were not written for |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
972 // double complex arguments. They have been modified by adding an |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
973 // implicit double precision (a-h,o-z) statement at the beginning of |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
974 // each subroutine. |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
975 |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
976 F77_RET_T |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
977 F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*); |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
978 |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
979 F77_RET_T |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
980 F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*); |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
981 |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
982 F77_RET_T |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
983 F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*); |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
984 } |
0ce82753dd72
more configure changes for libraries
John W. Eaton <jwe@octave.org>
parents:
9469
diff
changeset
|
985 |
458 | 986 ComplexMatrix |
987 Matrix::fourier (void) const | |
988 { | |
1948 | 989 ComplexMatrix retval; |
990 | |
5275 | 991 octave_idx_type nr = rows (); |
992 octave_idx_type nc = cols (); | |
993 | |
994 octave_idx_type npts, nsamples; | |
1948 | 995 |
458 | 996 if (nr == 1 || nc == 1) |
997 { | |
998 npts = nr > nc ? nr : nc; | |
999 nsamples = 1; | |
1000 } | |
1001 else | |
1002 { | |
1003 npts = nr; | |
1004 nsamples = nc; | |
1005 } | |
1006 | |
5275 | 1007 octave_idx_type nn = 4*npts+15; |
1948 | 1008 |
1009 Array<Complex> wsave (nn); | |
1010 Complex *pwsave = wsave.fortran_vec (); | |
1011 | |
3585 | 1012 retval = ComplexMatrix (*this); |
1948 | 1013 Complex *tmp_data = retval.fortran_vec (); |
1014 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1015 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
458 | 1016 |
5275 | 1017 for (octave_idx_type j = 0; j < nsamples; j++) |
4153 | 1018 { |
1019 OCTAVE_QUIT; | |
1020 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1021 F77_FUNC (zfftf, ZFFTF) (npts, &tmp_data[npts*j], pwsave); |
4153 | 1022 } |
1948 | 1023 |
1024 return retval; | |
458 | 1025 } |
1026 | |
1027 ComplexMatrix | |
1028 Matrix::ifourier (void) const | |
1029 { | |
1948 | 1030 ComplexMatrix retval; |
1031 | |
5275 | 1032 octave_idx_type nr = rows (); |
1033 octave_idx_type nc = cols (); | |
1034 | |
1035 octave_idx_type npts, nsamples; | |
1948 | 1036 |
458 | 1037 if (nr == 1 || nc == 1) |
1038 { | |
1039 npts = nr > nc ? nr : nc; | |
1040 nsamples = 1; | |
1041 } | |
1042 else | |
1043 { | |
1044 npts = nr; | |
1045 nsamples = nc; | |
1046 } | |
1047 | |
5275 | 1048 octave_idx_type nn = 4*npts+15; |
1948 | 1049 |
1050 Array<Complex> wsave (nn); | |
1051 Complex *pwsave = wsave.fortran_vec (); | |
1052 | |
3585 | 1053 retval = ComplexMatrix (*this); |
1948 | 1054 Complex *tmp_data = retval.fortran_vec (); |
1055 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1056 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
458 | 1057 |
5275 | 1058 for (octave_idx_type j = 0; j < nsamples; j++) |
4153 | 1059 { |
1060 OCTAVE_QUIT; | |
1061 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1062 F77_FUNC (zfftb, ZFFTB) (npts, &tmp_data[npts*j], pwsave); |
4153 | 1063 } |
458 | 1064 |
5275 | 1065 for (octave_idx_type j = 0; j < npts*nsamples; j++) |
3572 | 1066 tmp_data[j] = tmp_data[j] / static_cast<double> (npts); |
458 | 1067 |
1948 | 1068 return retval; |
458 | 1069 } |
1070 | |
677 | 1071 ComplexMatrix |
1072 Matrix::fourier2d (void) const | |
1073 { | |
1948 | 1074 ComplexMatrix retval; |
1075 | |
5275 | 1076 octave_idx_type nr = rows (); |
1077 octave_idx_type nc = cols (); | |
1078 | |
1079 octave_idx_type npts, nsamples; | |
1948 | 1080 |
677 | 1081 if (nr == 1 || nc == 1) |
1082 { | |
1083 npts = nr > nc ? nr : nc; | |
1084 nsamples = 1; | |
1085 } | |
1086 else | |
1087 { | |
1088 npts = nr; | |
1089 nsamples = nc; | |
1090 } | |
1091 | |
5275 | 1092 octave_idx_type nn = 4*npts+15; |
1948 | 1093 |
1094 Array<Complex> wsave (nn); | |
1095 Complex *pwsave = wsave.fortran_vec (); | |
1096 | |
3585 | 1097 retval = ComplexMatrix (*this); |
1948 | 1098 Complex *tmp_data = retval.fortran_vec (); |
1099 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1100 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
677 | 1101 |
5275 | 1102 for (octave_idx_type j = 0; j < nsamples; j++) |
4153 | 1103 { |
1104 OCTAVE_QUIT; | |
1105 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1106 F77_FUNC (zfftf, ZFFTF) (npts, &tmp_data[npts*j], pwsave); |
4153 | 1107 } |
677 | 1108 |
1109 npts = nc; | |
1110 nsamples = nr; | |
1111 nn = 4*npts+15; | |
1948 | 1112 |
1113 wsave.resize (nn); | |
1114 pwsave = wsave.fortran_vec (); | |
1115 | |
4773 | 1116 Array<Complex> tmp (npts); |
1117 Complex *prow = tmp.fortran_vec (); | |
1948 | 1118 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1119 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
677 | 1120 |
5275 | 1121 for (octave_idx_type j = 0; j < nsamples; j++) |
677 | 1122 { |
4153 | 1123 OCTAVE_QUIT; |
1124 | |
5275 | 1125 for (octave_idx_type i = 0; i < npts; i++) |
1948 | 1126 prow[i] = tmp_data[i*nr + j]; |
1127 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1128 F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave); |
677 | 1129 |
5275 | 1130 for (octave_idx_type i = 0; i < npts; i++) |
1948 | 1131 tmp_data[i*nr + j] = prow[i]; |
677 | 1132 } |
1133 | |
1948 | 1134 return retval; |
677 | 1135 } |
1136 | |
1137 ComplexMatrix | |
1138 Matrix::ifourier2d (void) const | |
1139 { | |
1948 | 1140 ComplexMatrix retval; |
1141 | |
5275 | 1142 octave_idx_type nr = rows (); |
1143 octave_idx_type nc = cols (); | |
1144 | |
1145 octave_idx_type npts, nsamples; | |
1948 | 1146 |
677 | 1147 if (nr == 1 || nc == 1) |
1148 { | |
1149 npts = nr > nc ? nr : nc; | |
1150 nsamples = 1; | |
1151 } | |
1152 else | |
1153 { | |
1154 npts = nr; | |
1155 nsamples = nc; | |
1156 } | |
1157 | |
5275 | 1158 octave_idx_type nn = 4*npts+15; |
1948 | 1159 |
1160 Array<Complex> wsave (nn); | |
1161 Complex *pwsave = wsave.fortran_vec (); | |
1162 | |
3585 | 1163 retval = ComplexMatrix (*this); |
1948 | 1164 Complex *tmp_data = retval.fortran_vec (); |
1165 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1166 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
677 | 1167 |
5275 | 1168 for (octave_idx_type j = 0; j < nsamples; j++) |
4153 | 1169 { |
1170 OCTAVE_QUIT; | |
1171 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1172 F77_FUNC (zfftb, ZFFTB) (npts, &tmp_data[npts*j], pwsave); |
4153 | 1173 } |
677 | 1174 |
5275 | 1175 for (octave_idx_type j = 0; j < npts*nsamples; j++) |
3572 | 1176 tmp_data[j] = tmp_data[j] / static_cast<double> (npts); |
677 | 1177 |
1178 npts = nc; | |
1179 nsamples = nr; | |
1180 nn = 4*npts+15; | |
1948 | 1181 |
1182 wsave.resize (nn); | |
1183 pwsave = wsave.fortran_vec (); | |
1184 | |
4773 | 1185 Array<Complex> tmp (npts); |
1186 Complex *prow = tmp.fortran_vec (); | |
1948 | 1187 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1188 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
677 | 1189 |
5275 | 1190 for (octave_idx_type j = 0; j < nsamples; j++) |
677 | 1191 { |
4153 | 1192 OCTAVE_QUIT; |
1193 | |
5275 | 1194 for (octave_idx_type i = 0; i < npts; i++) |
1948 | 1195 prow[i] = tmp_data[i*nr + j]; |
1196 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7788
diff
changeset
|
1197 F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave); |
677 | 1198 |
5275 | 1199 for (octave_idx_type i = 0; i < npts; i++) |
3572 | 1200 tmp_data[i*nr + j] = prow[i] / static_cast<double> (npts); |
677 | 1201 } |
1202 | |
1948 | 1203 return retval; |
677 | 1204 } |
1205 | |
3827 | 1206 #endif |
1207 | |
458 | 1208 DET |
1209 Matrix::determinant (void) const | |
1210 { | |
5275 | 1211 octave_idx_type info; |
7788 | 1212 double rcon; |
1213 return determinant (info, rcon, 0); | |
458 | 1214 } |
1215 | |
1216 DET | |
5275 | 1217 Matrix::determinant (octave_idx_type& info) const |
458 | 1218 { |
7788 | 1219 double rcon; |
1220 return determinant (info, rcon, 0); | |
458 | 1221 } |
1222 | |
1223 DET | |
7788 | 1224 Matrix::determinant (octave_idx_type& info, double& rcon, int calc_cond) const |
458 | 1225 { |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1226 MatrixType mattype (*this); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1227 return determinant (mattype, info, rcon, calc_cond); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1228 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1229 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1230 DET |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1231 Matrix::determinant (MatrixType& mattype, |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1232 octave_idx_type& info, double& rcon, int calc_cond) const |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1233 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1234 DET retval (1.0); |
458 | 1235 |
5275 | 1236 octave_idx_type nr = rows (); |
1237 octave_idx_type nc = cols (); | |
458 | 1238 |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1239 if (nr != nc) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1240 (*current_liboctave_error_handler) ("matrix must be square"); |
458 | 1241 else |
1242 { | |
8806 | 1243 volatile int typ = mattype.type (); |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1244 |
8337
e02242c54c49
reuse matrix type detected in det
Jaroslav Hajek <highegg@gmail.com>
parents:
8336
diff
changeset
|
1245 if (typ == MatrixType::Unknown) |
e02242c54c49
reuse matrix type detected in det
Jaroslav Hajek <highegg@gmail.com>
parents:
8336
diff
changeset
|
1246 typ = mattype.type (*this); |
e02242c54c49
reuse matrix type detected in det
Jaroslav Hajek <highegg@gmail.com>
parents:
8336
diff
changeset
|
1247 |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1248 if (typ == MatrixType::Lower || typ == MatrixType::Upper) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1249 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1250 for (octave_idx_type i = 0; i < nc; i++) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1251 retval *= elem (i,i); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1252 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1253 else if (typ == MatrixType::Hermitian) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1254 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1255 Matrix atmp = *this; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1256 double *tmp_data = atmp.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1257 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1258 info = 0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1259 double anorm = 0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1260 if (calc_cond) anorm = xnorm (*this, 1); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1261 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1262 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1263 char job = 'L'; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1264 F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1265 tmp_data, nr, info |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1266 F77_CHAR_ARG_LEN (1))); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1267 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1268 if (info != 0) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1269 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1270 rcon = 0.0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1271 mattype.mark_as_unsymmetric (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1272 typ = MatrixType::Full; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1273 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1274 else |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1275 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1276 Array<double> z (3 * nc); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1277 double *pz = z.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1278 Array<octave_idx_type> iz (nc); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1279 octave_idx_type *piz = iz.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1280 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1281 F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 (&job, 1), |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1282 nr, tmp_data, nr, anorm, |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1283 rcon, pz, piz, info |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1284 F77_CHAR_ARG_LEN (1))); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1285 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1286 if (info != 0) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1287 rcon = 0.0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1288 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1289 for (octave_idx_type i = 0; i < nc; i++) |
8337
e02242c54c49
reuse matrix type detected in det
Jaroslav Hajek <highegg@gmail.com>
parents:
8336
diff
changeset
|
1290 retval *= atmp (i,i); |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1291 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1292 retval = retval.square (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1293 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1294 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1295 else if (typ != MatrixType::Full) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1296 (*current_liboctave_error_handler) ("det: invalid dense matrix type"); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1297 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1298 if (typ == MatrixType::Full) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1299 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1300 Array<octave_idx_type> ipvt (nr); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1301 octave_idx_type *pipvt = ipvt.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1302 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1303 Matrix atmp = *this; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1304 double *tmp_data = atmp.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1305 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1306 info = 0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1307 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1308 // Calculate the norm of the matrix, for later use. |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1309 double anorm = 0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1310 if (calc_cond) anorm = xnorm (*this, 1); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1311 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1312 F77_XFCN (dgetrf, DGETRF, (nr, nr, tmp_data, nr, pipvt, info)); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1313 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1314 // Throw-away extra info LAPACK gives so as to not change output. |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1315 rcon = 0.0; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1316 if (info != 0) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1317 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1318 info = -1; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1319 retval = DET (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1320 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1321 else |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1322 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1323 if (calc_cond) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1324 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1325 // Now calc the condition number for non-singular matrix. |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1326 char job = '1'; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1327 Array<double> z (4 * nc); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1328 double *pz = z.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1329 Array<octave_idx_type> iz (nc); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1330 octave_idx_type *piz = iz.fortran_vec (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1331 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1332 F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1), |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1333 nc, tmp_data, nr, anorm, |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1334 rcon, pz, piz, info |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1335 F77_CHAR_ARG_LEN (1))); |
8335 | 1336 } |
8336
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1337 |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1338 if (info != 0) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1339 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1340 info = -1; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1341 retval = DET (); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1342 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1343 else |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1344 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1345 for (octave_idx_type i = 0; i < nc; i++) |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1346 { |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1347 double c = atmp(i,i); |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1348 retval *= (ipvt(i) != (i+1)) ? -c : c; |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1349 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1350 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1351 } |
9813c07ca946
make det take advantage of matrix type
Jaroslav Hajek <highegg@gmail.com>
parents:
8335
diff
changeset
|
1352 } |
458 | 1353 } |
1354 | |
1355 return retval; | |
1356 } | |
1357 | |
7788 | 1358 double |
1359 Matrix::rcond (void) const | |
1360 { | |
1361 MatrixType mattype (*this); | |
1362 return rcond (mattype); | |
1363 } | |
1364 | |
1365 double | |
1366 Matrix::rcond (MatrixType &mattype) const | |
1367 { | |
1368 double rcon; | |
1369 octave_idx_type nr = rows (); | |
1370 octave_idx_type nc = cols (); | |
1371 | |
1372 if (nr != nc) | |
1373 (*current_liboctave_error_handler) ("matrix must be square"); | |
1374 else if (nr == 0 || nc == 0) | |
1375 rcon = octave_Inf; | |
1376 else | |
1377 { | |
1378 int typ = mattype.type (); | |
1379 | |
1380 if (typ == MatrixType::Unknown) | |
1381 typ = mattype.type (*this); | |
1382 | |
1383 // Only calculate the condition number for LU/Cholesky | |
1384 if (typ == MatrixType::Upper) | |
1385 { | |
1386 const double *tmp_data = fortran_vec (); | |
1387 octave_idx_type info = 0; | |
1388 char norm = '1'; | |
1389 char uplo = 'U'; | |
1390 char dia = 'N'; | |
1391 | |
1392 Array<double> z (3 * nc); | |
1393 double *pz = z.fortran_vec (); | |
1394 Array<octave_idx_type> iz (nc); | |
1395 octave_idx_type *piz = iz.fortran_vec (); | |
1396 | |
1397 F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), | |
1398 F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1399 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1400 nr, tmp_data, nr, rcon, | |
1401 pz, piz, info | |
1402 F77_CHAR_ARG_LEN (1) | |
1403 F77_CHAR_ARG_LEN (1) | |
1404 F77_CHAR_ARG_LEN (1))); | |
1405 | |
1406 if (info != 0) | |
1407 rcon = 0.0; | |
1408 } | |
1409 else if (typ == MatrixType::Permuted_Upper) | |
1410 (*current_liboctave_error_handler) | |
1411 ("permuted triangular matrix not implemented"); | |
1412 else if (typ == MatrixType::Lower) | |
1413 { | |
1414 const double *tmp_data = fortran_vec (); | |
1415 octave_idx_type info = 0; | |
1416 char norm = '1'; | |
1417 char uplo = 'L'; | |
1418 char dia = 'N'; | |
1419 | |
1420 Array<double> z (3 * nc); | |
1421 double *pz = z.fortran_vec (); | |
1422 Array<octave_idx_type> iz (nc); | |
1423 octave_idx_type *piz = iz.fortran_vec (); | |
1424 | |
1425 F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), | |
1426 F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1427 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1428 nr, tmp_data, nr, rcon, | |
1429 pz, piz, info | |
1430 F77_CHAR_ARG_LEN (1) | |
1431 F77_CHAR_ARG_LEN (1) | |
1432 F77_CHAR_ARG_LEN (1))); | |
1433 | |
1434 if (info != 0) | |
1435 rcon = 0.0; | |
1436 } | |
1437 else if (typ == MatrixType::Permuted_Lower) | |
1438 (*current_liboctave_error_handler) | |
1439 ("permuted triangular matrix not implemented"); | |
1440 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) | |
1441 { | |
1442 double anorm = -1.0; | |
1443 Matrix atmp = *this; | |
1444 double *tmp_data = atmp.fortran_vec (); | |
1445 | |
1446 if (typ == MatrixType::Hermitian) | |
1447 { | |
1448 octave_idx_type info = 0; | |
1449 char job = 'L'; | |
1450 anorm = atmp.abs().sum(). | |
1451 row(static_cast<octave_idx_type>(0)).max(); | |
1452 | |
1453 F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, | |
1454 tmp_data, nr, info | |
1455 F77_CHAR_ARG_LEN (1))); | |
1456 | |
1457 if (info != 0) | |
1458 { | |
1459 rcon = 0.0; | |
1460 mattype.mark_as_unsymmetric (); | |
1461 typ = MatrixType::Full; | |
1462 } | |
1463 else | |
1464 { | |
1465 Array<double> z (3 * nc); | |
1466 double *pz = z.fortran_vec (); | |
1467 Array<octave_idx_type> iz (nc); | |
1468 octave_idx_type *piz = iz.fortran_vec (); | |
1469 | |
1470 F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1471 nr, tmp_data, nr, anorm, | |
1472 rcon, pz, piz, info | |
1473 F77_CHAR_ARG_LEN (1))); | |
1474 | |
1475 if (info != 0) | |
1476 rcon = 0.0; | |
1477 } | |
1478 } | |
1479 | |
1480 if (typ == MatrixType::Full) | |
1481 { | |
1482 octave_idx_type info = 0; | |
1483 | |
1484 Array<octave_idx_type> ipvt (nr); | |
1485 octave_idx_type *pipvt = ipvt.fortran_vec (); | |
1486 | |
1487 if(anorm < 0.) | |
1488 anorm = atmp.abs().sum(). | |
1489 row(static_cast<octave_idx_type>(0)).max(); | |
1490 | |
1491 Array<double> z (4 * nc); | |
1492 double *pz = z.fortran_vec (); | |
1493 Array<octave_idx_type> iz (nc); | |
1494 octave_idx_type *piz = iz.fortran_vec (); | |
1495 | |
1496 F77_XFCN (dgetrf, DGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1497 | |
1498 if (info != 0) | |
1499 { | |
1500 rcon = 0.0; | |
1501 mattype.mark_as_rectangular (); | |
1502 } | |
1503 else | |
1504 { | |
1505 char job = '1'; | |
1506 F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1), | |
1507 nc, tmp_data, nr, anorm, | |
1508 rcon, pz, piz, info | |
1509 F77_CHAR_ARG_LEN (1))); | |
1510 | |
1511 if (info != 0) | |
1512 rcon = 0.0; | |
1513 } | |
1514 } | |
1515 } | |
1516 else | |
1517 rcon = 0.0; | |
1518 } | |
1519 | |
1520 return rcon; | |
1521 } | |
1522 | |
458 | 1523 Matrix |
5785 | 1524 Matrix::utsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, |
7788 | 1525 double& rcon, solve_singularity_handler sing_handler, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1526 bool calc_cond, blas_trans_type transt) const |
5785 | 1527 { |
1528 Matrix retval; | |
1529 | |
1530 octave_idx_type nr = rows (); | |
1531 octave_idx_type nc = cols (); | |
1532 | |
6924 | 1533 if (nr != b.rows ()) |
5785 | 1534 (*current_liboctave_error_handler) |
1535 ("matrix dimension mismatch solution of linear equations"); | |
6924 | 1536 else if (nr == 0 || nc == 0 || b.cols () == 0) |
1537 retval = Matrix (nc, b.cols (), 0.0); | |
5785 | 1538 else |
1539 { | |
1540 volatile int typ = mattype.type (); | |
1541 | |
1542 if (typ == MatrixType::Permuted_Upper || | |
1543 typ == MatrixType::Upper) | |
1544 { | |
1545 octave_idx_type b_nc = b.cols (); | |
7788 | 1546 rcon = 1.; |
5785 | 1547 info = 0; |
1548 | |
1549 if (typ == MatrixType::Permuted_Upper) | |
1550 { | |
1551 (*current_liboctave_error_handler) | |
6390 | 1552 ("permuted triangular matrix not implemented"); |
5785 | 1553 } |
1554 else | |
1555 { | |
1556 const double *tmp_data = fortran_vec (); | |
1557 | |
1558 if (calc_cond) | |
1559 { | |
1560 char norm = '1'; | |
1561 char uplo = 'U'; | |
1562 char dia = 'N'; | |
1563 | |
1564 Array<double> z (3 * nc); | |
1565 double *pz = z.fortran_vec (); | |
1566 Array<octave_idx_type> iz (nc); | |
1567 octave_idx_type *piz = iz.fortran_vec (); | |
1568 | |
1569 F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), | |
1570 F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1571 F77_CONST_CHAR_ARG2 (&dia, 1), | |
7788 | 1572 nr, tmp_data, nr, rcon, |
5785 | 1573 pz, piz, info |
1574 F77_CHAR_ARG_LEN (1) | |
1575 F77_CHAR_ARG_LEN (1) | |
1576 F77_CHAR_ARG_LEN (1))); | |
1577 | |
1578 if (info != 0) | |
1579 info = -2; | |
1580 | |
7788 | 1581 volatile double rcond_plus_one = rcon + 1.0; |
1582 | |
1583 if (rcond_plus_one == 1.0 || xisnan (rcon)) | |
5785 | 1584 { |
1585 info = -2; | |
1586 | |
1587 if (sing_handler) | |
7788 | 1588 sing_handler (rcon); |
5785 | 1589 else |
1590 (*current_liboctave_error_handler) | |
1591 ("matrix singular to machine precision, rcond = %g", | |
7788 | 1592 rcon); |
5785 | 1593 } |
1594 } | |
1595 | |
1596 if (info == 0) | |
1597 { | |
1598 retval = b; | |
1599 double *result = retval.fortran_vec (); | |
1600 | |
1601 char uplo = 'U'; | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1602 char trans = get_blas_char (transt); |
5785 | 1603 char dia = 'N'; |
1604 | |
1605 F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1606 F77_CONST_CHAR_ARG2 (&trans, 1), | |
1607 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1608 nr, b_nc, tmp_data, nr, | |
1609 result, nr, info | |
1610 F77_CHAR_ARG_LEN (1) | |
1611 F77_CHAR_ARG_LEN (1) | |
1612 F77_CHAR_ARG_LEN (1))); | |
1613 } | |
1614 } | |
1615 } | |
1616 else | |
1617 (*current_liboctave_error_handler) ("incorrect matrix type"); | |
1618 } | |
1619 | |
1620 return retval; | |
1621 } | |
1622 | |
1623 Matrix | |
1624 Matrix::ltsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, | |
7788 | 1625 double& rcon, solve_singularity_handler sing_handler, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1626 bool calc_cond, blas_trans_type transt) const |
5785 | 1627 { |
1628 Matrix retval; | |
1629 | |
1630 octave_idx_type nr = rows (); | |
1631 octave_idx_type nc = cols (); | |
1632 | |
6924 | 1633 if (nr != b.rows ()) |
5785 | 1634 (*current_liboctave_error_handler) |
1635 ("matrix dimension mismatch solution of linear equations"); | |
6924 | 1636 else if (nr == 0 || nc == 0 || b.cols () == 0) |
1637 retval = Matrix (nc, b.cols (), 0.0); | |
5785 | 1638 else |
1639 { | |
1640 volatile int typ = mattype.type (); | |
1641 | |
1642 if (typ == MatrixType::Permuted_Lower || | |
1643 typ == MatrixType::Lower) | |
1644 { | |
1645 octave_idx_type b_nc = b.cols (); | |
7788 | 1646 rcon = 1.; |
5785 | 1647 info = 0; |
1648 | |
1649 if (typ == MatrixType::Permuted_Lower) | |
1650 { | |
1651 (*current_liboctave_error_handler) | |
6390 | 1652 ("permuted triangular matrix not implemented"); |
5785 | 1653 } |
1654 else | |
1655 { | |
1656 const double *tmp_data = fortran_vec (); | |
1657 | |
1658 if (calc_cond) | |
1659 { | |
1660 char norm = '1'; | |
1661 char uplo = 'L'; | |
1662 char dia = 'N'; | |
1663 | |
1664 Array<double> z (3 * nc); | |
1665 double *pz = z.fortran_vec (); | |
1666 Array<octave_idx_type> iz (nc); | |
1667 octave_idx_type *piz = iz.fortran_vec (); | |
1668 | |
1669 F77_XFCN (dtrcon, DTRCON, (F77_CONST_CHAR_ARG2 (&norm, 1), | |
1670 F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1671 F77_CONST_CHAR_ARG2 (&dia, 1), | |
7788 | 1672 nr, tmp_data, nr, rcon, |
5785 | 1673 pz, piz, info |
1674 F77_CHAR_ARG_LEN (1) | |
1675 F77_CHAR_ARG_LEN (1) | |
1676 F77_CHAR_ARG_LEN (1))); | |
1677 | |
1678 if (info != 0) | |
1679 info = -2; | |
1680 | |
7788 | 1681 volatile double rcond_plus_one = rcon + 1.0; |
1682 | |
1683 if (rcond_plus_one == 1.0 || xisnan (rcon)) | |
5785 | 1684 { |
1685 info = -2; | |
1686 | |
1687 if (sing_handler) | |
7788 | 1688 sing_handler (rcon); |
5785 | 1689 else |
1690 (*current_liboctave_error_handler) | |
1691 ("matrix singular to machine precision, rcond = %g", | |
7788 | 1692 rcon); |
5785 | 1693 } |
1694 } | |
1695 | |
1696 if (info == 0) | |
1697 { | |
1698 retval = b; | |
1699 double *result = retval.fortran_vec (); | |
1700 | |
1701 char uplo = 'L'; | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1702 char trans = get_blas_char (transt); |
5785 | 1703 char dia = 'N'; |
1704 | |
1705 F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1), | |
1706 F77_CONST_CHAR_ARG2 (&trans, 1), | |
1707 F77_CONST_CHAR_ARG2 (&dia, 1), | |
1708 nr, b_nc, tmp_data, nr, | |
1709 result, nr, info | |
1710 F77_CHAR_ARG_LEN (1) | |
1711 F77_CHAR_ARG_LEN (1) | |
1712 F77_CHAR_ARG_LEN (1))); | |
1713 } | |
1714 } | |
1715 } | |
1716 else | |
1717 (*current_liboctave_error_handler) ("incorrect matrix type"); | |
1718 } | |
1719 | |
1720 return retval; | |
1721 } | |
1722 | |
1723 Matrix | |
1724 Matrix::fsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, | |
7788 | 1725 double& rcon, solve_singularity_handler sing_handler, |
5785 | 1726 bool calc_cond) const |
1727 { | |
1728 Matrix retval; | |
1729 | |
1730 octave_idx_type nr = rows (); | |
1731 octave_idx_type nc = cols (); | |
1732 | |
6924 | 1733 if (nr != nc || nr != b.rows ()) |
5785 | 1734 (*current_liboctave_error_handler) |
1735 ("matrix dimension mismatch solution of linear equations"); | |
6924 | 1736 else if (nr == 0 || b.cols () == 0) |
1737 retval = Matrix (nc, b.cols (), 0.0); | |
5785 | 1738 else |
1739 { | |
1740 volatile int typ = mattype.type (); | |
1741 | |
1742 // Calculate the norm of the matrix, for later use. | |
1743 double anorm = -1.; | |
1744 | |
1745 if (typ == MatrixType::Hermitian) | |
1746 { | |
1747 info = 0; | |
1748 char job = 'L'; | |
1749 Matrix atmp = *this; | |
1750 double *tmp_data = atmp.fortran_vec (); | |
1751 anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); | |
1752 | |
1753 F77_XFCN (dpotrf, DPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr, | |
1754 tmp_data, nr, info | |
1755 F77_CHAR_ARG_LEN (1))); | |
1756 | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1757 // Throw-away extra info LAPACK gives so as to not change output. |
7788 | 1758 rcon = 0.0; |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1759 if (info != 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1760 { |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1761 info = -2; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1762 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1763 mattype.mark_as_unsymmetric (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1764 typ = MatrixType::Full; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1765 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1766 else |
5785 | 1767 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1768 if (calc_cond) |
5785 | 1769 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1770 Array<double> z (3 * nc); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1771 double *pz = z.fortran_vec (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1772 Array<octave_idx_type> iz (nc); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1773 octave_idx_type *piz = iz.fortran_vec (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1774 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1775 F77_XFCN (dpocon, DPOCON, (F77_CONST_CHAR_ARG2 (&job, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1776 nr, tmp_data, nr, anorm, |
7788 | 1777 rcon, pz, piz, info |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1778 F77_CHAR_ARG_LEN (1))); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1779 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1780 if (info != 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1781 info = -2; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1782 |
7788 | 1783 volatile double rcond_plus_one = rcon + 1.0; |
1784 | |
1785 if (rcond_plus_one == 1.0 || xisnan (rcon)) | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1786 { |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1787 info = -2; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1788 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1789 if (sing_handler) |
7788 | 1790 sing_handler (rcon); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1791 else |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1792 (*current_liboctave_error_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1793 ("matrix singular to machine precision, rcond = %g", |
7788 | 1794 rcon); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1795 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1796 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1797 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1798 if (info == 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1799 { |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1800 retval = b; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1801 double *result = retval.fortran_vec (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1802 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1803 octave_idx_type b_nc = b.cols (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1804 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1805 F77_XFCN (dpotrs, DPOTRS, (F77_CONST_CHAR_ARG2 (&job, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1806 nr, b_nc, tmp_data, nr, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1807 result, b.rows(), info |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1808 F77_CHAR_ARG_LEN (1))); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1809 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1810 else |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1811 { |
5785 | 1812 mattype.mark_as_unsymmetric (); |
1813 typ = MatrixType::Full; | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1814 } |
5785 | 1815 } |
1816 } | |
1817 | |
1818 if (typ == MatrixType::Full) | |
1819 { | |
1820 info = 0; | |
1821 | |
1822 Array<octave_idx_type> ipvt (nr); | |
1823 octave_idx_type *pipvt = ipvt.fortran_vec (); | |
1824 | |
1825 Matrix atmp = *this; | |
1826 double *tmp_data = atmp.fortran_vec (); | |
1827 if(anorm < 0.) | |
1828 anorm = atmp.abs().sum().row(static_cast<octave_idx_type>(0)).max(); | |
1829 | |
1830 Array<double> z (4 * nc); | |
1831 double *pz = z.fortran_vec (); | |
1832 Array<octave_idx_type> iz (nc); | |
1833 octave_idx_type *piz = iz.fortran_vec (); | |
1834 | |
1835 F77_XFCN (dgetrf, DGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1836 | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1837 // Throw-away extra info LAPACK gives so as to not change output. |
7788 | 1838 rcon = 0.0; |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1839 if (info != 0) |
5785 | 1840 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1841 info = -2; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1842 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1843 if (sing_handler) |
7788 | 1844 sing_handler (rcon); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1845 else |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1846 (*current_liboctave_error_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1847 ("matrix singular to machine precision"); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1848 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1849 mattype.mark_as_rectangular (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1850 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1851 else |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1852 { |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1853 if (calc_cond) |
5785 | 1854 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1855 // Now calculate the condition number for |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1856 // non-singular matrix. |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1857 char job = '1'; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1858 F77_XFCN (dgecon, DGECON, (F77_CONST_CHAR_ARG2 (&job, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1859 nc, tmp_data, nr, anorm, |
7788 | 1860 rcon, pz, piz, info |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1861 F77_CHAR_ARG_LEN (1))); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1862 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1863 if (info != 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1864 info = -2; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1865 |
7788 | 1866 volatile double rcond_plus_one = rcon + 1.0; |
1867 | |
1868 if (rcond_plus_one == 1.0 || xisnan (rcon)) | |
5785 | 1869 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1870 info = -2; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1871 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1872 if (sing_handler) |
7788 | 1873 sing_handler (rcon); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1874 else |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1875 (*current_liboctave_error_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1876 ("matrix singular to machine precision, rcond = %g", |
7788 | 1877 rcon); |
5785 | 1878 } |
1879 } | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1880 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1881 if (info == 0) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1882 { |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1883 retval = b; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1884 double *result = retval.fortran_vec (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1885 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1886 octave_idx_type b_nc = b.cols (); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1887 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1888 char job = 'N'; |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1889 F77_XFCN (dgetrs, DGETRS, (F77_CONST_CHAR_ARG2 (&job, 1), |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1890 nr, b_nc, tmp_data, nr, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1891 pipvt, result, b.rows(), info |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1892 F77_CHAR_ARG_LEN (1))); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1893 } |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1894 else |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
1895 mattype.mark_as_rectangular (); |
5785 | 1896 } |
1897 } | |
1898 else if (typ != MatrixType::Hermitian) | |
1899 (*current_liboctave_error_handler) ("incorrect matrix type"); | |
1900 } | |
1901 | |
1902 return retval; | |
1903 } | |
1904 | |
1905 Matrix | |
1906 Matrix::solve (MatrixType &typ, const Matrix& b) const | |
1907 { | |
1908 octave_idx_type info; | |
7788 | 1909 double rcon; |
1910 return solve (typ, b, info, rcon, 0); | |
5785 | 1911 } |
1912 | |
1913 Matrix | |
1914 Matrix::solve (MatrixType &typ, const Matrix& b, octave_idx_type& info, | |
7788 | 1915 double& rcon) const |
5785 | 1916 { |
7788 | 1917 return solve (typ, b, info, rcon, 0); |
5785 | 1918 } |
1919 | |
1920 Matrix | |
1921 Matrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, | |
7788 | 1922 double& rcon, solve_singularity_handler sing_handler, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1923 bool singular_fallback, blas_trans_type transt) const |
5785 | 1924 { |
1925 Matrix retval; | |
1926 int typ = mattype.type (); | |
1927 | |
1928 if (typ == MatrixType::Unknown) | |
1929 typ = mattype.type (*this); | |
1930 | |
1931 // Only calculate the condition number for LU/Cholesky | |
1932 if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper) | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1933 retval = utsolve (mattype, b, info, rcon, sing_handler, false, transt); |
5785 | 1934 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1935 retval = ltsolve (mattype, b, info, rcon, sing_handler, false, transt); |
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1936 else if (transt == blas_trans || transt == blas_conj_trans) |
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1937 return transpose ().solve (mattype, b, info, rcon, sing_handler, singular_fallback); |
5785 | 1938 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) |
7788 | 1939 retval = fsolve (mattype, b, info, rcon, sing_handler, true); |
5785 | 1940 else if (typ != MatrixType::Rectangular) |
1941 { | |
1942 (*current_liboctave_error_handler) ("unknown matrix type"); | |
1943 return Matrix (); | |
1944 } | |
1945 | |
1946 // Rectangular or one of the above solvers flags a singular matrix | |
1947 if (singular_fallback && mattype.type () == MatrixType::Rectangular) | |
1948 { | |
1949 octave_idx_type rank; | |
7788 | 1950 retval = lssolve (b, info, rank, rcon); |
5785 | 1951 } |
1952 | |
1953 return retval; | |
1954 } | |
1955 | |
1956 ComplexMatrix | |
1957 Matrix::solve (MatrixType &typ, const ComplexMatrix& b) const | |
1958 { | |
1959 ComplexMatrix tmp (*this); | |
1960 return tmp.solve (typ, b); | |
1961 } | |
1962 | |
1963 ComplexMatrix | |
1964 Matrix::solve (MatrixType &typ, const ComplexMatrix& b, | |
1965 octave_idx_type& info) const | |
1966 { | |
1967 ComplexMatrix tmp (*this); | |
1968 return tmp.solve (typ, b, info); | |
1969 } | |
1970 | |
1971 ComplexMatrix | |
1972 Matrix::solve (MatrixType &typ, const ComplexMatrix& b, octave_idx_type& info, | |
7788 | 1973 double& rcon) const |
5785 | 1974 { |
1975 ComplexMatrix tmp (*this); | |
7788 | 1976 return tmp.solve (typ, b, info, rcon); |
5785 | 1977 } |
1978 | |
1979 ComplexMatrix | |
1980 Matrix::solve (MatrixType &typ, const ComplexMatrix& b, octave_idx_type& info, | |
7788 | 1981 double& rcon, solve_singularity_handler sing_handler, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1982 bool singular_fallback, blas_trans_type transt) const |
5785 | 1983 { |
1984 ComplexMatrix tmp (*this); | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
1985 return tmp.solve (typ, b, info, rcon, sing_handler, singular_fallback, transt); |
5785 | 1986 } |
1987 | |
1988 ColumnVector | |
1989 Matrix::solve (MatrixType &typ, const ColumnVector& b) const | |
1990 { | |
7788 | 1991 octave_idx_type info; double rcon; |
1992 return solve (typ, b, info, rcon); | |
5785 | 1993 } |
1994 | |
1995 ColumnVector | |
1996 Matrix::solve (MatrixType &typ, const ColumnVector& b, | |
1997 octave_idx_type& info) const | |
1998 { | |
7788 | 1999 double rcon; |
2000 return solve (typ, b, info, rcon); | |
5785 | 2001 } |
2002 | |
2003 ColumnVector | |
2004 Matrix::solve (MatrixType &typ, const ColumnVector& b, octave_idx_type& info, | |
7788 | 2005 double& rcon) const |
5785 | 2006 { |
7788 | 2007 return solve (typ, b, info, rcon, 0); |
5785 | 2008 } |
2009 | |
2010 ColumnVector | |
2011 Matrix::solve (MatrixType &typ, const ColumnVector& b, octave_idx_type& info, | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2012 double& rcon, solve_singularity_handler sing_handler, blas_trans_type transt) const |
5785 | 2013 { |
2014 Matrix tmp (b); | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2015 return solve (typ, tmp, info, rcon, sing_handler, transt).column(static_cast<octave_idx_type> (0)); |
5785 | 2016 } |
2017 | |
2018 ComplexColumnVector | |
2019 Matrix::solve (MatrixType &typ, const ComplexColumnVector& b) const | |
2020 { | |
2021 ComplexMatrix tmp (*this); | |
2022 return tmp.solve (typ, b); | |
2023 } | |
2024 | |
2025 ComplexColumnVector | |
2026 Matrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
2027 octave_idx_type& info) const | |
2028 { | |
2029 ComplexMatrix tmp (*this); | |
2030 return tmp.solve (typ, b, info); | |
2031 } | |
2032 | |
2033 ComplexColumnVector | |
2034 Matrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
7788 | 2035 octave_idx_type& info, double& rcon) const |
5785 | 2036 { |
2037 ComplexMatrix tmp (*this); | |
7788 | 2038 return tmp.solve (typ, b, info, rcon); |
5785 | 2039 } |
2040 | |
2041 ComplexColumnVector | |
2042 Matrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
7788 | 2043 octave_idx_type& info, double& rcon, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2044 solve_singularity_handler sing_handler, blas_trans_type transt) const |
5785 | 2045 { |
2046 ComplexMatrix tmp (*this); | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2047 return tmp.solve(typ, b, info, rcon, sing_handler, transt); |
5785 | 2048 } |
2049 | |
2050 Matrix | |
458 | 2051 Matrix::solve (const Matrix& b) const |
2052 { | |
5275 | 2053 octave_idx_type info; |
7788 | 2054 double rcon; |
2055 return solve (b, info, rcon, 0); | |
458 | 2056 } |
2057 | |
2058 Matrix | |
5275 | 2059 Matrix::solve (const Matrix& b, octave_idx_type& info) const |
458 | 2060 { |
7788 | 2061 double rcon; |
2062 return solve (b, info, rcon, 0); | |
458 | 2063 } |
2064 | |
2065 Matrix | |
7788 | 2066 Matrix::solve (const Matrix& b, octave_idx_type& info, double& rcon) const |
458 | 2067 { |
7788 | 2068 return solve (b, info, rcon, 0); |
3480 | 2069 } |
2070 | |
2071 Matrix | |
5785 | 2072 Matrix::solve (const Matrix& b, octave_idx_type& info, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2073 double& rcon, solve_singularity_handler sing_handler, blas_trans_type transt) const |
3480 | 2074 { |
5785 | 2075 MatrixType mattype (*this); |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2076 return solve (mattype, b, info, rcon, sing_handler, true, transt); |
458 | 2077 } |
2078 | |
2079 ComplexMatrix | |
2080 Matrix::solve (const ComplexMatrix& b) const | |
2081 { | |
2082 ComplexMatrix tmp (*this); | |
2083 return tmp.solve (b); | |
2084 } | |
2085 | |
2086 ComplexMatrix | |
5275 | 2087 Matrix::solve (const ComplexMatrix& b, octave_idx_type& info) const |
458 | 2088 { |
2089 ComplexMatrix tmp (*this); | |
2090 return tmp.solve (b, info); | |
2091 } | |
2092 | |
2093 ComplexMatrix | |
7788 | 2094 Matrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon) const |
458 | 2095 { |
2096 ComplexMatrix tmp (*this); | |
7788 | 2097 return tmp.solve (b, info, rcon); |
458 | 2098 } |
2099 | |
3480 | 2100 ComplexMatrix |
7788 | 2101 Matrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2102 solve_singularity_handler sing_handler, blas_trans_type transt) const |
3480 | 2103 { |
2104 ComplexMatrix tmp (*this); | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2105 return tmp.solve (b, info, rcon, sing_handler, transt); |
3480 | 2106 } |
2107 | |
458 | 2108 ColumnVector |
2109 Matrix::solve (const ColumnVector& b) const | |
2110 { | |
7788 | 2111 octave_idx_type info; double rcon; |
2112 return solve (b, info, rcon); | |
458 | 2113 } |
2114 | |
2115 ColumnVector | |
5275 | 2116 Matrix::solve (const ColumnVector& b, octave_idx_type& info) const |
458 | 2117 { |
7788 | 2118 double rcon; |
2119 return solve (b, info, rcon); | |
458 | 2120 } |
2121 | |
2122 ColumnVector | |
7788 | 2123 Matrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcon) const |
458 | 2124 { |
7788 | 2125 return solve (b, info, rcon, 0); |
3480 | 2126 } |
2127 | |
2128 ColumnVector | |
7788 | 2129 Matrix::solve (const ColumnVector& b, octave_idx_type& info, double& rcon, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2130 solve_singularity_handler sing_handler, blas_trans_type transt) const |
3480 | 2131 { |
5785 | 2132 MatrixType mattype (*this); |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2133 return solve (mattype, b, info, rcon, sing_handler, transt); |
458 | 2134 } |
2135 | |
2136 ComplexColumnVector | |
2137 Matrix::solve (const ComplexColumnVector& b) const | |
2138 { | |
2139 ComplexMatrix tmp (*this); | |
2140 return tmp.solve (b); | |
2141 } | |
2142 | |
2143 ComplexColumnVector | |
5275 | 2144 Matrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const |
458 | 2145 { |
2146 ComplexMatrix tmp (*this); | |
2147 return tmp.solve (b, info); | |
2148 } | |
2149 | |
2150 ComplexColumnVector | |
7788 | 2151 Matrix::solve (const ComplexColumnVector& b, octave_idx_type& info, double& rcon) const |
458 | 2152 { |
2153 ComplexMatrix tmp (*this); | |
7788 | 2154 return tmp.solve (b, info, rcon); |
458 | 2155 } |
2156 | |
3480 | 2157 ComplexColumnVector |
7788 | 2158 Matrix::solve (const ComplexColumnVector& b, octave_idx_type& info, double& rcon, |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2159 solve_singularity_handler sing_handler, blas_trans_type transt) const |
3480 | 2160 { |
2161 ComplexMatrix tmp (*this); | |
9661
afcf852256d2
optimize / and '\ for triangular matrices
Jaroslav Hajek <highegg@gmail.com>
parents:
9658
diff
changeset
|
2162 return tmp.solve (b, info, rcon, sing_handler, transt); |
3480 | 2163 } |
2164 | |
458 | 2165 Matrix |
2166 Matrix::lssolve (const Matrix& b) const | |
2167 { | |
5275 | 2168 octave_idx_type info; |
2169 octave_idx_type rank; | |
7788 | 2170 double rcon; |
2171 return lssolve (b, info, rank, rcon); | |
458 | 2172 } |
2173 | |
2174 Matrix | |
5275 | 2175 Matrix::lssolve (const Matrix& b, octave_idx_type& info) const |
458 | 2176 { |
5275 | 2177 octave_idx_type rank; |
7788 | 2178 double rcon; |
2179 return lssolve (b, info, rank, rcon); | |
458 | 2180 } |
2181 | |
2182 Matrix | |
7072 | 2183 Matrix::lssolve (const Matrix& b, octave_idx_type& info, |
2184 octave_idx_type& rank) const | |
458 | 2185 { |
7788 | 2186 double rcon; |
2187 return lssolve (b, info, rank, rcon); | |
7076 | 2188 } |
2189 | |
2190 Matrix | |
2191 Matrix::lssolve (const Matrix& b, octave_idx_type& info, | |
7788 | 2192 octave_idx_type& rank, double &rcon) const |
7076 | 2193 { |
1948 | 2194 Matrix retval; |
2195 | |
5275 | 2196 octave_idx_type nrhs = b.cols (); |
2197 | |
2198 octave_idx_type m = rows (); | |
2199 octave_idx_type n = cols (); | |
458 | 2200 |
6924 | 2201 if (m != b.rows ()) |
1948 | 2202 (*current_liboctave_error_handler) |
6924 | 2203 ("matrix dimension mismatch solution of linear equations"); |
2204 else if (m == 0 || n == 0 || b.cols () == 0) | |
2205 retval = Matrix (n, b.cols (), 0.0); | |
1948 | 2206 else |
458 | 2207 { |
7072 | 2208 volatile octave_idx_type minmn = (m < n ? m : n); |
2209 octave_idx_type maxmn = m > n ? m : n; | |
7788 | 2210 rcon = -1.0; |
7072 | 2211 if (m != n) |
2212 { | |
2213 retval = Matrix (maxmn, nrhs, 0.0); | |
2214 | |
2215 for (octave_idx_type j = 0; j < nrhs; j++) | |
2216 for (octave_idx_type i = 0; i < m; i++) | |
2217 retval.elem (i, j) = b.elem (i, j); | |
2218 } | |
2219 else | |
2220 retval = b; | |
2221 | |
1948 | 2222 Matrix atmp = *this; |
2223 double *tmp_data = atmp.fortran_vec (); | |
2224 | |
7072 | 2225 double *pretval = retval.fortran_vec (); |
2226 Array<double> s (minmn); | |
7071 | 2227 double *ps = s.fortran_vec (); |
1948 | 2228 |
7072 | 2229 // Ask DGELSD what the dimension of WORK should be. |
5275 | 2230 octave_idx_type lwork = -1; |
3752 | 2231 |
2232 Array<double> work (1); | |
1948 | 2233 |
7477 | 2234 octave_idx_type smlsiz; |
2235 F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("DGELSD", 6), | |
2236 F77_CONST_CHAR_ARG2 (" ", 1), | |
7478 | 2237 0, 0, 0, 0, smlsiz |
7477 | 2238 F77_CHAR_ARG_LEN (6) |
7478 | 2239 F77_CHAR_ARG_LEN (1)); |
7079 | 2240 |
7486
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2241 octave_idx_type mnthr; |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2242 F77_FUNC (xilaenv, XILAENV) (6, F77_CONST_CHAR_ARG2 ("DGELSD", 6), |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2243 F77_CONST_CHAR_ARG2 (" ", 1), |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2244 m, n, nrhs, -1, mnthr |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2245 F77_CHAR_ARG_LEN (6) |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2246 F77_CHAR_ARG_LEN (1)); |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2247 |
7079 | 2248 // We compute the size of iwork because DGELSD in older versions |
2249 // of LAPACK does not return it on a query call. | |
7124 | 2250 double dminmn = static_cast<double> (minmn); |
2251 double dsmlsizp1 = static_cast<double> (smlsiz+1); | |
7079 | 2252 #if defined (HAVE_LOG2) |
7367 | 2253 double tmp = log2 (dminmn / dsmlsizp1); |
7079 | 2254 #else |
7367 | 2255 double tmp = log (dminmn / dsmlsizp1) / log (2.0); |
7079 | 2256 #endif |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2257 octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; |
7079 | 2258 if (nlvl < 0) |
2259 nlvl = 0; | |
2260 | |
2261 octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn; | |
2262 if (liwork < 1) | |
2263 liwork = 1; | |
7072 | 2264 Array<octave_idx_type> iwork (liwork); |
2265 octave_idx_type* piwork = iwork.fortran_vec (); | |
2266 | |
2267 F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn, | |
7788 | 2268 ps, rcon, rank, work.fortran_vec (), |
7072 | 2269 lwork, piwork, info)); |
1948 | 2270 |
7476 | 2271 // The workspace query is broken in at least LAPACK 3.0.0 |
7488
6470f946a425
another small xGELSD workspace fix
John W. Eaton <jwe@octave.org>
parents:
7486
diff
changeset
|
2272 // through 3.1.1 when n >= mnthr. The obtuse formula below |
7476 | 2273 // should provide sufficient workspace for DGELSD to operate |
2274 // efficiently. | |
7488
6470f946a425
another small xGELSD workspace fix
John W. Eaton <jwe@octave.org>
parents:
7486
diff
changeset
|
2275 if (n >= mnthr) |
7476 | 2276 { |
2277 const octave_idx_type wlalsd | |
2278 = 9*m + 2*m*smlsiz + 8*m*nlvl + m*nrhs + (smlsiz+1)*(smlsiz+1); | |
2279 | |
2280 octave_idx_type addend = m; | |
2281 | |
2282 if (2*m-4 > addend) | |
2283 addend = 2*m-4; | |
2284 | |
2285 if (nrhs > addend) | |
2286 addend = nrhs; | |
2287 | |
2288 if (n-3*m > addend) | |
2289 addend = n-3*m; | |
2290 | |
2291 if (wlalsd > addend) | |
2292 addend = wlalsd; | |
2293 | |
2294 const octave_idx_type lworkaround = 4*m + m*m + addend; | |
2295 | |
2296 if (work(0) < lworkaround) | |
2297 work(0) = lworkaround; | |
2298 } | |
7532
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2299 else if (m >= n) |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2300 { |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2301 octave_idx_type lworkaround |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2302 = 12*n + 2*n*smlsiz + 8*n*nlvl + n*nrhs + (smlsiz+1)*(smlsiz+1); |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2303 |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2304 if (work(0) < lworkaround) |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2305 work(0) = lworkaround; |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2306 } |
7476 | 2307 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2308 lwork = static_cast<octave_idx_type> (work(0)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2309 work.resize (lwork); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2310 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2311 F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval, |
7788 | 2312 maxmn, ps, rcon, rank, |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2313 work.fortran_vec (), lwork, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2314 piwork, info)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2315 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2316 if (rank < minmn) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2317 (*current_liboctave_warning_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2318 ("dgelsd: rank deficient %dx%d matrix, rank = %d", m, n, rank); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2319 if (s.elem (0) == 0.0) |
7788 | 2320 rcon = 0.0; |
1948 | 2321 else |
7788 | 2322 rcon = s.elem (minmn - 1) / s.elem (0); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2323 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2324 retval.resize (n, nrhs); |
458 | 2325 } |
2326 | |
2327 return retval; | |
2328 } | |
2329 | |
2330 ComplexMatrix | |
2331 Matrix::lssolve (const ComplexMatrix& b) const | |
2332 { | |
2333 ComplexMatrix tmp (*this); | |
5275 | 2334 octave_idx_type info; |
2335 octave_idx_type rank; | |
7788 | 2336 double rcon; |
2337 return tmp.lssolve (b, info, rank, rcon); | |
458 | 2338 } |
2339 | |
2340 ComplexMatrix | |
5275 | 2341 Matrix::lssolve (const ComplexMatrix& b, octave_idx_type& info) const |
458 | 2342 { |
2343 ComplexMatrix tmp (*this); | |
5275 | 2344 octave_idx_type rank; |
7788 | 2345 double rcon; |
2346 return tmp.lssolve (b, info, rank, rcon); | |
458 | 2347 } |
2348 | |
2349 ComplexMatrix | |
7076 | 2350 Matrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, |
2351 octave_idx_type& rank) const | |
458 | 2352 { |
2353 ComplexMatrix tmp (*this); | |
7788 | 2354 double rcon; |
2355 return tmp.lssolve (b, info, rank, rcon); | |
7076 | 2356 } |
2357 | |
2358 ComplexMatrix | |
2359 Matrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, | |
7788 | 2360 octave_idx_type& rank, double& rcon) const |
7076 | 2361 { |
2362 ComplexMatrix tmp (*this); | |
7788 | 2363 return tmp.lssolve (b, info, rank, rcon); |
458 | 2364 } |
2365 | |
2366 ColumnVector | |
2367 Matrix::lssolve (const ColumnVector& b) const | |
2368 { | |
5275 | 2369 octave_idx_type info; |
2370 octave_idx_type rank; | |
7788 | 2371 double rcon; |
2372 return lssolve (b, info, rank, rcon); | |
458 | 2373 } |
2374 | |
2375 ColumnVector | |
5275 | 2376 Matrix::lssolve (const ColumnVector& b, octave_idx_type& info) const |
458 | 2377 { |
5275 | 2378 octave_idx_type rank; |
7788 | 2379 double rcon; |
2380 return lssolve (b, info, rank, rcon); | |
458 | 2381 } |
2382 | |
2383 ColumnVector | |
7072 | 2384 Matrix::lssolve (const ColumnVector& b, octave_idx_type& info, |
2385 octave_idx_type& rank) const | |
458 | 2386 { |
7788 | 2387 double rcon; |
2388 return lssolve (b, info, rank, rcon); | |
7076 | 2389 } |
2390 | |
2391 ColumnVector | |
2392 Matrix::lssolve (const ColumnVector& b, octave_idx_type& info, | |
7788 | 2393 octave_idx_type& rank, double &rcon) const |
7076 | 2394 { |
1948 | 2395 ColumnVector retval; |
2396 | |
5275 | 2397 octave_idx_type nrhs = 1; |
2398 | |
2399 octave_idx_type m = rows (); | |
2400 octave_idx_type n = cols (); | |
458 | 2401 |
6924 | 2402 if (m != b.length ()) |
1948 | 2403 (*current_liboctave_error_handler) |
6924 | 2404 ("matrix dimension mismatch solution of linear equations"); |
2405 else if (m == 0 || n == 0) | |
2406 retval = ColumnVector (n, 0.0); | |
1948 | 2407 else |
458 | 2408 { |
7072 | 2409 volatile octave_idx_type minmn = (m < n ? m : n); |
2410 octave_idx_type maxmn = m > n ? m : n; | |
7788 | 2411 rcon = -1.0; |
7072 | 2412 |
2413 if (m != n) | |
2414 { | |
2415 retval = ColumnVector (maxmn, 0.0); | |
2416 | |
2417 for (octave_idx_type i = 0; i < m; i++) | |
2418 retval.elem (i) = b.elem (i); | |
2419 } | |
2420 else | |
2421 retval = b; | |
2422 | |
1948 | 2423 Matrix atmp = *this; |
2424 double *tmp_data = atmp.fortran_vec (); | |
2425 | |
7072 | 2426 double *pretval = retval.fortran_vec (); |
2427 Array<double> s (minmn); | |
7071 | 2428 double *ps = s.fortran_vec (); |
1948 | 2429 |
7072 | 2430 // Ask DGELSD what the dimension of WORK should be. |
5275 | 2431 octave_idx_type lwork = -1; |
3752 | 2432 |
2433 Array<double> work (1); | |
2434 | |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2435 octave_idx_type smlsiz; |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2436 F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("DGELSD", 6), |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2437 F77_CONST_CHAR_ARG2 (" ", 1), |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2438 0, 0, 0, 0, smlsiz |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2439 F77_CHAR_ARG_LEN (6) |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2440 F77_CHAR_ARG_LEN (1)); |
7079 | 2441 |
2442 // We compute the size of iwork because DGELSD in older versions | |
2443 // of LAPACK does not return it on a query call. | |
7124 | 2444 double dminmn = static_cast<double> (minmn); |
2445 double dsmlsizp1 = static_cast<double> (smlsiz+1); | |
7079 | 2446 #if defined (HAVE_LOG2) |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2447 double tmp = log2 (dminmn / dsmlsizp1); |
7079 | 2448 #else |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2449 double tmp = log (dminmn / dsmlsizp1) / log (2.0); |
7079 | 2450 #endif |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2451 octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; |
7079 | 2452 if (nlvl < 0) |
2453 nlvl = 0; | |
2454 | |
2455 octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn; | |
2456 if (liwork < 1) | |
2457 liwork = 1; | |
7072 | 2458 Array<octave_idx_type> iwork (liwork); |
2459 octave_idx_type* piwork = iwork.fortran_vec (); | |
2460 | |
2461 F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn, | |
7788 | 2462 ps, rcon, rank, work.fortran_vec (), |
7072 | 2463 lwork, piwork, info)); |
1948 | 2464 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2465 lwork = static_cast<octave_idx_type> (work(0)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2466 work.resize (lwork); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2467 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2468 F77_XFCN (dgelsd, DGELSD, (m, n, nrhs, tmp_data, m, pretval, |
7788 | 2469 maxmn, ps, rcon, rank, |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2470 work.fortran_vec (), lwork, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2471 piwork, info)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2472 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2473 if (rank < minmn) |
1948 | 2474 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2475 if (rank < minmn) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2476 (*current_liboctave_warning_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2477 ("dgelsd: rank deficient %dx%d matrix, rank = %d", m, n, rank); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2478 if (s.elem (0) == 0.0) |
7788 | 2479 rcon = 0.0; |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2480 else |
7788 | 2481 rcon = s.elem (minmn - 1) / s.elem (0); |
1948 | 2482 } |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2483 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2484 retval.resize (n, nrhs); |
458 | 2485 } |
2486 | |
2487 return retval; | |
2488 } | |
2489 | |
2490 ComplexColumnVector | |
2491 Matrix::lssolve (const ComplexColumnVector& b) const | |
2492 { | |
2493 ComplexMatrix tmp (*this); | |
7076 | 2494 octave_idx_type info; |
2495 octave_idx_type rank; | |
7788 | 2496 double rcon; |
2497 return tmp.lssolve (b, info, rank, rcon); | |
458 | 2498 } |
2499 | |
2500 ComplexColumnVector | |
5275 | 2501 Matrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info) const |
458 | 2502 { |
2503 ComplexMatrix tmp (*this); | |
7076 | 2504 octave_idx_type rank; |
7788 | 2505 double rcon; |
2506 return tmp.lssolve (b, info, rank, rcon); | |
458 | 2507 } |
2508 | |
2509 ComplexColumnVector | |
7076 | 2510 Matrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, |
2511 octave_idx_type& rank) const | |
458 | 2512 { |
2513 ComplexMatrix tmp (*this); | |
7788 | 2514 double rcon; |
2515 return tmp.lssolve (b, info, rank, rcon); | |
7076 | 2516 } |
2517 | |
2518 ComplexColumnVector | |
2519 Matrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, | |
7788 | 2520 octave_idx_type& rank, double &rcon) const |
7076 | 2521 { |
2522 ComplexMatrix tmp (*this); | |
7788 | 2523 return tmp.lssolve (b, info, rank, rcon); |
458 | 2524 } |
2525 | |
2526 Matrix& | |
2527 Matrix::operator += (const DiagMatrix& a) | |
2528 { | |
5275 | 2529 octave_idx_type nr = rows (); |
2530 octave_idx_type nc = cols (); | |
2531 | |
2532 octave_idx_type a_nr = a.rows (); | |
2533 octave_idx_type a_nc = a.cols (); | |
2385 | 2534 |
2535 if (nr != a_nr || nc != a_nc) | |
458 | 2536 { |
2385 | 2537 gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc); |
458 | 2538 return *this; |
2539 } | |
2540 | |
5275 | 2541 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 2542 elem (i, i) += a.elem (i, i); |
2543 | |
2544 return *this; | |
2545 } | |
2546 | |
2547 Matrix& | |
2548 Matrix::operator -= (const DiagMatrix& a) | |
2549 { | |
5275 | 2550 octave_idx_type nr = rows (); |
2551 octave_idx_type nc = cols (); | |
2552 | |
2553 octave_idx_type a_nr = a.rows (); | |
2554 octave_idx_type a_nc = a.cols (); | |
2385 | 2555 |
2556 if (nr != a_nr || nc != a_nc) | |
458 | 2557 { |
2385 | 2558 gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc); |
458 | 2559 return *this; |
2560 } | |
2561 | |
5275 | 2562 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 2563 elem (i, i) -= a.elem (i, i); |
2564 | |
2565 return *this; | |
2566 } | |
2567 | |
2568 // unary operations | |
2569 | |
2964 | 2570 boolMatrix |
458 | 2571 Matrix::operator ! (void) const |
2572 { | |
9553
0c72d9284087
further bool ops tweaks
Jaroslav Hajek <highegg@gmail.com>
parents:
9551
diff
changeset
|
2573 return do_mx_unary_op<boolMatrix, Matrix> (*this, mx_inline_not); |
458 | 2574 } |
2575 | |
1205 | 2576 // column vector by row vector -> matrix operations |
458 | 2577 |
1205 | 2578 Matrix |
2579 operator * (const ColumnVector& v, const RowVector& a) | |
458 | 2580 { |
1948 | 2581 Matrix retval; |
2582 | |
5275 | 2583 octave_idx_type len = v.length (); |
3233 | 2584 |
2585 if (len != 0) | |
1205 | 2586 { |
5275 | 2587 octave_idx_type a_len = a.length (); |
3233 | 2588 |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
2589 retval = Matrix (len, a_len); |
3233 | 2590 double *c = retval.fortran_vec (); |
2591 | |
4552 | 2592 F77_XFCN (dgemm, DGEMM, (F77_CONST_CHAR_ARG2 ("N", 1), |
2593 F77_CONST_CHAR_ARG2 ("N", 1), | |
2594 len, a_len, 1, 1.0, v.data (), len, | |
2595 a.data (), 1, 0.0, c, len | |
2596 F77_CHAR_ARG_LEN (1) | |
2597 F77_CHAR_ARG_LEN (1))); | |
1205 | 2598 } |
458 | 2599 |
1948 | 2600 return retval; |
458 | 2601 } |
2602 | |
2603 // other operations. | |
2604 | |
2605 Matrix | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2606 Matrix::map (dmapper fcn) const |
1205 | 2607 { |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2608 return MArray2<double>::map<double> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2609 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2610 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2611 ComplexMatrix |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2612 Matrix::map (cmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2613 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2614 return MArray2<double>::map<Complex> (func_ptr (fcn)); |
1205 | 2615 } |
2616 | |
3248 | 2617 boolMatrix |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2618 Matrix::map (bmapper fcn) const |
3248 | 2619 { |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
2620 return MArray2<double>::map<bool> (func_ptr (fcn)); |
458 | 2621 } |
2622 | |
2385 | 2623 bool |
4431 | 2624 Matrix::any_element_is_negative (bool neg_zero) const |
2385 | 2625 { |
5275 | 2626 octave_idx_type nel = nelem (); |
2385 | 2627 |
4431 | 2628 if (neg_zero) |
2629 { | |
5275 | 2630 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 2631 if (lo_ieee_signbit (elem (i))) |
2632 return true; | |
4431 | 2633 } |
2634 else | |
2635 { | |
5275 | 2636 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 2637 if (elem (i) < 0) |
2638 return true; | |
4431 | 2639 } |
2385 | 2640 |
2641 return false; | |
2642 } | |
2643 | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2644 bool |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2645 Matrix::any_element_is_nan (void) const |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2646 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2647 octave_idx_type nel = nelem (); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2648 |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2649 for (octave_idx_type i = 0; i < nel; i++) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2650 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2651 double val = elem (i); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2652 if (xisnan (val)) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2653 return true; |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2654 } |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2655 |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2656 return false; |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
2657 } |
2385 | 2658 |
2659 bool | |
2660 Matrix::any_element_is_inf_or_nan (void) const | |
2661 { | |
5275 | 2662 octave_idx_type nel = nelem (); |
2663 | |
2664 for (octave_idx_type i = 0; i < nel; i++) | |
4634 | 2665 { |
2666 double val = elem (i); | |
2667 if (xisinf (val) || xisnan (val)) | |
2668 return true; | |
2669 } | |
2670 | |
2671 return false; | |
2385 | 2672 } |
2673 | |
2674 bool | |
5943 | 2675 Matrix::any_element_not_one_or_zero (void) const |
2676 { | |
2677 octave_idx_type nel = nelem (); | |
2678 | |
2679 for (octave_idx_type i = 0; i < nel; i++) | |
2680 { | |
2681 double val = elem (i); | |
2682 if (val != 0 && val != 1) | |
2683 return true; | |
2684 } | |
2685 | |
2686 return false; | |
2687 } | |
2688 | |
2689 bool | |
2385 | 2690 Matrix::all_elements_are_int_or_inf_or_nan (void) const |
2691 { | |
5275 | 2692 octave_idx_type nel = nelem (); |
2693 | |
2694 for (octave_idx_type i = 0; i < nel; i++) | |
4634 | 2695 { |
2696 double val = elem (i); | |
2697 if (xisnan (val) || D_NINT (val) == val) | |
2698 continue; | |
2699 else | |
2700 return false; | |
2701 } | |
2385 | 2702 |
2703 return true; | |
2704 } | |
2705 | |
1968 | 2706 // Return nonzero if any element of M is not an integer. Also extract |
2707 // the largest and smallest values and return them in MAX_VAL and MIN_VAL. | |
2708 | |
2385 | 2709 bool |
1968 | 2710 Matrix::all_integers (double& max_val, double& min_val) const |
2711 { | |
5275 | 2712 octave_idx_type nel = nelem (); |
4634 | 2713 |
2714 if (nel > 0) | |
1968 | 2715 { |
4634 | 2716 max_val = elem (0); |
2717 min_val = elem (0); | |
1968 | 2718 } |
2719 else | |
2385 | 2720 return false; |
1968 | 2721 |
5275 | 2722 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 2723 { |
2724 double val = elem (i); | |
2725 | |
2726 if (val > max_val) | |
2727 max_val = val; | |
2728 | |
2729 if (val < min_val) | |
2730 min_val = val; | |
2731 | |
2732 if (D_NINT (val) != val) | |
2733 return false; | |
2734 } | |
2385 | 2735 |
2736 return true; | |
1968 | 2737 } |
2738 | |
2385 | 2739 bool |
1968 | 2740 Matrix::too_large_for_float (void) const |
2741 { | |
5275 | 2742 octave_idx_type nel = nelem (); |
2743 | |
2744 for (octave_idx_type i = 0; i < nel; i++) | |
4634 | 2745 { |
2746 double val = elem (i); | |
2747 | |
5389 | 2748 if (! (xisnan (val) || xisinf (val)) |
5387 | 2749 && fabs (val) > FLT_MAX) |
4634 | 2750 return true; |
2751 } | |
1968 | 2752 |
2385 | 2753 return false; |
1968 | 2754 } |
2755 | |
5775 | 2756 // FIXME Do these really belong here? Maybe they should be |
4015 | 2757 // in a base class? |
458 | 2758 |
2832 | 2759 boolMatrix |
4015 | 2760 Matrix::all (int dim) const |
458 | 2761 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2762 return do_mx_red_op<boolMatrix, double> (*this, dim, mx_inline_all); |
458 | 2763 } |
2764 | |
2832 | 2765 boolMatrix |
4015 | 2766 Matrix::any (int dim) const |
458 | 2767 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2768 return do_mx_red_op<boolMatrix, double> (*this, dim, mx_inline_any); |
458 | 2769 } |
2770 | |
2771 Matrix | |
3723 | 2772 Matrix::cumprod (int dim) const |
458 | 2773 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2774 return do_mx_cum_op<Matrix, double> (*this, dim, mx_inline_cumprod); |
458 | 2775 } |
2776 | |
2777 Matrix | |
3723 | 2778 Matrix::cumsum (int dim) const |
458 | 2779 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2780 return do_mx_cum_op<Matrix, double> (*this, dim, mx_inline_cumsum); |
458 | 2781 } |
2782 | |
2783 Matrix | |
3723 | 2784 Matrix::prod (int dim) const |
458 | 2785 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2786 return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_prod); |
458 | 2787 } |
2788 | |
2789 Matrix | |
3723 | 2790 Matrix::sum (int dim) const |
458 | 2791 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2792 return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_sum); |
458 | 2793 } |
2794 | |
2795 Matrix | |
3723 | 2796 Matrix::sumsq (int dim) const |
458 | 2797 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
2798 return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_sumsq); |
458 | 2799 } |
2800 | |
2385 | 2801 Matrix |
2802 Matrix::abs (void) const | |
2803 { | |
8650
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8614
diff
changeset
|
2804 return Matrix (mx_inline_fabs_dup (data (), length ()), |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8614
diff
changeset
|
2805 rows (), cols ()); |
2385 | 2806 } |
2807 | |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7544
diff
changeset
|
2808 Matrix |
5275 | 2809 Matrix::diag (octave_idx_type k) const |
458 | 2810 { |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7544
diff
changeset
|
2811 return MArray2<double>::diag (k); |
458 | 2812 } |
2813 | |
2814 ColumnVector | |
2815 Matrix::row_min (void) const | |
2816 { | |
5275 | 2817 Array<octave_idx_type> dummy_idx; |
4587 | 2818 return row_min (dummy_idx); |
458 | 2819 } |
2820 | |
2821 ColumnVector | |
5275 | 2822 Matrix::row_min (Array<octave_idx_type>& idx_arg) const |
458 | 2823 { |
2824 ColumnVector result; | |
2825 | |
5275 | 2826 octave_idx_type nr = rows (); |
2827 octave_idx_type nc = cols (); | |
458 | 2828 |
2829 if (nr > 0 && nc > 0) | |
2830 { | |
2831 result.resize (nr); | |
4587 | 2832 idx_arg.resize (nr); |
458 | 2833 |
5275 | 2834 for (octave_idx_type i = 0; i < nr; i++) |
458 | 2835 { |
5275 | 2836 octave_idx_type idx_j; |
4469 | 2837 |
2838 double tmp_min = octave_NaN; | |
2839 | |
2840 for (idx_j = 0; idx_j < nc; idx_j++) | |
2354 | 2841 { |
4469 | 2842 tmp_min = elem (i, idx_j); |
2843 | |
5389 | 2844 if (! xisnan (tmp_min)) |
4469 | 2845 break; |
2846 } | |
2847 | |
5275 | 2848 for (octave_idx_type j = idx_j+1; j < nc; j++) |
4469 | 2849 { |
2850 double tmp = elem (i, j); | |
2851 | |
5389 | 2852 if (xisnan (tmp)) |
4469 | 2853 continue; |
2854 else if (tmp < tmp_min) | |
2354 | 2855 { |
4469 | 2856 idx_j = j; |
2857 tmp_min = tmp; | |
2354 | 2858 } |
2859 } | |
2860 | |
4469 | 2861 result.elem (i) = tmp_min; |
5389 | 2862 idx_arg.elem (i) = xisnan (tmp_min) ? 0 : idx_j; |
458 | 2863 } |
2864 } | |
2865 | |
2866 return result; | |
2867 } | |
2868 | |
2869 ColumnVector | |
2870 Matrix::row_max (void) const | |
2871 { | |
5275 | 2872 Array<octave_idx_type> dummy_idx; |
4587 | 2873 return row_max (dummy_idx); |
458 | 2874 } |
2875 | |
2876 ColumnVector | |
5275 | 2877 Matrix::row_max (Array<octave_idx_type>& idx_arg) const |
458 | 2878 { |
2879 ColumnVector result; | |
2880 | |
5275 | 2881 octave_idx_type nr = rows (); |
2882 octave_idx_type nc = cols (); | |
458 | 2883 |
2884 if (nr > 0 && nc > 0) | |
2885 { | |
2886 result.resize (nr); | |
4587 | 2887 idx_arg.resize (nr); |
458 | 2888 |
5275 | 2889 for (octave_idx_type i = 0; i < nr; i++) |
458 | 2890 { |
5275 | 2891 octave_idx_type idx_j; |
4469 | 2892 |
2893 double tmp_max = octave_NaN; | |
2894 | |
2895 for (idx_j = 0; idx_j < nc; idx_j++) | |
2354 | 2896 { |
4469 | 2897 tmp_max = elem (i, idx_j); |
2898 | |
5389 | 2899 if (! xisnan (tmp_max)) |
4469 | 2900 break; |
2901 } | |
2902 | |
5275 | 2903 for (octave_idx_type j = idx_j+1; j < nc; j++) |
4469 | 2904 { |
2905 double tmp = elem (i, j); | |
2906 | |
5389 | 2907 if (xisnan (tmp)) |
4469 | 2908 continue; |
2909 else if (tmp > tmp_max) | |
2354 | 2910 { |
4469 | 2911 idx_j = j; |
2912 tmp_max = tmp; | |
2354 | 2913 } |
2914 } | |
2915 | |
4469 | 2916 result.elem (i) = tmp_max; |
5389 | 2917 idx_arg.elem (i) = xisnan (tmp_max) ? 0 : idx_j; |
458 | 2918 } |
2919 } | |
2920 | |
2921 return result; | |
2922 } | |
2923 | |
2924 RowVector | |
2925 Matrix::column_min (void) const | |
2926 { | |
5275 | 2927 Array<octave_idx_type> dummy_idx; |
4587 | 2928 return column_min (dummy_idx); |
458 | 2929 } |
2354 | 2930 |
458 | 2931 RowVector |
5275 | 2932 Matrix::column_min (Array<octave_idx_type>& idx_arg) const |
458 | 2933 { |
2934 RowVector result; | |
2935 | |
5275 | 2936 octave_idx_type nr = rows (); |
2937 octave_idx_type nc = cols (); | |
458 | 2938 |
2939 if (nr > 0 && nc > 0) | |
2940 { | |
2941 result.resize (nc); | |
4587 | 2942 idx_arg.resize (nc); |
458 | 2943 |
5275 | 2944 for (octave_idx_type j = 0; j < nc; j++) |
458 | 2945 { |
5275 | 2946 octave_idx_type idx_i; |
4469 | 2947 |
2948 double tmp_min = octave_NaN; | |
2949 | |
2950 for (idx_i = 0; idx_i < nr; idx_i++) | |
2354 | 2951 { |
4469 | 2952 tmp_min = elem (idx_i, j); |
2953 | |
5389 | 2954 if (! xisnan (tmp_min)) |
4469 | 2955 break; |
2956 } | |
2957 | |
5275 | 2958 for (octave_idx_type i = idx_i+1; i < nr; i++) |
4469 | 2959 { |
2960 double tmp = elem (i, j); | |
2961 | |
5389 | 2962 if (xisnan (tmp)) |
4469 | 2963 continue; |
2964 else if (tmp < tmp_min) | |
2354 | 2965 { |
4469 | 2966 idx_i = i; |
2967 tmp_min = tmp; | |
2354 | 2968 } |
2969 } | |
2970 | |
4469 | 2971 result.elem (j) = tmp_min; |
5389 | 2972 idx_arg.elem (j) = xisnan (tmp_min) ? 0 : idx_i; |
458 | 2973 } |
2974 } | |
2975 | |
2976 return result; | |
2977 } | |
2978 | |
2354 | 2979 RowVector |
2980 Matrix::column_max (void) const | |
2981 { | |
5275 | 2982 Array<octave_idx_type> dummy_idx; |
4587 | 2983 return column_max (dummy_idx); |
2354 | 2984 } |
458 | 2985 |
2986 RowVector | |
5275 | 2987 Matrix::column_max (Array<octave_idx_type>& idx_arg) const |
458 | 2988 { |
2989 RowVector result; | |
2990 | |
5275 | 2991 octave_idx_type nr = rows (); |
2992 octave_idx_type nc = cols (); | |
458 | 2993 |
2994 if (nr > 0 && nc > 0) | |
2995 { | |
2996 result.resize (nc); | |
4587 | 2997 idx_arg.resize (nc); |
458 | 2998 |
5275 | 2999 for (octave_idx_type j = 0; j < nc; j++) |
458 | 3000 { |
5275 | 3001 octave_idx_type idx_i; |
4469 | 3002 |
3003 double tmp_max = octave_NaN; | |
3004 | |
3005 for (idx_i = 0; idx_i < nr; idx_i++) | |
2354 | 3006 { |
4469 | 3007 tmp_max = elem (idx_i, j); |
3008 | |
5389 | 3009 if (! xisnan (tmp_max)) |
4469 | 3010 break; |
3011 } | |
3012 | |
5275 | 3013 for (octave_idx_type i = idx_i+1; i < nr; i++) |
4469 | 3014 { |
3015 double tmp = elem (i, j); | |
3016 | |
5389 | 3017 if (xisnan (tmp)) |
4469 | 3018 continue; |
3019 else if (tmp > tmp_max) | |
2354 | 3020 { |
4469 | 3021 idx_i = i; |
3022 tmp_max = tmp; | |
2354 | 3023 } |
3024 } | |
3025 | |
4469 | 3026 result.elem (j) = tmp_max; |
5389 | 3027 idx_arg.elem (j) = xisnan (tmp_max) ? 0 : idx_i; |
458 | 3028 } |
3029 } | |
3030 | |
3031 return result; | |
3032 } | |
3033 | |
3504 | 3034 std::ostream& |
3035 operator << (std::ostream& os, const Matrix& a) | |
458 | 3036 { |
5275 | 3037 for (octave_idx_type i = 0; i < a.rows (); i++) |
458 | 3038 { |
5275 | 3039 for (octave_idx_type j = 0; j < a.cols (); j++) |
4130 | 3040 { |
3041 os << " "; | |
3042 octave_write_double (os, a.elem (i, j)); | |
3043 } | |
458 | 3044 os << "\n"; |
3045 } | |
3046 return os; | |
3047 } | |
3048 | |
3504 | 3049 std::istream& |
3050 operator >> (std::istream& is, Matrix& a) | |
458 | 3051 { |
5275 | 3052 octave_idx_type nr = a.rows (); |
3053 octave_idx_type nc = a.cols (); | |
458 | 3054 |
8999
dc07bc4157b8
allow empty matrices in stream input operators
Jaroslav Hajek <highegg@gmail.com>
parents:
8956
diff
changeset
|
3055 if (nr > 0 && nc > 0) |
458 | 3056 { |
3057 double tmp; | |
5275 | 3058 for (octave_idx_type i = 0; i < nr; i++) |
3059 for (octave_idx_type j = 0; j < nc; j++) | |
458 | 3060 { |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9359
diff
changeset
|
3061 tmp = octave_read_value<double> (is); |
458 | 3062 if (is) |
3063 a.elem (i, j) = tmp; | |
3064 else | |
2795 | 3065 goto done; |
458 | 3066 } |
3067 } | |
3068 | |
2795 | 3069 done: |
3070 | |
458 | 3071 return is; |
3072 } | |
3073 | |
1819 | 3074 Matrix |
3075 Givens (double x, double y) | |
3076 { | |
3077 double cc, s, temp_r; | |
3078 | |
3887 | 3079 F77_FUNC (dlartg, DLARTG) (x, y, cc, s, temp_r); |
1819 | 3080 |
3081 Matrix g (2, 2); | |
3082 | |
3083 g.elem (0, 0) = cc; | |
3084 g.elem (1, 1) = cc; | |
3085 g.elem (0, 1) = s; | |
3086 g.elem (1, 0) = -s; | |
3087 | |
3088 return g; | |
3089 } | |
3090 | |
3091 Matrix | |
3092 Sylvester (const Matrix& a, const Matrix& b, const Matrix& c) | |
3093 { | |
3094 Matrix retval; | |
3095 | |
5775 | 3096 // FIXME -- need to check that a, b, and c are all the same |
1819 | 3097 // size. |
3098 | |
3099 // Compute Schur decompositions. | |
3100 | |
3101 SCHUR as (a, "U"); | |
3102 SCHUR bs (b, "U"); | |
3103 | |
3104 // Transform c to new coordinates. | |
3105 | |
3106 Matrix ua = as.unitary_matrix (); | |
3107 Matrix sch_a = as.schur_matrix (); | |
3108 | |
3109 Matrix ub = bs.unitary_matrix (); | |
3110 Matrix sch_b = bs.schur_matrix (); | |
3111 | |
3112 Matrix cx = ua.transpose () * c * ub; | |
3113 | |
3114 // Solve the sylvester equation, back-transform, and return the | |
3115 // solution. | |
3116 | |
5275 | 3117 octave_idx_type a_nr = a.rows (); |
3118 octave_idx_type b_nr = b.rows (); | |
1819 | 3119 |
3120 double scale; | |
5275 | 3121 octave_idx_type info; |
1819 | 3122 |
1950 | 3123 double *pa = sch_a.fortran_vec (); |
3124 double *pb = sch_b.fortran_vec (); | |
3125 double *px = cx.fortran_vec (); | |
3126 | |
4552 | 3127 F77_XFCN (dtrsyl, DTRSYL, (F77_CONST_CHAR_ARG2 ("N", 1), |
3128 F77_CONST_CHAR_ARG2 ("N", 1), | |
3129 1, a_nr, b_nr, pa, a_nr, pb, | |
3130 b_nr, px, a_nr, scale, info | |
3131 F77_CHAR_ARG_LEN (1) | |
3132 F77_CHAR_ARG_LEN (1))); | |
1950 | 3133 |
3134 | |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
3135 // FIXME -- check info? |
1819 | 3136 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
3137 retval = -ua*cx*ub.transpose (); |
1819 | 3138 |
3139 return retval; | |
3140 } | |
3141 | |
2828 | 3142 // matrix by matrix -> matrix operations |
3143 | |
6162 | 3144 /* Simple Dot Product, Matrix-Vector and Matrix-Matrix Unit tests |
3145 %!assert([1 2 3] * [ 4 ; 5 ; 6], 32, 1e-14) | |
3146 %!assert([1 2 ; 3 4 ] * [5 ; 6], [17 ; 39 ], 1e-14) | |
3147 %!assert([1 2 ; 3 4 ] * [5 6 ; 7 8], [19 22; 43 50], 1e-14) | |
3148 */ | |
3149 | |
3150 /* Test some simple identities | |
3151 %!shared M, cv, rv | |
3152 %! M = randn(10,10); | |
3153 %! cv = randn(10,1); | |
3154 %! rv = randn(1,10); | |
3155 %!assert([M*cv,M*cv],M*[cv,cv],1e-14) | |
9528
ec066ba012c8
more fixes & tests for matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9523
diff
changeset
|
3156 %!assert([M'*cv,M'*cv],M'*[cv,cv],1e-14) |
6162 | 3157 %!assert([rv*M;rv*M],[rv;rv]*M,1e-14) |
9528
ec066ba012c8
more fixes & tests for matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9523
diff
changeset
|
3158 %!assert([rv*M';rv*M'],[rv;rv]*M',1e-14) |
6162 | 3159 %!assert(2*rv*cv,[rv,rv]*[cv;cv],1e-14) |
3160 */ | |
3161 | |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3162 static const char * |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3163 get_blas_trans_arg (bool trans) |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3164 { |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3165 static char blas_notrans = 'N', blas_trans = 'T'; |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3166 return (trans) ? &blas_trans : &blas_notrans; |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3167 } |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3168 |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3169 // the general GEMM operation |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3170 |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3171 Matrix |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3172 xgemm (bool transa, const Matrix& a, bool transb, const Matrix& b) |
2828 | 3173 { |
3174 Matrix retval; | |
3175 | |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3176 octave_idx_type a_nr = transa ? a.cols () : a.rows (); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3177 octave_idx_type a_nc = transa ? a.rows () : a.cols (); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3178 |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3179 octave_idx_type b_nr = transb ? b.cols () : b.rows (); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3180 octave_idx_type b_nc = transb ? b.rows () : b.cols (); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3181 |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3182 if (a_nc != b_nr) |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3183 gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc); |
2828 | 3184 else |
3185 { | |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3186 if (a_nr == 0 || a_nc == 0 || b_nc == 0) |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
3187 retval = Matrix (a_nr, b_nc, 0.0); |
7801
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3188 else if (a.data () == b.data () && a_nr == b_nc && transa != transb) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3189 { |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3190 octave_idx_type lda = a.rows (); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3191 |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
3192 retval = Matrix (a_nr, b_nc); |
7801
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3193 double *c = retval.fortran_vec (); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3194 |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3195 const char *ctransa = get_blas_trans_arg (transa); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3196 F77_XFCN (dsyrk, DSYRK, (F77_CONST_CHAR_ARG2 ("U", 1), |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3197 F77_CONST_CHAR_ARG2 (ctransa, 1), |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3198 a_nr, a_nc, 1.0, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3199 a.data (), lda, 0.0, c, a_nr |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3200 F77_CHAR_ARG_LEN (1) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3201 F77_CHAR_ARG_LEN (1))); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3202 for (int j = 0; j < a_nr; j++) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3203 for (int i = 0; i < j; i++) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3204 retval.xelem (j,i) = retval.xelem (i,j); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3205 |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3206 } |
2828 | 3207 else |
3208 { | |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3209 octave_idx_type lda = a.rows (), tda = a.cols (); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3210 octave_idx_type ldb = b.rows (), tdb = b.cols (); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3211 |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
3212 retval = Matrix (a_nr, b_nc); |
2828 | 3213 double *c = retval.fortran_vec (); |
3214 | |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3215 if (b_nc == 1) |
5983 | 3216 { |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3217 if (a_nr == 1) |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3218 F77_FUNC (xddot, XDDOT) (a_nc, a.data (), 1, b.data (), 1, *c); |
5983 | 3219 else |
6390 | 3220 { |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3221 const char *ctransa = get_blas_trans_arg (transa); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3222 F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 (ctransa, 1), |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3223 lda, tda, 1.0, a.data (), lda, |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3224 b.data (), 1, 0.0, c, 1 |
6390 | 3225 F77_CHAR_ARG_LEN (1))); |
3226 } | |
5983 | 3227 } |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3228 else if (a_nr == 1) |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3229 { |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3230 const char *crevtransb = get_blas_trans_arg (! transb); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3231 F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 (crevtransb, 1), |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3232 ldb, tdb, 1.0, b.data (), ldb, |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3233 a.data (), 1, 0.0, c, 1 |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3234 F77_CHAR_ARG_LEN (1))); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3235 } |
5983 | 3236 else |
6390 | 3237 { |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3238 const char *ctransa = get_blas_trans_arg (transa); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3239 const char *ctransb = get_blas_trans_arg (transb); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3240 F77_XFCN (dgemm, DGEMM, (F77_CONST_CHAR_ARG2 (ctransa, 1), |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3241 F77_CONST_CHAR_ARG2 (ctransb, 1), |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3242 a_nr, b_nc, a_nc, 1.0, a.data (), |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3243 lda, b.data (), ldb, 0.0, c, a_nr |
6390 | 3244 F77_CHAR_ARG_LEN (1) |
3245 F77_CHAR_ARG_LEN (1))); | |
3246 } | |
2828 | 3247 } |
3248 } | |
3249 | |
3250 return retval; | |
3251 } | |
3252 | |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3253 Matrix |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3254 operator * (const Matrix& a, const Matrix& b) |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3255 { |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3256 return xgemm (false, a, false, b); |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3257 } |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3258 |
5775 | 3259 // FIXME -- it would be nice to share code among the min/max |
4309 | 3260 // functions below. |
3261 | |
3262 #define EMPTY_RETURN_CHECK(T) \ | |
3263 if (nr == 0 || nc == 0) \ | |
3264 return T (nr, nc); | |
3265 | |
3266 Matrix | |
3267 min (double d, const Matrix& m) | |
3268 { | |
5275 | 3269 octave_idx_type nr = m.rows (); |
3270 octave_idx_type nc = m.columns (); | |
4309 | 3271 |
3272 EMPTY_RETURN_CHECK (Matrix); | |
3273 | |
3274 Matrix result (nr, nc); | |
3275 | |
5275 | 3276 for (octave_idx_type j = 0; j < nc; j++) |
3277 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3278 { |
3279 OCTAVE_QUIT; | |
3280 result (i, j) = xmin (d, m (i, j)); | |
3281 } | |
3282 | |
3283 return result; | |
3284 } | |
3285 | |
3286 Matrix | |
3287 min (const Matrix& m, double d) | |
3288 { | |
5275 | 3289 octave_idx_type nr = m.rows (); |
3290 octave_idx_type nc = m.columns (); | |
4309 | 3291 |
3292 EMPTY_RETURN_CHECK (Matrix); | |
3293 | |
3294 Matrix result (nr, nc); | |
3295 | |
5275 | 3296 for (octave_idx_type j = 0; j < nc; j++) |
3297 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3298 { |
3299 OCTAVE_QUIT; | |
3300 result (i, j) = xmin (m (i, j), d); | |
3301 } | |
3302 | |
3303 return result; | |
3304 } | |
3305 | |
3306 Matrix | |
3307 min (const Matrix& a, const Matrix& b) | |
3308 { | |
5275 | 3309 octave_idx_type nr = a.rows (); |
3310 octave_idx_type nc = a.columns (); | |
4309 | 3311 |
3312 if (nr != b.rows () || nc != b.columns ()) | |
3313 { | |
3314 (*current_liboctave_error_handler) | |
3315 ("two-arg min expecting args of same size"); | |
3316 return Matrix (); | |
3317 } | |
3318 | |
3319 EMPTY_RETURN_CHECK (Matrix); | |
3320 | |
3321 Matrix result (nr, nc); | |
3322 | |
5275 | 3323 for (octave_idx_type j = 0; j < nc; j++) |
3324 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3325 { |
3326 OCTAVE_QUIT; | |
3327 result (i, j) = xmin (a (i, j), b (i, j)); | |
3328 } | |
3329 | |
3330 return result; | |
3331 } | |
3332 | |
3333 Matrix | |
3334 max (double d, const Matrix& m) | |
3335 { | |
5275 | 3336 octave_idx_type nr = m.rows (); |
3337 octave_idx_type nc = m.columns (); | |
4309 | 3338 |
3339 EMPTY_RETURN_CHECK (Matrix); | |
3340 | |
3341 Matrix result (nr, nc); | |
3342 | |
5275 | 3343 for (octave_idx_type j = 0; j < nc; j++) |
3344 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3345 { |
3346 OCTAVE_QUIT; | |
3347 result (i, j) = xmax (d, m (i, j)); | |
3348 } | |
3349 | |
3350 return result; | |
3351 } | |
3352 | |
3353 Matrix | |
3354 max (const Matrix& m, double d) | |
3355 { | |
5275 | 3356 octave_idx_type nr = m.rows (); |
3357 octave_idx_type nc = m.columns (); | |
4309 | 3358 |
3359 EMPTY_RETURN_CHECK (Matrix); | |
3360 | |
3361 Matrix result (nr, nc); | |
3362 | |
5275 | 3363 for (octave_idx_type j = 0; j < nc; j++) |
3364 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3365 { |
3366 OCTAVE_QUIT; | |
3367 result (i, j) = xmax (m (i, j), d); | |
3368 } | |
3369 | |
3370 return result; | |
3371 } | |
3372 | |
3373 Matrix | |
3374 max (const Matrix& a, const Matrix& b) | |
3375 { | |
5275 | 3376 octave_idx_type nr = a.rows (); |
3377 octave_idx_type nc = a.columns (); | |
4309 | 3378 |
3379 if (nr != b.rows () || nc != b.columns ()) | |
3380 { | |
3381 (*current_liboctave_error_handler) | |
3382 ("two-arg max expecting args of same size"); | |
3383 return Matrix (); | |
3384 } | |
3385 | |
3386 EMPTY_RETURN_CHECK (Matrix); | |
3387 | |
3388 Matrix result (nr, nc); | |
3389 | |
5275 | 3390 for (octave_idx_type j = 0; j < nc; j++) |
3391 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3392 { |
3393 OCTAVE_QUIT; | |
3394 result (i, j) = xmax (a (i, j), b (i, j)); | |
3395 } | |
3396 | |
3397 return result; | |
3398 } | |
3399 | |
9653
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3400 Matrix linspace (const ColumnVector& x1, |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3401 const ColumnVector& x2, |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3402 octave_idx_type n) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3403 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3404 { |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3405 if (n < 1) n = 1; |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3406 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3407 octave_idx_type m = x1.length (); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3408 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3409 if (x2.length () != m) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3410 (*current_liboctave_error_handler) ("linspace: vectors must be of equal length"); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3411 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3412 NoAlias<Matrix> retval; |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3413 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3414 retval.clear (m, n); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3415 for (octave_idx_type i = 0; i < m; i++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3416 retval(i, 0) = x1(i); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3417 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3418 // The last column is not needed while using delta. |
9658
3429c956de6f
extend linspace & fix up liboctave rewrite
Jaroslav Hajek <highegg@gmail.com>
parents:
9653
diff
changeset
|
3419 double *delta = &retval(0, n-1); |
9653
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3420 for (octave_idx_type i = 0; i < m; i++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3421 delta[i] = (x2(i) - x1(i)) / (n - 1); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3422 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3423 for (octave_idx_type j = 1; j < n-1; j++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3424 for (octave_idx_type i = 0; i < m; i++) |
9658
3429c956de6f
extend linspace & fix up liboctave rewrite
Jaroslav Hajek <highegg@gmail.com>
parents:
9653
diff
changeset
|
3425 retval(i, j) = x1(i) + j*delta[i]; |
9653
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3426 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3427 for (octave_idx_type i = 0; i < m; i++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3428 retval(i, n-1) = x2(i); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3429 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3430 return retval; |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3431 } |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
3432 |
9578
7dafdb8b062f
refactor comparison ops implementations
Jaroslav Hajek <highegg@gmail.com>
parents:
9553
diff
changeset
|
3433 MS_CMP_OPS (Matrix, double) |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
3434 MS_BOOL_OPS (Matrix, double) |
2870 | 3435 |
9578
7dafdb8b062f
refactor comparison ops implementations
Jaroslav Hajek <highegg@gmail.com>
parents:
9553
diff
changeset
|
3436 SM_CMP_OPS (double, Matrix) |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
3437 SM_BOOL_OPS (double, Matrix) |
2870 | 3438 |
9578
7dafdb8b062f
refactor comparison ops implementations
Jaroslav Hajek <highegg@gmail.com>
parents:
9553
diff
changeset
|
3439 MM_CMP_OPS (Matrix, Matrix) |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
3440 MM_BOOL_OPS (Matrix, Matrix) |
2870 | 3441 |
458 | 3442 /* |
3443 ;;; Local Variables: *** | |
3444 ;;; mode: C++ *** | |
3445 ;;; End: *** | |
3446 */ |