source: Sophya/trunk/SophyaLib/TArray/sopemtx.cc@ 935

Last change on this file since 935 was 935, checked in by ansari, 25 years ago

doc + inversion de matrice template real+complex

File size: 21.0 KB
Line 
1// C.Magneville, R.Ansari 03/2000
2
3#include "machdefs.h"
4#include <stdio.h>
5#include <iostream.h>
6#include <complex>
7#include <math.h>
8#include "sopemtx.h"
9#include "smathconst.h"
10
11////////////////////////////////////////////////////////////////
12// -------------------------------------------------------------
13// La classe de gestion des lignes et colonnes d'une matrice
14// -------------------------------------------------------------
15////////////////////////////////////////////////////////////////
16
17//! Class of line, column or diagonal of a TMatrix
18/*!
19 A TMatrixRC represents a line, a column or the diagonal of a TMatrix
20 */
21template <class T>
22class TMatrixRC {
23public:
24 //! Define type of TMatrixRC
25 enum TRCKind {
26 TmatrixRow=0, //!< TMatrixRC ligne
27 TmatrixCol=1, //!< TMatrixRC column
28 TmatrixDiag=2 //!< TMatrixRC diagonal
29 };
30 TMatrixRC();
31 TMatrixRC(TMatrix<T>& m, TRCKind kind, uint_4 index=0);
32 virtual ~TMatrixRC() {}
33
34 // Acces aux rangees et colonnes de matrices
35 static TMatrixRC<T> Row(TMatrix<T> & m, uint_4 r);
36 static TMatrixRC<T> Col(TMatrix<T> & m, uint_4 c);
37 static TMatrixRC<T> Diag(TMatrix<T> & m);
38
39 // ---- A virer $CHECK$ Reza 03/2000
40 // int_4 Next();
41 // int_4 Prev();
42 int_4 SetCol(int_4 c);
43 int_4 SetRow(int_4 r);
44 int_4 SetDiag();
45
46 static uint_4 Step(const TMatrix<T>& m, TRCKind rckind);
47 static T* Org(const TMatrix<T>&, TRCKind rckind, uint_4 ind=0);
48
49 //! Return the kind of TMatrix (line,column,diagonal)
50 TRCKind Kind() const { return kind; }
51 uint_4 NElts() const;
52 T& operator()(uint_4 i);
53 T operator()(uint_4 i) const;
54
55
56 TMatrixRC<T>& operator = (const TMatrixRC<T>& rc);
57
58// ---- A virer $CHECK$ Reza 03/2000
59// TVector<T> GetVect() const;
60// TMatrixRC<T>& operator += (const TMatrixRC<T>& rc);
61// TMatrixRC<T>& operator -= (const TMatrixRC<T>& rc);
62
63 TMatrixRC<T>& operator *= (T x);
64 TMatrixRC<T>& operator /= (T x);
65
66// TMatrixRC<T>& operator -= (T x);
67// TMatrixRC<T>& operator += (T x);
68
69
70 TMatrixRC<T>& LinComb(T a, T b, const TMatrixRC& rc, uint_4 first=0);
71 TMatrixRC<T>& LinComb(T b, const TMatrixRC<T>& rc, uint_4 first=0);
72
73 uint_4 IMaxAbs(uint_4 first=0);
74 void Print(ostream & os) const ;
75
76 static void Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2);
77
78 //! Define Absolute value for uint_1
79 inline static double Abs_Value(uint_1 v) {return (double) v;}
80 //! Define Absolute value for uint_2
81 inline static double Abs_Value(uint_2 v) {return (double) v;}
82 //! Define Absolute value for int_2
83 inline static double Abs_Value(int_2 v) {return (v>0)? (double) v: (double) -v;}
84 //! Define Absolute value for int_4
85 inline static double Abs_Value(int_4 v) {return (v>0)? (double) v: (double) -v;}
86 //! Define Absolute value for int_8
87 inline static double Abs_Value(int_8 v) {return (v>0)? (double) v: (double) -v;}
88 //! Define Absolute value for uint_4
89 inline static double Abs_Value(uint_4 v) {return (double) v;}
90 //! Define Absolute value for uint_8
91 inline static double Abs_Value(uint_8 v) {return (double) v;}
92 //! Define Absolute value for r_4
93 inline static double Abs_Value(r_4 v) {return (double) fabsf(v);}
94 //! Define Absolute value for r_8
95 inline static double Abs_Value(r_8 v) {return fabs(v);}
96 //! Define Absolute value for complex r_4
97 inline static double Abs_Value(complex<r_4> v)
98 {return sqrt(v.real()*v.real()+v.imag()*v.imag());}
99 //! Define Absolute value for complex r_8
100 inline static double Abs_Value(complex<r_8> v)
101 {return sqrt(v.real()*v.real()+v.imag()*v.imag());}
102
103protected:
104 TMatrix<T>* matrix; //!< pointer to the TMatrix
105 T* data; //!< pointer to the beginnig of interesting datas
106 int_4 index; //!< index of the line/column
107 uint_4 step; //!< step of the line/column
108 TRCKind kind; //!< type: line, column or diagonal
109};
110
111
112//! Scalar product of two TMatrixRC
113/*!
114 \return sum[ a(i) * b(i) ]
115 */
116template <class T>
117inline T operator * (const TMatrixRC<T>& a, const TMatrixRC<T>& b)
118 {
119 if ( a.NElts() != b.NElts() )
120 throw(SzMismatchError("TMatrixRC::operator * size mismatch\n"));
121 if ( a.Kind() != b.Kind() )
122 throw(SzMismatchError("TMatrixRC::operator * type mismatch\n"));
123 T sum = 0;
124 for(uint_4 i=0; i<a.NElts(); i++) sum += a(i)*b(i);
125 return sum;
126 }
127
128//! Get the step in datas for a TMatrix for type rckind
129/*!
130 \param rckind : line, column or diagonal
131 \return step in TMatrix along TMatrixRC
132 */
133template <class T>
134inline uint_4 TMatrixRC<T>::Step(const TMatrix<T>& m, TRCKind rckind)
135 { switch (rckind) { case TmatrixRow : return m.Step(m.ColsKA());
136 case TmatrixCol : return m.Step(m.RowsKA());
137 case TmatrixDiag : return (m.Step(m.RowsKA())+m.Step(m.ColsKA())); }
138 return 0; }
139
140//! Get the origin of datas.
141/*!
142 Get the origin of datas in the TMatrix for a TMatrixRC for type
143 \b rckind and index \b index .
144 \param rckind : line, column or diagonal
145 \param index : index of the line or column.
146 \return adress of the first element in datas.
147 */
148template <class T>
149inline T* TMatrixRC<T>::Org(const TMatrix<T>& m, TRCKind rckind, uint_4 index)
150 { switch (rckind) { case TmatrixRow : return const_cast<T *>(&(m(index,0)));
151 case TmatrixCol : return const_cast<T *>(&(m(0,index)));
152 case TmatrixDiag : return const_cast<T *>(m.Data()); }
153 return NULL; }
154
155//! return number of elements for a TMatrixRC
156template <class T> inline uint_4 TMatrixRC<T>::NElts() const
157 { if (!matrix) return 0;
158 switch (kind) { case TmatrixRow : return matrix->NCols();
159 case TmatrixCol : return matrix->NRows();
160 case TmatrixDiag : return matrix->NCols(); }
161 return 0; }
162
163//! access of element \b i
164template <class T>
165inline T& TMatrixRC<T>::operator()(uint_4 i) {return data[i*step];}
166//! access of element \b i
167template <class T>
168inline T TMatrixRC<T>::operator()(uint_4 i) const {return data[i*step];}
169
170////////////////////////////////////////////////////////////////
171//! Typedef to simplify TMatrixRC<r_8> writing
172typedef TMatrixRC<r_8> MatrixRC;
173
174
175//! Default constructor
176template <class T> TMatrixRC<T>::TMatrixRC()
177: matrix(NULL), data(NULL), index(0), step(0)
178{}
179
180//! Constructor
181/*!
182 \param m : matrix
183 \param rckind : select line, column or diagonal
184 \param ind : number of the line or column
185*/
186template <class T> TMatrixRC<T>::TMatrixRC(TMatrix<T>& m,TRCKind rckind,uint_4 ind)
187: matrix(&m), data(Org(m,rckind,ind)),
188 index(ind), step(Step(m,rckind)), kind(rckind)
189{
190if (kind == TmatrixDiag && m.NCols() != m.NRows())
191 throw(SzMismatchError("TMatrixRC::TMatrixRC(...,TmatrixDiag,...) size mismatch\n"));
192}
193
194////////////////////////////////////////////////////////////////
195// Acces aux rangees et colonnes de matrices
196
197//! Return TMatrixRC for line \b r of matrix \b m
198template <class T>
199TMatrixRC<T> TMatrixRC<T>::Row(TMatrix<T> & m, uint_4 r)
200{
201TMatrixRC<T> rc(m, TmatrixRow, r);
202return rc;
203}
204
205//! Return TMatrixRC for column \b r of matrix \b m
206template <class T>
207TMatrixRC<T> TMatrixRC<T>::Col(TMatrix<T> & m, uint_4 c)
208{
209TMatrixRC<T> rc(m, TmatrixCol, c);
210return rc;
211}
212
213//! Return TMatrixRC for diagonal of matrix \b m
214template <class T>
215TMatrixRC<T> TMatrixRC<T>::Diag(TMatrix<T> & m)
216{
217TMatrixRC<T> rc(m, TmatrixDiag);
218return rc;
219}
220
221
222// ---- A virer $CHECK$ Reza 03/2000
223// template <class T> int_4 TMatrixRC<T>::Next()
224// {
225// if (!matrix || kind==TmatrixDiag) return -1;
226// index++;
227// if(kind == TmatrixRow) {
228// if(index > (int_4)matrix->NRows()) {index = (int_4)matrix->NRows(); return -1;}
229// data += matrix->NCols();
230// } else {
231// if (index > (int_4)matrix->NCols()) {index = (int_4)matrix->NCols(); return -1;}
232// data++;
233// }
234// return index;
235// }
236
237// template <class T> int_4 TMatrixRC<T>::Prev()
238// {
239// if (!matrix || kind == TmatrixDiag) return -1;
240// index--;
241// if(index < 0) {index = 0; return -1;}
242// if(kind == TmatrixRow) data -= matrix->NCols();
243// else data--;
244// return index;
245// }
246
247//! Set column \b c for this TMatrixRC
248template <class T> int_4 TMatrixRC<T>::SetCol(int_4 c)
249{
250if(!matrix) return -1;
251if(c<0 || c>(int_4)matrix->NCols()) return -1;
252kind = TmatrixCol;
253index = c;
254step = Step(*matrix, TmatrixCol);
255data = Org(*matrix, TmatrixCol, c);
256return c;
257}
258
259//! Set line \b r for this TMatrixRC
260template <class T> int_4 TMatrixRC<T>::SetRow(int_4 r)
261{
262if(!matrix) return -1;
263if(r<0 && r>(int_4)matrix->NRows()) return -1;
264kind = TmatrixRow;
265index = r;
266step = Step(*matrix, TmatrixRow);
267data = Org(*matrix, TmatrixRow, r);
268return r;
269}
270
271//! Set line diaginal for this TMatrixRC
272template <class T> int_4 TMatrixRC<T>::SetDiag()
273{
274if (!matrix) return -1;
275if (matrix->NCols() != matrix->NRows())
276 throw(SzMismatchError("TMatrixRC::SetDiag size mismatch\n"));
277kind = TmatrixDiag;
278index = 0;
279step = Step(*matrix, TmatrixDiag);
280data = Org(*matrix, TmatrixDiag);
281return 0;
282}
283
284//! Operator =
285template <class T> TMatrixRC<T>& TMatrixRC<T>::operator = (const TMatrixRC<T>& rc)
286{
287matrix = rc.matrix;
288data = rc.data;
289index = rc.index;
290step = rc.step;
291kind = rc.kind;
292return *this;
293}
294
295// ---- A virer $CHECK$ Reza 03/2000
296// template <class T> TVector<T> TMatrixRC<T>::GetVect() const
297// {
298// TVector<T> v(NElts());
299// for (uint_4 i=0; i<NElts(); i++) v(i) = (*this)(i);
300// return v;
301// }
302
303// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (const TMatrixRC<T>& rc)
304// {
305// if ( NElts() != rc.NElts() )
306// throw(SzMismatchError("TMatrixRC::operator+= size mismatch\n"));
307// if ( kind != rc.kind )
308// throw(SzMismatchError("TMatrixRC::operator+= type mismatch\n"));
309// for (uint_4 i=0; i<NElts(); i++) (*this)(i) += rc(i);
310// return *this;
311// }
312
313// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (const TMatrixRC<T>& rc)
314// {
315// if( NElts() != rc.NElts() )
316// throw(SzMismatchError("TMatrixRC::operator-= size mismatch\n"));
317// if( kind != rc.kind )
318// throw(SzMismatchError("TMatrixRC::operator-= type mismatch\n"));
319// for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= rc(i);
320// return *this;
321// }
322
323//! Operator to multiply by constant \b x
324template <class T> TMatrixRC<T>& TMatrixRC<T>::operator *= (T x)
325{
326for(uint_4 i=0; i<NElts(); i++) (*this)(i) *= x;
327return *this;
328}
329
330//! Operator to divide by constant \b x
331template <class T> TMatrixRC<T>& TMatrixRC<T>::operator /= (T x)
332{
333for(uint_4 i=0; i<NElts(); i++) (*this)(i) /= x;
334return *this;
335}
336
337
338// ---- A virer $CHECK$ Reza 03/2000
339// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (T x)
340// {
341// for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= x;
342// return *this;
343// }
344
345// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (T x)
346// {
347// for(uint_4 i=0; i<NElts(); i++) (*this)(i) += x;
348// return *this;
349// }
350
351//! Linear combination
352/*!
353 Do : \f$ MRC(i) = MRC(i)*a + rc(i)*b \f$
354 \return *this
355 */
356template <class T>
357TMatrixRC<T>& TMatrixRC<T>::LinComb(T a, T b, const TMatrixRC<T>& rc, uint_4 first)
358{
359if ( NElts() != rc.NElts() )
360 throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
361if ( kind != rc.kind )
362 throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
363for(uint_4 i=first; i<NElts(); i++) (*this)(i) = (*this)(i)*a + rc(i)*b;
364return *this;
365}
366
367//! Linear combination
368/*!
369 Do : \f$ MRC(i) = MRC(i) + rc(i)*b \f$
370 */
371template <class T>
372TMatrixRC<T>& TMatrixRC<T>::LinComb(T b, const TMatrixRC<T>& rc, uint_4 first)
373{
374if ( NElts() != rc.NElts() )
375 throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
376if ( kind != rc.kind )
377 throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
378for(uint_4 i=first; i<NElts(); i++) (*this)(i) += rc(i)*b;
379return *this;
380}
381
382//! Find maximum absolute value in TMatrixRC, search begin at \b first
383template <class T> uint_4 TMatrixRC<T>::IMaxAbs(uint_4 first)
384{
385if (first>NElts())
386 throw(SzMismatchError("TMatrixRC::IMaxAbs size mismatch\n"));
387uint_4 imax = first;
388double vmax = Abs_Value((*this)(first));
389for(uint_4 i=first+1; i<NElts(); i++) {
390 double v = Abs_Value((*this)(i));
391 if(v > vmax) {vmax = v; imax = i;}
392}
393return imax;
394}
395
396//! Print on stream \b os
397template <class T>
398void TMatrixRC<T>::Print(ostream & os) const
399{
400 os << " TMatrixRC<T>::Print(ostream & os) " << NElts() << " Kind="
401 << kind << " Index=" << index << " Step= " << step << endl;
402 for(uint_4 i=0; i<NElts(); i++) {
403 os << (*this)(i);
404 if (kind == TmatrixCol) os << endl;
405 else os << ", ";
406 }
407 os << endl;
408}
409
410//! Swap two TMatrixRC of the same kind
411template <class T>
412void TMatrixRC<T>::Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2)
413{
414if(rc1.NElts() != rc2.NElts())
415 throw(SzMismatchError("TMatrixRC::Swap size mismatch\n"));
416if(rc1.kind != rc2.kind)
417 throw(SzMismatchError("TMatrixRC::Swap type mismatch\n"));
418if(rc1.data == rc2.data) return;
419for(uint_4 i=0; i<rc1.NElts(); i++)
420 {T tmp = rc1(i); rc1(i) = rc2(i); rc2(i) = tmp;}
421}
422
423
424////////////////////////////////////////////////////////////////
425// -------------------------------------------------------------
426// La classe de calcul simple sur les TMatrix
427// -------------------------------------------------------------
428////////////////////////////////////////////////////////////////
429
430//**** Pour inversion
431#ifndef M_LN2
432#define M_LN2 0.69314718055994530942
433#endif
434#ifndef LN_MINDOUBLE
435#define LN_MINDOUBLE (M_LN2 * (DMINEXP - 1))
436#endif
437#ifndef LN_MAXDOUBLE
438#define LN_MAXDOUBLE (M_LN2 * DMAXEXP)
439#endif
440
441//! Gaussian pivoting
442/*!
443 Diagonalize matrix \b a, doing the same operations on matrix \b b
444 \return determinat of \b a.
445
446 If \b b is identity matrix, return inverse of \b a
447 */
448template <class T>
449T SimpleMatrixOperation<T>::GausPiv(TMatrix<T>& a, TMatrix<T>& b)
450// Pivot de Gauss
451// * Attention: egcs impose que cette fonction soit mise dans le .cc
452// avant ::Inverse() (car Inverse() l'utilise)
453// {TMatrix A(a); TMatrix B(b); return (T) TMatrix::GausPiv(A,B);}
454{
455uint_4 n = a.NRows();
456if(n!=b.NRows())
457 throw(SzMismatchError("TMatrix::GausPiv size mismatch\n"));
458// On fait une normalisation un peu brutale...
459double vmin=MAXDOUBLE;
460double vmax=0;
461for(uint_4 iii=0; iii<a.NRows(); iii++)
462 for(uint_4 jjj=0; jjj<a.NCols(); jjj++) {
463 double v = TMatrixRC<T>::Abs_Value(a(iii,jjj));
464 if(v>vmax) vmax = v;
465 if(v<vmin && v>0) vmin = v;
466}
467double nrm = sqrt(vmin*vmax);
468if(nrm > 1.e5 || nrm < 1.e-5) {
469 a /= (T) nrm;
470 b /= (T) nrm;
471 //cout << "normalisation matrice " << nrm << endl;
472} else nrm=1;
473
474T det = 1;
475if(nrm != 1) {
476 double ld = a.NRows() * log(nrm);
477 if (ld <= LN_MINDOUBLE || ld >= LN_MAXDOUBLE) {
478 // cerr << "TMatrix warning, overflow for det" << endl;
479 } else {
480 det = (T) exp(ld);
481 }
482}
483
484TMatrixRC<T> pivRowa(a,TMatrixRC<T>::TmatrixRow);
485TMatrixRC<T> pivRowb(b,TMatrixRC<T>::TmatrixRow);
486
487for(uint_4 k=0; k<n-1; k++) {
488 uint_4 iPiv = TMatrixRC<T>::Col(a, k).IMaxAbs(k);
489 if(iPiv != k) {
490 TMatrixRC<T> aIPiv(TMatrixRC<T>::Row(a,iPiv));
491 TMatrixRC<T> aK(TMatrixRC<T>::Row(a, k));
492 TMatrixRC<T>::Swap(aIPiv,aK);
493 TMatrixRC<T> bIPiv(TMatrixRC<T>::Row(b, iPiv));
494 TMatrixRC<T> bK(TMatrixRC<T>::Row(b, k));
495 TMatrixRC<T>::Swap(bIPiv,bK);
496 }
497 T pivot = a(k,k);
498 if( TMatrixRC<T>::Abs_Value(pivot) < 1.e-50 ) return (T) 0;
499 //det *= pivot;
500 pivRowa.SetRow(k); // to avoid constructors
501 pivRowb.SetRow(k);
502 for (uint_4 i=k+1; i<n; i++) {
503 T r = -a(i,k)/pivot;
504 TMatrixRC<T>::Row(a, i).LinComb(r, pivRowa); // + rapide que -= r * pivRowa
505 TMatrixRC<T>::Row(b, i).LinComb(r, pivRowb);
506 }
507}
508det *= a(n-1, n-1);
509
510// on remonte
511for(uint_4 kk=n-1; kk>0; kk--) {
512 T pivot = a(kk,kk);
513 if( TMatrixRC<T>::Abs_Value(pivot) <= 1.e-50 ) return (T) 0;
514 pivRowa.SetRow(kk); // to avoid constructors
515 pivRowb.SetRow(kk);
516 for(uint_4 jj=0; jj<kk; jj++) {
517 T r = -a(jj,kk)/pivot;
518 TMatrixRC<T>::Row(a, jj).LinComb(r, pivRowa);
519 TMatrixRC<T>::Row(b, jj).LinComb(r, pivRowb);
520 }
521}
522
523for(uint_4 l=0; l<n; l++) {
524 if( TMatrixRC<T>::Abs_Value(a(l,l)) <= 1.e-50 ) return (T) 0;
525 TMatrixRC<T>::Row(b, l) /= a(l,l);
526}
527
528return det;
529}
530
531//! Return the inverse matrix of \b A
532template <class T>
533TMatrix<T> SimpleMatrixOperation<T>::Inverse(TMatrix<T> const & A)
534{
535TMatrix<T> a(A);
536TMatrix<T> b(a.NCols(),a.NRows()); b = IdentityMatrix(1.);
537if( TMatrixRC<T>::Abs_Value(GausPiv(a,b)) < 1.e-50)
538 throw(MathExc("TMatrix Inverse() Singular Matrix"));
539return b;
540}
541
542
543////////////////////////////////////////////////////////////////
544// -------------------------------------------------------------
545// La classe fit lineaire
546// -------------------------------------------------------------
547////////////////////////////////////////////////////////////////
548
549LinFitter::LinFitter()
550{
551}
552
553LinFitter::~LinFitter()
554{
555}
556
557double LinFitter::LinFit(const Vector& x, const Vector& y, int nf,
558 double (*f)(int, double), Vector& c)
559{
560 int n = x.NElts();
561 if (n != y.NElts()) THROW(sizeMismatchErr);
562
563 Matrix fx(nf, n);
564 for (int i=0; i<nf; i++)
565 for (int j=0; j<n; j++)
566 fx(i,j) = f(i,x(j));
567
568 return LinFit(fx,y,c);
569}
570
571
572
573double LinFitter::LinFit(const Matrix& fx, const Vector& y, Vector& c)
574{
575 int n = y.NElts();
576 if ( n != fx.NCol()) THROW(sizeMismatchErr);
577
578 int nf = fx.NRows();
579
580 Matrix a(nf,nf);
581
582 for (int j=0; j<nf; j++)
583 for (int k=j; k<nf; k++)
584 a(j,k) = a(k,j) = TMatrixRC<r_8>::Row(const_cast<Matrix &>(fx), j)
585
586 * TMatrixRC<r_8>::Row(const_cast<Matrix &>(fx), k); /* $CHECK$ Reza 10/3/2000 */
587
588 c = fx * y;
589
590 if (SimpleMatrixOperation<r_8>::GausPiv(a,c) == 0) THROW(singMatxErr); /* $CHECK$ Reza 10/3/2000 */
591
592 double xi2 = 0;
593
594 for (int k=0; k<n; k++) {
595 double x = 0;
596 for (int i=0; i<nf; i++)
597 x += c(i) * fx(i,k);
598 x -= y(k);
599 xi2 += x*x;
600 }
601 return xi2;
602}
603
604
605
606double LinFitter::LinFit(const Vector& x, const Vector& y, const Vector& errY2, int nf,
607 double (*f)(int, double), Vector& c, Vector& errC)
608{
609 int n = x.NElts();
610 if (n != y.NElts()) THROW(sizeMismatchErr);
611
612 Matrix fx(nf, n);
613 for (int i=0; i<nf; i++)
614 for (int j=0; j<n; j++)
615 fx(i,j) = f(i,x(j));
616
617 return LinFit(fx,y,errY2,c,errC);
618}
619
620
621double LinFitter::LinFit(const Matrix& fx, const Vector& y, const Vector& errY2,
622 Vector& c, Vector& errC)
623{
624 int n = y.NElts();
625 if ( n != errY2.NElts()) THROW(sizeMismatchErr);
626 if ( n != fx.NCol()) THROW(sizeMismatchErr);
627
628 int nf = fx.NRows();
629
630 Matrix a(nf,nf);
631
632 c.Realloc(nf);
633 errC.Realloc(nf);
634
635 for (int j=0; j<nf; j++)
636 for (int k=j; k<nf; k++) {
637 double x=0;
638 for (int l=0; l<n; l++)
639 x += fx(j,l) * fx(k,l) / errY2(l); // Matrice a inverser
640 a(j,k) = a(k,j) = x;
641 }
642
643 Matrix d(nf,nf+1);
644 for (int k=0; k<nf; k++) {
645 double x=0;
646 for (int l=0; l<n; l++)
647 x += fx(k,l) * y(l) / errY2(l); // Second membre 1ere colonne
648 d(k,0) = x;
649 for (int m=1; m<=nf; m++)
650 d(k,m) = (k==m) ? 1 : 0; // Reste second membre = Id.
651 }
652
653 if (SimpleMatrixOperation<r_8>::GausPiv(a,d) == 0) THROW(singMatxErr); /* $CHECK$ Reza 10/3/2000 */
654
655 for (int l=0; l<nf; l++) {
656 c(l) = d(l,0); // Parametres = 1ere colonne
657 errC(l) = d(l,l+1); // Erreurs = diag inverse.
658 }
659
660 double xi2 = 0;
661
662 for (int jj=0; jj<n; jj++) {
663 double x = 0;
664 for (int ii=0; ii<nf; ii++)
665 x += c(ii) * fx(ii,jj);
666 x -= y(jj);
667 xi2 += x*x/errY2(jj);
668 }
669 return xi2;
670}
671
672
673void _ZZ_TestTMatrixRC_YY_(TMatrix<r_8> & m)
674{
675 cout << " ::::: _ZZ_TestTMatrixRC_YY_ :::: M= \n" << m << endl;
676 TMatrixRC<r_8> l0 = TMatrixRC<r_8>::Row(m,0);
677 cout << "TMatrixRC<r_8>::Row(m,0) = \n" ;
678 l0.Print(cout);
679 TMatrixRC<r_8> l1 = TMatrixRC<r_8>::Row(m,1);
680 cout << "TMatrixRC<r_8>::Row(m,1) = \n" ;
681 l1.Print(cout);
682 l0.SetRow(2);
683 cout << "TMatrixRC<r_8>::l0.SetRow(2 = \n" ;
684 l0.Print(cout);
685
686 TMatrixRC<r_8> c0 = TMatrixRC<r_8>::Col(m,0);
687 cout << "TMatrixRC<r_8>::Col(m,0) = \n" ;
688 c0.Print(cout);
689 TMatrixRC<r_8> c1 = TMatrixRC<r_8>::Col(m,1);
690 cout << "TMatrixRC<r_8>::Col(m,1) = \n" ;
691 c1.Print(cout);
692 c0.SetCol(2);
693 cout << "TMatrixRC<r_8>::c0.SetCol(2) = \n" ;
694 c0.Print(cout);
695 TMatrixRC<r_8> c00 = TMatrixRC<r_8>::Col(m,0);
696 TMatrixRC<r_8>::Swap(c0, c00);
697 cout << " ::::: M Apres Swap = \n" << m << endl;
698
699}
700
701///////////////////////////////////////////////////////////////
702#ifdef __CXX_PRAGMA_TEMPLATES__
703// Instances gestion lignes/colonnes
704#pragma define_template TMatrixRC<int_4>
705#pragma define_template TMatrixRC<r_4>
706#pragma define_template TMatrixRC<r_8>
707#pragma define_template TMatrixRC< complex<r_4> >
708#pragma define_template TMatrixRC< complex<r_8> >
709#pragma define_template SimpleMatrixOperation<int_4>
710#pragma define_template SimpleMatrixOperation<r_4>
711#pragma define_template SimpleMatrixOperation<r_8>
712#pragma define_template SimpleMatrixOperation< complex<r_4> >
713#pragma define_template SimpleMatrixOperation< complex<r_8> >
714#endif
715
716#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
717// Instances gestion lignes/colonnes
718template class TMatrixRC<int_4>;
719template class TMatrixRC<r_4>;
720template class TMatrixRC<r_8>;
721template class TMatrixRC< complex<r_4> >;
722template class TMatrixRC< complex<r_8> >;
723template class SimpleMatrixOperation<int_4>;
724template class SimpleMatrixOperation<r_4>;
725template class SimpleMatrixOperation<r_8>;
726template class SimpleMatrixOperation< complex<r_4> >;
727template class SimpleMatrixOperation< complex<r_8> >;
728#endif
729
730
731
732
733
734
735
736
737
738
739
740
741
Note: See TracBrowser for help on using the repository browser.