source: Sophya/trunk/SophyaLib/NTools/matrix.cc@ 656

Last change on this file since 656 was 508, checked in by ansari, 26 years ago

Vector/Matrix OVector/OMatrix cmv 25/10/99

File size: 18.5 KB
Line 
1// $Id: matrix.cc,v 1.6 1999-10-25 10:36:09 ansari Exp $
2
3#include "machdefs.h"
4#include <string.h>
5#include <iostream.h>
6#include <iomanip.h>
7#include <values.h>
8#include "peida.h"
9#include "matrix.h"
10#include "cvector.h"
11#include "generalfit.h"
12#include "tmatrix.h"
13
14// Sous Linux, LN_MAXDOUBLE LN_MINDOUBLE ne semblent pas etre definies
15// Reza 11/02/99
16#ifndef M_LN2
17#define M_LN2 0.69314718055994530942
18#endif
19#ifndef LN_MINDOUBLE
20#define LN_MINDOUBLE (M_LN2 * (DMINEXP - 1))
21#endif
22#ifndef LN_MAXDOUBLE
23#define LN_MAXDOUBLE (M_LN2 * DMAXEXP)
24#endif
25
26
27//++
28// Class OMatrix
29// Lib Outils++
30// include matrix.h
31//
32// Classe générale de matrice, calculs matriciels et algèbre linéaire.
33//--
34
35//++
36// Titre Constructeurs
37//--
38
39//++
40OMatrix::OMatrix()
41//
42// Construit une matrice 1x1 (pour ppersist).
43//--
44: nr(1), nc(1), ndata(1), nalloc(1), data(new double[1]), FromTmatrix(false)
45{
46 // if (r<=0 || c<=0) THROW(rangeCheckErr);
47 memset(data, 0, nalloc*sizeof(double));
48 END_CONSTRUCTOR
49}
50
51//++
52OMatrix::OMatrix(int r, int c)
53//
54// Construit une matrice de r lignes et c colonnes.
55//--
56: nr(r), nc(c), ndata(r*c), nalloc(r*c), data(new double[r*c]), FromTmatrix(false)
57{
58 // if (r<=0 || c<=0) THROW(rangeCheckErr);
59 memset(data, 0, nalloc*sizeof(double));
60 END_CONSTRUCTOR
61}
62
63//++
64OMatrix::OMatrix(int r, int c, double* values)
65//
66// Construit une matrice de r lignes et c colonnes. On fournit
67// le tableau des valeurs : pas d'allocation.
68//--
69: nr(r), nc(c), ndata(r*c), nalloc(0), data(values), FromTmatrix(false)
70{
71 END_CONSTRUCTOR
72}
73
74//++
75OMatrix::OMatrix(const OMatrix& a)
76//
77// Constructeur par copie.
78//--
79: nr(a.nr), nc(a.nc), ndata(a.nr*a.nc), nalloc(a.nr*a.nc),
80 data(new double[a.nr*a.nc]), FromTmatrix(false)
81{
82 memcpy(data, a.data, nalloc * sizeof(double));
83 END_CONSTRUCTOR
84}
85
86//++
87OMatrix::OMatrix(const TMatrix<r_8>& a)
88//
89// Constructeur par copie a partir d'une TMatrix<r_8>.
90// Attention, les donnees sont partagees.
91//--
92: nr(a.NRows()), nc(a.NCols()), ndata(a.NRows()*a.NCols())
93, nalloc(a.NRows()*a.NCols())
94, data(const_cast<r_8 *>(a.Data()))
95, FromTmatrix(true)
96{
97 END_CONSTRUCTOR
98}
99
100
101OMatrix::~OMatrix()
102{
103 DBASSERT(ndata == nr*nc);
104 if (nalloc && !FromTmatrix) delete[] data;
105}
106
107//++
108// Titre Méthodes
109//--
110
111
112//++
113void OMatrix::Zero()
114//
115// Remise à zero de tous les éléments
116//--
117{
118 DBASSERT(ndata == nr*nc);
119 for (int i=0; i<ndata; i++) data[i] = 0;
120}
121
122//++
123void OMatrix::Realloc(int r, int c, bool force)
124//
125// Change la taille de la matrice. Réallocation physique seulement si
126// pas assez de place, ou forcée si force=true.
127//--
128{
129 DBASSERT(ndata == nr*nc);
130 if (!nalloc) THROW(allocationErr);
131 int ncop = ndata; // ancien elements
132 ndata = r*c;
133 if (ndata < ncop) ncop = ndata;
134 nr = r;
135 nc = c;
136 if (nalloc < ndata || force) {
137 double* p = new double[ndata];
138 memcpy(p,data,ncop * sizeof(double));
139 delete[] data;
140 data = p;
141 nalloc = ndata;
142 } else if (nalloc != ndata) // Sans doute facultatif, mais plus
143 memset(data+ndata, 0, (nalloc-ndata)*sizeof(double)); //propre
144}
145
146//++
147OMatrix& OMatrix::operator = (const OMatrix& a)
148//
149// Opérateur d'affectation.
150//--
151{
152 if (this == &a) return *this;
153 Realloc(a.nr, a.nc);
154 memcpy(data, a.data, ndata * sizeof(double));
155 return *this;
156}
157
158
159//++
160OMatrix& OMatrix::operator = (double x)
161//
162// Opérateur d'affectation depuis scalaire : identité * scalaire.
163//--
164{
165 if (nr != nc) THROW(sizeMismatchErr);
166 for (int r=0; r<nr; r++)
167 for (int c=0; c<nc; c++)
168 (*this)(r,c) = (r==c) ? x : 0.0;
169 return *this;
170}
171
172//++
173// r_8& [const] operator()(int r, int c) [const]
174// Accès aux éléments
175//--
176
177//++
178ostream& operator << (ostream& s, const OMatrix& a)
179//
180// Impression
181//--
182{
183 for (int r=0; r<a.nr; r++) {
184 s << "| ";
185 for (int c=0; c<a.nc; c++)
186 s << setw(6) << a(r,c) << " ";
187 s << "|\n";
188 }
189 return s;
190}
191
192// ****************** MATRIX / SCALAR ******************************
193
194
195//++
196OMatrix& OMatrix::operator *= (double b)
197//
198//--
199{
200 double* p = data;
201 double* pEnd = data + ndata;
202
203 while (p < pEnd)
204 *p++ *= b;
205
206 return *this;
207}
208
209//++
210OMatrix& OMatrix::operator += (double b)
211//
212//--
213{
214 double* p = data;
215 double* pEnd = data + ndata;
216
217 while (p < pEnd)
218 *p++ += b;
219
220 return *this;
221}
222
223//++
224OMatrix& OMatrix::operator -= (double b)
225//
226//--
227{
228 double* p = data;
229 double* pEnd = data + ndata;
230
231 while (p < pEnd)
232 *p++ -= b;
233
234 return *this;
235}
236
237//++
238OMatrix& OMatrix::operator /= (double b)
239//
240//--
241{
242 ASSERT( b != 0. );
243 double* p = data;
244 double* pEnd = data + ndata;
245
246 while (p < pEnd)
247 *p++ /= b;
248
249 return *this;
250}
251
252//++
253OMatrix operator * (const OMatrix& a, double b)
254//
255//--
256{
257 OMatrix result(a);
258 return (result *= b);
259}
260
261//++
262OMatrix operator * (double b, const OMatrix& a)
263//
264//--
265{
266 OMatrix result(a);
267 return (result *= b);
268}
269
270//++
271OMatrix operator + (const OMatrix& a, double b)
272//
273//--
274{
275 OMatrix result(a);
276 return (result += b);
277}
278
279//++
280OMatrix operator + (double b, const OMatrix& a)
281//
282//--
283{
284 OMatrix result(a);
285 return (result += b);
286}
287
288//++
289OMatrix operator - (const OMatrix& a, double b)
290//
291//--
292{
293 OMatrix result(a);
294 return (result -= b);
295}
296
297//++
298OMatrix operator - (double b, const OMatrix& a)
299//
300//--
301{
302 OMatrix result(a);
303 result *= -1;
304 return (result += b);
305}
306
307//++
308OMatrix operator / (const OMatrix& a, double b)
309//
310//--
311{
312 OMatrix result(a);
313 return (result /= b);
314}
315
316//++
317OMatrix operator * (const OMatrix& a, int b)
318//
319//--
320{
321 OMatrix result(a);
322 return (result *= b);
323}
324
325//++
326OMatrix operator * (int b, const OMatrix& a)
327//
328//--
329{
330 OMatrix result(a);
331 return (result *= b);
332}
333
334//++
335OMatrix operator + (const OMatrix& a, int b)
336//
337//--
338{
339 OMatrix result(a);
340 return (result += b);
341}
342
343//++
344OMatrix operator + (int b, const OMatrix& a)
345//
346//--
347{
348 OMatrix result(a);
349 return (result += b);
350}
351
352//++
353OMatrix operator - (const OMatrix& a, int b)
354//
355//--
356{
357 OMatrix result(a);
358 return (result -= b);
359}
360
361//++
362OMatrix operator - (int b, const OMatrix& a)
363//
364//--
365{
366 OMatrix result(a);
367 result *= -1;
368 return (result += b);
369}
370
371//++
372OMatrix operator / (const OMatrix& a, int b)
373//
374//--
375{
376 OMatrix result(a);
377 return (result /= b);
378}
379
380
381// **************** MATRIX / MATRIX ***********************88
382
383//++
384OMatrix& OMatrix::operator += (const OMatrix& a)
385//
386//--
387{
388 if (nc!=a.nc || nr!=a.nr) THROW(sizeMismatchErr);
389
390 double* p = data;
391 double* pEnd = data + ndata;
392 double* q = a.data;
393
394 while (p < pEnd)
395 *p++ += *q++;
396
397 return *this;
398}
399
400//++
401OMatrix& OMatrix::operator -= (const OMatrix& a)
402//
403//--
404{
405 if (nc!=a.nc || nr!=a.nr) THROW(sizeMismatchErr);
406
407 double* p = data;
408 double* pEnd = data + ndata;
409 double* q = a.data;
410
411 while (p < pEnd)
412 *p++ -= *q++;
413
414 return *this;
415}
416
417
418//++
419OMatrix& OMatrix::operator *= (const OMatrix& a)
420//
421//--
422{
423 if (nc != a.nc || nr != a.nr || nc != nr) THROW(sizeMismatchErr);
424
425 double* oldRow = new double[nr];
426 double* orEnd = oldRow + nc;
427 double* orp;
428 double* trp;
429
430 for (double* tr = data; tr < data+ndata; tr += nc) {
431 for (orp = oldRow, trp = tr;
432 orp < orEnd;)
433 *orp++ = *trp++;
434
435 double* ac;
436 double* acp;
437
438 for (trp = tr, ac = a.data; ac< a.data+nr; ac++, trp++) {
439 double sum = 0;
440 for (orp = oldRow, acp = ac; acp < ac+ndata; acp += nr, orp++)
441 sum += *orp * *acp;
442 *trp = sum;
443 }
444 }
445 delete[] oldRow;
446 return *this;
447}
448
449//++
450OMatrix operator + (const OMatrix& a, const OMatrix& b)
451//
452//--
453{
454 if (b.nc != a.nc || b.nr != a.nr) THROW(sizeMismatchErr);
455
456 OMatrix c(a);
457 return (c += b);
458}
459
460//++
461OMatrix operator - (const OMatrix& a, const OMatrix& b)
462//
463//--
464{
465 if (b.nc != a.nc || b.nr != a.nr) THROW(sizeMismatchErr);
466
467 OMatrix c(a);
468 return (c -= b);
469}
470
471#if 0
472
473OMatrix operator * (const OMatrix& a, const OMatrix& b)
474{
475 if (a.nc != b.nr) THROW(sizeMismatchErr);
476
477 OMatrix c(a.nr, b.nc);
478
479 double* pc = c.data;
480
481 double* pa = a.data;
482
483 double* pb = b.data;
484
485 for (int rc = 0; rc < c.nr; rc++) {
486 for (int cc = 0; cc < c.nc; cc++) { // boucle sur c
487 double sum = 0;
488 for (int ca = 0; ca < a.nc; ca++) { // boucle sur a & b
489 sum += *pa * *pb;
490 pa++;
491 pb += b.nc;
492 }
493 *pc++ = sum;
494 pa -= a.nc; // retour meme ligne
495 pb -= b.ndata - 1; // haut de la colonne suiv
496 }
497 // ligne suivante c
498 pb = b.data; // en revient en b(1,1)
499 pa += a.nc; // debut ligne suivante
500 }
501
502 return c;
503}
504#endif
505
506//++
507OMatrix operator * (const OMatrix& a, const OMatrix& b)
508//
509//--
510{
511 if (a.nc != b.nr) THROW(sizeMismatchErr);
512
513 OMatrix c(a.nr, b.nc);
514
515 for (int rc = 0; rc < c.nr; rc++)
516 for (int cc = 0; cc < c.nc; cc++) { // boucle sur c
517 double sum = 0;
518 for (int ca = 0; ca < a.nc; ca++) // boucle sur a & b
519 sum += a(rc,ca) * b(ca,cc);
520 c(rc,cc) = sum;
521 }
522
523 return c;
524
525}
526
527
528//++
529OMatrix OMatrix::Transpose() const
530//
531// Retourne la transposée.
532//--
533#if HAS_NAMED_RETURN
534return a(nc,nr)
535#endif
536{
537#if !HAS_NAMED_RETURN
538OMatrix a(nc,nr);
539#endif
540 for (int i=0; i<nr; i++)
541 for (int j=0; j<nc; j++)
542 a(j,i) = (*this)(i,j);
543#if !HAS_NAMED_RETURN
544return a;
545#endif
546}
547
548
549//++
550OMatrix OMatrix::Inverse() const
551//
552// Retourne la matrice inverse.
553//
554// *Exception* : singMatxErr si la matrice est singulière.
555//--
556#if HAS_NAMED_RETURN
557return b(nr,nc)
558#endif
559{
560#if !HAS_NAMED_RETURN
561OMatrix b(nc,nr);
562#endif
563 OMatrix a(*this);
564 b = 1.0;
565 if (fabs(OMatrix::GausPiv(a,b)) < 1.e-50) THROW(singMatxErr);
566#if !HAS_NAMED_RETURN
567return b;
568#endif
569}
570
571
572void OMatrix::WriteSelf(POutPersist& s) const
573{
574 ASSERT(ndata == nr*nc);
575 s << nr << nc;
576 s.PutR8s(data, ndata);
577}
578
579void OMatrix::ReadSelf(PInPersist& s)
580{
581 int_4 r,c;
582 s >> r >> c;
583 Realloc(r,c);
584 ASSERT(ndata == nr*nc);
585 s.GetR8s(data, ndata);
586}
587
588
589OMatrixRC::OMatrixRC()
590: matrix(0), data(0), index(0), step(0)
591{}
592
593OMatrixRC::OMatrixRC(OMatrix& m, RCKind rckind, int ind)
594: matrix(&m), data(Org(m,rckind,ind)),
595 index(ind), step(Step(m,rckind)), kind(rckind)
596{
597 if (kind == matrixDiag & m.nc != m.nr) THROW(sizeMismatchErr);
598}
599
600
601int OMatrixRC::Next()
602{
603 if (!matrix) return -1; // Failure ?
604 if (kind == matrixDiag) return -1; // Failure ?
605 index++;
606 if (kind == matrixRow) {
607 if (index > matrix->nr) {
608 index = matrix->nr;
609 return -1;
610 }
611 data += matrix->nc;
612 } else {
613 if (index > matrix->nc) {
614 index = matrix->nc;
615 return -1;
616 }
617 data++;
618 }
619 return index;
620}
621
622
623int OMatrixRC::Prev()
624{
625 if (!matrix) return -1; // Failure ?
626 if (kind == matrixDiag) return -1; // Failure ?
627 index--;
628 if (index < 0) {
629 index = 0;
630 return -1;
631 }
632 if (kind == matrixRow)
633 data -= matrix->nc;
634 else
635 data--;
636 return index;
637}
638
639
640int OMatrixRC::SetCol(int c)
641{
642 if (!matrix) return -1; // Failure ?
643 if (c<0 || c>matrix->nc) return -1;
644 kind = matrixCol;
645 index = c;
646 step = Step(*matrix, matrixCol);
647 data = Org(*matrix, matrixCol, c);
648 return c;
649}
650
651
652int OMatrixRC::SetRow(int r)
653{
654 if (!matrix) return -1; // Failure ?
655 if (r<0 || r>matrix->nr) return -1;
656 kind = matrixRow;
657 index = r;
658 step = Step(*matrix, matrixRow);
659 data = Org(*matrix, matrixRow, r);
660 return r;
661}
662
663
664int OMatrixRC::SetDiag()
665{
666 if (!matrix) return -1; // Failure ?
667 if (matrix->nc != matrix->nr) THROW(sizeMismatchErr);
668 kind = matrixDiag;
669 index = 0;
670 step = Step(*matrix, matrixDiag);
671 data = Org(*matrix, matrixDiag);
672 return 0;
673}
674
675
676OMatrixRC& OMatrixRC::operator = (const OMatrixRC& rc)
677{
678 matrix = rc.matrix;
679 data = rc.data;
680 index = rc.index;
681 step = rc.step;
682 kind = rc.kind;
683 return *this;
684}
685
686//OMatrixRC::operator OVector() const
687OVector OMatrixRC::GetVect() const
688#if HAS_NAMED_RETURN
689return v(NElts())
690#endif
691{
692#if !HAS_NAMED_RETURN
693 OVector v(NElts());
694#endif
695 int n = NElts();
696 for (int i=0; i<n; i++)
697 v(i) = (*this)(i);
698#if !HAS_NAMED_RETURN
699 return v;
700#endif
701}
702
703
704OMatrixRC& OMatrixRC::operator += (const OMatrixRC& rc)
705{
706 int n = NElts();
707 if ( n != rc.NElts() ) THROW(sizeMismatchErr);
708 if ( kind != rc.kind ) THROW(sizeMismatchErr);
709
710 for (int i=0; i<n; i++)
711 (*this)(i) += rc(i);
712
713 return *this;
714}
715
716
717
718OMatrixRC& OMatrixRC::operator -= (const OMatrixRC& rc)
719{
720 int n = NElts();
721 if ( n != rc.NElts() ) THROW(sizeMismatchErr);
722 if ( kind != rc.kind ) THROW(sizeMismatchErr);
723
724 for (int i=0; i<n; i++)
725 (*this)(i) -= rc(i);
726
727 return *this;
728}
729
730
731OMatrixRC& OMatrixRC::operator *= (double x)
732{
733 int n = NElts();
734
735 for (int i=0; i<n; i++)
736 (*this)(i) *= x;
737
738 return *this;
739}
740
741
742OMatrixRC& OMatrixRC::operator /= (double x)
743{
744 int n = NElts();
745
746 for (int i=0; i<n; i++)
747 (*this)(i) /= x;
748
749 return *this;
750}
751
752
753OMatrixRC& OMatrixRC::operator -= (double x)
754{
755 int n = NElts();
756
757 for (int i=0; i<n; i++)
758 (*this)(i) -= x;
759
760 return *this;
761}
762
763
764OMatrixRC& OMatrixRC::operator += (double x)
765{
766 int n = NElts();
767
768 for (int i=0; i<n; i++)
769 (*this)(i) += x;
770
771 return *this;
772
773}
774
775
776double operator * (const OMatrixRC& a, const OMatrixRC& b)
777{
778 int n = a.NElts();
779 if ( n != b.NElts() ) THROW(sizeMismatchErr);
780 if ( a.kind != b.kind ) THROW(sizeMismatchErr);
781 double sum = 0;
782 for (int i=0; i<n; i++)
783 sum += a(i)*b(i);
784 return sum;
785}
786
787
788OMatrixRC& OMatrixRC::LinComb(double a, double b, const OMatrixRC& rc, int first)
789{
790 int n = NElts();
791 if ( n != rc.NElts() ) THROW(sizeMismatchErr);
792 if ( kind != rc.kind ) THROW(sizeMismatchErr);
793
794 for (int i=first; i<n; i++)
795 (*this)(i) = (*this)(i)*a + rc(i)*b;
796
797 return *this;
798}
799
800
801OMatrixRC& OMatrixRC::LinComb(double b, const OMatrixRC& rc, int first)
802{
803 int n = NElts();
804 if ( n != rc.NElts() ) THROW(sizeMismatchErr);
805 if ( kind != rc.kind ) THROW(sizeMismatchErr);
806
807 for (int i=first; i<n; i++)
808 (*this)(i) += rc(i)*b;
809
810 return *this;
811}
812
813
814
815OMatrixRC OMatrix::Row(int r) const
816#if HAS_NAMED_RETURN
817return rc((OMatrix&)*this, matrixRow, r)
818#endif
819{
820#if !HAS_NAMED_RETURN
821 OMatrixRC rc((OMatrix&)*this, matrixRow, r);
822 return rc;
823#endif
824}
825
826
827OMatrixRC OMatrix::Col(int c) const
828#if HAS_NAMED_RETURN
829return rc((OMatrix&)*this, matrixCol, c)
830#endif
831{
832#if !HAS_NAMED_RETURN
833 OMatrixRC rc((OMatrix&)*this, matrixCol, c);
834 return rc;
835#endif
836}
837
838
839OMatrixRC OMatrix::Diag() const
840#if HAS_NAMED_RETURN
841return rc((OMatrix&)*this, matrixDiag)
842#endif
843{
844#if !HAS_NAMED_RETURN
845 OMatrixRC rc((OMatrix&)*this, matrixDiag);
846 return rc;
847#endif
848}
849
850
851int OMatrixRC::IMaxAbs(int first)
852{
853 int n=NElts();
854 if (first>n) THROW(rangeCheckErr);
855 int imax=first;
856 double vmax = fabs((*this)(first));
857 double v;
858 for (int i=first+1; i<n; i++)
859 if ((v=fabs((*this)(i))) > vmax) {
860 vmax = v;
861 imax = i;
862 }
863 return imax;
864}
865
866
867void OMatrixRC::Swap(OMatrixRC& rc1, OMatrixRC& rc2)
868{
869 int n=rc1.NElts();
870 if (n != rc2.NElts()) THROW(sizeMismatchErr);
871 if (rc1.kind != rc2.kind) THROW(sizeMismatchErr);
872 if (rc1.data == rc2.data) return; // C'est le meme
873 for (int i=0; i<n; i++)
874 {double tmp = rc1(i); rc1(i) = rc2(i); rc2(i) = tmp;}
875}
876
877
878
879double OMatrix::GausPiv(OMatrix& a, OMatrix& b)
880{
881 int n = a.NRows();
882 if ( n != b.NRows()) THROW(sizeMismatchErr);
883
884 // On fait une normalisation un peu brutale...
885 double vmin=MAXDOUBLE;
886 double vmax=0;
887 for (int iii=0; iii<a.NRows(); iii++)
888 for (int jjj=0; jjj<a.NCol(); jjj++) {
889 if (fabs(a(iii,jjj)) > vmax) vmax = fabs(a(iii,jjj));
890 if (fabs(a(iii,jjj)) < vmin && fabs(a(iii,jjj))>0) vmin = fabs(a(iii,jjj));
891 }
892 double nrm = sqrt(vmin*vmax);
893 if (nrm > 1.e5 || nrm < 1.e-5) {
894 a /= nrm;
895 b /= nrm;
896 //cout << "normalisation matrice " << nrm << endl;
897 } else
898 nrm=1;
899
900 double det = 1.0;
901 if (nrm != 1) {
902 double ld = a.NRows() * log(nrm);
903 if (ld <= LN_MINDOUBLE || ld >= LN_MAXDOUBLE) {
904 // cerr << "OMatrix warning, overflow for det" << endl;
905 } else {
906 det = exp(ld);
907 }
908 }
909
910 OMatrixRC pivRowa(a,matrixRow);
911 OMatrixRC pivRowb(b,matrixRow);
912
913 for (int k=0; k<n-1; k++) {
914 int iPiv = a.Col(k).IMaxAbs(k);
915 if (iPiv != k) {
916 OMatrixRC aIPiv(a.Row(iPiv));
917 OMatrixRC aK(a.Row(k));
918 OMatrixRC::Swap(aIPiv,aK);
919 OMatrixRC bIPiv(b.Row(iPiv));
920 OMatrixRC bK(b.Row(k));
921 OMatrixRC::Swap(bIPiv,bK);
922 }
923 double pivot = a(k,k);
924 if (fabs(pivot) < 1.e-50) return 0.0;
925 //det *= pivot;
926 pivRowa.SetRow(k); // to avoid constructors
927 pivRowb.SetRow(k);
928 for (int i=k+1; i<n; i++) {
929 double r = -a(i,k)/pivot;
930 a.Row(i).LinComb(r, pivRowa); // + rapide que -= r * pivRowa
931 b.Row(i).LinComb(r, pivRowb);
932 }
933 }
934 det *= a(n-1, n-1);
935
936 // on remonte
937
938 for (int kk=n-1; kk>0; kk--) {
939 double pivot = a(kk,kk);
940 if (fabs(pivot) <= 1.e-50) return 0.0;
941 pivRowa.SetRow(kk); // to avoid constructors
942 pivRowb.SetRow(kk);
943 for (int jj=0; jj<kk; jj++) {
944 double r = -a(jj,kk)/pivot;
945 a.Row(jj).LinComb(r, pivRowa);
946 b.Row(jj).LinComb(r, pivRowb);
947 }
948 }
949
950
951 for (int l=0; l<n; l++) {
952 if (fabs(a(l,l)) <= 1.e-50) return 0.0;
953 b.Row(l) /= a(l,l);
954 }
955
956 return det;
957}
958
959//++
960double OMatrix::Norm1()
961//
962// Norme 1 : somme des valeurs absolues.
963//--
964{
965 double s = 0;
966 for (int k = 0; k < nr*nc; k++)
967 s += fabs(data[k]);
968 return s;
969}
970
971//++
972double OMatrix::Norm2()
973//
974// Norme 2, euclidienne.
975//--
976{
977 double s = 0;
978 for (int k = 0; k < nr*nc; k++)
979 s += data[k] * data[k];
980 return sqrt(s);
981}
982
983//////////////////////////////////////////////////////////
984//++
985OMatrix OMatrix::FitResidus(GeneralFit& gfit
986 ,double xorg,double yorg,double dx,double dy)
987//
988// Retourne une classe contenant les residus du fit ``gfit''.
989// Les coordonnees de l'element (i,j) sont :
990// (i,j) -> x = xorg + j*dx , y = yorg + i*dy
991//--
992{
993if(NCol()<=0||NRows()<=0)
994 throw(SzMismatchError("OMatrix::FitResidus: size mismatch\n"));
995GeneralFunction* f = gfit.GetFunction();
996if(f==NULL)
997 throw(NullPtrError("OMatrix::FitResidus: NULL pointer\n"));
998OVector par = gfit.GetParm();
999OMatrix m(*this);
1000for(int i=0;i<NRows();i++) for(int j=0;j<NCol();j++) {
1001 double x[2] = {xorg+j*dx,yorg+i*dy};
1002 m(i,j) -= f->Value(x,par.Data());
1003}
1004return m;
1005}
1006
1007//++
1008OMatrix OMatrix::FitFunction(GeneralFit& gfit
1009 ,double xorg,double yorg,double dx,double dy)
1010//
1011// Retourne une classe contenant la fonction du fit ``gfit''.
1012// Les coordonnees de l'element (i,j) sont :
1013// (i,j) -> x = xorg + j*dx , y = yorg + i*dy
1014//--
1015{
1016if(NCol()<=0||NRows()<=0)
1017 throw(SzMismatchError("OMatrix::FitFunction: size mismatch\n"));
1018GeneralFunction* f = gfit.GetFunction();
1019if(f==NULL)
1020 throw(NullPtrError("OMatrix::FitFunction: NULL pointer\n"));
1021OVector par = gfit.GetParm();
1022OMatrix m(*this);
1023for(int i=0;i<NRows();i++) for(int j=0;j<NCol();j++) {
1024 double x[2] = {xorg+j*dx,yorg+i*dy};
1025 m(i,j) = f->Value(x,par.Data());
1026}
1027return m;
1028}
Note: See TracBrowser for help on using the repository browser.