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