Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/newmat/newmat4.cpp @ 4639

Last change on this file since 4639 was 4565, checked in by patrick, 19 years ago

orxonox/trunk: added the newmat library to the project. needs some translation in directory, temp under util/newmat. is needed by the collision detection engine to perform lin alg operations such as eigenvector decomposition. perhaps we will make our own library to do that later.

File size: 24.1 KB
Line 
1//$$ newmat4.cpp       Constructors, ReSize, basic utilities
2
3// Copyright (C) 1991,2,3,4,8,9: R B Davies
4
5#include "include.h"
6
7#include "newmat.h"
8#include "newmatrc.h"
9
10#ifdef use_namespace
11namespace NEWMAT {
12#endif
13
14
15
16#ifdef DO_REPORT
17#define REPORT { static ExeCounter ExeCount(__LINE__,4); ++ExeCount; }
18#else
19#define REPORT {}
20#endif
21
22
23#define DO_SEARCH                   // search for LHS of = in RHS
24
25// ************************* general utilities *************************/
26
27static int tristore(int n)                    // elements in triangular matrix
28{ return (n*(n+1))/2; }
29
30
31// **************************** constructors ***************************/
32
33GeneralMatrix::GeneralMatrix()
34{ store=0; storage=0; nrows=0; ncols=0; tag=-1; }
35
36GeneralMatrix::GeneralMatrix(ArrayLengthSpecifier s)
37{
38   REPORT
39   storage=s.Value(); tag=-1;
40   if (storage)
41   {
42      store = new Real [storage]; MatrixErrorNoSpace(store);
43      MONITOR_REAL_NEW("Make (GenMatrix)",storage,store)
44   }
45   else store = 0;
46}
47
48Matrix::Matrix(int m, int n) : GeneralMatrix(m*n)
49{ REPORT nrows=m; ncols=n; }
50
51SymmetricMatrix::SymmetricMatrix(ArrayLengthSpecifier n)
52   : GeneralMatrix(tristore(n.Value()))
53{ REPORT nrows=n.Value(); ncols=n.Value(); }
54
55UpperTriangularMatrix::UpperTriangularMatrix(ArrayLengthSpecifier n)
56   : GeneralMatrix(tristore(n.Value()))
57{ REPORT nrows=n.Value(); ncols=n.Value(); }
58
59LowerTriangularMatrix::LowerTriangularMatrix(ArrayLengthSpecifier n)
60   : GeneralMatrix(tristore(n.Value()))
61{ REPORT nrows=n.Value(); ncols=n.Value(); }
62
63DiagonalMatrix::DiagonalMatrix(ArrayLengthSpecifier m) : GeneralMatrix(m)
64{ REPORT nrows=m.Value(); ncols=m.Value(); }
65
66Matrix::Matrix(const BaseMatrix& M)
67{
68   REPORT // CheckConversion(M);
69   // MatrixConversionCheck mcc;
70   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Rt);
71   GetMatrix(gmx);
72}
73
74RowVector::RowVector(const BaseMatrix& M) : Matrix(M)
75{
76   if (nrows!=1)
77   {
78      Tracer tr("RowVector");
79      Throw(VectorException(*this));
80   }
81}
82
83ColumnVector::ColumnVector(const BaseMatrix& M) : Matrix(M)
84{
85   if (ncols!=1)
86   {
87      Tracer tr("ColumnVector");
88      Throw(VectorException(*this));
89   }
90}
91
92SymmetricMatrix::SymmetricMatrix(const BaseMatrix& M)
93{
94   REPORT  // CheckConversion(M);
95   // MatrixConversionCheck mcc;
96   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Sm);
97   GetMatrix(gmx);
98}
99
100UpperTriangularMatrix::UpperTriangularMatrix(const BaseMatrix& M)
101{
102   REPORT // CheckConversion(M);
103   // MatrixConversionCheck mcc;
104   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::UT);
105   GetMatrix(gmx);
106}
107
108LowerTriangularMatrix::LowerTriangularMatrix(const BaseMatrix& M)
109{
110   REPORT // CheckConversion(M);
111   // MatrixConversionCheck mcc;
112   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::LT);
113   GetMatrix(gmx);
114}
115
116DiagonalMatrix::DiagonalMatrix(const BaseMatrix& M)
117{
118   REPORT //CheckConversion(M);
119   // MatrixConversionCheck mcc;
120   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Dg);
121   GetMatrix(gmx);
122}
123
124IdentityMatrix::IdentityMatrix(const BaseMatrix& M)
125{
126   REPORT //CheckConversion(M);
127   // MatrixConversionCheck mcc;
128   GeneralMatrix* gmx=((BaseMatrix&)M).Evaluate(MatrixType::Id);
129   GetMatrix(gmx);
130}
131
132GeneralMatrix::~GeneralMatrix()
133{
134   if (store)
135   {
136      MONITOR_REAL_DELETE("Free (GenMatrix)",storage,store)
137      delete [] store;
138   }
139}
140
141CroutMatrix::CroutMatrix(const BaseMatrix& m)
142{
143   REPORT
144   Tracer tr("CroutMatrix");
145   indx = 0;                     // in case of exception at next line
146   GeneralMatrix* gm = ((BaseMatrix&)m).Evaluate(MatrixType::Rt);
147   GetMatrix(gm);
148   if (nrows!=ncols) { CleanUp(); Throw(NotSquareException(*gm)); }
149   d=true; sing=false;
150   indx=new int [nrows]; MatrixErrorNoSpace(indx);
151   MONITOR_INT_NEW("Index (CroutMat)",nrows,indx)
152   ludcmp();
153}
154
155CroutMatrix::~CroutMatrix()
156{
157   MONITOR_INT_DELETE("Index (CroutMat)",nrows,indx)
158   delete [] indx;
159}
160
161//ReturnMatrixX::ReturnMatrixX(GeneralMatrix& gmx)
162//{
163//   REPORT
164//   gm = gmx.Image(); gm->ReleaseAndDelete();
165//}
166
167#ifndef TEMPS_DESTROYED_QUICKLY_R
168
169GeneralMatrix::operator ReturnMatrixX() const
170{
171   REPORT
172   GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
173   return ReturnMatrixX(gm);
174}
175
176#else
177
178GeneralMatrix::operator ReturnMatrixX&() const
179{
180   REPORT
181   GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
182   ReturnMatrixX* x = new ReturnMatrixX(gm);
183   MatrixErrorNoSpace(x); return *x;
184}
185
186#endif
187
188#ifndef TEMPS_DESTROYED_QUICKLY_R
189
190ReturnMatrixX GeneralMatrix::ForReturn() const
191{
192   REPORT
193   GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
194   return ReturnMatrixX(gm);
195}
196
197#else
198
199ReturnMatrixX& GeneralMatrix::ForReturn() const
200{
201   REPORT
202   GeneralMatrix* gm = Image(); gm->ReleaseAndDelete();
203   ReturnMatrixX* x = new ReturnMatrixX(gm);
204   MatrixErrorNoSpace(x); return *x;
205}
206
207#endif
208
209// ************************** ReSize matrices ***************************/
210
211void GeneralMatrix::ReSize(int nr, int nc, int s)
212{
213   REPORT
214   if (store)
215   {
216      MONITOR_REAL_DELETE("Free (ReDimensi)",storage,store)
217      delete [] store;
218   }
219   storage=s; nrows=nr; ncols=nc; tag=-1;
220   if (s)
221   {
222      store = new Real [storage]; MatrixErrorNoSpace(store);
223      MONITOR_REAL_NEW("Make (ReDimensi)",storage,store)
224   }
225   else store = 0;
226}
227
228void Matrix::ReSize(int nr, int nc)
229{ REPORT GeneralMatrix::ReSize(nr,nc,nr*nc); }
230
231void SymmetricMatrix::ReSize(int nr)
232{ REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
233
234void UpperTriangularMatrix::ReSize(int nr)
235{ REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
236
237void LowerTriangularMatrix::ReSize(int nr)
238{ REPORT GeneralMatrix::ReSize(nr,nr,tristore(nr)); }
239
240void DiagonalMatrix::ReSize(int nr)
241{ REPORT GeneralMatrix::ReSize(nr,nr,nr); }
242
243void RowVector::ReSize(int nc)
244{ REPORT GeneralMatrix::ReSize(1,nc,nc); }
245
246void ColumnVector::ReSize(int nr)
247{ REPORT GeneralMatrix::ReSize(nr,1,nr); }
248
249void RowVector::ReSize(int nr, int nc)
250{
251   Tracer tr("RowVector::ReSize");
252   if (nr != 1) Throw(VectorException(*this));
253   REPORT GeneralMatrix::ReSize(1,nc,nc);
254}
255
256void ColumnVector::ReSize(int nr, int nc)
257{
258   Tracer tr("ColumnVector::ReSize");
259   if (nc != 1) Throw(VectorException(*this));
260   REPORT GeneralMatrix::ReSize(nr,1,nr);
261}
262
263void IdentityMatrix::ReSize(int nr)
264{ REPORT GeneralMatrix::ReSize(nr,nr,1); *store = 1; }
265
266
267void Matrix::ReSize(const GeneralMatrix& A)
268{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
269
270void nricMatrix::ReSize(const GeneralMatrix& A)
271{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
272
273void ColumnVector::ReSize(const GeneralMatrix& A)
274{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
275
276void RowVector::ReSize(const GeneralMatrix& A)
277{ REPORT  ReSize(A.Nrows(), A.Ncols()); }
278
279void SymmetricMatrix::ReSize(const GeneralMatrix& A)
280{
281   REPORT
282   int n = A.Nrows();
283   if (n != A.Ncols())
284   {
285      Tracer tr("SymmetricMatrix::ReSize(GM)");
286      Throw(NotSquareException(*this));
287   }
288   ReSize(n);
289}
290
291void DiagonalMatrix::ReSize(const GeneralMatrix& A)
292{
293   REPORT
294   int n = A.Nrows();
295   if (n != A.Ncols())
296   {
297      Tracer tr("DiagonalMatrix::ReSize(GM)");
298      Throw(NotSquareException(*this));
299   }
300   ReSize(n);
301}
302
303void UpperTriangularMatrix::ReSize(const GeneralMatrix& A)
304{
305   REPORT
306   int n = A.Nrows();
307   if (n != A.Ncols())
308   {
309      Tracer tr("UpperTriangularMatrix::ReSize(GM)");
310      Throw(NotSquareException(*this));
311   }
312   ReSize(n);
313}
314
315void LowerTriangularMatrix::ReSize(const GeneralMatrix& A)
316{
317   REPORT
318   int n = A.Nrows();
319   if (n != A.Ncols())
320   {
321      Tracer tr("LowerTriangularMatrix::ReSize(GM)");
322      Throw(NotSquareException(*this));
323   }
324   ReSize(n);
325}
326
327void IdentityMatrix::ReSize(const GeneralMatrix& A)
328{
329   REPORT
330   int n = A.Nrows();
331   if (n != A.Ncols())
332   {
333      Tracer tr("IdentityMatrix::ReSize(GM)");
334      Throw(NotSquareException(*this));
335   }
336   ReSize(n);
337}
338
339void GeneralMatrix::ReSize(const GeneralMatrix&)
340{
341   REPORT
342   Tracer tr("GeneralMatrix::ReSize(GM)");
343   Throw(NotDefinedException("ReSize", "this type of matrix"));
344}
345
346void GeneralMatrix::ReSizeForAdd(const GeneralMatrix& A, const GeneralMatrix&)
347{ REPORT ReSize(A); }
348
349void GeneralMatrix::ReSizeForSP(const GeneralMatrix& A, const GeneralMatrix&)
350{ REPORT ReSize(A); }
351
352
353// ************************* SameStorageType ******************************/
354
355// SameStorageType checks A and B have same storage type including bandwidth
356// It does not check same dimensions since we assume this is already done
357
358bool GeneralMatrix::SameStorageType(const GeneralMatrix& A) const
359{
360   REPORT
361   return Type() == A.Type();
362}
363
364
365// ******************* manipulate types, storage **************************/
366
367int GeneralMatrix::search(const BaseMatrix* s) const
368{ REPORT return (s==this) ? 1 : 0; }
369
370int GenericMatrix::search(const BaseMatrix* s) const
371{ REPORT return gm->search(s); }
372
373int MultipliedMatrix::search(const BaseMatrix* s) const
374{ REPORT return bm1->search(s) + bm2->search(s); }
375
376int ShiftedMatrix::search(const BaseMatrix* s) const
377{ REPORT return bm->search(s); }
378
379int NegatedMatrix::search(const BaseMatrix* s) const
380{ REPORT return bm->search(s); }
381
382int ReturnMatrixX::search(const BaseMatrix* s) const
383{ REPORT return (s==gm) ? 1 : 0; }
384
385MatrixType Matrix::Type() const { return MatrixType::Rt; }
386MatrixType SymmetricMatrix::Type() const { return MatrixType::Sm; }
387MatrixType UpperTriangularMatrix::Type() const { return MatrixType::UT; }
388MatrixType LowerTriangularMatrix::Type() const { return MatrixType::LT; }
389MatrixType DiagonalMatrix::Type() const { return MatrixType::Dg; }
390MatrixType RowVector::Type() const { return MatrixType::RV; }
391MatrixType ColumnVector::Type() const { return MatrixType::CV; }
392MatrixType CroutMatrix::Type() const { return MatrixType::Ct; }
393MatrixType BandMatrix::Type() const { return MatrixType::BM; }
394MatrixType UpperBandMatrix::Type() const { return MatrixType::UB; }
395MatrixType LowerBandMatrix::Type() const { return MatrixType::LB; }
396MatrixType SymmetricBandMatrix::Type() const { return MatrixType::SB; }
397
398MatrixType IdentityMatrix::Type() const { return MatrixType::Id; }
399
400
401
402MatrixBandWidth BaseMatrix::BandWidth() const { REPORT return -1; }
403MatrixBandWidth DiagonalMatrix::BandWidth() const { REPORT return 0; }
404MatrixBandWidth IdentityMatrix::BandWidth() const { REPORT return 0; }
405
406MatrixBandWidth UpperTriangularMatrix::BandWidth() const
407   { REPORT return MatrixBandWidth(0,-1); }
408
409MatrixBandWidth LowerTriangularMatrix::BandWidth() const
410   { REPORT return MatrixBandWidth(-1,0); }
411
412MatrixBandWidth BandMatrix::BandWidth() const
413   { REPORT return MatrixBandWidth(lower,upper); }
414
415MatrixBandWidth GenericMatrix::BandWidth()const
416   { REPORT return gm->BandWidth(); }
417
418MatrixBandWidth AddedMatrix::BandWidth() const
419   { REPORT return gm1->BandWidth() + gm2->BandWidth(); }
420
421MatrixBandWidth SPMatrix::BandWidth() const
422   { REPORT return gm1->BandWidth().minimum(gm2->BandWidth()); }
423
424MatrixBandWidth KPMatrix::BandWidth() const
425{
426   int lower, upper;
427   MatrixBandWidth bw1 = gm1->BandWidth(), bw2 = gm2->BandWidth();
428   if (bw1.Lower() < 0)
429   {
430      if (bw2.Lower() < 0) { REPORT lower = -1; }
431      else { REPORT lower = bw2.Lower() + (gm1->Nrows() - 1) * gm2->Nrows(); }
432   }
433   else
434   {
435      if (bw2.Lower() < 0)
436         { REPORT lower = (1 + bw1.Lower()) * gm2->Nrows() - 1; }
437      else { REPORT lower = bw2.Lower() + bw1.Lower() * gm2->Nrows(); }
438   }
439   if (bw1.Upper() < 0)
440   {
441      if (bw2.Upper() < 0) { REPORT upper = -1; }
442      else { REPORT upper = bw2.Upper() + (gm1->Nrows() - 1) * gm2->Nrows(); }
443   }
444   else
445   {
446      if (bw2.Upper() < 0)
447         { REPORT upper = (1 + bw1.Upper()) * gm2->Nrows() - 1; }
448      else { REPORT upper = bw2.Upper() + bw1.Upper() * gm2->Nrows(); }
449   }
450   return MatrixBandWidth(lower, upper);
451}
452
453MatrixBandWidth MultipliedMatrix::BandWidth() const
454{ REPORT return gm1->BandWidth() * gm2->BandWidth(); }
455
456MatrixBandWidth ConcatenatedMatrix::BandWidth() const { REPORT return -1; }
457
458MatrixBandWidth SolvedMatrix::BandWidth() const
459{
460   if (+gm1->Type() & MatrixType::Diagonal)
461      { REPORT return gm2->BandWidth(); }
462   else { REPORT return -1; }
463}
464
465MatrixBandWidth ScaledMatrix::BandWidth() const
466   { REPORT return gm->BandWidth(); }
467
468MatrixBandWidth NegatedMatrix::BandWidth() const
469   { REPORT return gm->BandWidth(); }
470
471MatrixBandWidth TransposedMatrix::BandWidth() const
472   { REPORT return gm->BandWidth().t(); }
473
474MatrixBandWidth InvertedMatrix::BandWidth() const
475{
476   if (+gm->Type() & MatrixType::Diagonal)
477      { REPORT return MatrixBandWidth(0,0); }
478   else { REPORT return -1; }
479}
480
481MatrixBandWidth RowedMatrix::BandWidth() const { REPORT return -1; }
482MatrixBandWidth ColedMatrix::BandWidth() const { REPORT return -1; }
483MatrixBandWidth DiagedMatrix::BandWidth() const { REPORT return 0; }
484MatrixBandWidth MatedMatrix::BandWidth() const { REPORT return -1; }
485MatrixBandWidth ReturnMatrixX::BandWidth() const
486   { REPORT return gm->BandWidth(); }
487
488MatrixBandWidth GetSubMatrix::BandWidth() const
489{
490
491   if (row_skip==col_skip && row_number==col_number)
492      { REPORT return gm->BandWidth(); }
493   else { REPORT return MatrixBandWidth(-1); }
494}
495
496// ********************** the memory managment tools **********************/
497
498//  Rules regarding tDelete, reuse, GetStore
499//    All matrices processed during expression evaluation must be subject
500//    to exactly one of reuse(), tDelete(), GetStore() or BorrowStore().
501//    If reuse returns true the matrix must be reused.
502//    GetMatrix(gm) always calls gm->GetStore()
503//    gm->Evaluate obeys rules
504//    bm->Evaluate obeys rules for matrices in bm structure
505
506void GeneralMatrix::tDelete()
507{
508   if (tag<0)
509   {
510      if (tag<-1) { REPORT store=0; delete this; return; }  // borrowed
511      else { REPORT return; }
512   }
513   if (tag==1)
514   {
515      if (store)
516      {
517         REPORT  MONITOR_REAL_DELETE("Free   (tDelete)",storage,store)
518         delete [] store;
519      }
520      store=0; CleanUp(); tag=-1; return;
521   }
522   if (tag==0) { REPORT delete this; return; }
523   REPORT tag--; return;
524}
525
526static void BlockCopy(int n, Real* from, Real* to)
527{
528   REPORT
529   int i = (n >> 3);
530   while (i--)
531   {
532      *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
533      *to++ = *from++; *to++ = *from++; *to++ = *from++; *to++ = *from++;
534   }
535   i = n & 7; while (i--) *to++ = *from++;
536}
537
538bool GeneralMatrix::reuse()
539{
540   if (tag<-1)
541   {
542      if (storage)
543      {
544         REPORT
545         Real* s = new Real [storage]; MatrixErrorNoSpace(s);
546         MONITOR_REAL_NEW("Make     (reuse)",storage,s)
547         BlockCopy(storage, store, s); store=s;
548      }
549      else { REPORT store = 0; CleanUp(); }
550      tag=0; return true;
551   }
552   if (tag<0) { REPORT return false; }
553   if (tag<=1)  { REPORT return true; }
554   REPORT tag--; return false;
555}
556
557Real* GeneralMatrix::GetStore()
558{
559   if (tag<0 || tag>1)
560   {
561      Real* s;
562      if (storage)
563      {
564         s = new Real [storage]; MatrixErrorNoSpace(s);
565         MONITOR_REAL_NEW("Make  (GetStore)",storage,s)
566         BlockCopy(storage, store, s);
567      }
568      else s = 0;
569      if (tag>1) { REPORT tag--; }
570      else if (tag < -1) { REPORT store=0; delete this; } // borrowed store
571      else { REPORT }
572      return s;
573   }
574   Real* s=store; store=0;
575   if (tag==0) { REPORT delete this; }
576   else { REPORT CleanUp(); tag=-1; }
577   return s;
578}
579
580void GeneralMatrix::GetMatrix(const GeneralMatrix* gmx)
581{
582   REPORT  tag=-1; nrows=gmx->Nrows(); ncols=gmx->Ncols();
583   storage=gmx->storage; SetParameters(gmx);
584   store=((GeneralMatrix*)gmx)->GetStore();
585}
586
587GeneralMatrix* GeneralMatrix::BorrowStore(GeneralMatrix* gmx, MatrixType mt)
588// Copy storage of *this to storage of *gmx. Then convert to type mt.
589// If mt == 0 just let *gmx point to storage of *this if tag==-1.
590{
591   if (!mt)
592   {
593      if (tag == -1) { REPORT gmx->tag = -2; gmx->store = store; }
594      else { REPORT gmx->tag = 0; gmx->store = GetStore(); }
595   }
596   else if (Compare(gmx->Type(),mt))
597   { REPORT  gmx->tag = 0; gmx->store = GetStore(); }
598   else
599   {
600      REPORT gmx->tag = -2; gmx->store = store;
601      gmx = gmx->Evaluate(mt); gmx->tag = 0; tDelete();
602   }
603
604   return gmx;
605}
606
607void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt)
608// Count number of references to this in X.
609// If zero delete storage in this;
610// otherwise tag this to show when storage can be deleted
611// evaluate X and copy to this
612{
613#ifdef DO_SEARCH
614   int counter=X.search(this);
615   if (counter==0)
616   {
617      REPORT
618      if (store)
619      {
620         MONITOR_REAL_DELETE("Free (operator=)",storage,store)
621         REPORT delete [] store; storage=0; store = 0;
622      }
623   }
624   else { REPORT Release(counter); }
625   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
626   if (gmx!=this) { REPORT GetMatrix(gmx); }
627   else { REPORT }
628   Protect();
629#else
630   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
631   if (gmx!=this)
632   {
633      REPORT
634      if (store)
635      {
636         MONITOR_REAL_DELETE("Free (operator=)",storage,store)
637         REPORT delete [] store; storage=0; store = 0;
638      }
639      GetMatrix(gmx);
640   }
641   else { REPORT }
642   Protect();
643#endif
644}
645
646// version to work with operator<<
647void GeneralMatrix::Eq(const BaseMatrix& X, MatrixType mt, bool ldok)
648{
649   REPORT
650   if (ldok) mt.SetDataLossOK();
651   Eq(X, mt);
652}
653
654void GeneralMatrix::Eq2(const BaseMatrix& X, MatrixType mt)
655// a cut down version of Eq for use with += etc.
656// we know BaseMatrix points to two GeneralMatrix objects,
657// the first being this (may be the same).
658// we know tag has been set correctly in each.
659{
660   GeneralMatrix* gmx = ((BaseMatrix&)X).Evaluate(mt);
661   if (gmx!=this) { REPORT GetMatrix(gmx); }  // simplify GetMatrix ?
662   else { REPORT }
663   Protect();
664}
665
666void GeneralMatrix::Inject(const GeneralMatrix& X)
667// copy stored values of X; otherwise leave els of *this unchanged
668{
669   REPORT
670   Tracer tr("Inject");
671   if (nrows != X.nrows || ncols != X.ncols)
672      Throw(IncompatibleDimensionsException());
673   MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
674   MatrixRow mrx(this, LoadOnEntry+StoreOnExit+DirectPart);
675   int i=nrows;
676   while (i--) { mrx.Inject(mr); mrx.Next(); mr.Next(); }
677}
678
679// ************* checking for data loss during conversion *******************/
680
681bool Compare(const MatrixType& source, MatrixType& destination)
682{
683   if (!destination) { destination=source; return true; }
684   if (destination==source) return true;
685   if (!destination.DataLossOK && !(destination>=source))
686      Throw(ProgramException("Illegal Conversion", source, destination));
687   return false;
688}
689
690// ************* Make a copy of a matrix on the heap *********************/
691
692GeneralMatrix* Matrix::Image() const
693{
694   REPORT
695   GeneralMatrix* gm = new Matrix(*this); MatrixErrorNoSpace(gm);
696   return gm;
697}
698
699GeneralMatrix* SymmetricMatrix::Image() const
700{
701   REPORT
702   GeneralMatrix* gm = new SymmetricMatrix(*this); MatrixErrorNoSpace(gm);
703   return gm;
704}
705
706GeneralMatrix* UpperTriangularMatrix::Image() const
707{
708   REPORT
709   GeneralMatrix* gm = new UpperTriangularMatrix(*this);
710   MatrixErrorNoSpace(gm); return gm;
711}
712
713GeneralMatrix* LowerTriangularMatrix::Image() const
714{
715   REPORT
716   GeneralMatrix* gm = new LowerTriangularMatrix(*this);
717   MatrixErrorNoSpace(gm); return gm;
718}
719
720GeneralMatrix* DiagonalMatrix::Image() const
721{
722   REPORT
723   GeneralMatrix* gm = new DiagonalMatrix(*this); MatrixErrorNoSpace(gm);
724   return gm;
725}
726
727GeneralMatrix* RowVector::Image() const
728{
729   REPORT
730   GeneralMatrix* gm = new RowVector(*this); MatrixErrorNoSpace(gm);
731   return gm;
732}
733
734GeneralMatrix* ColumnVector::Image() const
735{
736   REPORT
737   GeneralMatrix* gm = new ColumnVector(*this); MatrixErrorNoSpace(gm);
738   return gm;
739}
740
741GeneralMatrix* BandMatrix::Image() const
742{
743   REPORT
744   GeneralMatrix* gm = new BandMatrix(*this); MatrixErrorNoSpace(gm);
745   return gm;
746}
747
748GeneralMatrix* UpperBandMatrix::Image() const
749{
750   REPORT
751   GeneralMatrix* gm = new UpperBandMatrix(*this); MatrixErrorNoSpace(gm);
752   return gm;
753}
754
755GeneralMatrix* LowerBandMatrix::Image() const
756{
757   REPORT
758   GeneralMatrix* gm = new LowerBandMatrix(*this); MatrixErrorNoSpace(gm);
759   return gm;
760}
761
762GeneralMatrix* SymmetricBandMatrix::Image() const
763{
764   REPORT
765   GeneralMatrix* gm = new SymmetricBandMatrix(*this); MatrixErrorNoSpace(gm);
766   return gm;
767}
768
769GeneralMatrix* nricMatrix::Image() const
770{
771   REPORT
772   GeneralMatrix* gm = new nricMatrix(*this); MatrixErrorNoSpace(gm);
773   return gm;
774}
775
776GeneralMatrix* IdentityMatrix::Image() const
777{
778   REPORT
779   GeneralMatrix* gm = new IdentityMatrix(*this); MatrixErrorNoSpace(gm);
780   return gm;
781}
782
783GeneralMatrix* GeneralMatrix::Image() const
784{
785   bool dummy = true;
786   if (dummy)                                   // get rid of warning message
787      Throw(InternalException("Cannot apply Image to this matrix type"));
788   return 0;
789}
790
791
792// *********************** nricMatrix routines *****************************/
793
794void nricMatrix::MakeRowPointer()
795{
796   if (nrows > 0)
797   {
798      row_pointer = new Real* [nrows]; MatrixErrorNoSpace(row_pointer);
799      Real* s = Store() - 1; int i = nrows; Real** rp = row_pointer;
800      if (i) for (;;) { *rp++ = s; if (!(--i)) break; s+=ncols; }
801   }
802   else row_pointer = 0;
803}
804
805void nricMatrix::DeleteRowPointer()
806{ if (nrows) delete [] row_pointer; }
807
808void GeneralMatrix::CheckStore() const
809{
810   if (!store)
811      Throw(ProgramException("NRIC accessing matrix with unset dimensions"));
812}
813
814
815// *************************** CleanUp routines *****************************/
816
817void GeneralMatrix::CleanUp()
818{
819   // set matrix dimensions to zero, delete storage
820   REPORT
821   if (store && storage)
822   {
823      MONITOR_REAL_DELETE("Free (CleanUp)    ",storage,store)
824      REPORT delete [] store;
825   }
826   store=0; storage=0; nrows=0; ncols=0;
827}
828
829void nricMatrix::CleanUp()
830{ DeleteRowPointer(); GeneralMatrix::CleanUp(); }
831
832void RowVector::CleanUp()
833{ GeneralMatrix::CleanUp(); nrows=1; }
834
835void ColumnVector::CleanUp()
836{ GeneralMatrix::CleanUp(); ncols=1; }
837
838void CroutMatrix::CleanUp()
839{
840   if (nrows) delete [] indx;
841   GeneralMatrix::CleanUp();
842}
843
844void BandLUMatrix::CleanUp()
845{
846   if (nrows) delete [] indx;
847   if (storage2) delete [] store2;
848   GeneralMatrix::CleanUp();
849}
850
851// ************************ simple integer array class ***********************
852
853// construct a new array of length xn. Check that xn is non-negative and
854// that space is available
855
856SimpleIntArray::SimpleIntArray(int xn) : n(xn)
857{
858   if (n < 0) Throw(Logic_error("invalid array length"));
859   else if (n == 0) { REPORT  a = 0; }
860   else { REPORT  a = new int [n]; if (!a) Throw(Bad_alloc()); }
861}
862
863// destroy an array - return its space to memory
864
865SimpleIntArray::~SimpleIntArray() { REPORT  if (a) delete [] a; }
866
867// access an element of an array; return a "reference" so elements
868// can be modified.
869// check index is within range
870// in this array class the index runs from 0 to n-1
871
872int& SimpleIntArray::operator[](int i)
873{
874   REPORT
875   if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
876   return a[i];
877}
878
879// same thing again but for arrays declared constant so we can't
880// modify its elements
881
882int SimpleIntArray::operator[](int i) const
883{
884   REPORT
885   if (i < 0 || i >= n) Throw(Logic_error("array index out of range"));
886   return a[i];
887}
888
889// set all the elements equal to a given value
890
891void SimpleIntArray::operator=(int ai)
892   { REPORT  for (int i = 0; i < n; i++) a[i] = ai; }
893
894// set the elements equal to those of another array.
895// check the arrays are of the same length
896
897void SimpleIntArray::operator=(const SimpleIntArray& b)
898{
899   REPORT
900   if (b.n != n) Throw(Logic_error("array lengths differ in copy"));
901   for (int i = 0; i < n; i++) a[i] = b.a[i];
902}
903
904// construct a new array equal to an existing array
905// check that space is available
906
907SimpleIntArray::SimpleIntArray(const SimpleIntArray& b) : n(b.n)
908{
909   if (n == 0) { REPORT  a = 0; }
910   else
911   {
912      REPORT
913      a = new int [n]; if (!a) Throw(Bad_alloc());
914      for (int i = 0; i < n; i++) a[i] = b.a[i];
915   }
916}
917
918// change the size of an array; optionally copy data from old array to
919// new array
920
921void SimpleIntArray::ReSize(int n1, bool keep)
922{
923   if (n1 == n) { REPORT  return; }
924   else if (n1 == 0) { REPORT  n = 0; delete [] a; a = 0; }
925   else if (n == 0)
926      { REPORT  a = new int [n1]; if (!a) Throw(Bad_alloc()); n = n1; }
927   else
928   {
929      int* a1 = a;
930      if (keep)
931      {
932         REPORT
933         a = new int [n1]; if (!a) Throw(Bad_alloc());
934         if (n > n1) n = n1;
935         for (int i = 0; i < n; i++) a[i] = a1[i];
936         n = n1; delete [] a1;
937      }
938      else
939      {
940         REPORT  n = n1; delete [] a1;
941         a = new int [n]; if (!a) Throw(Bad_alloc());
942      }
943   }
944}
945
946
947#ifdef use_namespace
948}
949#endif
950
Note: See TracBrowser for help on using the repository browser.