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

Last change on this file since 266 was 244, checked in by ansari, 26 years ago

beaucoup modifs rz+cmv 22/4/99

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