Mercurial > hg > octave-lyh
annotate liboctave/CMatrix.cc @ 9658:3429c956de6f
extend linspace & fix up liboctave rewrite
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Sat, 19 Sep 2009 22:17:12 +0200 |
parents | e087d7c77ff9 |
children | afcf852256d2 |
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, |
1855 bool calc_cond) const | |
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'; | |
1931 char trans = 'N'; | |
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, |
1956 bool calc_cond) const | |
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'; | |
2032 char trans = 'N'; | |
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, |
5785 | 2263 bool singular_fallback) const |
2264 { | |
2265 ComplexMatrix tmp (b); | |
7788 | 2266 return solve (typ, tmp, info, rcon, sing_handler, singular_fallback); |
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, |
2296 bool singular_fallback) const | |
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) | |
7788 | 2306 retval = utsolve (mattype, b, info, rcon, sing_handler, false); |
5785 | 2307 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
7788 | 2308 retval = ltsolve (mattype, b, info, rcon, sing_handler, false); |
5785 | 2309 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) |
7788 | 2310 retval = fsolve (mattype, b, info, rcon, sing_handler, true); |
5785 | 2311 else if (typ != MatrixType::Rectangular) |
2312 { | |
2313 (*current_liboctave_error_handler) ("unknown matrix type"); | |
2314 return ComplexMatrix (); | |
2315 } | |
2316 | |
2317 // Rectangular or one of the above solvers flags a singular matrix | |
2318 if (singular_fallback && mattype.type () == MatrixType::Rectangular) | |
2319 { | |
2320 octave_idx_type rank; | |
7788 | 2321 retval = lssolve (b, info, rank, rcon); |
5785 | 2322 } |
2323 | |
2324 return retval; | |
2325 } | |
2326 | |
2327 ComplexColumnVector | |
2328 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b) const | |
2329 { | |
2330 octave_idx_type info; | |
7788 | 2331 double rcon; |
2332 return solve (typ, ComplexColumnVector (b), info, rcon, 0); | |
5785 | 2333 } |
2334 | |
2335 ComplexColumnVector | |
2336 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, | |
2337 octave_idx_type& info) const | |
2338 { | |
7788 | 2339 double rcon; |
2340 return solve (typ, ComplexColumnVector (b), info, rcon, 0); | |
5785 | 2341 } |
2342 | |
2343 ComplexColumnVector | |
2344 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, | |
7788 | 2345 octave_idx_type& info, double& rcon) const |
5785 | 2346 { |
7788 | 2347 return solve (typ, ComplexColumnVector (b), info, rcon, 0); |
5785 | 2348 } |
2349 | |
2350 ComplexColumnVector | |
2351 ComplexMatrix::solve (MatrixType &typ, const ColumnVector& b, | |
7788 | 2352 octave_idx_type& info, double& rcon, |
5785 | 2353 solve_singularity_handler sing_handler) const |
2354 { | |
7788 | 2355 return solve (typ, ComplexColumnVector (b), info, rcon, sing_handler); |
5785 | 2356 } |
2357 | |
2358 ComplexColumnVector | |
2359 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b) const | |
2360 { | |
2361 octave_idx_type info; | |
7788 | 2362 double rcon; |
2363 return solve (typ, b, info, rcon, 0); | |
5785 | 2364 } |
2365 | |
2366 ComplexColumnVector | |
2367 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
2368 octave_idx_type& info) const | |
2369 { | |
7788 | 2370 double rcon; |
2371 return solve (typ, b, info, rcon, 0); | |
5785 | 2372 } |
2373 | |
2374 ComplexColumnVector | |
2375 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
7788 | 2376 octave_idx_type& info, double& rcon) const |
5785 | 2377 { |
7788 | 2378 return solve (typ, b, info, rcon, 0); |
5785 | 2379 } |
2380 | |
2381 ComplexColumnVector | |
2382 ComplexMatrix::solve (MatrixType &typ, const ComplexColumnVector& b, | |
7788 | 2383 octave_idx_type& info, double& rcon, |
5785 | 2384 solve_singularity_handler sing_handler) const |
2385 { | |
2386 | |
2387 ComplexMatrix tmp (b); | |
7788 | 2388 return solve (typ, tmp, info, rcon, sing_handler).column(static_cast<octave_idx_type> (0)); |
5785 | 2389 } |
2390 | |
2391 ComplexMatrix | |
458 | 2392 ComplexMatrix::solve (const Matrix& b) const |
2393 { | |
5275 | 2394 octave_idx_type info; |
7788 | 2395 double rcon; |
2396 return solve (b, info, rcon, 0); | |
458 | 2397 } |
2398 | |
2399 ComplexMatrix | |
5275 | 2400 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info) const |
458 | 2401 { |
7788 | 2402 double rcon; |
2403 return solve (b, info, rcon, 0); | |
458 | 2404 } |
2405 | |
2406 ComplexMatrix | |
7788 | 2407 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcon) const |
458 | 2408 { |
7788 | 2409 return solve (b, info, rcon, 0); |
3480 | 2410 } |
2411 | |
2412 ComplexMatrix | |
7788 | 2413 ComplexMatrix::solve (const Matrix& b, octave_idx_type& info, double& rcon, |
3480 | 2414 solve_singularity_handler sing_handler) const |
2415 { | |
458 | 2416 ComplexMatrix tmp (b); |
7788 | 2417 return solve (tmp, info, rcon, sing_handler); |
458 | 2418 } |
2419 | |
2420 ComplexMatrix | |
2421 ComplexMatrix::solve (const ComplexMatrix& b) const | |
2422 { | |
5275 | 2423 octave_idx_type info; |
7788 | 2424 double rcon; |
2425 return solve (b, info, rcon, 0); | |
458 | 2426 } |
2427 | |
2428 ComplexMatrix | |
5275 | 2429 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info) const |
458 | 2430 { |
7788 | 2431 double rcon; |
2432 return solve (b, info, rcon, 0); | |
458 | 2433 } |
3480 | 2434 |
458 | 2435 ComplexMatrix |
7788 | 2436 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon) const |
458 | 2437 { |
7788 | 2438 return solve (b, info, rcon, 0); |
3480 | 2439 } |
2440 | |
2441 ComplexMatrix | |
7788 | 2442 ComplexMatrix::solve (const ComplexMatrix& b, octave_idx_type& info, double& rcon, |
3480 | 2443 solve_singularity_handler sing_handler) const |
2444 { | |
5785 | 2445 MatrixType mattype (*this); |
7788 | 2446 return solve (mattype, b, info, rcon, sing_handler); |
458 | 2447 } |
2448 | |
2449 ComplexColumnVector | |
3585 | 2450 ComplexMatrix::solve (const ColumnVector& b) const |
2451 { | |
5275 | 2452 octave_idx_type info; |
7788 | 2453 double rcon; |
2454 return solve (ComplexColumnVector (b), info, rcon, 0); | |
3585 | 2455 } |
2456 | |
2457 ComplexColumnVector | |
5275 | 2458 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info) const |
3585 | 2459 { |
7788 | 2460 double rcon; |
2461 return solve (ComplexColumnVector (b), info, rcon, 0); | |
3585 | 2462 } |
2463 | |
2464 ComplexColumnVector | |
5785 | 2465 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, |
7788 | 2466 double& rcon) const |
3585 | 2467 { |
7788 | 2468 return solve (ComplexColumnVector (b), info, rcon, 0); |
3585 | 2469 } |
2470 | |
2471 ComplexColumnVector | |
5785 | 2472 ComplexMatrix::solve (const ColumnVector& b, octave_idx_type& info, |
7788 | 2473 double& rcon, |
3585 | 2474 solve_singularity_handler sing_handler) const |
2475 { | |
7788 | 2476 return solve (ComplexColumnVector (b), info, rcon, sing_handler); |
3585 | 2477 } |
2478 | |
2479 ComplexColumnVector | |
458 | 2480 ComplexMatrix::solve (const ComplexColumnVector& b) const |
2481 { | |
5275 | 2482 octave_idx_type info; |
7788 | 2483 double rcon; |
2484 return solve (b, info, rcon, 0); | |
458 | 2485 } |
2486 | |
2487 ComplexColumnVector | |
5275 | 2488 ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info) const |
458 | 2489 { |
7788 | 2490 double rcon; |
2491 return solve (b, info, rcon, 0); | |
458 | 2492 } |
2493 | |
2494 ComplexColumnVector | |
5275 | 2495 ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, |
7788 | 2496 double& rcon) const |
458 | 2497 { |
7788 | 2498 return solve (b, info, rcon, 0); |
3480 | 2499 } |
2500 | |
2501 ComplexColumnVector | |
5275 | 2502 ComplexMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, |
7788 | 2503 double& rcon, |
3480 | 2504 solve_singularity_handler sing_handler) const |
2505 { | |
5785 | 2506 MatrixType mattype (*this); |
7788 | 2507 return solve (mattype, b, info, rcon, sing_handler); |
458 | 2508 } |
2509 | |
2510 ComplexMatrix | |
3585 | 2511 ComplexMatrix::lssolve (const Matrix& b) const |
2512 { | |
5275 | 2513 octave_idx_type info; |
2514 octave_idx_type rank; | |
7788 | 2515 double rcon; |
2516 return lssolve (ComplexMatrix (b), info, rank, rcon); | |
3585 | 2517 } |
2518 | |
2519 ComplexMatrix | |
5275 | 2520 ComplexMatrix::lssolve (const Matrix& b, octave_idx_type& info) const |
3585 | 2521 { |
5275 | 2522 octave_idx_type rank; |
7788 | 2523 double rcon; |
2524 return lssolve (ComplexMatrix (b), info, rank, rcon); | |
3585 | 2525 } |
2526 | |
2527 ComplexMatrix | |
7076 | 2528 ComplexMatrix::lssolve (const Matrix& b, octave_idx_type& info, |
2529 octave_idx_type& rank) const | |
3585 | 2530 { |
7788 | 2531 double rcon; |
2532 return lssolve (ComplexMatrix (b), info, rank, rcon); | |
7076 | 2533 } |
2534 | |
2535 ComplexMatrix | |
2536 ComplexMatrix::lssolve (const Matrix& b, octave_idx_type& info, | |
7788 | 2537 octave_idx_type& rank, double& rcon) const |
7076 | 2538 { |
7788 | 2539 return lssolve (ComplexMatrix (b), info, rank, rcon); |
3585 | 2540 } |
2541 | |
2542 ComplexMatrix | |
458 | 2543 ComplexMatrix::lssolve (const ComplexMatrix& b) const |
2544 { | |
5275 | 2545 octave_idx_type info; |
2546 octave_idx_type rank; | |
7788 | 2547 double rcon; |
2548 return lssolve (b, info, rank, rcon); | |
458 | 2549 } |
2550 | |
2551 ComplexMatrix | |
5275 | 2552 ComplexMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info) const |
458 | 2553 { |
5275 | 2554 octave_idx_type rank; |
7788 | 2555 double rcon; |
2556 return lssolve (b, info, rank, rcon); | |
458 | 2557 } |
2558 | |
2559 ComplexMatrix | |
7076 | 2560 ComplexMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, |
2561 octave_idx_type& rank) const | |
2562 { | |
7788 | 2563 double rcon; |
2564 return lssolve (b, info, rank, rcon); | |
7076 | 2565 } |
2566 | |
2567 ComplexMatrix | |
2568 ComplexMatrix::lssolve (const ComplexMatrix& b, octave_idx_type& info, | |
7788 | 2569 octave_idx_type& rank, double& rcon) const |
458 | 2570 { |
1948 | 2571 ComplexMatrix retval; |
2572 | |
5275 | 2573 octave_idx_type nrhs = b.cols (); |
2574 | |
2575 octave_idx_type m = rows (); | |
2576 octave_idx_type n = cols (); | |
458 | 2577 |
6924 | 2578 if (m != b.rows ()) |
1948 | 2579 (*current_liboctave_error_handler) |
2580 ("matrix dimension mismatch solution of linear equations"); | |
6924 | 2581 else if (m== 0 || n == 0 || b.cols () == 0) |
2582 retval = ComplexMatrix (n, b.cols (), Complex (0.0, 0.0)); | |
1948 | 2583 else |
458 | 2584 { |
7072 | 2585 volatile octave_idx_type minmn = (m < n ? m : n); |
2586 octave_idx_type maxmn = m > n ? m : n; | |
7788 | 2587 rcon = -1.0; |
7072 | 2588 |
2589 if (m != n) | |
2590 { | |
2591 retval = ComplexMatrix (maxmn, nrhs); | |
2592 | |
2593 for (octave_idx_type j = 0; j < nrhs; j++) | |
2594 for (octave_idx_type i = 0; i < m; i++) | |
2595 retval.elem (i, j) = b.elem (i, j); | |
2596 } | |
2597 else | |
2598 retval = b; | |
2599 | |
1948 | 2600 ComplexMatrix atmp = *this; |
2601 Complex *tmp_data = atmp.fortran_vec (); | |
2602 | |
7072 | 2603 Complex *pretval = retval.fortran_vec (); |
2604 Array<double> s (minmn); | |
7071 | 2605 double *ps = s.fortran_vec (); |
2563 | 2606 |
7072 | 2607 // Ask ZGELSD what the dimension of WORK should be. |
5275 | 2608 octave_idx_type lwork = -1; |
3752 | 2609 |
2610 Array<Complex> work (1); | |
7079 | 2611 |
7477 | 2612 octave_idx_type smlsiz; |
2613 F77_FUNC (xilaenv, XILAENV) (9, F77_CONST_CHAR_ARG2 ("ZGELSD", 6), | |
2614 F77_CONST_CHAR_ARG2 (" ", 1), | |
7478 | 2615 0, 0, 0, 0, smlsiz |
7477 | 2616 F77_CHAR_ARG_LEN (6) |
7478 | 2617 F77_CHAR_ARG_LEN (1)); |
7079 | 2618 |
7486
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2619 octave_idx_type mnthr; |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2620 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
|
2621 F77_CONST_CHAR_ARG2 (" ", 1), |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2622 m, n, nrhs, -1, mnthr |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2623 F77_CHAR_ARG_LEN (6) |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2624 F77_CHAR_ARG_LEN (1)); |
6a6d2abe51ff
more xGELSD workspace fixes
John W. Eaton <jwe@octave.org>
parents:
7482
diff
changeset
|
2625 |
7079 | 2626 // We compute the size of rwork and iwork because ZGELSD in |
2627 // older versions of LAPACK does not return them on a query | |
2628 // call. | |
7124 | 2629 double dminmn = static_cast<double> (minmn); |
2630 double dsmlsizp1 = static_cast<double> (smlsiz+1); | |
7079 | 2631 #if defined (HAVE_LOG2) |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2632 double tmp = log2 (dminmn / dsmlsizp1); |
7079 | 2633 #else |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2634 double tmp = log (dminmn / dsmlsizp1) / log (2.0); |
7079 | 2635 #endif |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2636 octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; |
7079 | 2637 if (nlvl < 0) |
2638 nlvl = 0; | |
2639 | |
2640 octave_idx_type lrwork = minmn*(10 + 2*smlsiz + 8*nlvl) | |
2641 + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1); | |
2642 if (lrwork < 1) | |
2643 lrwork = 1; | |
2644 Array<double> rwork (lrwork); | |
2645 double *prwork = rwork.fortran_vec (); | |
2646 | |
2647 octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn; | |
2648 if (liwork < 1) | |
2649 liwork = 1; | |
2650 Array<octave_idx_type> iwork (liwork); | |
2651 octave_idx_type* piwork = iwork.fortran_vec (); | |
7072 | 2652 |
2653 F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn, | |
7788 | 2654 ps, rcon, rank, work.fortran_vec (), |
7079 | 2655 lwork, prwork, piwork, info)); |
1948 | 2656 |
7476 | 2657 // 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
|
2658 // 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
|
2659 // should provide sufficient workspace for ZGELSD to operate |
7476 | 2660 // efficiently. |
7488
6470f946a425
another small xGELSD workspace fix
John W. Eaton <jwe@octave.org>
parents:
7486
diff
changeset
|
2661 if (n >= mnthr) |
7476 | 2662 { |
2663 octave_idx_type addend = m; | |
2664 | |
2665 if (2*m-4 > addend) | |
2666 addend = 2*m-4; | |
2667 | |
2668 if (nrhs > addend) | |
2669 addend = nrhs; | |
2670 | |
2671 if (n-3*m > addend) | |
2672 addend = n-3*m; | |
2673 | |
2674 const octave_idx_type lworkaround = 4*m + m*m + addend; | |
2675 | |
2676 if (std::real (work(0)) < lworkaround) | |
2677 work(0) = lworkaround; | |
2678 } | |
7532
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2679 else if (m >= n) |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2680 { |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2681 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
|
2682 |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2683 if (std::real (work(0)) < lworkaround) |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2684 work(0) = lworkaround; |
493bb0de3199
avoid another xGELSD workspace query bug
John W. Eaton <jwe@octave.org>
parents:
7503
diff
changeset
|
2685 } |
7476 | 2686 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2687 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
|
2688 work.resize (lwork); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2689 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2690 F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval, |
7788 | 2691 maxmn, ps, rcon, rank, |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2692 work.fortran_vec (), lwork, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2693 prwork, piwork, info)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2694 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2695 if (rank < minmn) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2696 (*current_liboctave_warning_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2697 ("zgelsd: rank deficient %dx%d matrix, rank = %d, tol = %e", |
7788 | 2698 m, n, rank, rcon); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2699 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2700 if (s.elem (0) == 0.0) |
7788 | 2701 rcon = 0.0; |
1948 | 2702 else |
7788 | 2703 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
|
2704 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2705 retval.resize (n, nrhs); |
458 | 2706 } |
2707 | |
2708 return retval; | |
2709 } | |
2710 | |
2711 ComplexColumnVector | |
3585 | 2712 ComplexMatrix::lssolve (const ColumnVector& b) const |
2713 { | |
5275 | 2714 octave_idx_type info; |
2715 octave_idx_type rank; | |
7788 | 2716 double rcon; |
2717 return lssolve (ComplexColumnVector (b), info, rank, rcon); | |
3585 | 2718 } |
2719 | |
2720 ComplexColumnVector | |
5275 | 2721 ComplexMatrix::lssolve (const ColumnVector& b, octave_idx_type& info) const |
3585 | 2722 { |
5275 | 2723 octave_idx_type rank; |
7788 | 2724 double rcon; |
2725 return lssolve (ComplexColumnVector (b), info, rank, rcon); | |
3585 | 2726 } |
2727 | |
2728 ComplexColumnVector | |
7076 | 2729 ComplexMatrix::lssolve (const ColumnVector& b, octave_idx_type& info, |
2730 octave_idx_type& rank) const | |
3585 | 2731 { |
7788 | 2732 double rcon; |
2733 return lssolve (ComplexColumnVector (b), info, rank, rcon); | |
7076 | 2734 } |
2735 | |
2736 ComplexColumnVector | |
2737 ComplexMatrix::lssolve (const ColumnVector& b, octave_idx_type& info, | |
7788 | 2738 octave_idx_type& rank, double& rcon) const |
7076 | 2739 { |
7788 | 2740 return lssolve (ComplexColumnVector (b), info, rank, rcon); |
3585 | 2741 } |
2742 | |
2743 ComplexColumnVector | |
458 | 2744 ComplexMatrix::lssolve (const ComplexColumnVector& b) const |
2745 { | |
5275 | 2746 octave_idx_type info; |
2747 octave_idx_type rank; | |
7788 | 2748 double rcon; |
2749 return lssolve (b, info, rank, rcon); | |
458 | 2750 } |
2751 | |
2752 ComplexColumnVector | |
5275 | 2753 ComplexMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info) const |
458 | 2754 { |
5275 | 2755 octave_idx_type rank; |
7788 | 2756 double rcon; |
2757 return lssolve (b, info, rank, rcon); | |
458 | 2758 } |
2759 | |
2760 ComplexColumnVector | |
5275 | 2761 ComplexMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, |
2762 octave_idx_type& rank) const | |
458 | 2763 { |
7788 | 2764 double rcon; |
2765 return lssolve (b, info, rank, rcon); | |
7076 | 2766 |
2767 } | |
2768 | |
2769 ComplexColumnVector | |
2770 ComplexMatrix::lssolve (const ComplexColumnVector& b, octave_idx_type& info, | |
7788 | 2771 octave_idx_type& rank, double& rcon) const |
7076 | 2772 { |
1948 | 2773 ComplexColumnVector retval; |
2774 | |
5275 | 2775 octave_idx_type nrhs = 1; |
2776 | |
2777 octave_idx_type m = rows (); | |
2778 octave_idx_type n = cols (); | |
458 | 2779 |
6924 | 2780 if (m != b.length ()) |
1948 | 2781 (*current_liboctave_error_handler) |
6924 | 2782 ("matrix dimension mismatch solution of linear equations"); |
2783 else if (m == 0 || n == 0 || b.cols () == 0) | |
2784 retval = ComplexColumnVector (n, Complex (0.0, 0.0)); | |
1948 | 2785 else |
458 | 2786 { |
7072 | 2787 volatile octave_idx_type minmn = (m < n ? m : n); |
2788 octave_idx_type maxmn = m > n ? m : n; | |
7788 | 2789 rcon = -1.0; |
7072 | 2790 |
2791 if (m != n) | |
2792 { | |
2793 retval = ComplexColumnVector (maxmn); | |
2794 | |
2795 for (octave_idx_type i = 0; i < m; i++) | |
2796 retval.elem (i) = b.elem (i); | |
2797 } | |
2798 else | |
2799 retval = b; | |
2800 | |
1948 | 2801 ComplexMatrix atmp = *this; |
2802 Complex *tmp_data = atmp.fortran_vec (); | |
2803 | |
7072 | 2804 Complex *pretval = retval.fortran_vec (); |
2805 Array<double> s (minmn); | |
7071 | 2806 double *ps = s.fortran_vec (); |
1948 | 2807 |
7072 | 2808 // Ask ZGELSD what the dimension of WORK should be. |
5275 | 2809 octave_idx_type lwork = -1; |
3752 | 2810 |
2811 Array<Complex> work (1); | |
7079 | 2812 |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2813 octave_idx_type smlsiz; |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2814 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
|
2815 F77_CONST_CHAR_ARG2 (" ", 1), |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2816 0, 0, 0, 0, smlsiz |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2817 F77_CHAR_ARG_LEN (6) |
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2818 F77_CHAR_ARG_LEN (1)); |
7079 | 2819 |
2820 // We compute the size of rwork and iwork because ZGELSD in | |
2821 // older versions of LAPACK does not return them on a query | |
2822 // call. | |
7124 | 2823 double dminmn = static_cast<double> (minmn); |
2824 double dsmlsizp1 = static_cast<double> (smlsiz+1); | |
7079 | 2825 #if defined (HAVE_LOG2) |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2826 double tmp = log2 (dminmn / dsmlsizp1); |
7079 | 2827 #else |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2828 double tmp = log (dminmn / dsmlsizp1) / log (2.0); |
7079 | 2829 #endif |
7544
f9983d2761df
more xGELSD workspace fixes
Jaroslav Hajek <highegg@gmail.com>
parents:
7532
diff
changeset
|
2830 octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; |
7079 | 2831 if (nlvl < 0) |
2832 nlvl = 0; | |
2833 | |
2834 octave_idx_type lrwork = minmn*(10 + 2*smlsiz + 8*nlvl) | |
2835 + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1); | |
2836 if (lrwork < 1) | |
2837 lrwork = 1; | |
2838 Array<double> rwork (lrwork); | |
2839 double *prwork = rwork.fortran_vec (); | |
2840 | |
2841 octave_idx_type liwork = 3 * minmn * nlvl + 11 * minmn; | |
2842 if (liwork < 1) | |
2843 liwork = 1; | |
2844 Array<octave_idx_type> iwork (liwork); | |
2845 octave_idx_type* piwork = iwork.fortran_vec (); | |
7072 | 2846 |
2847 F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval, maxmn, | |
7788 | 2848 ps, rcon, rank, work.fortran_vec (), |
7079 | 2849 lwork, prwork, piwork, info)); |
1948 | 2850 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2851 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
|
2852 work.resize (lwork); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2853 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
|
2854 iwork.resize (iwork(0)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2855 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2856 F77_XFCN (zgelsd, ZGELSD, (m, n, nrhs, tmp_data, m, pretval, |
7788 | 2857 maxmn, ps, rcon, rank, |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2858 work.fortran_vec (), lwork, |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2859 prwork, piwork, info)); |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2860 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2861 if (rank < minmn) |
1948 | 2862 { |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2863 if (rank < minmn) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2864 (*current_liboctave_warning_handler) |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2865 ("zgelsd: rank deficient %dx%d matrix, rank = %d, tol = %e", |
7788 | 2866 m, n, rank, rcon); |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2867 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2868 if (s.elem (0) == 0.0) |
7788 | 2869 rcon = 0.0; |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2870 else |
7788 | 2871 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
|
2872 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
2873 retval.resize (n, nrhs); |
1948 | 2874 } |
458 | 2875 } |
2876 | |
2877 return retval; | |
2878 } | |
2879 | |
1205 | 2880 // column vector by row vector -> matrix operations |
2881 | |
2882 ComplexMatrix | |
2883 operator * (const ColumnVector& v, const ComplexRowVector& a) | |
2884 { | |
2885 ComplexColumnVector tmp (v); | |
2886 return tmp * a; | |
2887 } | |
2888 | |
2889 ComplexMatrix | |
2890 operator * (const ComplexColumnVector& a, const RowVector& b) | |
2891 { | |
2892 ComplexRowVector tmp (b); | |
2893 return a * tmp; | |
2894 } | |
2895 | |
2896 ComplexMatrix | |
2897 operator * (const ComplexColumnVector& v, const ComplexRowVector& a) | |
2898 { | |
1948 | 2899 ComplexMatrix retval; |
2900 | |
5275 | 2901 octave_idx_type len = v.length (); |
3233 | 2902 |
2903 if (len != 0) | |
1205 | 2904 { |
5275 | 2905 octave_idx_type a_len = a.length (); |
3233 | 2906 |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
2907 retval = ComplexMatrix (len, a_len); |
3233 | 2908 Complex *c = retval.fortran_vec (); |
2909 | |
4552 | 2910 F77_XFCN (zgemm, ZGEMM, (F77_CONST_CHAR_ARG2 ("N", 1), |
2911 F77_CONST_CHAR_ARG2 ("N", 1), | |
2912 len, a_len, 1, 1.0, v.data (), len, | |
2913 a.data (), 1, 0.0, c, len | |
2914 F77_CHAR_ARG_LEN (1) | |
2915 F77_CHAR_ARG_LEN (1))); | |
1205 | 2916 } |
2917 | |
1948 | 2918 return retval; |
1205 | 2919 } |
2920 | |
458 | 2921 // matrix by diagonal matrix -> matrix operations |
2922 | |
2923 ComplexMatrix& | |
2924 ComplexMatrix::operator += (const DiagMatrix& a) | |
2925 { | |
5275 | 2926 octave_idx_type nr = rows (); |
2927 octave_idx_type nc = cols (); | |
2928 | |
2929 octave_idx_type a_nr = rows (); | |
2930 octave_idx_type a_nc = cols (); | |
2384 | 2931 |
2932 if (nr != a_nr || nc != a_nc) | |
458 | 2933 { |
2384 | 2934 gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc); |
889 | 2935 return *this; |
458 | 2936 } |
2937 | |
5275 | 2938 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 2939 elem (i, i) += a.elem (i, i); |
2940 | |
2941 return *this; | |
2942 } | |
2943 | |
2944 ComplexMatrix& | |
2945 ComplexMatrix::operator -= (const DiagMatrix& a) | |
2946 { | |
5275 | 2947 octave_idx_type nr = rows (); |
2948 octave_idx_type nc = cols (); | |
2949 | |
2950 octave_idx_type a_nr = rows (); | |
2951 octave_idx_type a_nc = cols (); | |
2384 | 2952 |
2953 if (nr != a_nr || nc != a_nc) | |
458 | 2954 { |
2384 | 2955 gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc); |
889 | 2956 return *this; |
458 | 2957 } |
2958 | |
5275 | 2959 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 2960 elem (i, i) -= a.elem (i, i); |
2961 | |
2962 return *this; | |
2963 } | |
2964 | |
2965 ComplexMatrix& | |
2966 ComplexMatrix::operator += (const ComplexDiagMatrix& a) | |
2967 { | |
5275 | 2968 octave_idx_type nr = rows (); |
2969 octave_idx_type nc = cols (); | |
2970 | |
2971 octave_idx_type a_nr = rows (); | |
2972 octave_idx_type a_nc = cols (); | |
2384 | 2973 |
2974 if (nr != a_nr || nc != a_nc) | |
458 | 2975 { |
2384 | 2976 gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc); |
889 | 2977 return *this; |
458 | 2978 } |
2979 | |
5275 | 2980 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 2981 elem (i, i) += a.elem (i, i); |
2982 | |
2983 return *this; | |
2984 } | |
2985 | |
2986 ComplexMatrix& | |
2987 ComplexMatrix::operator -= (const ComplexDiagMatrix& a) | |
2988 { | |
5275 | 2989 octave_idx_type nr = rows (); |
2990 octave_idx_type nc = cols (); | |
2991 | |
2992 octave_idx_type a_nr = rows (); | |
2993 octave_idx_type a_nc = cols (); | |
2384 | 2994 |
2995 if (nr != a_nr || nc != a_nc) | |
458 | 2996 { |
2384 | 2997 gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc); |
889 | 2998 return *this; |
458 | 2999 } |
3000 | |
5275 | 3001 for (octave_idx_type i = 0; i < a.length (); i++) |
458 | 3002 elem (i, i) -= a.elem (i, i); |
3003 | |
3004 return *this; | |
3005 } | |
3006 | |
3007 // matrix by matrix -> matrix operations | |
3008 | |
3009 ComplexMatrix& | |
3010 ComplexMatrix::operator += (const Matrix& a) | |
3011 { | |
5275 | 3012 octave_idx_type nr = rows (); |
3013 octave_idx_type nc = cols (); | |
3014 | |
3015 octave_idx_type a_nr = a.rows (); | |
3016 octave_idx_type a_nc = a.cols (); | |
2384 | 3017 |
3018 if (nr != a_nr || nc != a_nc) | |
458 | 3019 { |
2384 | 3020 gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc); |
458 | 3021 return *this; |
3022 } | |
3023 | |
3024 if (nr == 0 || nc == 0) | |
3025 return *this; | |
3026 | |
3027 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
3028 | |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
3029 mx_inline_add2 (length (), d, a.data ()); |
458 | 3030 return *this; |
3031 } | |
3032 | |
3033 ComplexMatrix& | |
3034 ComplexMatrix::operator -= (const Matrix& a) | |
3035 { | |
5275 | 3036 octave_idx_type nr = rows (); |
3037 octave_idx_type nc = cols (); | |
3038 | |
3039 octave_idx_type a_nr = a.rows (); | |
3040 octave_idx_type a_nc = a.cols (); | |
2384 | 3041 |
3042 if (nr != a_nr || nc != a_nc) | |
458 | 3043 { |
2384 | 3044 gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc); |
458 | 3045 return *this; |
3046 } | |
3047 | |
3048 if (nr == 0 || nc == 0) | |
3049 return *this; | |
3050 | |
3051 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
3052 | |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
3053 mx_inline_sub2 (length (), d, a.data ()); |
458 | 3054 return *this; |
3055 } | |
3056 | |
3057 // unary operations | |
3058 | |
2964 | 3059 boolMatrix |
458 | 3060 ComplexMatrix::operator ! (void) const |
3061 { | |
9553
0c72d9284087
further bool ops tweaks
Jaroslav Hajek <highegg@gmail.com>
parents:
9551
diff
changeset
|
3062 return do_mx_unary_op<boolMatrix, ComplexMatrix> (*this, mx_inline_not); |
458 | 3063 } |
3064 | |
3065 // other operations | |
3066 | |
2676 | 3067 Matrix |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3068 ComplexMatrix::map (dmapper fcn) const |
458 | 3069 { |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3070 return MArray2<Complex>::map<double> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3071 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3072 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3073 ComplexMatrix |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3074 ComplexMatrix::map (cmapper fcn) const |
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 return MArray2<Complex>::map<Complex> (func_ptr (fcn)); |
3248 | 3077 } |
3078 | |
3079 boolMatrix | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3080 ComplexMatrix::map (bmapper fcn) const |
3248 | 3081 { |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7488
diff
changeset
|
3082 return MArray2<Complex>::map<bool> (func_ptr (fcn)); |
458 | 3083 } |
3084 | |
2384 | 3085 bool |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3086 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
|
3087 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3088 octave_idx_type nr = rows (); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3089 octave_idx_type nc = cols (); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3090 |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3091 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
|
3092 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
|
3093 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3094 Complex val = elem (i, j); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3095 if (xisnan (val)) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3096 return true; |
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 |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3099 return false; |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7803
diff
changeset
|
3100 } |
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 bool |
2384 | 3103 ComplexMatrix::any_element_is_inf_or_nan (void) const |
3104 { | |
5275 | 3105 octave_idx_type nr = rows (); |
3106 octave_idx_type nc = cols (); | |
3107 | |
3108 for (octave_idx_type j = 0; j < nc; j++) | |
3109 for (octave_idx_type i = 0; i < nr; i++) | |
2384 | 3110 { |
3111 Complex val = elem (i, j); | |
3112 if (xisinf (val) || xisnan (val)) | |
3113 return true; | |
3114 } | |
3115 | |
3116 return false; | |
3117 } | |
3118 | |
2408 | 3119 // Return true if no elements have imaginary components. |
3120 | |
3121 bool | |
3122 ComplexMatrix::all_elements_are_real (void) const | |
3123 { | |
5275 | 3124 octave_idx_type nr = rows (); |
3125 octave_idx_type nc = cols (); | |
3126 | |
3127 for (octave_idx_type j = 0; j < nc; j++) | |
4349 | 3128 { |
5275 | 3129 for (octave_idx_type i = 0; i < nr; i++) |
4349 | 3130 { |
5315 | 3131 double ip = std::imag (elem (i, j)); |
4349 | 3132 |
3133 if (ip != 0.0 || lo_ieee_signbit (ip)) | |
3134 return false; | |
3135 } | |
3136 } | |
2408 | 3137 |
3138 return true; | |
3139 } | |
3140 | |
1968 | 3141 // Return nonzero if any element of CM has a non-integer real or |
3142 // imaginary part. Also extract the largest and smallest (real or | |
3143 // imaginary) values and return them in MAX_VAL and MIN_VAL. | |
3144 | |
2384 | 3145 bool |
1968 | 3146 ComplexMatrix::all_integers (double& max_val, double& min_val) const |
3147 { | |
5275 | 3148 octave_idx_type nr = rows (); |
3149 octave_idx_type nc = cols (); | |
1968 | 3150 |
3151 if (nr > 0 && nc > 0) | |
3152 { | |
3153 Complex val = elem (0, 0); | |
3154 | |
5315 | 3155 double r_val = std::real (val); |
3156 double i_val = std::imag (val); | |
1968 | 3157 |
3158 max_val = r_val; | |
3159 min_val = r_val; | |
3160 | |
3161 if (i_val > max_val) | |
3162 max_val = i_val; | |
3163 | |
3164 if (i_val < max_val) | |
3165 min_val = i_val; | |
3166 } | |
3167 else | |
2384 | 3168 return false; |
1968 | 3169 |
5275 | 3170 for (octave_idx_type j = 0; j < nc; j++) |
3171 for (octave_idx_type i = 0; i < nr; i++) | |
1968 | 3172 { |
3173 Complex val = elem (i, j); | |
3174 | |
5315 | 3175 double r_val = std::real (val); |
3176 double i_val = std::imag (val); | |
1968 | 3177 |
3178 if (r_val > max_val) | |
3179 max_val = r_val; | |
3180 | |
3181 if (i_val > max_val) | |
3182 max_val = i_val; | |
3183 | |
3184 if (r_val < min_val) | |
3185 min_val = r_val; | |
3186 | |
3187 if (i_val < min_val) | |
3188 min_val = i_val; | |
3189 | |
3190 if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val) | |
2384 | 3191 return false; |
1968 | 3192 } |
2384 | 3193 |
3194 return true; | |
1968 | 3195 } |
3196 | |
2384 | 3197 bool |
1968 | 3198 ComplexMatrix::too_large_for_float (void) const |
3199 { | |
5275 | 3200 octave_idx_type nr = rows (); |
3201 octave_idx_type nc = cols (); | |
3202 | |
3203 for (octave_idx_type j = 0; j < nc; j++) | |
3204 for (octave_idx_type i = 0; i < nr; i++) | |
1968 | 3205 { |
3206 Complex val = elem (i, j); | |
3207 | |
5315 | 3208 double r_val = std::real (val); |
3209 double i_val = std::imag (val); | |
1968 | 3210 |
5389 | 3211 if ((! (xisnan (r_val) || xisinf (r_val)) |
5387 | 3212 && fabs (r_val) > FLT_MAX) |
5389 | 3213 || (! (xisnan (i_val) || xisinf (i_val)) |
5387 | 3214 && fabs (i_val) > FLT_MAX)) |
2384 | 3215 return true; |
1968 | 3216 } |
3217 | |
2384 | 3218 return false; |
1968 | 3219 } |
3220 | |
5775 | 3221 // FIXME Do these really belong here? Maybe they should be |
4015 | 3222 // in a base class? |
3223 | |
2832 | 3224 boolMatrix |
4015 | 3225 ComplexMatrix::all (int dim) const |
458 | 3226 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3227 return do_mx_red_op<boolMatrix, Complex> (*this, dim, mx_inline_all); |
458 | 3228 } |
3229 | |
2832 | 3230 boolMatrix |
4015 | 3231 ComplexMatrix::any (int dim) const |
458 | 3232 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3233 return do_mx_red_op<boolMatrix, Complex> (*this, dim, mx_inline_any); |
458 | 3234 } |
3235 | |
3236 ComplexMatrix | |
3723 | 3237 ComplexMatrix::cumprod (int dim) const |
458 | 3238 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3239 return do_mx_cum_op<ComplexMatrix, Complex> (*this, dim, mx_inline_cumprod); |
458 | 3240 } |
3241 | |
3242 ComplexMatrix | |
3723 | 3243 ComplexMatrix::cumsum (int dim) const |
458 | 3244 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3245 return do_mx_cum_op<ComplexMatrix, Complex> (*this, dim, mx_inline_cumsum); |
458 | 3246 } |
3247 | |
3248 ComplexMatrix | |
3723 | 3249 ComplexMatrix::prod (int dim) const |
458 | 3250 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3251 return do_mx_red_op<ComplexMatrix, Complex> (*this, dim, mx_inline_prod); |
458 | 3252 } |
3253 | |
3254 ComplexMatrix | |
3723 | 3255 ComplexMatrix::sum (int dim) const |
458 | 3256 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3257 return do_mx_red_op<ComplexMatrix, Complex> (*this, dim, mx_inline_sum); |
458 | 3258 } |
3259 | |
3260 ComplexMatrix | |
3723 | 3261 ComplexMatrix::sumsq (int dim) const |
458 | 3262 { |
9227
8145f2255276
use explicit template qualifs to please Intel C++ and MSVC++
Jaroslav Hajek <highegg@gmail.com>
parents:
8999
diff
changeset
|
3263 return do_mx_red_op<Matrix, Complex> (*this, dim, mx_inline_sumsq); |
458 | 3264 } |
3265 | |
4329 | 3266 Matrix ComplexMatrix::abs (void) const |
3267 { | |
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
|
3268 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
|
3269 rows (), cols ()); |
4329 | 3270 } |
3271 | |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7544
diff
changeset
|
3272 ComplexMatrix |
5275 | 3273 ComplexMatrix::diag (octave_idx_type k) const |
458 | 3274 { |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7544
diff
changeset
|
3275 return MArray2<Complex>::diag (k); |
458 | 3276 } |
3277 | |
2354 | 3278 bool |
5275 | 3279 ComplexMatrix::row_is_real_only (octave_idx_type i) const |
2354 | 3280 { |
3281 bool retval = true; | |
3282 | |
5275 | 3283 octave_idx_type nc = columns (); |
3284 | |
3285 for (octave_idx_type j = 0; j < nc; j++) | |
2354 | 3286 { |
5315 | 3287 if (std::imag (elem (i, j)) != 0.0) |
2354 | 3288 { |
3289 retval = false; | |
3290 break; | |
3291 } | |
3292 } | |
3293 | |
3294 return retval; | |
3295 } | |
3296 | |
3297 bool | |
5275 | 3298 ComplexMatrix::column_is_real_only (octave_idx_type j) const |
2354 | 3299 { |
3300 bool retval = true; | |
3301 | |
5275 | 3302 octave_idx_type nr = rows (); |
3303 | |
3304 for (octave_idx_type i = 0; i < nr; i++) | |
2354 | 3305 { |
5315 | 3306 if (std::imag (elem (i, j)) != 0.0) |
2354 | 3307 { |
3308 retval = false; | |
3309 break; | |
3310 } | |
3311 } | |
3312 | |
3313 return retval; | |
3314 } | |
891 | 3315 |
458 | 3316 ComplexColumnVector |
3317 ComplexMatrix::row_min (void) const | |
3318 { | |
5275 | 3319 Array<octave_idx_type> dummy_idx; |
4587 | 3320 return row_min (dummy_idx); |
458 | 3321 } |
3322 | |
3323 ComplexColumnVector | |
5275 | 3324 ComplexMatrix::row_min (Array<octave_idx_type>& idx_arg) const |
458 | 3325 { |
3326 ComplexColumnVector result; | |
3327 | |
5275 | 3328 octave_idx_type nr = rows (); |
3329 octave_idx_type nc = cols (); | |
458 | 3330 |
3331 if (nr > 0 && nc > 0) | |
3332 { | |
3333 result.resize (nr); | |
4587 | 3334 idx_arg.resize (nr); |
458 | 3335 |
5275 | 3336 for (octave_idx_type i = 0; i < nr; i++) |
458 | 3337 { |
2354 | 3338 bool real_only = row_is_real_only (i); |
3339 | |
5275 | 3340 octave_idx_type idx_j; |
4469 | 3341 |
3342 Complex tmp_min; | |
3343 | |
3344 double abs_min = octave_NaN; | |
3345 | |
3346 for (idx_j = 0; idx_j < nc; idx_j++) | |
3347 { | |
3348 tmp_min = elem (i, idx_j); | |
3349 | |
5389 | 3350 if (! xisnan (tmp_min)) |
4469 | 3351 { |
5315 | 3352 abs_min = real_only ? std::real (tmp_min) : std::abs (tmp_min); |
4469 | 3353 break; |
3354 } | |
3355 } | |
3356 | |
5275 | 3357 for (octave_idx_type j = idx_j+1; j < nc; j++) |
4469 | 3358 { |
3359 Complex tmp = elem (i, j); | |
3360 | |
5389 | 3361 if (xisnan (tmp)) |
4469 | 3362 continue; |
3363 | |
5315 | 3364 double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp); |
4469 | 3365 |
3366 if (abs_tmp < abs_min) | |
3367 { | |
3368 idx_j = j; | |
3369 tmp_min = tmp; | |
3370 abs_min = abs_tmp; | |
3371 } | |
3372 } | |
3373 | |
5389 | 3374 if (xisnan (tmp_min)) |
4469 | 3375 { |
3376 result.elem (i) = Complex_NaN_result; | |
4587 | 3377 idx_arg.elem (i) = 0; |
4469 | 3378 } |
891 | 3379 else |
3380 { | |
4469 | 3381 result.elem (i) = tmp_min; |
4587 | 3382 idx_arg.elem (i) = idx_j; |
891 | 3383 } |
458 | 3384 } |
3385 } | |
3386 | |
3387 return result; | |
3388 } | |
3389 | |
3390 ComplexColumnVector | |
3391 ComplexMatrix::row_max (void) const | |
3392 { | |
5275 | 3393 Array<octave_idx_type> dummy_idx; |
4587 | 3394 return row_max (dummy_idx); |
458 | 3395 } |
3396 | |
3397 ComplexColumnVector | |
5275 | 3398 ComplexMatrix::row_max (Array<octave_idx_type>& idx_arg) const |
458 | 3399 { |
3400 ComplexColumnVector result; | |
3401 | |
5275 | 3402 octave_idx_type nr = rows (); |
3403 octave_idx_type nc = cols (); | |
458 | 3404 |
3405 if (nr > 0 && nc > 0) | |
3406 { | |
3407 result.resize (nr); | |
4587 | 3408 idx_arg.resize (nr); |
458 | 3409 |
5275 | 3410 for (octave_idx_type i = 0; i < nr; i++) |
458 | 3411 { |
2354 | 3412 bool real_only = row_is_real_only (i); |
3413 | |
5275 | 3414 octave_idx_type idx_j; |
4469 | 3415 |
3416 Complex tmp_max; | |
3417 | |
3418 double abs_max = octave_NaN; | |
3419 | |
3420 for (idx_j = 0; idx_j < nc; idx_j++) | |
3421 { | |
3422 tmp_max = elem (i, idx_j); | |
3423 | |
5389 | 3424 if (! xisnan (tmp_max)) |
4469 | 3425 { |
5315 | 3426 abs_max = real_only ? std::real (tmp_max) : std::abs (tmp_max); |
4469 | 3427 break; |
3428 } | |
3429 } | |
3430 | |
5275 | 3431 for (octave_idx_type j = idx_j+1; j < nc; j++) |
4469 | 3432 { |
3433 Complex tmp = elem (i, j); | |
3434 | |
5389 | 3435 if (xisnan (tmp)) |
4469 | 3436 continue; |
3437 | |
5315 | 3438 double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp); |
4469 | 3439 |
3440 if (abs_tmp > abs_max) | |
3441 { | |
3442 idx_j = j; | |
3443 tmp_max = tmp; | |
3444 abs_max = abs_tmp; | |
3445 } | |
3446 } | |
3447 | |
5389 | 3448 if (xisnan (tmp_max)) |
4469 | 3449 { |
3450 result.elem (i) = Complex_NaN_result; | |
4587 | 3451 idx_arg.elem (i) = 0; |
4469 | 3452 } |
891 | 3453 else |
3454 { | |
4469 | 3455 result.elem (i) = tmp_max; |
4587 | 3456 idx_arg.elem (i) = idx_j; |
891 | 3457 } |
458 | 3458 } |
3459 } | |
3460 | |
3461 return result; | |
3462 } | |
3463 | |
3464 ComplexRowVector | |
3465 ComplexMatrix::column_min (void) const | |
3466 { | |
5275 | 3467 Array<octave_idx_type> dummy_idx; |
4587 | 3468 return column_min (dummy_idx); |
458 | 3469 } |
3470 | |
3471 ComplexRowVector | |
5275 | 3472 ComplexMatrix::column_min (Array<octave_idx_type>& idx_arg) const |
458 | 3473 { |
3474 ComplexRowVector result; | |
3475 | |
5275 | 3476 octave_idx_type nr = rows (); |
3477 octave_idx_type nc = cols (); | |
458 | 3478 |
3479 if (nr > 0 && nc > 0) | |
3480 { | |
3481 result.resize (nc); | |
4587 | 3482 idx_arg.resize (nc); |
458 | 3483 |
5275 | 3484 for (octave_idx_type j = 0; j < nc; j++) |
458 | 3485 { |
2354 | 3486 bool real_only = column_is_real_only (j); |
3487 | |
5275 | 3488 octave_idx_type idx_i; |
4469 | 3489 |
3490 Complex tmp_min; | |
3491 | |
3492 double abs_min = octave_NaN; | |
3493 | |
3494 for (idx_i = 0; idx_i < nr; idx_i++) | |
3495 { | |
3496 tmp_min = elem (idx_i, j); | |
3497 | |
5389 | 3498 if (! xisnan (tmp_min)) |
4469 | 3499 { |
5315 | 3500 abs_min = real_only ? std::real (tmp_min) : std::abs (tmp_min); |
4469 | 3501 break; |
3502 } | |
3503 } | |
3504 | |
5275 | 3505 for (octave_idx_type i = idx_i+1; i < nr; i++) |
4469 | 3506 { |
3507 Complex tmp = elem (i, j); | |
3508 | |
5389 | 3509 if (xisnan (tmp)) |
4469 | 3510 continue; |
3511 | |
5315 | 3512 double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp); |
4469 | 3513 |
3514 if (abs_tmp < abs_min) | |
3515 { | |
3516 idx_i = i; | |
3517 tmp_min = tmp; | |
3518 abs_min = abs_tmp; | |
3519 } | |
3520 } | |
3521 | |
5389 | 3522 if (xisnan (tmp_min)) |
4469 | 3523 { |
3524 result.elem (j) = Complex_NaN_result; | |
4587 | 3525 idx_arg.elem (j) = 0; |
4469 | 3526 } |
891 | 3527 else |
3528 { | |
4469 | 3529 result.elem (j) = tmp_min; |
4587 | 3530 idx_arg.elem (j) = idx_i; |
891 | 3531 } |
458 | 3532 } |
3533 } | |
3534 | |
3535 return result; | |
3536 } | |
3537 | |
3538 ComplexRowVector | |
3539 ComplexMatrix::column_max (void) const | |
3540 { | |
5275 | 3541 Array<octave_idx_type> dummy_idx; |
4587 | 3542 return column_max (dummy_idx); |
458 | 3543 } |
3544 | |
3545 ComplexRowVector | |
5275 | 3546 ComplexMatrix::column_max (Array<octave_idx_type>& idx_arg) const |
458 | 3547 { |
3548 ComplexRowVector result; | |
3549 | |
5275 | 3550 octave_idx_type nr = rows (); |
3551 octave_idx_type nc = cols (); | |
458 | 3552 |
3553 if (nr > 0 && nc > 0) | |
3554 { | |
3555 result.resize (nc); | |
4587 | 3556 idx_arg.resize (nc); |
458 | 3557 |
5275 | 3558 for (octave_idx_type j = 0; j < nc; j++) |
458 | 3559 { |
2354 | 3560 bool real_only = column_is_real_only (j); |
3561 | |
5275 | 3562 octave_idx_type idx_i; |
4469 | 3563 |
3564 Complex tmp_max; | |
3565 | |
3566 double abs_max = octave_NaN; | |
3567 | |
3568 for (idx_i = 0; idx_i < nr; idx_i++) | |
3569 { | |
3570 tmp_max = elem (idx_i, j); | |
3571 | |
5389 | 3572 if (! xisnan (tmp_max)) |
4469 | 3573 { |
5315 | 3574 abs_max = real_only ? std::real (tmp_max) : std::abs (tmp_max); |
4469 | 3575 break; |
3576 } | |
3577 } | |
3578 | |
5275 | 3579 for (octave_idx_type i = idx_i+1; i < nr; i++) |
4469 | 3580 { |
3581 Complex tmp = elem (i, j); | |
3582 | |
5389 | 3583 if (xisnan (tmp)) |
4469 | 3584 continue; |
3585 | |
5315 | 3586 double abs_tmp = real_only ? std::real (tmp) : std::abs (tmp); |
4469 | 3587 |
3588 if (abs_tmp > abs_max) | |
3589 { | |
3590 idx_i = i; | |
3591 tmp_max = tmp; | |
3592 abs_max = abs_tmp; | |
3593 } | |
3594 } | |
3595 | |
5389 | 3596 if (xisnan (tmp_max)) |
4469 | 3597 { |
3598 result.elem (j) = Complex_NaN_result; | |
4587 | 3599 idx_arg.elem (j) = 0; |
4469 | 3600 } |
891 | 3601 else |
3602 { | |
4469 | 3603 result.elem (j) = tmp_max; |
4587 | 3604 idx_arg.elem (j) = idx_i; |
891 | 3605 } |
458 | 3606 } |
3607 } | |
3608 | |
3609 return result; | |
3610 } | |
3611 | |
3612 // i/o | |
3613 | |
3504 | 3614 std::ostream& |
3615 operator << (std::ostream& os, const ComplexMatrix& a) | |
458 | 3616 { |
5275 | 3617 for (octave_idx_type i = 0; i < a.rows (); i++) |
458 | 3618 { |
5275 | 3619 for (octave_idx_type j = 0; j < a.cols (); j++) |
4130 | 3620 { |
3621 os << " "; | |
3622 octave_write_complex (os, a.elem (i, j)); | |
3623 } | |
458 | 3624 os << "\n"; |
3625 } | |
3626 return os; | |
3627 } | |
3628 | |
3504 | 3629 std::istream& |
3630 operator >> (std::istream& is, ComplexMatrix& a) | |
458 | 3631 { |
5275 | 3632 octave_idx_type nr = a.rows (); |
3633 octave_idx_type nc = a.cols (); | |
458 | 3634 |
8999
dc07bc4157b8
allow empty matrices in stream input operators
Jaroslav Hajek <highegg@gmail.com>
parents:
8956
diff
changeset
|
3635 if (nr > 0 && nc > 0) |
458 | 3636 { |
3637 Complex tmp; | |
5275 | 3638 for (octave_idx_type i = 0; i < nr; i++) |
3639 for (octave_idx_type j = 0; j < nc; j++) | |
458 | 3640 { |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
9359
diff
changeset
|
3641 tmp = octave_read_value<Complex> (is); |
458 | 3642 if (is) |
3643 a.elem (i, j) = tmp; | |
3644 else | |
2993 | 3645 goto done; |
458 | 3646 } |
3647 } | |
3648 | |
2993 | 3649 done: |
3650 | |
458 | 3651 return is; |
3652 } | |
3653 | |
1819 | 3654 ComplexMatrix |
3655 Givens (const Complex& x, const Complex& y) | |
3656 { | |
3657 double cc; | |
3658 Complex cs, temp_r; | |
3659 | |
3887 | 3660 F77_FUNC (zlartg, ZLARTG) (x, y, cc, cs, temp_r); |
1819 | 3661 |
3662 ComplexMatrix g (2, 2); | |
3663 | |
3664 g.elem (0, 0) = cc; | |
3665 g.elem (1, 1) = cc; | |
3666 g.elem (0, 1) = cs; | |
3667 g.elem (1, 0) = -conj (cs); | |
3668 | |
3669 return g; | |
3670 } | |
3671 | |
3672 ComplexMatrix | |
3673 Sylvester (const ComplexMatrix& a, const ComplexMatrix& b, | |
3674 const ComplexMatrix& c) | |
3675 { | |
3676 ComplexMatrix retval; | |
3677 | |
5775 | 3678 // FIXME -- need to check that a, b, and c are all the same |
1819 | 3679 // size. |
3680 | |
3681 // Compute Schur decompositions | |
3682 | |
3683 ComplexSCHUR as (a, "U"); | |
3684 ComplexSCHUR bs (b, "U"); | |
3685 | |
3686 // Transform c to new coordinates. | |
3687 | |
3688 ComplexMatrix ua = as.unitary_matrix (); | |
3689 ComplexMatrix sch_a = as.schur_matrix (); | |
3690 | |
3691 ComplexMatrix ub = bs.unitary_matrix (); | |
3692 ComplexMatrix sch_b = bs.schur_matrix (); | |
3693 | |
3694 ComplexMatrix cx = ua.hermitian () * c * ub; | |
3695 | |
3696 // Solve the sylvester equation, back-transform, and return the | |
3697 // solution. | |
3698 | |
5275 | 3699 octave_idx_type a_nr = a.rows (); |
3700 octave_idx_type b_nr = b.rows (); | |
1819 | 3701 |
3702 double scale; | |
5275 | 3703 octave_idx_type info; |
1950 | 3704 |
3705 Complex *pa = sch_a.fortran_vec (); | |
3706 Complex *pb = sch_b.fortran_vec (); | |
3707 Complex *px = cx.fortran_vec (); | |
1819 | 3708 |
4552 | 3709 F77_XFCN (ztrsyl, ZTRSYL, (F77_CONST_CHAR_ARG2 ("N", 1), |
3710 F77_CONST_CHAR_ARG2 ("N", 1), | |
3711 1, a_nr, b_nr, pa, a_nr, pb, | |
3712 b_nr, px, a_nr, scale, info | |
3713 F77_CHAR_ARG_LEN (1) | |
3714 F77_CHAR_ARG_LEN (1))); | |
1950 | 3715 |
7482
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
3716 // FIXME -- check info? |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
3717 |
29980c6b8604
don't check f77_exception_encountered
John W. Eaton <jwe@octave.org>
parents:
7478
diff
changeset
|
3718 retval = -ua * cx * ub.hermitian (); |
1819 | 3719 |
3720 return retval; | |
3721 } | |
3722 | |
2828 | 3723 ComplexMatrix |
3724 operator * (const ComplexMatrix& m, const Matrix& a) | |
3725 { | |
3726 ComplexMatrix tmp (a); | |
3727 return m * tmp; | |
3728 } | |
3729 | |
3730 ComplexMatrix | |
3731 operator * (const Matrix& m, const ComplexMatrix& a) | |
3732 { | |
3733 ComplexMatrix tmp (m); | |
3734 return tmp * a; | |
3735 } | |
3736 | |
6162 | 3737 /* Simple Dot Product, Matrix-Vector and Matrix-Matrix Unit tests |
3738 %!assert([1+i 2+i 3+i] * [ 4+i ; 5+i ; 6+i], 29+21i, 1e-14) | |
3739 %!assert([1+i 2+i ; 3+i 4+i ] * [5+i ; 6+i], [15 + 14i ; 37 + 18i], 1e-14) | |
3740 %!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
|
3741 %!assert([1 i]*[i 0]', -i); |
6162 | 3742 */ |
3743 | |
3744 /* Test some simple identities | |
3745 %!shared M, cv, rv | |
3746 %! M = randn(10,10)+i*rand(10,10); | |
3747 %! cv = randn(10,1)+i*rand(10,1); | |
3748 %! rv = randn(1,10)+i*rand(1,10); | |
3749 %!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
|
3750 %!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
|
3751 %!assert([M'*cv,M'*cv],M'*[cv,cv],1e-14) |
6162 | 3752 %!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
|
3753 %!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
|
3754 %!assert([rv*M';rv*M'],[rv;rv]*M',1e-14) |
6162 | 3755 %!assert(2*rv*cv,[rv,rv]*[cv;cv],1e-14) |
3756 */ | |
3757 | |
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
|
3758 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
|
3759 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
|
3760 { |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3761 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
|
3762 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
|
3763 } |
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 // 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
|
3766 |
2828 | 3767 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
|
3768 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
|
3769 bool transb, bool conjb, const ComplexMatrix& b) |
2828 | 3770 { |
3771 ComplexMatrix retval; | |
3772 | |
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
|
3773 // 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
|
3774 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
|
3775 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
|
3776 |
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 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
|
3778 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
|
3779 |
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 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
|
3781 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
|
3782 |
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 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
|
3784 gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc); |
2828 | 3785 else |
3786 { | |
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
|
3787 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
|
3788 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
|
3789 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
|
3790 { |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3791 octave_idx_type lda = a.rows (); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3792 |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
3793 retval = ComplexMatrix (a_nr, b_nc); |
7801
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3794 Complex *c = retval.fortran_vec (); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3795 |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3796 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
|
3797 if (conja || conjb) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3798 { |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3799 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
|
3800 F77_CONST_CHAR_ARG2 (ctransa, 1), |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3801 a_nr, a_nc, 1.0, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3802 a.data (), lda, 0.0, c, a_nr |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3803 F77_CHAR_ARG_LEN (1) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3804 F77_CHAR_ARG_LEN (1))); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3805 for (int j = 0; j < a_nr; j++) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3806 for (int i = 0; i < j; i++) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3807 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
|
3808 } |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3809 else |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3810 { |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3811 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
|
3812 F77_CONST_CHAR_ARG2 (ctransa, 1), |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3813 a_nr, a_nc, 1.0, |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3814 a.data (), lda, 0.0, c, a_nr |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3815 F77_CHAR_ARG_LEN (1) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3816 F77_CHAR_ARG_LEN (1))); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3817 for (int j = 0; j < a_nr; j++) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3818 for (int i = 0; i < j; i++) |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3819 retval.xelem (j,i) = retval.xelem (i,j); |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3820 |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3821 } |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3822 |
776791438957
map symmetric cases to xHERK, xSYRK
Jaroslav Hajek <highegg@gmail.com>
parents:
7800
diff
changeset
|
3823 } |
2828 | 3824 else |
3825 { | |
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
|
3826 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
|
3827 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
|
3828 |
9359
be6867ba8104
avoid useless zero initialization when doing matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9227
diff
changeset
|
3829 retval = ComplexMatrix (a_nr, b_nc); |
2828 | 3830 Complex *c = retval.fortran_vec (); |
3831 | |
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
|
3832 if (b_nc == 1 && a_nr == 1) |
5983 | 3833 { |
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
|
3834 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
|
3835 { |
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 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
|
3837 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
|
3838 } |
9526
f3ebc728ffd7
fix typos in complex xgemm
Jaroslav Hajek <highegg@gmail.com>
parents:
9523
diff
changeset
|
3839 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
|
3840 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
|
3841 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
|
3842 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
|
3843 } |
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 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
|
3845 { |
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 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
|
3847 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
|
3848 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
|
3849 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
|
3850 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
|
3851 } |
9528
ec066ba012c8
more fixes & tests for matrix multiply
Jaroslav Hajek <highegg@gmail.com>
parents:
9526
diff
changeset
|
3852 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
|
3853 { |
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 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
|
3855 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
|
3856 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
|
3857 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
|
3858 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
|
3859 } |
5983 | 3860 else |
6390 | 3861 { |
7800
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3862 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
|
3863 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
|
3864 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
|
3865 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
|
3866 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
|
3867 lda, b.data (), ldb, 0.0, c, a_nr |
6390 | 3868 F77_CHAR_ARG_LEN (1) |
3869 F77_CHAR_ARG_LEN (1))); | |
3870 } | |
2828 | 3871 } |
3872 } | |
3873 | |
3874 return retval; | |
3875 } | |
3876 | |
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
|
3877 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
|
3878 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
|
3879 { |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3880 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
|
3881 } |
5861b95e9879
support for compound operators, implement trans_mul, mul_trans, herm_mul and mul_herm
Jaroslav Hajek <highegg@gmail.com>
parents:
7789
diff
changeset
|
3882 |
5775 | 3883 // FIXME -- it would be nice to share code among the min/max |
4309 | 3884 // functions below. |
3885 | |
3886 #define EMPTY_RETURN_CHECK(T) \ | |
3887 if (nr == 0 || nc == 0) \ | |
3888 return T (nr, nc); | |
3889 | |
3890 ComplexMatrix | |
3891 min (const Complex& c, const ComplexMatrix& m) | |
3892 { | |
5275 | 3893 octave_idx_type nr = m.rows (); |
3894 octave_idx_type nc = m.columns (); | |
4309 | 3895 |
3896 EMPTY_RETURN_CHECK (ComplexMatrix); | |
3897 | |
3898 ComplexMatrix result (nr, nc); | |
3899 | |
5275 | 3900 for (octave_idx_type j = 0; j < nc; j++) |
3901 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3902 { |
3903 OCTAVE_QUIT; | |
3904 result (i, j) = xmin (c, m (i, j)); | |
3905 } | |
3906 | |
3907 return result; | |
3908 } | |
3909 | |
3910 ComplexMatrix | |
3911 min (const ComplexMatrix& m, const Complex& c) | |
3912 { | |
5275 | 3913 octave_idx_type nr = m.rows (); |
3914 octave_idx_type nc = m.columns (); | |
4309 | 3915 |
3916 EMPTY_RETURN_CHECK (ComplexMatrix); | |
3917 | |
3918 ComplexMatrix result (nr, nc); | |
3919 | |
5275 | 3920 for (octave_idx_type j = 0; j < nc; j++) |
3921 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3922 { |
3923 OCTAVE_QUIT; | |
3924 result (i, j) = xmin (m (i, j), c); | |
3925 } | |
3926 | |
3927 return result; | |
3928 } | |
3929 | |
3930 ComplexMatrix | |
3931 min (const ComplexMatrix& a, const ComplexMatrix& b) | |
3932 { | |
5275 | 3933 octave_idx_type nr = a.rows (); |
3934 octave_idx_type nc = a.columns (); | |
4309 | 3935 |
3936 if (nr != b.rows () || nc != b.columns ()) | |
3937 { | |
3938 (*current_liboctave_error_handler) | |
3939 ("two-arg min expecting args of same size"); | |
3940 return ComplexMatrix (); | |
3941 } | |
3942 | |
3943 EMPTY_RETURN_CHECK (ComplexMatrix); | |
3944 | |
3945 ComplexMatrix result (nr, nc); | |
3946 | |
5275 | 3947 for (octave_idx_type j = 0; j < nc; j++) |
4309 | 3948 { |
3949 int columns_are_real_only = 1; | |
5275 | 3950 for (octave_idx_type i = 0; i < nr; i++) |
4309 | 3951 { |
3952 OCTAVE_QUIT; | |
5315 | 3953 if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0) |
4309 | 3954 { |
3955 columns_are_real_only = 0; | |
3956 break; | |
3957 } | |
3958 } | |
3959 | |
3960 if (columns_are_real_only) | |
3961 { | |
5275 | 3962 for (octave_idx_type i = 0; i < nr; i++) |
5315 | 3963 result (i, j) = xmin (std::real (a (i, j)), std::real (b (i, j))); |
4309 | 3964 } |
3965 else | |
3966 { | |
5275 | 3967 for (octave_idx_type i = 0; i < nr; i++) |
4309 | 3968 { |
3969 OCTAVE_QUIT; | |
3970 result (i, j) = xmin (a (i, j), b (i, j)); | |
3971 } | |
3972 } | |
3973 } | |
3974 | |
3975 return result; | |
3976 } | |
3977 | |
3978 ComplexMatrix | |
3979 max (const Complex& c, const ComplexMatrix& m) | |
3980 { | |
5275 | 3981 octave_idx_type nr = m.rows (); |
3982 octave_idx_type nc = m.columns (); | |
4309 | 3983 |
3984 EMPTY_RETURN_CHECK (ComplexMatrix); | |
3985 | |
3986 ComplexMatrix result (nr, nc); | |
3987 | |
5275 | 3988 for (octave_idx_type j = 0; j < nc; j++) |
3989 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 3990 { |
3991 OCTAVE_QUIT; | |
3992 result (i, j) = xmax (c, m (i, j)); | |
3993 } | |
3994 | |
3995 return result; | |
3996 } | |
3997 | |
3998 ComplexMatrix | |
3999 max (const ComplexMatrix& m, const Complex& c) | |
4000 { | |
5275 | 4001 octave_idx_type nr = m.rows (); |
4002 octave_idx_type nc = m.columns (); | |
4309 | 4003 |
4004 EMPTY_RETURN_CHECK (ComplexMatrix); | |
4005 | |
4006 ComplexMatrix result (nr, nc); | |
4007 | |
5275 | 4008 for (octave_idx_type j = 0; j < nc; j++) |
4009 for (octave_idx_type i = 0; i < nr; i++) | |
4309 | 4010 { |
4011 OCTAVE_QUIT; | |
4012 result (i, j) = xmax (m (i, j), c); | |
4013 } | |
4014 | |
4015 return result; | |
4016 } | |
4017 | |
4018 ComplexMatrix | |
4019 max (const ComplexMatrix& a, const ComplexMatrix& b) | |
4020 { | |
5275 | 4021 octave_idx_type nr = a.rows (); |
4022 octave_idx_type nc = a.columns (); | |
4309 | 4023 |
4024 if (nr != b.rows () || nc != b.columns ()) | |
4025 { | |
4026 (*current_liboctave_error_handler) | |
4027 ("two-arg max expecting args of same size"); | |
4028 return ComplexMatrix (); | |
4029 } | |
4030 | |
4031 EMPTY_RETURN_CHECK (ComplexMatrix); | |
4032 | |
4033 ComplexMatrix result (nr, nc); | |
4034 | |
5275 | 4035 for (octave_idx_type j = 0; j < nc; j++) |
4309 | 4036 { |
4037 int columns_are_real_only = 1; | |
5275 | 4038 for (octave_idx_type i = 0; i < nr; i++) |
4309 | 4039 { |
4040 OCTAVE_QUIT; | |
5315 | 4041 if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0) |
4309 | 4042 { |
4043 columns_are_real_only = 0; | |
4044 break; | |
4045 } | |
4046 } | |
4047 | |
4048 if (columns_are_real_only) | |
4049 { | |
5275 | 4050 for (octave_idx_type i = 0; i < nr; i++) |
4309 | 4051 { |
4052 OCTAVE_QUIT; | |
5315 | 4053 result (i, j) = xmax (std::real (a (i, j)), std::real (b (i, j))); |
4309 | 4054 } |
4055 } | |
4056 else | |
4057 { | |
5275 | 4058 for (octave_idx_type i = 0; i < nr; i++) |
4309 | 4059 { |
4060 OCTAVE_QUIT; | |
4061 result (i, j) = xmax (a (i, j), b (i, j)); | |
4062 } | |
4063 } | |
4064 } | |
4065 | |
4066 return result; | |
4067 } | |
4068 | |
9653
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4069 ComplexMatrix linspace (const ComplexColumnVector& x1, |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4070 const ComplexColumnVector& x2, |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4071 octave_idx_type n) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4072 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4073 { |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4074 if (n < 1) n = 1; |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4075 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4076 octave_idx_type m = x1.length (); |
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 (x2.length () != m) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4079 (*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
|
4080 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4081 NoAlias<ComplexMatrix> retval; |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4082 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4083 retval.clear (m, n); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4084 for (octave_idx_type i = 0; i < m; i++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4085 retval(i, 0) = x1(i); |
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 // 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
|
4088 Complex *delta = &retval(0, n-1); |
9653
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4089 for (octave_idx_type i = 0; i < m; i++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4090 delta[i] = (x2(i) - x1(i)) / (n - 1.0); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4091 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4092 for (octave_idx_type j = 1; j < n-1; j++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4093 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
|
4094 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
|
4095 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4096 for (octave_idx_type i = 0; i < m; i++) |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4097 retval(i, n-1) = x2(i); |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4098 |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4099 return retval; |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4100 } |
e087d7c77ff9
improve linspace in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9601
diff
changeset
|
4101 |
9578
7dafdb8b062f
refactor comparison ops implementations
Jaroslav Hajek <highegg@gmail.com>
parents:
9553
diff
changeset
|
4102 MS_CMP_OPS (ComplexMatrix, Complex) |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
4103 MS_BOOL_OPS (ComplexMatrix, Complex) |
2870 | 4104 |
9578
7dafdb8b062f
refactor comparison ops implementations
Jaroslav Hajek <highegg@gmail.com>
parents:
9553
diff
changeset
|
4105 SM_CMP_OPS (Complex, ComplexMatrix) |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
4106 SM_BOOL_OPS (Complex, ComplexMatrix) |
2870 | 4107 |
9578
7dafdb8b062f
refactor comparison ops implementations
Jaroslav Hajek <highegg@gmail.com>
parents:
9553
diff
changeset
|
4108 MM_CMP_OPS (ComplexMatrix, ComplexMatrix) |
9550
3d6a9aea2aea
refactor binary & bool ops in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9528
diff
changeset
|
4109 MM_BOOL_OPS (ComplexMatrix, ComplexMatrix) |
2870 | 4110 |
458 | 4111 /* |
4112 ;;; Local Variables: *** | |
4113 ;;; mode: C++ *** | |
4114 ;;; End: *** | |
4115 */ |