1 | /// \ingroup newmat |
---|
2 | ///@{ |
---|
3 | |
---|
4 | /// \file newmat4.cpp |
---|
5 | /// Constructors, resize, basic utilities, SimpleIntArray. |
---|
6 | |
---|
7 | |
---|
8 | // Copyright (C) 1991,2,3,4,8,9: R B Davies |
---|
9 | |
---|
10 | //#define WANT_STREAM |
---|
11 | |
---|
12 | #include "include.h" |
---|
13 | |
---|
14 | #include "newmat.h" |
---|
15 | #include "newmatrc.h" |
---|
16 | |
---|
17 | #ifdef use_namespace |
---|
18 | namespace NEWMAT { |
---|
19 | #endif |
---|
20 | |
---|
21 | |
---|
22 | |
---|
23 | #ifdef DO_REPORT |
---|
24 | #define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; } |
---|
25 | #else |
---|
26 | #define REPORT {} |
---|
27 | #endif |
---|
28 | |
---|
29 | |
---|
30 | #define DO_SEARCH // search for LHS of = in RHS |
---|
31 | |
---|
32 | // ************************* general utilities *************************/ |
---|
33 | |
---|
34 | static int tristore(int n) // elements in triangular matrix |
---|
35 | { return (n*(n+1))/2; } |
---|
36 | |
---|
37 | |
---|
38 | // **************************** constructors ***************************/ |
---|
39 | |
---|
40 | GeneralMatrix::GeneralMatrix() |
---|
41 | { store=0; storage=0; nrows_val=0; ncols_val=0; tag_val=-1; } |
---|
42 | |
---|
43 | GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s) |
---|
44 | { |
---|
45 | REPORT |
---|
46 | storage=s.Value(); tag_val=-1; |
---|
47 | if (storage) |
---|
48 | { |
---|
49 | store = new Real [storage]; MatrixErrorNoSpace(store); |
---|
50 | MONITOR_REAL_NEW("Make (GenMatrix)",storage,store) |
---|
51 | } |
---|
52 | else store = 0; |
---|
53 | } |
---|
54 | |
---|
55 | Matrix::Matrix(int m, int n) : GeneralMatrix(m*n) |
---|
56 | { REPORT nrows_val=m; ncols_val=n; } |
---|
57 | |
---|
58 | SquareMatrix::SquareMatrix(ArrayLengthSpecifier n) |
---|
59 | : Matrix(n.Value(),n.Value()) |
---|
60 | { REPORT } |
---|
61 | |
---|
62 | SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n) |
---|
63 | : GeneralMatrix(tristore(n.Value())) |
---|
64 | { REPORT nrows_val=n.Value(); ncols_val=n.Value(); } |
---|
65 | |
---|
66 | UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n) |
---|
67 | : GeneralMatrix(tristore(n.Value())) |
---|
68 | { REPORT nrows_val=n.Value(); ncols_val=n.Value(); } |
---|
69 | |
---|
70 | LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n) |
---|
71 | : GeneralMatrix(tristore(n.Value())) |
---|
72 | { REPORT nrows_val=n.Value(); ncols_val=n.Value(); } |
---|
73 | |
---|
74 | DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m) |
---|
75 | { REPORT nrows_val=m.Value(); ncols_val=m.Value(); } |
---|
76 | |
---|
77 | Matrix::Matrix(const BaseMatrix& M) |
---|
78 | { |
---|
79 | REPORT // CheckConversion(M); |
---|
80 | // MatrixConversionCheck mcc; |
---|
81 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt); |
---|
82 | GetMatrix(gmx); |
---|
83 | } |
---|
84 | |
---|
85 | SquareMatrix::SquareMatrix(const BaseMatrix& M) : Matrix(M) |
---|
86 | { |
---|
87 | REPORT |
---|
88 | if (ncols_val != nrows_val) |
---|
89 | { |
---|
90 | Tracer tr("SquareMatrix"); |
---|
91 | Throw(NotSquareException(*this)); |
---|
92 | } |
---|
93 | } |
---|
94 | |
---|
95 | |
---|
96 | SquareMatrix::SquareMatrix(const Matrix& gm) |
---|
97 | { |
---|
98 | REPORT |
---|
99 | if (gm.ncols_val != gm.nrows_val) |
---|
100 | { |
---|
101 | Tracer tr("SquareMatrix(Matrix)"); |
---|
102 | Throw(NotSquareException(gm)); |
---|
103 | } |
---|
104 | GetMatrix(&gm); |
---|
105 | } |
---|
106 | |
---|
107 | |
---|
108 | RowVector::RowVector(const BaseMatrix& M) : Matrix(M) |
---|
109 | { |
---|
110 | REPORT |
---|
111 | if (nrows_val!=1) |
---|
112 | { |
---|
113 | Tracer tr("RowVector"); |
---|
114 | Throw(VectorException(*this)); |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M) |
---|
119 | { |
---|
120 | REPORT |
---|
121 | if (ncols_val!=1) |
---|
122 | { |
---|
123 | Tracer tr("ColumnVector"); |
---|
124 | Throw(VectorException(*this)); |
---|
125 | } |
---|
126 | } |
---|
127 | |
---|
128 | SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M) |
---|
129 | { |
---|
130 | REPORT // CheckConversion(M); |
---|
131 | // MatrixConversionCheck mcc; |
---|
132 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm); |
---|
133 | GetMatrix(gmx); |
---|
134 | } |
---|
135 | |
---|
136 | UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M) |
---|
137 | { |
---|
138 | REPORT // CheckConversion(M); |
---|
139 | // MatrixConversionCheck mcc; |
---|
140 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT); |
---|
141 | GetMatrix(gmx); |
---|
142 | } |
---|
143 | |
---|
144 | LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M) |
---|
145 | { |
---|
146 | REPORT // CheckConversion(M); |
---|
147 | // MatrixConversionCheck mcc; |
---|
148 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT); |
---|
149 | GetMatrix(gmx); |
---|
150 | } |
---|
151 | |
---|
152 | DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M) |
---|
153 | { |
---|
154 | REPORT //CheckConversion(M); |
---|
155 | // MatrixConversionCheck mcc; |
---|
156 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg); |
---|
157 | GetMatrix(gmx); |
---|
158 | } |
---|
159 | |
---|
160 | IdentityMatrix::IdentityMatrix(const BaseMatrix& M) |
---|
161 | { |
---|
162 | REPORT //CheckConversion(M); |
---|
163 | // MatrixConversionCheck mcc; |
---|
164 | GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id); |
---|
165 | GetMatrix(gmx); |
---|
166 | } |
---|
167 | |
---|
168 | GeneralMatrix::~GeneralMatrix() |
---|
169 | { |
---|
170 | if (store) |
---|
171 | { |
---|
172 | MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store) |
---|
173 | delete [] store; |
---|
174 | } |
---|
175 | } |
---|
176 | |
---|
177 | CroutMatrix::CroutMatrix(const BaseMatrix& m) |
---|
178 | { |
---|
179 | REPORT |
---|
180 | Tracer tr("CroutMatrix"); |
---|
181 | indx = 0; // in case of exception at next line |
---|
182 | GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(); |
---|
183 | if (gm->nrows_val!=gm->ncols_val) |
---|
184 | { gm->tDelete(); Throw(NotSquareException(*gm)); } |
---|
185 | if (gm->type() == MatrixType::Ct) |
---|
186 | { REPORT ((CroutMatrix*)gm)->get_aux(*this); GetMatrix(gm); } |
---|
187 | else |
---|
188 | { |
---|
189 | REPORT |
---|
190 | GeneralMatrix* gm1 = gm->Evaluate(MatrixType::Rt); |
---|
191 | GetMatrix(gm1); |
---|
192 | d=true; sing=false; |
---|
193 | indx=new int [nrows_val]; MatrixErrorNoSpace(indx); |
---|
194 | MONITOR_INT_NEW("Index (CroutMat)",nrows_val,indx) |
---|
195 | ludcmp(); |
---|
196 | } |
---|
197 | } |
---|
198 | |
---|
199 | // could we use SetParameters instead of this |
---|
200 | void CroutMatrix::get_aux(CroutMatrix& X) |
---|
201 | { |
---|
202 | X.d = d; X.sing = sing; |
---|
203 | if (tag_val == 0 || tag_val == 1) // reuse the array |
---|
204 | { REPORT X.indx = indx; indx = 0; d = true; sing = true; return; } |
---|
205 | else if (nrows_val == 0) |
---|
206 | { REPORT indx = 0; d = true; sing = true; return; } |
---|
207 | else // copy the array |
---|
208 | { |
---|
209 | REPORT |
---|
210 | Tracer tr("CroutMatrix::get_aux"); |
---|
211 | int *ix = new int [nrows_val]; MatrixErrorNoSpace(ix); |
---|
212 | MONITOR_INT_NEW("Index (CM::get_aux)", nrows_val, ix) |
---|
213 | int n = nrows_val; int* i = ix; int* j = indx; |
---|
214 | while(n--) *i++ = *j++; |
---|
215 | X.indx = ix; |
---|
216 | } |
---|
217 | } |
---|
218 | |
---|
219 | CroutMatrix::CroutMatrix(const CroutMatrix& gm) : GeneralMatrix() |
---|
220 | { |
---|
221 | REPORT |
---|
222 | Tracer tr("CroutMatrix(const CroutMatrix&)"); |
---|
223 | ((CroutMatrix&)gm).get_aux(*this); |
---|
224 | GetMatrix(&gm); |
---|
225 | } |
---|
226 | |
---|
227 | CroutMatrix::~CroutMatrix() |
---|
228 | { |
---|
229 | MONITOR_INT_DELETE("Index (CroutMat)",nrows_val,indx) |
---|
230 | delete [] indx; |
---|
231 | } |
---|
232 | |
---|
233 | //ReturnMatrix::ReturnMatrix(GeneralMatrix& gmx) |
---|
234 | //{ |
---|
235 | // REPORT |
---|
236 | // gm = gmx.Image(); gm->ReleaseAndDelete(); |
---|
237 | //} |
---|
238 | |
---|
239 | |
---|
240 | GeneralMatrix::operator ReturnMatrix() const |
---|
241 | { |
---|
242 | REPORT |
---|
243 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); |
---|
244 | return ReturnMatrix(gm); |
---|
245 | } |
---|
246 | |
---|
247 | |
---|
248 | |
---|
249 | ReturnMatrix GeneralMatrix::for_return() const |
---|
250 | { |
---|
251 | REPORT |
---|
252 | GeneralMatrix* gm = Image(); gm->ReleaseAndDelete(); |
---|
253 | return ReturnMatrix(gm); |
---|
254 | } |
---|
255 | |
---|
256 | // ************ Constructors for use with NR in C++ interface *********** |
---|
257 | |
---|
258 | #ifdef SETUP_C_SUBSCRIPTS |
---|
259 | |
---|
260 | Matrix::Matrix(Real a, int m, int n) : GeneralMatrix(m * n) |
---|
261 | { REPORT nrows_val=m; ncols_val=n; operator=(a); } |
---|
262 | |
---|
263 | Matrix::Matrix(const Real* a, int m, int n) : GeneralMatrix(m * n) |
---|
264 | { REPORT nrows_val=m; ncols_val=n; *this << a; } |
---|
265 | |
---|
266 | #endif |
---|
267 | |
---|
268 | |
---|
269 | |
---|
270 | // ************************** resize matrices ***************************/ |
---|
271 | |
---|
272 | void GeneralMatrix::resize(int nr, int nc, int s) |
---|
273 | { |
---|
274 | REPORT |
---|
275 | if (store) |
---|
276 | { |
---|
277 | MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store) |
---|
278 | delete [] store; |
---|
279 | } |
---|
280 | storage=s; nrows_val=nr; ncols_val=nc; tag_val=-1; |
---|
281 | if (s) |
---|
282 | { |
---|
283 | store = new Real [storage]; MatrixErrorNoSpace(store); |
---|
284 | MONITOR_REAL_NEW("Make (ReDimensi)",storage,store) |
---|
285 | } |
---|
286 | else store = 0; |
---|
287 | } |
---|
288 | |
---|
289 | void Matrix::resize(int nr, int nc) |
---|
290 | { REPORT GeneralMatrix::resize(nr,nc,nr*nc); } |
---|
291 | |
---|
292 | void SquareMatrix::resize(int n) |
---|
293 | { REPORT GeneralMatrix::resize(n,n,n*n); } |
---|
294 | |
---|
295 | void SquareMatrix::resize(int nr, int nc) |
---|
296 | { |
---|
297 | REPORT |
---|
298 | Tracer tr("SquareMatrix::resize"); |
---|
299 | if (nc != nr) Throw(NotSquareException(*this)); |
---|
300 | GeneralMatrix::resize(nr,nc,nr*nc); |
---|
301 | } |
---|
302 | |
---|
303 | void SymmetricMatrix::resize(int nr) |
---|
304 | { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); } |
---|
305 | |
---|
306 | void UpperTriangularMatrix::resize(int nr) |
---|
307 | { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); } |
---|
308 | |
---|
309 | void LowerTriangularMatrix::resize(int nr) |
---|
310 | { REPORT GeneralMatrix::resize(nr,nr,tristore(nr)); } |
---|
311 | |
---|
312 | void DiagonalMatrix::resize(int nr) |
---|
313 | { REPORT GeneralMatrix::resize(nr,nr,nr); } |
---|
314 | |
---|
315 | void RowVector::resize(int nc) |
---|
316 | { REPORT GeneralMatrix::resize(1,nc,nc); } |
---|
317 | |
---|
318 | void ColumnVector::resize(int nr) |
---|
319 | { REPORT GeneralMatrix::resize(nr,1,nr); } |
---|
320 | |
---|
321 | void RowVector::resize(int nr, int nc) |
---|
322 | { |
---|
323 | Tracer tr("RowVector::resize"); |
---|
324 | if (nr != 1) Throw(VectorException(*this)); |
---|
325 | REPORT GeneralMatrix::resize(1,nc,nc); |
---|
326 | } |
---|
327 | |
---|
328 | void ColumnVector::resize(int nr, int nc) |
---|
329 | { |
---|
330 | Tracer tr("ColumnVector::resize"); |
---|
331 | if (nc != 1) Throw(VectorException(*this)); |
---|
332 | REPORT GeneralMatrix::resize(nr,1,nr); |
---|
333 | } |
---|
334 | |
---|
335 | void IdentityMatrix::resize(int nr) |
---|
336 | { REPORT GeneralMatrix::resize(nr,nr,1); *store = 1; } |
---|
337 | |
---|
338 | |
---|
339 | void Matrix::resize(const GeneralMatrix& A) |
---|
340 | { REPORT resize(A.Nrows(), A.Ncols()); } |
---|
341 | |
---|
342 | void SquareMatrix::resize(const GeneralMatrix& A) |
---|
343 | { |
---|
344 | REPORT |
---|
345 | int n = A.Nrows(); |
---|
346 | if (n != A.Ncols()) |
---|
347 | { |
---|
348 | Tracer tr("SquareMatrix::resize(GM)"); |
---|
349 | Throw(NotSquareException(*this)); |
---|
350 | } |
---|
351 | resize(n); |
---|
352 | } |
---|
353 | |
---|
354 | void nricMatrix::resize(const GeneralMatrix& A) |
---|
355 | { REPORT resize(A.Nrows(), A.Ncols()); } |
---|
356 | |
---|
357 | void ColumnVector::resize(const GeneralMatrix& A) |
---|
358 | { REPORT resize(A.Nrows(), A.Ncols()); } |
---|
359 | |
---|
360 | void RowVector::resize(const GeneralMatrix& A) |
---|
361 | { REPORT resize(A.Nrows(), A.Ncols()); } |
---|
362 | |
---|
363 | void SymmetricMatrix::resize(const GeneralMatrix& A) |
---|
364 | { |
---|
365 | REPORT |
---|
366 | int n = A.Nrows(); |
---|
367 | if (n != A.Ncols()) |
---|
368 | { |
---|
369 | Tracer tr("SymmetricMatrix::resize(GM)"); |
---|
370 | Throw(NotSquareException(*this)); |
---|
371 | } |
---|
372 | resize(n); |
---|
373 | } |
---|
374 | |
---|
375 | void DiagonalMatrix::resize(const GeneralMatrix& A) |
---|
376 | { |
---|
377 | REPORT |
---|
378 | int n = A.Nrows(); |
---|
379 | if (n != A.Ncols()) |
---|
380 | { |
---|
381 | Tracer tr("DiagonalMatrix::resize(GM)"); |
---|
382 | Throw(NotSquareException(*this)); |
---|
383 | } |
---|
384 | resize(n); |
---|
385 | } |
---|
386 | |
---|
387 | void UpperTriangularMatrix::resize(const GeneralMatrix& A) |
---|
388 | { |
---|
389 | REPORT |
---|
390 | int n = A.Nrows(); |
---|
391 | if (n != A.Ncols()) |
---|
392 | { |
---|
393 | Tracer tr("UpperTriangularMatrix::resize(GM)"); |
---|
394 | Throw(NotSquareException(*this)); |
---|
395 | } |
---|
396 | resize(n); |
---|
397 | } |
---|
398 | |
---|
399 | void LowerTriangularMatrix::resize(const GeneralMatrix& A) |
---|
400 | { |
---|
401 | REPORT |
---|
402 | int n = A.Nrows(); |
---|
403 | if (n != A.Ncols()) |
---|
404 | { |
---|
405 | Tracer tr("LowerTriangularMatrix::resize(GM)"); |
---|
406 | Throw(NotSquareException(*this)); |
---|
407 | } |
---|
408 | resize(n); |
---|
409 | } |
---|
410 | |
---|
411 | void IdentityMatrix::resize(const GeneralMatrix& A) |
---|
412 | { |
---|
413 | REPORT |
---|
414 | int n = A.Nrows(); |
---|
415 | if (n != A.Ncols()) |
---|
416 | { |
---|
417 | Tracer tr("IdentityMatrix::resize(GM)"); |
---|
418 | Throw(NotSquareException(*this)); |
---|
419 | } |
---|
420 | resize(n); |
---|
421 | } |
---|
422 | |
---|
423 | void GeneralMatrix::resize(const GeneralMatrix&) |
---|
424 | { |
---|
425 | REPORT |
---|
426 | Tracer tr("GeneralMatrix::resize(GM)"); |
---|
427 | Throw(NotDefinedException("resize", "this type of matrix")); |
---|
428 | } |
---|
429 | |
---|
430 | //*********************** resize_keep ******************************* |
---|
431 | |
---|
432 | void Matrix::resize_keep(int nr, int nc) |
---|
433 | { |
---|
434 | Tracer tr("Matrix::resize_keep"); |
---|
435 | if (nr == nrows_val && nc == ncols_val) { REPORT return; } |
---|
436 | |
---|
437 | if (nr <= nrows_val && nc <= ncols_val) |
---|
438 | { |
---|
439 | REPORT |
---|
440 | Matrix X = submatrix(1,nr,1,nc); |
---|
441 | swap(X); |
---|
442 | } |
---|
443 | else if (nr >= nrows_val && nc >= ncols_val) |
---|
444 | { |
---|
445 | REPORT |
---|
446 | Matrix X(nr, nc); X = 0; |
---|
447 | X.submatrix(1,nrows_val,1,ncols_val) = *this; |
---|
448 | swap(X); |
---|
449 | } |
---|
450 | else |
---|
451 | { |
---|
452 | REPORT |
---|
453 | Matrix X(nr, nc); X = 0; |
---|
454 | if (nr > nrows_val) nr = nrows_val; |
---|
455 | if (nc > ncols_val) nc = ncols_val; |
---|
456 | X.submatrix(1,nr,1,nc) = submatrix(1,nr,1,nc); |
---|
457 | swap(X); |
---|
458 | } |
---|
459 | } |
---|
460 | |
---|
461 | void SquareMatrix::resize_keep(int nr) |
---|
462 | { |
---|
463 | Tracer tr("SquareMatrix::resize_keep"); |
---|
464 | if (nr < nrows_val) |
---|
465 | { |
---|
466 | REPORT |
---|
467 | SquareMatrix X = sym_submatrix(1,nr); |
---|
468 | swap(X); |
---|
469 | } |
---|
470 | else if (nr > nrows_val) |
---|
471 | { |
---|
472 | REPORT |
---|
473 | SquareMatrix X(nr); X = 0; |
---|
474 | X.sym_submatrix(1,nrows_val) = *this; |
---|
475 | swap(X); |
---|
476 | } |
---|
477 | } |
---|
478 | |
---|
479 | void SquareMatrix::resize_keep(int nr, int nc) |
---|
480 | { |
---|
481 | Tracer tr("SquareMatrix::resize_keep 2"); |
---|
482 | REPORT |
---|
483 | if (nr != nc) Throw(NotSquareException(*this)); |
---|
484 | resize_keep(nr); |
---|
485 | } |
---|
486 | |
---|
487 | |
---|
488 | void SymmetricMatrix::resize_keep(int nr) |
---|
489 | { |
---|
490 | Tracer tr("SymmetricMatrix::resize_keep"); |
---|
491 | if (nr < nrows_val) |
---|
492 | { |
---|
493 | REPORT |
---|
494 | SymmetricMatrix X = sym_submatrix(1,nr); |
---|
495 | swap(X); |
---|
496 | } |
---|
497 | else if (nr > nrows_val) |
---|
498 | { |
---|
499 | REPORT |
---|
500 | SymmetricMatrix X(nr); X = 0; |
---|
501 | X.sym_submatrix(1,nrows_val) = *this; |
---|
502 | swap(X); |
---|
503 | } |
---|
504 | } |
---|
505 | |
---|
506 | void UpperTriangularMatrix::resize_keep(int nr) |
---|
507 | { |
---|
508 | Tracer tr("UpperTriangularMatrix::resize_keep"); |
---|
509 | if (nr < nrows_val) |
---|
510 | { |
---|
511 | REPORT |
---|
512 | UpperTriangularMatrix X = sym_submatrix(1,nr); |
---|
513 | swap(X); |
---|
514 | } |
---|
515 | else if (nr > nrows_val) |
---|
516 | { |
---|
517 | REPORT |
---|
518 | UpperTriangularMatrix X(nr); X = 0; |
---|
519 | X.sym_submatrix(1,nrows_val) = *this; |
---|
520 | swap(X); |
---|
521 | } |
---|
522 | } |
---|
523 | |
---|
524 | void LowerTriangularMatrix::resize_keep(int nr) |
---|
525 | { |
---|
526 | Tracer tr("LowerTriangularMatrix::resize_keep"); |
---|
527 | if (nr < nrows_val) |
---|
528 | { |
---|
529 | REPORT |
---|
530 | LowerTriangularMatrix X = sym_submatrix(1,nr); |
---|
531 | swap(X); |
---|
532 | } |
---|
533 | else if (nr > nrows_val) |
---|
534 | { |
---|
535 | REPORT |
---|
536 | LowerTriangularMatrix X(nr); X = 0; |
---|
537 | X.sym_submatrix(1,nrows_val) = *this; |
---|
538 | swap(X); |
---|
539 | } |
---|
540 | } |
---|
541 | |
---|
542 | void DiagonalMatrix::resize_keep(int nr) |
---|
543 | { |
---|
544 | Tracer tr("DiagonalMatrix::resize_keep"); |
---|
545 | if (nr < nrows_val) |
---|
546 | { |
---|
547 | REPORT |
---|
548 | DiagonalMatrix X = sym_submatrix(1,nr); |
---|
549 | swap(X); |
---|
550 | } |
---|
551 | else if (nr > nrows_val) |
---|
552 | { |
---|
553 | REPORT |
---|
554 | DiagonalMatrix X(nr); X = 0; |
---|
555 | X.sym_submatrix(1,nrows_val) = *this; |
---|
556 | swap(X); |
---|
557 | } |
---|
558 | } |
---|
559 | |
---|
560 | void RowVector::resize_keep(int nc) |
---|
561 | { |
---|
562 | Tracer tr("RowVector::resize_keep"); |
---|
563 | if (nc < ncols_val) |
---|
564 | { |
---|
565 | REPORT |
---|
566 | RowVector X = columns(1,nc); |
---|
567 | swap(X); |
---|
568 | } |
---|
569 | else if (nc > ncols_val) |
---|
570 | { |
---|
571 | REPORT |
---|
572 | RowVector X(nc); X = 0; |
---|
573 | X.columns(1,ncols_val) = *this; |
---|
574 | swap(X); |
---|
575 | } |
---|
576 | } |
---|
577 | |
---|
578 | void RowVector::resize_keep(int nr, int nc) |
---|
579 | { |
---|
580 | Tracer tr("RowVector::resize_keep 2"); |
---|
581 | REPORT |
---|
582 | if (nr != 1) Throw(VectorException(*this)); |
---|
583 | resize_keep(nc); |
---|
584 | } |
---|
585 | |
---|
586 | void ColumnVector::resize_keep(int nr) |
---|
587 | { |
---|
588 | Tracer tr("ColumnVector::resize_keep"); |
---|
589 | if (nr < nrows_val) |
---|
590 | { |
---|
591 | REPORT |
---|
592 | ColumnVector X = rows(1,nr); |
---|
593 | swap(X); |
---|
594 | } |
---|
595 | else if (nr > nrows_val) |
---|
596 | { |
---|
597 | REPORT |
---|
598 | ColumnVector X(nr); X = 0; |
---|
599 | X.rows(1,nrows_val) = *this; |
---|
600 | swap(X); |
---|
601 | } |
---|
602 | } |
---|
603 | |
---|
604 | void ColumnVector::resize_keep(int nr, int nc) |
---|
605 | { |
---|
606 | Tracer tr("ColumnVector::resize_keep 2"); |
---|
607 | REPORT |
---|
608 | if (nc != 1) Throw(VectorException(*this)); |
---|
609 | resize_keep(nr); |
---|
610 | } |
---|
611 | |
---|
612 | |
---|
613 | /* |
---|
614 | void GeneralMatrix::resizeForAdd(const GeneralMatrix& A, const GeneralMatrix&) |
---|
615 | { REPORT resize(A); } |
---|
616 | |
---|
617 | void GeneralMatrix::resizeForSP(const GeneralMatrix& A, const GeneralMatrix&) |
---|
618 | { REPORT resize(A); } |
---|
619 | |
---|
620 | |
---|
621 | // ************************* SameStorageType ****************************** |
---|
622 | |
---|
623 | // SameStorageType checks A and B have same storage type including bandwidth |
---|
624 | // It does not check same dimensions since we assume this is already done |
---|
625 | |
---|
626 | bool GeneralMatrix::SameStorageType(const GeneralMatrix& A) const |
---|
627 | { |
---|
628 | REPORT |
---|
629 | return type() == A.type(); |
---|
630 | } |
---|
631 | */ |
---|
632 | |
---|
633 | // ******************* manipulate types, storage **************************/ |
---|
634 | |
---|
635 | int GeneralMatrix::search(const BaseMatrix* s) const |
---|
636 | { REPORT return (s==this) ? 1 : 0; } |
---|
637 | |
---|
638 | int GenericMatrix::search(const BaseMatrix* s) const |
---|
639 | { REPORT return gm->search(s); } |
---|
640 | |
---|
641 | int MultipliedMatrix::search(const BaseMatrix* s) const |
---|
642 | { REPORT return bm1->search(s) + bm2->search(s); } |
---|
643 | |
---|
644 | int ShiftedMatrix::search(const BaseMatrix* s) const |
---|
645 | { REPORT return bm->search(s); } |
---|
646 | |
---|
647 | int NegatedMatrix::search(const BaseMatrix* s) const |
---|
648 | { REPORT return bm->search(s); } |
---|
649 | |
---|
650 | int ReturnMatrix::search(const BaseMatrix* s) const |
---|
651 | { REPORT return (s==gm) ? 1 : 0; } |
---|
652 | |
---|
653 | MatrixType Matrix::type() const { return MatrixType::Rt; } |
---|
654 | MatrixType SquareMatrix::type() const { return MatrixType::Sq; } |
---|
655 | MatrixType SymmetricMatrix::type() const { return MatrixType::Sm; } |
---|
656 | MatrixType UpperTriangularMatrix::type() const { return MatrixType::UT; } |
---|
657 | MatrixType LowerTriangularMatrix::type() const { return MatrixType::LT; } |
---|
658 | MatrixType DiagonalMatrix::type() const { return MatrixType::Dg; } |
---|
659 | MatrixType RowVector::type() const { return MatrixType::RV; } |
---|
660 | MatrixType ColumnVector::type() const { return MatrixType::CV; } |
---|
661 | MatrixType CroutMatrix::type() const { return MatrixType::Ct; } |
---|
662 | MatrixType BandMatrix::type() const { return MatrixType::BM; } |
---|
663 | MatrixType UpperBandMatrix::type() const { return MatrixType::UB; } |
---|
664 | MatrixType LowerBandMatrix::type() const { return MatrixType::LB; } |
---|
665 | MatrixType SymmetricBandMatrix::type() const { return MatrixType::SB; } |
---|
666 | |
---|
667 | MatrixType IdentityMatrix::type() const { return MatrixType::Id; } |
---|
668 | |
---|
669 | |
---|
670 | |
---|
671 | MatrixBandWidth BaseMatrix::bandwidth() const { REPORT return -1; } |
---|
672 | MatrixBandWidth DiagonalMatrix::bandwidth() const { REPORT return 0; } |
---|
673 | MatrixBandWidth IdentityMatrix::bandwidth() const { REPORT return 0; } |
---|
674 | |
---|
675 | MatrixBandWidth UpperTriangularMatrix::bandwidth() const |
---|
676 | { REPORT return MatrixBandWidth(0,-1); } |
---|
677 | |
---|
678 | MatrixBandWidth LowerTriangularMatrix::bandwidth() const |
---|
679 | { REPORT return MatrixBandWidth(-1,0); } |
---|
680 | |
---|
681 | MatrixBandWidth BandMatrix::bandwidth() const |
---|
682 | { REPORT return MatrixBandWidth(lower_val,upper_val); } |
---|
683 | |
---|
684 | MatrixBandWidth BandLUMatrix::bandwidth() const |
---|
685 | { REPORT return MatrixBandWidth(m1,m2); } |
---|
686 | |
---|
687 | MatrixBandWidth GenericMatrix::bandwidth()const |
---|
688 | { REPORT return gm->bandwidth(); } |
---|
689 | |
---|
690 | MatrixBandWidth AddedMatrix::bandwidth() const |
---|
691 | { REPORT return gm1->bandwidth() + gm2->bandwidth(); } |
---|
692 | |
---|
693 | MatrixBandWidth SPMatrix::bandwidth() const |
---|
694 | { REPORT return gm1->bandwidth().minimum(gm2->bandwidth()); } |
---|
695 | |
---|
696 | MatrixBandWidth KPMatrix::bandwidth() const |
---|
697 | { |
---|
698 | int lower, upper; |
---|
699 | MatrixBandWidth bw1 = gm1->bandwidth(), bw2 = gm2->bandwidth(); |
---|
700 | if (bw1.Lower() < 0) |
---|
701 | { |
---|
702 | if (bw2.Lower() < 0) { REPORT lower = -1; } |
---|
703 | else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); } |
---|
704 | } |
---|
705 | else |
---|
706 | { |
---|
707 | if (bw2.Lower() < 0) |
---|
708 | { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; } |
---|
709 | else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); } |
---|
710 | } |
---|
711 | if (bw1.Upper() < 0) |
---|
712 | { |
---|
713 | if (bw2.Upper() < 0) { REPORT upper = -1; } |
---|
714 | else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); } |
---|
715 | } |
---|
716 | else |
---|
717 | { |
---|
718 | if (bw2.Upper() < 0) |
---|
719 | { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; } |
---|
720 | else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); } |
---|
721 | } |
---|
722 | return MatrixBandWidth(lower, upper); |
---|
723 | } |
---|
724 | |
---|
725 | MatrixBandWidth MultipliedMatrix::bandwidth() const |
---|
726 | { REPORT return gm1->bandwidth() * gm2->bandwidth(); } |
---|
727 | |
---|
728 | MatrixBandWidth ConcatenatedMatrix::bandwidth() const { REPORT return -1; } |
---|
729 | |
---|
730 | MatrixBandWidth SolvedMatrix::bandwidth() const |
---|
731 | { |
---|
732 | if (+gm1->type() & MatrixType::Diagonal) |
---|
733 | { REPORT return gm2->bandwidth(); } |
---|
734 | else { REPORT return -1; } |
---|
735 | } |
---|
736 | |
---|
737 | MatrixBandWidth ScaledMatrix::bandwidth() const |
---|
738 | { REPORT return gm->bandwidth(); } |
---|
739 | |
---|
740 | MatrixBandWidth NegatedMatrix::bandwidth() const |
---|
741 | { REPORT return gm->bandwidth(); } |
---|
742 | |
---|
743 | MatrixBandWidth TransposedMatrix::bandwidth() const |
---|
744 | { REPORT return gm->bandwidth().t(); } |
---|
745 | |
---|
746 | MatrixBandWidth InvertedMatrix::bandwidth() const |
---|
747 | { |
---|
748 | if (+gm->type() & MatrixType::Diagonal) |
---|
749 | { REPORT return MatrixBandWidth(0,0); } |
---|
750 | else { REPORT return -1; } |
---|
751 | } |
---|
752 | |
---|
753 | MatrixBandWidth RowedMatrix::bandwidth() const { REPORT return -1; } |
---|
754 | MatrixBandWidth ColedMatrix::bandwidth() const { REPORT return -1; } |
---|
755 | MatrixBandWidth DiagedMatrix::bandwidth() const { REPORT return 0; } |
---|
756 | MatrixBandWidth MatedMatrix::bandwidth() const { REPORT return -1; } |
---|
757 | MatrixBandWidth ReturnMatrix::bandwidth() const |
---|
758 | { REPORT return gm->bandwidth(); } |
---|
759 | |
---|
760 | MatrixBandWidth GetSubMatrix::bandwidth() const |
---|
761 | { |
---|
762 | |
---|
763 | if (row_skip==col_skip && row_number==col_number) |
---|
764 | { REPORT return gm->bandwidth(); } |
---|
765 | else { REPORT return MatrixBandWidth(-1); } |
---|
766 | } |
---|
767 | |
---|
768 | // ********************** the memory managment tools **********************/ |
---|
769 | |
---|
770 | // Rules regarding tDelete, reuse, GetStore, BorrowStore |
---|
771 | // All matrices processed during expression evaluation must be subject |
---|
772 | // to exactly one of reuse(), tDelete(), GetStore() or BorrowStore(). |
---|
773 | // If reuse returns true the matrix must be reused. |
---|
774 | // GetMatrix(gm) always calls gm->GetStore() |
---|
775 | // gm->Evaluate obeys rules |
---|
776 | // bm->Evaluate obeys rules for matrices in bm structure |
---|
777 | |
---|
778 | // Meaning of tag_val |
---|
779 | // tag_val = -1 memory cannot be reused (default situation) |
---|
780 | // tag_val = -2 memory has been borrowed from another matrix |
---|
781 | // (don't change values) |
---|
782 | // tag_val = i > 0 delete or reuse memory after i operations |
---|
783 | // tag_val = 0 like value 1 but matrix was created by new |
---|
784 | // so delete it |
---|
785 | |
---|
786 | void GeneralMatrix::tDelete() |
---|
787 | { |
---|
788 | if (tag_val<0) |
---|
789 | { |
---|
790 | if (tag_val<-1) { REPORT store = 0; delete this; return; } // borrowed |
---|
791 | else { REPORT return; } // not a temporary matrix - leave alone |
---|
792 | } |
---|
793 | if (tag_val==1) |
---|
794 | { |
---|
795 | if (store) |
---|
796 | { |
---|
797 | REPORT MONITOR_REAL_DELETE("Free (tDelete)",storage,store) |
---|
798 | delete [] store; |
---|
799 | } |
---|
800 | MiniCleanUp(); return; // CleanUp |
---|
801 | } |
---|
802 | if (tag_val==0) { REPORT delete this; return; } |
---|
803 | |
---|
804 | REPORT tag_val--; return; |
---|
805 | } |
---|
806 | |
---|
807 | void newmat_block_copy(int n, Real* from, Real* to) |
---|
808 | { |
---|
809 | REPORT |
---|
810 | int i = (n >> 3); |
---|
811 | while (i--) |
---|
812 | { |
---|
813 | *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++; |
---|
814 | *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++; |
---|
815 | } |
---|
816 | i = n & 7; while (i--) *to++ = *from++; |
---|
817 | } |
---|
818 | |
---|
819 | bool GeneralMatrix::reuse() |
---|
820 | { |
---|
821 | if (tag_val < -1) // borrowed storage |
---|
822 | { |
---|
823 | if (storage) |
---|
824 | { |
---|
825 | REPORT |
---|
826 | Real* s = new Real [storage]; MatrixErrorNoSpace(s); |
---|
827 | MONITOR_REAL_NEW("Make (reuse)",storage,s) |
---|
828 | newmat_block_copy(storage, store, s); store = s; |
---|
829 | } |
---|
830 | else { REPORT MiniCleanUp(); } // CleanUp |
---|
831 | tag_val = 0; return true; |
---|
832 | } |
---|
833 | if (tag_val < 0 ) { REPORT return false; } |
---|
834 | if (tag_val <= 1 ) { REPORT return true; } |
---|
835 | REPORT tag_val--; return false; |
---|
836 | } |
---|
837 | |
---|
838 | Real* GeneralMatrix::GetStore() |
---|
839 | { |
---|
840 | if (tag_val<0 || tag_val>1) |
---|
841 | { |
---|
842 | Real* s; |
---|
843 | if (storage) |
---|
844 | { |
---|
845 | s = new Real [storage]; MatrixErrorNoSpace(s); |
---|
846 | MONITOR_REAL_NEW("Make (GetStore)",storage,s) |
---|
847 | newmat_block_copy(storage, store, s); |
---|
848 | } |
---|
849 | else s = 0; |
---|
850 | if (tag_val > 1) { REPORT tag_val--; } |
---|
851 | else if (tag_val < -1) { REPORT store = 0; delete this; } // borrowed store |
---|
852 | else { REPORT } |
---|
853 | return s; |
---|
854 | } |
---|
855 | Real* s = store; // cleanup - done later |
---|
856 | if (tag_val==0) { REPORT store = 0; delete this; } |
---|
857 | else { REPORT MiniCleanUp(); } |
---|
858 | return s; |
---|
859 | } |
---|
860 | |
---|
861 | void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx) |
---|
862 | { |
---|
863 | REPORT tag_val=-1; nrows_val=gmx->Nrows(); ncols_val=gmx->Ncols(); |
---|
864 | storage=gmx->storage; SetParameters(gmx); |
---|
865 | store=((GeneralMatrix*)gmx)->GetStore(); |
---|
866 | } |
---|
867 | |
---|
868 | GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt) |
---|
869 | // Copy storage of *this to storage of *gmx. Then convert to type mt. |
---|
870 | // If mt == 0 just let *gmx point to storage of *this if tag_val==-1. |
---|
871 | { |
---|
872 | if (!mt) |
---|
873 | { |
---|
874 | if (tag_val == -1) { REPORT gmx->tag_val = -2; gmx->store = store; } |
---|
875 | else { REPORT gmx->tag_val = 0; gmx->store = GetStore(); } |
---|
876 | } |
---|
877 | else if (Compare(gmx->type(),mt)) |
---|
878 | { REPORT gmx->tag_val = 0; gmx->store = GetStore(); } |
---|
879 | else |
---|
880 | { |
---|
881 | REPORT gmx->tag_val = -2; gmx->store = store; |
---|
882 | gmx = gmx->Evaluate(mt); gmx->tag_val = 0; tDelete(); |
---|
883 | } |
---|
884 | |
---|
885 | return gmx; |
---|
886 | } |
---|
887 | |
---|
888 | void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt) |
---|
889 | // Count number of references to this in X. |
---|
890 | // If zero delete storage in this; |
---|
891 | // otherwise tag this to show when storage can be deleted |
---|
892 | // evaluate X and copy to this |
---|
893 | { |
---|
894 | #ifdef DO_SEARCH |
---|
895 | int counter=X.search(this); |
---|
896 | if (counter==0) |
---|
897 | { |
---|
898 | REPORT |
---|
899 | if (store) |
---|
900 | { |
---|
901 | MONITOR_REAL_DELETE("Free (operator=)",storage,store) |
---|
902 | REPORT delete [] store; storage = 0; store = 0; |
---|
903 | } |
---|
904 | } |
---|
905 | else { REPORT Release(counter); } |
---|
906 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); |
---|
907 | if (gmx!=this) { REPORT GetMatrix(gmx); } |
---|
908 | else { REPORT } |
---|
909 | Protect(); |
---|
910 | #else |
---|
911 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); |
---|
912 | if (gmx!=this) |
---|
913 | { |
---|
914 | REPORT |
---|
915 | if (store) |
---|
916 | { |
---|
917 | MONITOR_REAL_DELETE("Free (operator=)",storage,store) |
---|
918 | REPORT delete [] store; storage = 0; store = 0; |
---|
919 | } |
---|
920 | GetMatrix(gmx); |
---|
921 | } |
---|
922 | else { REPORT } |
---|
923 | Protect(); |
---|
924 | #endif |
---|
925 | } |
---|
926 | |
---|
927 | // version with no conversion |
---|
928 | void GeneralMatrix::Eq(const GeneralMatrix& X) |
---|
929 | { |
---|
930 | GeneralMatrix* gmx = (GeneralMatrix*)&X; |
---|
931 | if (gmx!=this) |
---|
932 | { |
---|
933 | REPORT |
---|
934 | if (store) |
---|
935 | { |
---|
936 | MONITOR_REAL_DELETE("Free (operator=)",storage,store) |
---|
937 | REPORT delete [] store; storage = 0; store = 0; |
---|
938 | } |
---|
939 | GetMatrix(gmx); |
---|
940 | } |
---|
941 | else { REPORT } |
---|
942 | Protect(); |
---|
943 | } |
---|
944 | |
---|
945 | // version to work with operator<< |
---|
946 | void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok) |
---|
947 | { |
---|
948 | REPORT |
---|
949 | if (ldok) mt.SetDataLossOK(); |
---|
950 | Eq(X, mt); |
---|
951 | } |
---|
952 | |
---|
953 | void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt) |
---|
954 | // a cut down version of Eq for use with += etc. |
---|
955 | // we know BaseMatrix points to two GeneralMatrix objects, |
---|
956 | // the first being this (may be the same). |
---|
957 | // we know tag_val has been set correctly in each. |
---|
958 | { |
---|
959 | GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt); |
---|
960 | if (gmx!=this) { REPORT GetMatrix(gmx); } // simplify GetMatrix ? |
---|
961 | else { REPORT } |
---|
962 | Protect(); |
---|
963 | } |
---|
964 | |
---|
965 | void GeneralMatrix::inject(const GeneralMatrix& X) |
---|
966 | // copy stored values of X; otherwise leave els of *this unchanged |
---|
967 | { |
---|
968 | REPORT |
---|
969 | Tracer tr("inject"); |
---|
970 | if (nrows_val != X.nrows_val || ncols_val != X.ncols_val) |
---|
971 | Throw(IncompatibleDimensionsException()); |
---|
972 | MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry); |
---|
973 | MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart); |
---|
974 | int i=nrows_val; |
---|
975 | while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); } |
---|
976 | } |
---|
977 | |
---|
978 | // ************* checking for data loss during conversion *******************/ |
---|
979 | |
---|
980 | bool Compare(const MatrixType& source, MatrixType& destination) |
---|
981 | { |
---|
982 | if (!destination) { destination=source; return true; } |
---|
983 | if (destination==source) return true; |
---|
984 | if (!destination.DataLossOK && !(destination>=source)) |
---|
985 | Throw(ProgramException("Illegal Conversion", source, destination)); |
---|
986 | return false; |
---|
987 | } |
---|
988 | |
---|
989 | // ************* Make a copy of a matrix on the heap *********************/ |
---|
990 | |
---|
991 | GeneralMatrix* Matrix::Image() const |
---|
992 | { |
---|
993 | REPORT |
---|
994 | GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm); |
---|
995 | return gm; |
---|
996 | } |
---|
997 | |
---|
998 | GeneralMatrix* SquareMatrix::Image() const |
---|
999 | { |
---|
1000 | REPORT |
---|
1001 | GeneralMatrix* gm = new SquareMatrix(*this); MatrixErrorNoSpace(gm); |
---|
1002 | return gm; |
---|
1003 | } |
---|
1004 | |
---|
1005 | GeneralMatrix* SymmetricMatrix::Image() const |
---|
1006 | { |
---|
1007 | REPORT |
---|
1008 | GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm); |
---|
1009 | return gm; |
---|
1010 | } |
---|
1011 | |
---|
1012 | GeneralMatrix* UpperTriangularMatrix::Image() const |
---|
1013 | { |
---|
1014 | REPORT |
---|
1015 | GeneralMatrix* gm = new UpperTriangularMatrix(*this); |
---|
1016 | MatrixErrorNoSpace(gm); return gm; |
---|
1017 | } |
---|
1018 | |
---|
1019 | GeneralMatrix* LowerTriangularMatrix::Image() const |
---|
1020 | { |
---|
1021 | REPORT |
---|
1022 | GeneralMatrix* gm = new LowerTriangularMatrix(*this); |
---|
1023 | MatrixErrorNoSpace(gm); return gm; |
---|
1024 | } |
---|
1025 | |
---|
1026 | GeneralMatrix* DiagonalMatrix::Image() const |
---|
1027 | { |
---|
1028 | REPORT |
---|
1029 | GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm); |
---|
1030 | return gm; |
---|
1031 | } |
---|
1032 | |
---|
1033 | GeneralMatrix* RowVector::Image() const |
---|
1034 | { |
---|
1035 | REPORT |
---|
1036 | GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm); |
---|
1037 | return gm; |
---|
1038 | } |
---|
1039 | |
---|
1040 | GeneralMatrix* ColumnVector::Image() const |
---|
1041 | { |
---|
1042 | REPORT |
---|
1043 | GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm); |
---|
1044 | return gm; |
---|
1045 | } |
---|
1046 | |
---|
1047 | GeneralMatrix* nricMatrix::Image() const |
---|
1048 | { |
---|
1049 | REPORT |
---|
1050 | GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm); |
---|
1051 | return gm; |
---|
1052 | } |
---|
1053 | |
---|
1054 | GeneralMatrix* IdentityMatrix::Image() const |
---|
1055 | { |
---|
1056 | REPORT |
---|
1057 | GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm); |
---|
1058 | return gm; |
---|
1059 | } |
---|
1060 | |
---|
1061 | GeneralMatrix* CroutMatrix::Image() const |
---|
1062 | { |
---|
1063 | REPORT |
---|
1064 | GeneralMatrix* gm = new CroutMatrix(*this); MatrixErrorNoSpace(gm); |
---|
1065 | return gm; |
---|
1066 | } |
---|
1067 | |
---|
1068 | GeneralMatrix* GeneralMatrix::Image() const |
---|
1069 | { |
---|
1070 | bool dummy = true; |
---|
1071 | if (dummy) // get rid of warning message |
---|
1072 | Throw(InternalException("Cannot apply Image to this matrix type")); |
---|
1073 | return 0; |
---|
1074 | } |
---|
1075 | |
---|
1076 | |
---|
1077 | // *********************** nricMatrix routines *****************************/ |
---|
1078 | |
---|
1079 | void nricMatrix::MakeRowPointer() |
---|
1080 | { |
---|
1081 | REPORT |
---|
1082 | if (nrows_val > 0) |
---|
1083 | { |
---|
1084 | row_pointer = new Real* [nrows_val]; MatrixErrorNoSpace(row_pointer); |
---|
1085 | Real* s = Store() - 1; int i = nrows_val; Real** rp = row_pointer; |
---|
1086 | if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols_val; } |
---|
1087 | } |
---|
1088 | else row_pointer = 0; |
---|
1089 | } |
---|
1090 | |
---|
1091 | void nricMatrix::DeleteRowPointer() |
---|
1092 | { REPORT if (nrows_val) delete [] row_pointer; } |
---|
1093 | |
---|
1094 | void GeneralMatrix::CheckStore() const |
---|
1095 | { |
---|
1096 | REPORT |
---|
1097 | if (!store) |
---|
1098 | Throw(ProgramException("NRIC accessing matrix with unset dimensions")); |
---|
1099 | } |
---|
1100 | |
---|
1101 | |
---|
1102 | // *************************** CleanUp routines *****************************/ |
---|
1103 | |
---|
1104 | void GeneralMatrix::cleanup() |
---|
1105 | { |
---|
1106 | // set matrix dimensions to zero, delete storage |
---|
1107 | REPORT |
---|
1108 | if (store && storage) |
---|
1109 | { |
---|
1110 | MONITOR_REAL_DELETE("Free (cleanup) ",storage,store) |
---|
1111 | REPORT delete [] store; |
---|
1112 | } |
---|
1113 | store=0; storage=0; nrows_val=0; ncols_val=0; tag_val = -1; |
---|
1114 | } |
---|
1115 | |
---|
1116 | void nricMatrix::cleanup() |
---|
1117 | { REPORT DeleteRowPointer(); GeneralMatrix::cleanup(); } |
---|
1118 | |
---|
1119 | void nricMatrix::MiniCleanUp() |
---|
1120 | { REPORT DeleteRowPointer(); GeneralMatrix::MiniCleanUp(); } |
---|
1121 | |
---|
1122 | void RowVector::cleanup() |
---|
1123 | { REPORT GeneralMatrix::cleanup(); nrows_val=1; } |
---|
1124 | |
---|
1125 | void ColumnVector::cleanup() |
---|
1126 | { REPORT GeneralMatrix::cleanup(); ncols_val=1; } |
---|
1127 | |
---|
1128 | void CroutMatrix::cleanup() |
---|
1129 | { |
---|
1130 | REPORT |
---|
1131 | if (nrows_val) delete [] indx; |
---|
1132 | GeneralMatrix::cleanup(); |
---|
1133 | } |
---|
1134 | |
---|
1135 | void CroutMatrix::MiniCleanUp() |
---|
1136 | { |
---|
1137 | REPORT |
---|
1138 | if (nrows_val) delete [] indx; |
---|
1139 | GeneralMatrix::MiniCleanUp(); |
---|
1140 | } |
---|
1141 | |
---|
1142 | void BandLUMatrix::cleanup() |
---|
1143 | { |
---|
1144 | REPORT |
---|
1145 | if (nrows_val) delete [] indx; |
---|
1146 | if (storage2) delete [] store2; |
---|
1147 | GeneralMatrix::cleanup(); |
---|
1148 | } |
---|
1149 | |
---|
1150 | void BandLUMatrix::MiniCleanUp() |
---|
1151 | { |
---|
1152 | REPORT |
---|
1153 | if (nrows_val) delete [] indx; |
---|
1154 | if (storage2) delete [] store2; |
---|
1155 | GeneralMatrix::MiniCleanUp(); |
---|
1156 | } |
---|
1157 | |
---|
1158 | // ************************ simple integer array class *********************** |
---|
1159 | |
---|
1160 | // construct a new array of length xn. Check that xn is non-negative and |
---|
1161 | // that space is available |
---|
1162 | |
---|
1163 | SimpleIntArray::SimpleIntArray(int xn) : n(xn) |
---|
1164 | { |
---|
1165 | if (n < 0) Throw(Logic_error("invalid array length")); |
---|
1166 | else if (n == 0) { REPORT a = 0; } |
---|
1167 | else { REPORT a = new int [n]; if (!a) Throw(Bad_alloc()); } |
---|
1168 | } |
---|
1169 | |
---|
1170 | // destroy an array - return its space to memory |
---|
1171 | |
---|
1172 | SimpleIntArray::~SimpleIntArray() { REPORT if (a) delete [] a; } |
---|
1173 | |
---|
1174 | // access an element of an array; return a "reference" so elements |
---|
1175 | // can be modified. |
---|
1176 | // check index is within range |
---|
1177 | // in this array class the index runs from 0 to n-1 |
---|
1178 | |
---|
1179 | int& SimpleIntArray::operator[](int i) |
---|
1180 | { |
---|
1181 | REPORT |
---|
1182 | if (i < 0 || i >= n) Throw(Logic_error("array index out of range")); |
---|
1183 | return a[i]; |
---|
1184 | } |
---|
1185 | |
---|
1186 | // same thing again but for arrays declared constant so we can't |
---|
1187 | // modify its elements |
---|
1188 | |
---|
1189 | int SimpleIntArray::operator[](int i) const |
---|
1190 | { |
---|
1191 | REPORT |
---|
1192 | if (i < 0 || i >= n) Throw(Logic_error("array index out of range")); |
---|
1193 | return a[i]; |
---|
1194 | } |
---|
1195 | |
---|
1196 | // set all the elements equal to a given value |
---|
1197 | |
---|
1198 | void SimpleIntArray::operator=(int ai) |
---|
1199 | { REPORT for (int i = 0; i < n; i++) a[i] = ai; } |
---|
1200 | |
---|
1201 | // set the elements equal to those of another array. |
---|
1202 | // now allow length to be changed |
---|
1203 | |
---|
1204 | void SimpleIntArray::operator=(const SimpleIntArray& b) |
---|
1205 | { |
---|
1206 | REPORT |
---|
1207 | if (b.n != n) resize(b.n); |
---|
1208 | for (int i = 0; i < n; i++) a[i] = b.a[i]; |
---|
1209 | } |
---|
1210 | |
---|
1211 | // construct a new array equal to an existing array |
---|
1212 | // check that space is available |
---|
1213 | |
---|
1214 | SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : Janitor(), n(b.n) |
---|
1215 | { |
---|
1216 | if (n == 0) { REPORT a = 0; } |
---|
1217 | else |
---|
1218 | { |
---|
1219 | REPORT |
---|
1220 | a = new int [n]; if (!a) Throw(Bad_alloc()); |
---|
1221 | for (int i = 0; i < n; i++) a[i] = b.a[i]; |
---|
1222 | } |
---|
1223 | } |
---|
1224 | |
---|
1225 | // change the size of an array; optionally copy data from old array to |
---|
1226 | // new array |
---|
1227 | |
---|
1228 | void SimpleIntArray::resize(int n1, bool keep) |
---|
1229 | { |
---|
1230 | if (n1 == n) { REPORT return; } |
---|
1231 | else if (n1 == 0) { REPORT n = 0; delete [] a; a = 0; } |
---|
1232 | else if (n == 0) |
---|
1233 | { |
---|
1234 | REPORT |
---|
1235 | a = new int [n1]; if (!a) Throw(Bad_alloc()); |
---|
1236 | n = n1; |
---|
1237 | if (keep) operator=(0); |
---|
1238 | } |
---|
1239 | else |
---|
1240 | { |
---|
1241 | int* a1 = a; |
---|
1242 | if (keep) |
---|
1243 | { |
---|
1244 | REPORT |
---|
1245 | int i; |
---|
1246 | a = new int [n1]; if (!a) Throw(Bad_alloc()); |
---|
1247 | if (n > n1) n = n1; |
---|
1248 | else for (i = n; i < n1; i++) a[i] = 0; |
---|
1249 | for (i = 0; i < n; i++) a[i] = a1[i]; |
---|
1250 | n = n1; delete [] a1; |
---|
1251 | } |
---|
1252 | else |
---|
1253 | { |
---|
1254 | REPORT n = n1; delete [] a1; |
---|
1255 | a = new int [n]; if (!a) Throw(Bad_alloc()); |
---|
1256 | } |
---|
1257 | } |
---|
1258 | } |
---|
1259 | |
---|
1260 | //************************** swap values ******************************** |
---|
1261 | |
---|
1262 | // swap values |
---|
1263 | |
---|
1264 | void GeneralMatrix::swap(GeneralMatrix& gm) |
---|
1265 | { |
---|
1266 | REPORT |
---|
1267 | int t; |
---|
1268 | t = tag_val; tag_val = gm.tag_val; gm.tag_val = t; |
---|
1269 | t = nrows_val; nrows_val = gm.nrows_val; gm.nrows_val = t; |
---|
1270 | t = ncols_val; ncols_val = gm.ncols_val; gm.ncols_val = t; |
---|
1271 | t = storage; storage = gm.storage; gm.storage = t; |
---|
1272 | Real* s = store; store = gm.store; gm.store = s; |
---|
1273 | } |
---|
1274 | |
---|
1275 | void nricMatrix::swap(nricMatrix& gm) |
---|
1276 | { |
---|
1277 | REPORT |
---|
1278 | GeneralMatrix::swap((GeneralMatrix&)gm); |
---|
1279 | Real** rp = row_pointer; row_pointer = gm.row_pointer; gm.row_pointer = rp; |
---|
1280 | } |
---|
1281 | |
---|
1282 | void CroutMatrix::swap(CroutMatrix& gm) |
---|
1283 | { |
---|
1284 | REPORT |
---|
1285 | GeneralMatrix::swap((GeneralMatrix&)gm); |
---|
1286 | int* i = indx; indx = gm.indx; gm.indx = i; |
---|
1287 | bool b; |
---|
1288 | b = d; d = gm.d; gm.d = b; |
---|
1289 | b = sing; sing = gm.sing; gm.sing = b; |
---|
1290 | } |
---|
1291 | |
---|
1292 | void BandMatrix::swap(BandMatrix& gm) |
---|
1293 | { |
---|
1294 | REPORT |
---|
1295 | GeneralMatrix::swap((GeneralMatrix&)gm); |
---|
1296 | int i; |
---|
1297 | i = lower_val; lower_val = gm.lower_val; gm.lower_val = i; |
---|
1298 | i = upper_val; upper_val = gm.upper_val; gm.upper_val = i; |
---|
1299 | } |
---|
1300 | |
---|
1301 | void SymmetricBandMatrix::swap(SymmetricBandMatrix& gm) |
---|
1302 | { |
---|
1303 | REPORT |
---|
1304 | GeneralMatrix::swap((GeneralMatrix&)gm); |
---|
1305 | int i; |
---|
1306 | i = lower_val; lower_val = gm.lower_val; gm.lower_val = i; |
---|
1307 | } |
---|
1308 | |
---|
1309 | void BandLUMatrix::swap(BandLUMatrix& gm) |
---|
1310 | { |
---|
1311 | REPORT |
---|
1312 | GeneralMatrix::swap((GeneralMatrix&)gm); |
---|
1313 | int* i = indx; indx = gm.indx; gm.indx = i; |
---|
1314 | bool b; |
---|
1315 | b = d; d = gm.d; gm.d = b; |
---|
1316 | b = sing; sing = gm.sing; gm.sing = b; |
---|
1317 | int m; |
---|
1318 | m = storage2; storage2 = gm.storage2; gm.storage2 = m; |
---|
1319 | m = m1; m1 = gm.m1; gm.m1 = m; |
---|
1320 | m = m2; m2 = gm.m2; gm.m2 = m; |
---|
1321 | Real* s = store2; store2 = gm.store2; gm.store2 = s; |
---|
1322 | } |
---|
1323 | |
---|
1324 | void GenericMatrix::swap(GenericMatrix& x) |
---|
1325 | { |
---|
1326 | REPORT |
---|
1327 | GeneralMatrix* tgm = gm; gm = x.gm; x.gm = tgm; |
---|
1328 | } |
---|
1329 | |
---|
1330 | // ********************** C subscript classes **************************** |
---|
1331 | |
---|
1332 | RealStarStar::RealStarStar(Matrix& A) |
---|
1333 | { |
---|
1334 | REPORT |
---|
1335 | Tracer tr("RealStarStar"); |
---|
1336 | int n = A.ncols(); |
---|
1337 | int m = A.nrows(); |
---|
1338 | a = new Real*[m]; |
---|
1339 | MatrixErrorNoSpace(a); |
---|
1340 | Real* d = A.data(); |
---|
1341 | for (int i = 0; i < m; ++i) a[i] = d + i * n; |
---|
1342 | } |
---|
1343 | |
---|
1344 | ConstRealStarStar::ConstRealStarStar(const Matrix& A) |
---|
1345 | { |
---|
1346 | REPORT |
---|
1347 | Tracer tr("ConstRealStarStar"); |
---|
1348 | int n = A.ncols(); |
---|
1349 | int m = A.nrows(); |
---|
1350 | a = new const Real*[m]; |
---|
1351 | MatrixErrorNoSpace(a); |
---|
1352 | const Real* d = A.data(); |
---|
1353 | for (int i = 0; i < m; ++i) a[i] = d + i * n; |
---|
1354 | } |
---|
1355 | |
---|
1356 | |
---|
1357 | |
---|
1358 | #ifdef use_namespace |
---|
1359 | } |
---|
1360 | #endif |
---|
1361 | |
---|
1362 | |
---|
1363 | /// \fn GeneralMatrix::SimpleAddOK(const GeneralMatrix* gm) |
---|
1364 | /// Can we add two matrices with simple vector add. |
---|
1365 | /// SimpleAddOK shows when we can add two matrices by a simple vector add |
---|
1366 | /// and when we can add one matrix into another |
---|
1367 | /// |
---|
1368 | /// *gm must be the same type as *this |
---|
1369 | /// - return 0 if simple add is OK |
---|
1370 | /// - return 1 if we can add into *gm only |
---|
1371 | /// - return 2 if we can add into *this only |
---|
1372 | /// - return 3 if we can't add either way |
---|
1373 | /// |
---|
1374 | /// Also applies to subtract; |
---|
1375 | /// for SP this will still be valid if we swap 1 and 2 |
---|
1376 | /// |
---|
1377 | /// For types Matrix, DiagonalMatrix, UpperTriangularMatrix, |
---|
1378 | /// LowerTriangularMatrix, SymmetricMatrix etc return 0. |
---|
1379 | /// For band matrices we will need to check bandwidths. |
---|
1380 | |
---|
1381 | |
---|
1382 | |
---|
1383 | |
---|
1384 | |
---|
1385 | |
---|
1386 | |
---|
1387 | ///@} |
---|