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