Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/newmat/newmat3.cpp @ 4572

Last change on this file since 4572 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: 23.8 KB
Line 
1//$$ newmat3.cpp        Matrix get and restore rows and columns
2
3// Copyright (C) 1991,2,3,4: R B Davies
4
5//#define WANT_STREAM
6
7#include "include.h"
8
9#include "newmat.h"
10#include "newmatrc.h"
11
12#ifdef use_namespace
13namespace NEWMAT {
14#endif
15
16
17#ifdef DO_REPORT
18#define REPORT { static ExeCounter ExeCount(__LINE__,3); ++ExeCount; }
19#else
20#define REPORT {}
21#endif
22
23//#define MONITOR(what,storage,store)
24//   { cout << what << " " << storage << " at " << (long)store << "\n"; }
25
26#define MONITOR(what,store,storage) {}
27
28
29// Control bits codes for GetRow, GetCol, RestoreRow, RestoreCol
30//
31// LoadOnEntry:
32//    Load data into MatrixRow or Col dummy array under GetRow or GetCol
33// StoreOnExit:
34//    Restore data to original matrix under RestoreRow or RestoreCol
35// DirectPart:
36//    Load or restore only part directly stored; must be set with StoreOnExit
37//    Still have decide how to handle this with symmetric
38// StoreHere:
39//    used in columns only - store data at supplied storage address;
40//    used for GetCol, NextCol & RestoreCol. No need to fill out zeros
41// HaveStore:
42//    dummy array has been assigned (internal use only).
43
44// For symmetric matrices, treat columns as rows unless StoreHere is set;
45// then stick to columns as this will give better performance for doing
46// inverses
47
48// How components are used:
49
50// Use rows wherever possible in preference to columns
51
52// Columns without StoreHere are used in in-exact transpose, sum column,
53// multiply a column vector, and maybe in future access to column,
54// additional multiply functions, add transpose
55
56// Columns with StoreHere are used in exact transpose (not symmetric matrices
57// or vectors, load only)
58
59// Columns with MatrixColX (Store to full column) are used in inverse and solve
60
61// Functions required for each matrix class
62
63// GetRow(MatrixRowCol& mrc)
64// GetCol(MatrixRowCol& mrc)
65// GetCol(MatrixColX& mrc)
66// RestoreRow(MatrixRowCol& mrc)
67// RestoreCol(MatrixRowCol& mrc)
68// RestoreCol(MatrixColX& mrc)
69// NextRow(MatrixRowCol& mrc)
70// NextCol(MatrixRowCol& mrc)
71// NextCol(MatrixColX& mrc)
72
73// The Restore routines assume StoreOnExit has already been checked
74// Defaults for the Next routines are given below
75// Assume cannot have both !DirectPart && StoreHere for MatrixRowCol routines
76
77
78// Default NextRow and NextCol:
79// will work as a default but need to override NextRow for efficiency
80
81void GeneralMatrix::NextRow(MatrixRowCol& mrc)
82{
83   REPORT
84   if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreRow(mrc); }
85   mrc.rowcol++;
86   if (mrc.rowcol<nrows) { REPORT this->GetRow(mrc); }
87   else { REPORT mrc.cw -= StoreOnExit; }
88}
89
90void GeneralMatrix::NextCol(MatrixRowCol& mrc)
91{
92   REPORT                                                // 423
93   if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
94   mrc.rowcol++;
95   if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); }
96   else { REPORT mrc.cw -= StoreOnExit; }
97}
98
99void GeneralMatrix::NextCol(MatrixColX& mrc)
100{
101   REPORT                                                // 423
102   if (+(mrc.cw*StoreOnExit)) { REPORT this->RestoreCol(mrc); }
103   mrc.rowcol++;
104   if (mrc.rowcol<ncols) { REPORT this->GetCol(mrc); }
105   else { REPORT mrc.cw -= StoreOnExit; }
106}
107
108
109// routines for matrix
110
111void Matrix::GetRow(MatrixRowCol& mrc)
112{
113   REPORT
114   mrc.skip=0; mrc.storage=mrc.length=ncols; mrc.data=store+mrc.rowcol*ncols;
115}
116
117
118void Matrix::GetCol(MatrixRowCol& mrc)
119{
120   REPORT
121   mrc.skip=0; mrc.storage=mrc.length=nrows;
122   if ( ncols==1 && !(mrc.cw*StoreHere) )      // ColumnVector
123      { REPORT mrc.data=store; }
124   else
125   {
126      Real* ColCopy;
127      if ( !(mrc.cw*(HaveStore+StoreHere)) )
128      {
129         REPORT
130         ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
131         MONITOR_REAL_NEW("Make (MatGetCol)",nrows,ColCopy)
132         mrc.data = ColCopy; mrc.cw += HaveStore;
133      }
134      else { REPORT ColCopy = mrc.data; }
135      if (+(mrc.cw*LoadOnEntry))
136      {
137         REPORT
138         Real* Mstore = store+mrc.rowcol; int i=nrows;
139         //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
140         if (i) for (;;)
141            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
142      }
143   }
144}
145
146void Matrix::GetCol(MatrixColX& mrc)
147{
148   REPORT
149   mrc.skip=0; mrc.storage=nrows; mrc.length=nrows;
150   if (+(mrc.cw*LoadOnEntry))
151   {
152      REPORT  Real* ColCopy = mrc.data;
153      Real* Mstore = store+mrc.rowcol; int i=nrows;
154      //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
155      if (i) for (;;)
156          { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
157   }
158}
159
160void Matrix::RestoreCol(MatrixRowCol& mrc)
161{
162   // always check StoreOnExit before calling RestoreCol
163   REPORT                                   // 429
164   if (+(mrc.cw*HaveStore))
165   {
166      REPORT                                // 426
167      Real* Mstore = store+mrc.rowcol; int i=nrows;
168      Real* Cstore = mrc.data;
169      // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; }
170      if (i) for (;;)
171          { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }
172   }
173}
174
175void Matrix::RestoreCol(MatrixColX& mrc)
176{
177   REPORT
178   Real* Mstore = store+mrc.rowcol; int i=nrows; Real* Cstore = mrc.data;
179   // while (i--) { *Mstore = *Cstore++; Mstore+=ncols; }
180   if (i) for (;;)
181      { *Mstore = *Cstore++; if (!(--i)) break; Mstore+=ncols; }
182}
183
184void Matrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrMat(); }  // 1808
185
186void Matrix::NextCol(MatrixRowCol& mrc)
187{
188   REPORT                                        // 632
189   if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
190   mrc.rowcol++;
191   if (mrc.rowcol<ncols)
192   {
193      if (+(mrc.cw*LoadOnEntry))
194      {
195         REPORT
196         Real* ColCopy = mrc.data;
197         Real* Mstore = store+mrc.rowcol; int i=nrows;
198         //while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
199         if (i) for (;;)
200            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
201      }
202   }
203   else { REPORT mrc.cw -= StoreOnExit; }
204}
205
206void Matrix::NextCol(MatrixColX& mrc)
207{
208   REPORT
209   if (+(mrc.cw*StoreOnExit)) { REPORT RestoreCol(mrc); }
210   mrc.rowcol++;
211   if (mrc.rowcol<ncols)
212   {
213      if (+(mrc.cw*LoadOnEntry))
214      {
215         REPORT
216         Real* ColCopy = mrc.data;
217         Real* Mstore = store+mrc.rowcol; int i=nrows;
218         // while (i--) { *ColCopy++ = *Mstore; Mstore+=ncols; }
219         if (i) for (;;)
220            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore+=ncols; }
221      }
222   }
223   else { REPORT mrc.cw -= StoreOnExit; }
224}
225
226// routines for diagonal matrix
227
228void DiagonalMatrix::GetRow(MatrixRowCol& mrc)
229{
230   REPORT
231   mrc.skip=mrc.rowcol; mrc.storage=1;
232   mrc.data=store+mrc.skip; mrc.length=ncols;
233}
234
235void DiagonalMatrix::GetCol(MatrixRowCol& mrc)
236{
237   REPORT
238   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
239   if (+(mrc.cw*StoreHere))              // should not happen
240      Throw(InternalException("DiagonalMatrix::GetCol(MatrixRowCol&)"));
241   else  { REPORT mrc.data=store+mrc.skip; }
242                                                      // not accessed
243}
244
245void DiagonalMatrix::GetCol(MatrixColX& mrc)
246{
247   REPORT
248   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
249   mrc.data = mrc.store+mrc.skip;
250   *(mrc.data)=*(store+mrc.skip);
251}
252
253void DiagonalMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
254                                                      // 800
255
256void DiagonalMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrDiag(); }
257                        // not accessed
258
259void DiagonalMatrix::NextCol(MatrixColX& mrc)
260{
261   REPORT
262   if (+(mrc.cw*StoreOnExit))
263      { REPORT *(store+mrc.rowcol)=*(mrc.data); }
264   mrc.IncrDiag();
265   int t1 = +(mrc.cw*LoadOnEntry);
266   if (t1 && mrc.rowcol < ncols)
267      { REPORT *(mrc.data)=*(store+mrc.rowcol); }
268}
269
270// routines for upper triangular matrix
271
272void UpperTriangularMatrix::GetRow(MatrixRowCol& mrc)
273{
274   REPORT
275   int row = mrc.rowcol; mrc.skip=row; mrc.length=ncols;
276   mrc.storage=ncols-row; mrc.data=store+(row*(2*ncols-row+1))/2;
277}
278
279
280void UpperTriangularMatrix::GetCol(MatrixRowCol& mrc)
281{
282   REPORT
283   mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
284   mrc.length=nrows; Real* ColCopy;
285   if ( !(mrc.cw*(StoreHere+HaveStore)) )
286   {
287      REPORT                                              // not accessed
288      ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
289      MONITOR_REAL_NEW("Make (UT GetCol)",nrows,ColCopy)
290      mrc.data = ColCopy; mrc.cw += HaveStore;
291   }
292   else { REPORT ColCopy = mrc.data; }
293   if (+(mrc.cw*LoadOnEntry))
294   {
295      REPORT
296      Real* Mstore = store+mrc.rowcol; int j = ncols;
297      // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; }
298      if (i) for (;;)
299         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
300   }
301}
302
303void UpperTriangularMatrix::GetCol(MatrixColX& mrc)
304{
305   REPORT
306   mrc.skip=0; int i=mrc.rowcol+1; mrc.storage=i;
307   mrc.length=nrows;
308   if (+(mrc.cw*LoadOnEntry))
309   {
310      REPORT
311      Real* ColCopy = mrc.data;
312      Real* Mstore = store+mrc.rowcol; int j = ncols;
313      // while (i--) { *ColCopy++ = *Mstore; Mstore += --j; }
314      if (i) for (;;)
315         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += --j; }
316   }
317}
318
319void UpperTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
320{
321  REPORT
322  Real* Mstore = store+mrc.rowcol; int i=mrc.rowcol+1; int j = ncols;
323  Real* Cstore = mrc.data;
324  // while (i--) { *Mstore = *Cstore++; Mstore += --j; }
325  if (i) for (;;)
326     { *Mstore = *Cstore++; if (!(--i)) break; Mstore += --j; }
327}
328
329void UpperTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrUT(); }
330                                                      // 722
331
332// routines for lower triangular matrix
333
334void LowerTriangularMatrix::GetRow(MatrixRowCol& mrc)
335{
336   REPORT
337   int row=mrc.rowcol; mrc.skip=0; mrc.storage=row+1; mrc.length=ncols;
338   mrc.data=store+(row*(row+1))/2;
339}
340
341void LowerTriangularMatrix::GetCol(MatrixRowCol& mrc)
342{
343   REPORT
344   int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows;
345   int i=nrows-col; mrc.storage=i; Real* ColCopy;
346   if ( +(mrc.cw*(StoreHere+HaveStore)) )
347      { REPORT  ColCopy = mrc.data; }
348   else
349   {
350      REPORT                                            // not accessed
351      ColCopy = new Real [nrows]; MatrixErrorNoSpace(ColCopy);
352      MONITOR_REAL_NEW("Make (LT GetCol)",nrows,ColCopy)
353      mrc.cw += HaveStore; mrc.data = ColCopy;
354   }
355
356   if (+(mrc.cw*LoadOnEntry))
357   {
358      REPORT
359      Real* Mstore = store+(col*(col+3))/2;
360      // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
361      if (i) for (;;)
362         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
363   }
364}
365
366void LowerTriangularMatrix::GetCol(MatrixColX& mrc)
367{
368   REPORT
369   int col=mrc.rowcol; mrc.skip=col; mrc.length=nrows;
370   int i=nrows-col; mrc.storage=i; mrc.data = mrc.store + col;
371
372   if (+(mrc.cw*LoadOnEntry))
373   {
374      REPORT  Real* ColCopy = mrc.data;
375      Real* Mstore = store+(col*(col+3))/2;
376      // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
377      if (i) for (;;)
378         { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
379   }
380}
381
382void LowerTriangularMatrix::RestoreCol(MatrixRowCol& mrc)
383{
384   REPORT
385   int col=mrc.rowcol; Real* Cstore = mrc.data;
386   Real* Mstore = store+(col*(col+3))/2; int i=nrows-col;
387   //while (i--) { *Mstore = *Cstore++; Mstore += ++col; }
388   if (i) for (;;)
389      { *Mstore = *Cstore++; if (!(--i)) break; Mstore += ++col; }
390}
391
392void LowerTriangularMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrLT(); }
393                                                         //712
394
395// routines for symmetric matrix
396
397void SymmetricMatrix::GetRow(MatrixRowCol& mrc)
398{
399   REPORT                                                //571
400   mrc.skip=0; int row=mrc.rowcol; mrc.length=ncols;
401   if (+(mrc.cw*DirectPart))
402      { REPORT mrc.storage=row+1; mrc.data=store+(row*(row+1))/2; }
403   else
404   {
405      // do not allow StoreOnExit and !DirectPart
406      if (+(mrc.cw*StoreOnExit))
407         Throw(InternalException("SymmetricMatrix::GetRow(MatrixRowCol&)"));
408      mrc.storage=ncols; Real* RowCopy;
409      if (!(mrc.cw*HaveStore))
410      {
411         REPORT
412         RowCopy = new Real [ncols]; MatrixErrorNoSpace(RowCopy);
413         MONITOR_REAL_NEW("Make (SymGetRow)",ncols,RowCopy)
414         mrc.cw += HaveStore; mrc.data = RowCopy;
415      }
416      else { REPORT RowCopy = mrc.data; }
417      if (+(mrc.cw*LoadOnEntry))
418      {
419         REPORT                                         // 544
420         Real* Mstore = store+(row*(row+1))/2; int i = row;
421         while (i--) *RowCopy++ = *Mstore++;
422         i = ncols-row;
423         // while (i--) { *RowCopy++ = *Mstore; Mstore += ++row; }
424         if (i) for (;;)
425            { *RowCopy++ = *Mstore; if (!(--i)) break; Mstore += ++row; }
426      }
427   }
428}
429
430void SymmetricMatrix::GetCol(MatrixRowCol& mrc)
431{
432   // do not allow StoreHere
433   if (+(mrc.cw*StoreHere))
434      Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
435
436   int col=mrc.rowcol; mrc.length=nrows;
437   REPORT
438   mrc.skip=0;
439   if (+(mrc.cw*DirectPart))    // actually get row ??
440      { REPORT mrc.storage=col+1; mrc.data=store+(col*(col+1))/2; }
441   else
442   {
443      // do not allow StoreOnExit and !DirectPart
444      if (+(mrc.cw*StoreOnExit))
445         Throw(InternalException("SymmetricMatrix::GetCol(MatrixRowCol&)"));
446
447      mrc.storage=ncols; Real* ColCopy;
448      if ( +(mrc.cw*HaveStore)) { REPORT ColCopy = mrc.data; }
449      else
450      {
451         REPORT                                      // not accessed
452         ColCopy = new Real [ncols]; MatrixErrorNoSpace(ColCopy);
453         MONITOR_REAL_NEW("Make (SymGetCol)",ncols,ColCopy)
454         mrc.cw += HaveStore; mrc.data = ColCopy;
455      }
456      if (+(mrc.cw*LoadOnEntry))
457      {
458         REPORT
459         Real* Mstore = store+(col*(col+1))/2; int i = col;
460         while (i--) *ColCopy++ = *Mstore++;
461         i = ncols-col;
462         // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
463         if (i) for (;;)
464            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
465      }
466   }
467}
468
469void SymmetricMatrix::GetCol(MatrixColX& mrc)
470{
471   int col=mrc.rowcol; mrc.length=nrows;
472   if (+(mrc.cw*DirectPart))
473   {
474      REPORT
475      mrc.skip=col; int i=nrows-col; mrc.storage=i;
476      mrc.data = mrc.store+col;
477      if (+(mrc.cw*LoadOnEntry))
478      {
479         REPORT                           // not accessed
480         Real* ColCopy = mrc.data;
481         Real* Mstore = store+(col*(col+3))/2;
482         // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
483         if (i) for (;;)
484            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
485      }
486   }
487   else
488   {
489      REPORT
490      // do not allow StoreOnExit and !DirectPart
491      if (+(mrc.cw*StoreOnExit))
492         Throw(InternalException("SymmetricMatrix::GetCol(MatrixColX&)"));
493
494      mrc.skip=0; mrc.storage=ncols;
495      if (+(mrc.cw*LoadOnEntry))
496      {
497         REPORT
498         Real* ColCopy = mrc.data;
499         Real* Mstore = store+(col*(col+1))/2; int i = col;
500         while (i--) *ColCopy++ = *Mstore++;
501         i = ncols-col;
502         // while (i--) { *ColCopy++ = *Mstore; Mstore += ++col; }
503         if (i) for (;;)
504            { *ColCopy++ = *Mstore; if (!(--i)) break; Mstore += ++col; }
505      }
506   }
507}
508
509// Do not need RestoreRow because we do not allow !DirectPart && StoreOnExit
510
511void SymmetricMatrix::RestoreCol(MatrixColX& mrc)
512{
513   REPORT
514   // Really do restore column
515   int col=mrc.rowcol; Real* Cstore = mrc.data;
516   Real* Mstore = store+(col*(col+3))/2; int i = nrows-col;
517   // while (i--) { *Mstore = *Cstore++; Mstore+= ++col; }
518   if (i) for (;;)
519      { *Mstore = *Cstore++; if (!(--i)) break; Mstore+= ++col; }
520
521}
522
523// routines for row vector
524
525void RowVector::GetCol(MatrixRowCol& mrc)
526{
527   REPORT
528   // do not allow StoreHere
529   if (+(mrc.cw*StoreHere))
530      Throw(InternalException("RowVector::GetCol(MatrixRowCol&)"));
531
532   mrc.skip=0; mrc.storage=1; mrc.length=nrows; mrc.data = store+mrc.rowcol;
533
534}
535
536void RowVector::GetCol(MatrixColX& mrc)
537{
538   REPORT
539   mrc.skip=0; mrc.storage=1; mrc.length=nrows;
540   if (mrc.cw >= LoadOnEntry)
541      { REPORT *(mrc.data) = *(store+mrc.rowcol); }
542
543}
544
545void RowVector::NextCol(MatrixRowCol& mrc)
546{ REPORT mrc.rowcol++; mrc.data++; }
547
548void RowVector::NextCol(MatrixColX& mrc)
549{
550   if (+(mrc.cw*StoreOnExit)) { REPORT *(store+mrc.rowcol)=*(mrc.data); }
551
552   mrc.rowcol++;
553   if (mrc.rowcol < ncols)
554   {
555      if (+(mrc.cw*LoadOnEntry)) { REPORT *(mrc.data)=*(store+mrc.rowcol); }
556   }
557   else { REPORT mrc.cw -= StoreOnExit; }
558}
559
560void RowVector::RestoreCol(MatrixColX& mrc)
561   { REPORT *(store+mrc.rowcol)=*(mrc.data); }           // not accessed
562
563
564// routines for band matrices
565
566void BandMatrix::GetRow(MatrixRowCol& mrc)
567{
568   REPORT
569   int r = mrc.rowcol; int w = lower+1+upper; mrc.length=ncols;
570   int s = r-lower;
571   if (s<0) { mrc.data = store+(r*w-s); w += s; s = 0; }
572   else mrc.data = store+r*w;
573   mrc.skip = s; s += w-ncols; if (s>0) w -= s; mrc.storage = w;
574}
575
576// should make special versions of this for upper and lower band matrices
577
578void BandMatrix::NextRow(MatrixRowCol& mrc)
579{
580   REPORT
581   int r = ++mrc.rowcol;
582   if (r<=lower) { mrc.storage++; mrc.data += lower+upper; }
583   else  { mrc.skip++; mrc.data += lower+upper+1; }
584   if (r>=ncols-upper) mrc.storage--;
585}
586
587void BandMatrix::GetCol(MatrixRowCol& mrc)
588{
589   REPORT
590   int c = mrc.rowcol; int n = lower+upper; int w = n+1;
591   mrc.length=nrows; Real* ColCopy;
592   int b; int s = c-upper;
593   if (s<=0) { w += s; s = 0; b = c+lower; } else b = s*w+n;
594   mrc.skip = s; s += w-nrows; if (s>0) w -= s; mrc.storage = w;
595   if ( +(mrc.cw*(StoreHere+HaveStore)) )
596      { REPORT ColCopy = mrc.data; }
597   else
598   {
599      REPORT
600      ColCopy = new Real [n+1]; MatrixErrorNoSpace(ColCopy);
601      MONITOR_REAL_NEW("Make (BMGetCol)",n+1,ColCopy)
602      mrc.cw += HaveStore; mrc.data = ColCopy;
603   }
604
605   if (+(mrc.cw*LoadOnEntry))
606   {
607      REPORT
608      Real* Mstore = store+b;
609      // while (w--) { *ColCopy++ = *Mstore; Mstore+=n; }
610      if (w) for (;;)
611         { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
612   }
613}
614
615void BandMatrix::GetCol(MatrixColX& mrc)
616{
617   REPORT
618   int c = mrc.rowcol; int n = lower+upper; int w = n+1;
619   mrc.length=nrows; int b; int s = c-upper;
620   if (s<=0) { w += s; s = 0; b = c+lower; } else b = s*w+n;
621   mrc.skip = s; s += w-nrows; if (s>0) w -= s; mrc.storage = w;
622   mrc.data = mrc.store+mrc.skip;
623
624   if (+(mrc.cw*LoadOnEntry))
625   {
626      REPORT
627      Real* ColCopy = mrc.data; Real* Mstore = store+b;
628      // while (w--) { *ColCopy++ = *Mstore; Mstore+=n; }
629      if (w) for (;;)
630         { *ColCopy++ = *Mstore; if (!(--w)) break; Mstore+=n; }
631   }
632}
633
634void BandMatrix::RestoreCol(MatrixRowCol& mrc)
635{
636   REPORT
637   int c = mrc.rowcol; int n = lower+upper; int s = c-upper;
638   Real* Mstore = store + ((s<=0) ? c+lower : s*n+s+n);
639   Real* Cstore = mrc.data;
640   int w = mrc.storage;
641   // while (w--) { *Mstore = *Cstore++; Mstore += n; }
642   if (w) for (;;)
643      { *Mstore = *Cstore++; if (!(--w)) break; Mstore += n; }
644}
645
646// routines for symmetric band matrix
647
648void SymmetricBandMatrix::GetRow(MatrixRowCol& mrc)
649{
650   REPORT
651   int r=mrc.rowcol; int s = r-lower; int w1 = lower+1; int o = r*w1;
652   mrc.length = ncols;
653   if (s<0) { w1 += s; o -= s; s = 0; }
654   mrc.skip = s;
655
656   if (+(mrc.cw*DirectPart))
657      { REPORT  mrc.data = store+o; mrc.storage = w1; }
658   else
659   {
660      // do not allow StoreOnExit and !DirectPart
661      if (+(mrc.cw*StoreOnExit))
662         Throw(InternalException("SymmetricBandMatrix::GetRow(MatrixRowCol&)"));
663      int w = w1+lower; s += w-ncols; Real* RowCopy;
664      if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
665      if (!(mrc.cw*HaveStore))
666      {
667         REPORT
668         RowCopy = new Real [2*lower+1]; MatrixErrorNoSpace(RowCopy);
669         MONITOR_REAL_NEW("Make (SmBGetRow)",2*lower+1,RowCopy)
670         mrc.cw += HaveStore; mrc.data = RowCopy;
671      }
672      else { REPORT  RowCopy = mrc.data; }
673
674      if (+(mrc.cw*LoadOnEntry))
675      {
676              REPORT
677         Real* Mstore = store+o;
678         while (w1--) *RowCopy++ = *Mstore++;
679         Mstore--;
680         while (w2--) { Mstore += lower; *RowCopy++ = *Mstore; }
681      }
682   }
683}
684
685void SymmetricBandMatrix::GetCol(MatrixRowCol& mrc)
686{
687   // do not allow StoreHere
688   if (+(mrc.cw*StoreHere))
689      Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
690
691   int c=mrc.rowcol; int w1 = lower+1; mrc.length=nrows;
692   REPORT
693   int s = c-lower; int o = c*w1;
694   if (s<0) { w1 += s; o -= s; s = 0; }
695   mrc.skip = s;
696
697   if (+(mrc.cw*DirectPart))
698   { REPORT  mrc.data = store+o; mrc.storage = w1; }
699   else
700   {
701      // do not allow StoreOnExit and !DirectPart
702      if (+(mrc.cw*StoreOnExit))
703         Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
704      int w = w1+lower; s += w-ncols; Real* ColCopy;
705      if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
706
707      if ( +(mrc.cw*HaveStore) ) { REPORT ColCopy = mrc.data; }
708      else
709      {
710         REPORT ColCopy = new Real [2*lower+1]; MatrixErrorNoSpace(ColCopy);
711         MONITOR_REAL_NEW("Make (SmBGetCol)",2*lower+1,ColCopy)
712         mrc.cw += HaveStore; mrc.data = ColCopy;
713      }
714
715      if (+(mrc.cw*LoadOnEntry))
716      {
717         REPORT
718         Real* Mstore = store+o;
719         while (w1--) *ColCopy++ = *Mstore++;
720         Mstore--;
721         while (w2--) { Mstore += lower; *ColCopy++ = *Mstore; }
722      }
723   }
724}
725
726void SymmetricBandMatrix::GetCol(MatrixColX& mrc)
727{
728   int c=mrc.rowcol; int w1 = lower+1; mrc.length=nrows;
729   if (+(mrc.cw*DirectPart))
730   {
731      REPORT
732      int b = c*w1+lower;
733      mrc.skip = c; c += w1-nrows; w1 -= c; mrc.storage = w1;
734      Real* ColCopy = mrc.data = mrc.store+mrc.skip;
735      if (+(mrc.cw*LoadOnEntry))
736      {
737         REPORT
738         Real* Mstore = store+b;
739         // while (w1--) { *ColCopy++ = *Mstore; Mstore += lower; }
740         if (w1) for (;;)
741            { *ColCopy++ = *Mstore; if (!(--w1)) break; Mstore += lower; }
742      }
743   }
744   else
745   {
746      REPORT
747      // do not allow StoreOnExit and !DirectPart
748      if (+(mrc.cw*StoreOnExit))
749         Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixColX&)"));
750      int s = c-lower; int o = c*w1;
751      if (s<0) { w1 += s; o -= s; s = 0; }
752      mrc.skip = s;
753
754      int w = w1+lower; s += w-ncols;
755      if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
756
757      Real* ColCopy = mrc.data = mrc.store+mrc.skip;
758
759      if (+(mrc.cw*LoadOnEntry))
760      {
761         REPORT
762         Real* Mstore = store+o;
763         while (w1--) *ColCopy++ = *Mstore++;
764         Mstore--;
765         while (w2--) { Mstore += lower; *ColCopy++ = *Mstore; }
766      }
767
768   }
769}
770
771void SymmetricBandMatrix::RestoreCol(MatrixColX& mrc)
772{
773   REPORT
774   int c = mrc.rowcol;
775   Real* Mstore = store + c*lower+c+lower;
776   Real* Cstore = mrc.data; int w = mrc.storage;
777   // while (w--) { *Mstore = *Cstore++; Mstore += lower; }
778   if (w) for (;;)
779      { *Mstore = *Cstore++; if (!(--w)) break; Mstore += lower; }
780}
781
782// routines for identity matrix
783
784void IdentityMatrix::GetRow(MatrixRowCol& mrc)
785{
786   REPORT
787   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.data=store; mrc.length=ncols;
788}
789
790void IdentityMatrix::GetCol(MatrixRowCol& mrc)
791{
792   REPORT
793   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
794   if (+(mrc.cw*StoreHere))              // should not happen
795      Throw(InternalException("IdentityMatrix::GetCol(MatrixRowCol&)"));
796   else  { REPORT mrc.data=store; }
797}
798
799void IdentityMatrix::GetCol(MatrixColX& mrc)
800{
801   REPORT
802   mrc.skip=mrc.rowcol; mrc.storage=1; mrc.length=nrows;
803   mrc.data = mrc.store+mrc.skip; *(mrc.data)=*store;
804}
805
806void IdentityMatrix::NextRow(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
807
808void IdentityMatrix::NextCol(MatrixRowCol& mrc) { REPORT mrc.IncrId(); }
809
810void IdentityMatrix::NextCol(MatrixColX& mrc)
811{
812   REPORT
813   if (+(mrc.cw*StoreOnExit)) { REPORT *store=*(mrc.data); }
814   mrc.IncrDiag();            // must increase mrc.data so need IncrDiag
815   int t1 = +(mrc.cw*LoadOnEntry);
816   if (t1 && mrc.rowcol < ncols) { REPORT *(mrc.data)=*store; }
817}
818
819
820
821
822// *************************** destructors *******************************
823
824MatrixRowCol::~MatrixRowCol()
825{
826   if (+(cw*HaveStore))
827   {
828      MONITOR_REAL_DELETE("Free    (RowCol)",-1,data)  // do not know length
829      delete [] data;
830   }
831}
832
833MatrixRow::~MatrixRow() { if (+(cw*StoreOnExit)) gm->RestoreRow(*this); }
834
835MatrixCol::~MatrixCol() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
836
837MatrixColX::~MatrixColX() { if (+(cw*StoreOnExit)) gm->RestoreCol(*this); }
838
839#ifdef use_namespace
840}
841#endif
842
Note: See TracBrowser for help on using the repository browser.