| [658] | 1 | #include "machdefs.h" | 
|---|
|  | 2 | #include "peida.h" | 
|---|
|  | 3 | #include "linfit.h" | 
|---|
|  | 4 |  | 
|---|
|  | 5 | LinFitter::LinFitter() | 
|---|
|  | 6 | { | 
|---|
|  | 7 | } | 
|---|
|  | 8 |  | 
|---|
|  | 9 | LinFitter::~LinFitter() | 
|---|
|  | 10 | { | 
|---|
|  | 11 | } | 
|---|
|  | 12 |  | 
|---|
|  | 13 | double LinFitter::LinFit(const Vector& x, const Vector& y, int nf, | 
|---|
|  | 14 | double (*f)(int, double), Vector& c) | 
|---|
|  | 15 | { | 
|---|
|  | 16 | int n = x.NElts(); | 
|---|
|  | 17 | if (n != y.NElts()) THROW(sizeMismatchErr); | 
|---|
|  | 18 |  | 
|---|
|  | 19 | Matrix fx(nf, n); | 
|---|
|  | 20 | for (int i=0; i<nf; i++) | 
|---|
|  | 21 | for (int j=0; j<n; j++) | 
|---|
|  | 22 | fx(i,j) = f(i,x(j)); | 
|---|
|  | 23 |  | 
|---|
|  | 24 | return LinFit(fx,y,c); | 
|---|
|  | 25 | } | 
|---|
|  | 26 |  | 
|---|
|  | 27 |  | 
|---|
|  | 28 |  | 
|---|
|  | 29 | double LinFitter::LinFit(const Matrix& fx, const Vector& y, Vector& c) | 
|---|
|  | 30 | { | 
|---|
|  | 31 | int n = y.NElts(); | 
|---|
|  | 32 | if ( n != fx.NCol()) THROW(sizeMismatchErr); | 
|---|
|  | 33 |  | 
|---|
|  | 34 | int nf = fx.NRows(); | 
|---|
|  | 35 |  | 
|---|
|  | 36 | Matrix a(nf,nf); | 
|---|
|  | 37 |  | 
|---|
|  | 38 | for (int j=0; j<nf; j++) | 
|---|
|  | 39 | for (int k=j; k<nf; k++) | 
|---|
|  | 40 | a(j,k) = a(k,j) = fx.Row(j) * fx.Row(k); | 
|---|
|  | 41 |  | 
|---|
|  | 42 | c = fx * y; | 
|---|
|  | 43 |  | 
|---|
|  | 44 | if (Matrix::GausPiv(a,c) == 0) THROW(singMatxErr); | 
|---|
|  | 45 |  | 
|---|
|  | 46 | double xi2 = 0; | 
|---|
|  | 47 |  | 
|---|
|  | 48 | for (int k=0; k<n; k++) { | 
|---|
|  | 49 | double x = 0; | 
|---|
|  | 50 | for (int i=0; i<nf; i++) | 
|---|
|  | 51 | x += c(i) * fx(i,k); | 
|---|
|  | 52 | x -= y(k); | 
|---|
|  | 53 | xi2 += x*x; | 
|---|
|  | 54 | } | 
|---|
|  | 55 | return xi2; | 
|---|
|  | 56 | } | 
|---|
|  | 57 |  | 
|---|
|  | 58 |  | 
|---|
|  | 59 |  | 
|---|
|  | 60 | double LinFitter::LinFit(const Vector& x, const Vector& y, const Vector& errY2, int nf, | 
|---|
|  | 61 | double (*f)(int, double), Vector& c, Vector& errC) | 
|---|
|  | 62 | { | 
|---|
|  | 63 | int n = x.NElts(); | 
|---|
|  | 64 | if (n != y.NElts()) THROW(sizeMismatchErr); | 
|---|
|  | 65 |  | 
|---|
|  | 66 | Matrix fx(nf, n); | 
|---|
|  | 67 | for (int i=0; i<nf; i++) | 
|---|
|  | 68 | for (int j=0; j<n; j++) | 
|---|
|  | 69 | fx(i,j) = f(i,x(j)); | 
|---|
|  | 70 |  | 
|---|
|  | 71 | return LinFit(fx,y,errY2,c,errC); | 
|---|
|  | 72 | } | 
|---|
|  | 73 |  | 
|---|
|  | 74 |  | 
|---|
|  | 75 | double LinFitter::LinFit(const Matrix& fx, const Vector& y, const Vector& errY2, | 
|---|
|  | 76 | Vector& c, Vector& errC) | 
|---|
|  | 77 | { | 
|---|
|  | 78 | int n = y.NElts(); | 
|---|
|  | 79 | if ( n != errY2.NElts()) THROW(sizeMismatchErr); | 
|---|
|  | 80 | if ( n != fx.NCol()) THROW(sizeMismatchErr); | 
|---|
|  | 81 |  | 
|---|
|  | 82 | int nf = fx.NRows(); | 
|---|
|  | 83 |  | 
|---|
|  | 84 | Matrix a(nf,nf); | 
|---|
|  | 85 |  | 
|---|
|  | 86 | c.Realloc(nf); | 
|---|
|  | 87 | errC.Realloc(nf); | 
|---|
|  | 88 |  | 
|---|
|  | 89 | for (int j=0; j<nf; j++) | 
|---|
|  | 90 | for (int k=j; k<nf; k++) { | 
|---|
|  | 91 | double x=0; | 
|---|
|  | 92 | for (int l=0; l<n; l++) | 
|---|
|  | 93 | x += fx(j,l) * fx(k,l) / errY2(l);        // Matrice a inverser | 
|---|
|  | 94 | a(j,k) = a(k,j) = x; | 
|---|
|  | 95 | } | 
|---|
|  | 96 |  | 
|---|
|  | 97 | Matrix d(nf,nf+1); | 
|---|
|  | 98 | for (int k=0; k<nf; k++) { | 
|---|
|  | 99 | double x=0; | 
|---|
|  | 100 | for (int l=0; l<n; l++) | 
|---|
|  | 101 | x += fx(k,l) * y(l) / errY2(l);             // Second membre 1ere colonne | 
|---|
|  | 102 | d(k,0) = x; | 
|---|
|  | 103 | for (int m=1; m<=nf; m++) | 
|---|
|  | 104 | d(k,m) = (k==m) ? 1 : 0;                // Reste second membre = Id. | 
|---|
|  | 105 | } | 
|---|
|  | 106 |  | 
|---|
|  | 107 | if (Matrix::GausPiv(a,d) == 0) THROW(singMatxErr); | 
|---|
|  | 108 |  | 
|---|
|  | 109 | for (int l=0; l<nf; l++) { | 
|---|
|  | 110 | c(l) = d(l,0);                            // Parametres = 1ere colonne | 
|---|
|  | 111 | errC(l) = d(l,l+1);                        // Erreurs = diag inverse. | 
|---|
|  | 112 | } | 
|---|
|  | 113 |  | 
|---|
|  | 114 | double xi2 = 0; | 
|---|
|  | 115 |  | 
|---|
|  | 116 | for (int jj=0; jj<n; jj++) { | 
|---|
|  | 117 | double x = 0; | 
|---|
|  | 118 | for (int ii=0; ii<nf; ii++) | 
|---|
|  | 119 | x += c(ii) * fx(ii,jj); | 
|---|
|  | 120 | x -= y(jj); | 
|---|
|  | 121 | xi2 += x*x/errY2(jj); | 
|---|
|  | 122 | } | 
|---|
|  | 123 | return xi2; | 
|---|
|  | 124 | } | 
|---|
|  | 125 |  | 
|---|
|  | 126 |  | 
|---|