StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TPolynomial.cxx
1 #include "TPolynomial.h"
2 using namespace std;
3 //________________________________________________________________________________
4 void TPolynomial::MakePolySeries(Double_t x, Int_t type, Int_t Np, Double_t *P) {
5  // Recurrent formulae to polynoms
6  P[0] = 1.;
7  for (Int_t i = 1; i < Np; i++) {
8  Int_t n = i - 1;
9  if (!n) {
10  switch (type) {
11  case 3: P[n+1] = -x + 1; break; // Laguerre
12  case 4: P[n+1] = 2*x; break; // Hermite
13  case 0: // Polymonial
14  case 1: // Tchebyshev
15  case 2: // Legendre
16  default: P[n+1] = x; break;
17  }
18  }
19  else {
20  switch (type) {
21  case 1: P[n+1] = 2*x*P[n] - P[n-1]; break;//Tchebyshev[-1,1]: P_0 = 1; P_1 = x; P_n+1 = 2*x*P_n - P_n-1
22  case 2: P[n+1] =((2.*n+1)*x*P[n] - n*P[n-1])/(n+1); break;//Legendre [-1,1]: P_0 = 1, P_1 = x, P_n+1 = (2*n+1)/(n+1)*x*P[n]-n/(n+1)*P_n-1
23  case 3: P[n+1] = (2*n+1-x)*P[n]-n*n*P[n-1]; break;//Laguerre : P_n+1 = (2*n+1-x)*P_n - n**2*P_n-1
24  case 4: P[n+1] = 2*x*P[n]-2*n*P[n-1]; break;//Hermite : P_n+1 = 2*x*P_n - 2*n*P_n-1
25  case 0:
26  default: P[n+1] = P[n]*x; break; // Polymonial : P_n+1 = P_n *x;
27  }
28  }
29  }
30 }
31 //________________________________________________________________________________
32 Double_t TPolynomial::CalcPoly(Double_t *x, Double_t *par) {
33  // Int_t key = Npar + 1 + 100*(100*R + T);
34  Int_t key = TMath::Nint(par[0]);
35  Int_t R = key/(100*100);
36  key -= R*(100*100);
37  Int_t T = key/100;
38  key -= T*100;
39  Int_t n = key; // no. of coeff.
40  Double_t X;
41  Double_t scale = 1;
42  Int_t i1 = 1;
43  Int_t i2 = n;
44  switch (R) {
45  case 1: X = 2*x[0]; break; // [-0.5,0.5] => [-1,1]
46  case 2: X = TMath::Log(x[0]); break;
47  case 3: X = TMath::Exp(x[0]); break;
48  case 4: X = 2*x[0] - 1; break; // [0,1] => [-1,1]
49  case 6: scale = x[0]*(1-TMath::Abs(x[0])); i1 = 0; i2--;
50  case 5: X = 2*TMath::Power(x[0],2) - 1; break; // [-1,1]
51  case 8: scale = 2*x[0]*(1-TMath::Abs(2*x[0])); i1 = 0; i2--;
52  case 7: X = 8*TMath::Power(x[0],2) - 1; break; // [-.5,0.5]
53  default: X = x[0]; break;
54  }
55  Int_t np = n+i1;
56  Double_t *P = new Double_t[np];
57  TPolynomial::MakePolySeries(X,T,np,P);
58  Int_t ip = 1;
59  Double_t val = par[ip]*P[0]; ip++;
60  for (Int_t i = i1; ip < n; i++, ip++) {
61  val += scale*par[ip]*P[i];
62  }
63  delete [] P;
64  return val;
65 }
66 //________________________________________________________________________________
67 TF1 *TPolynomial::MakePoly(TString Name, Int_t Npar, Int_t R, Double_t xmin, Double_t xmax) {
68  // param[0] = RRTTnn
69  // R = 0: X => x
70  // R = 1: X => 2*x
71  // R = 2: X => log(x)
72  // R = 3: X => exp(x);
73  // R = 4: X => 2*x - 1
74  // R = 5; X => 2*x**2 - 1; f = a_0 + P(X); use only const + even series member [-1,1]
75  // R = 6: X => 2*x**2 - 1; f = a_0 + x*P(X); use only const + odd series member
76  // R = 7; X => 8*x**2 - 1; f = a_0 + P(X); use only const + even series member [-.5,0.5]
77  // R = 8: X => 8*x**2 - 1; f = a_0 + x*P(X); use only const + odd series member
78  Int_t T = 0;
79  if (Name.BeginsWith("Pol",TString::kIgnoreCase)) T = 0; // Polymonial
80  if (Name.BeginsWith("Tch",TString::kIgnoreCase)) T = 1; // Tchebyshev
81  if (Name.BeginsWith("Leg",TString::kIgnoreCase)) T = 2; // Legendre
82  if (Name.BeginsWith("Lag",TString::kIgnoreCase)) T = 3; // Laguerre
83  if (Name.BeginsWith("Her",TString::kIgnoreCase)) T = 4; // Hermite
84  Int_t key = Npar + 1 + 100*(100*R + T);
85  TF1 *f = new TF1(Form("%s_%i_%i",Name.Data(),R,Npar),TPolynomial::CalcPoly,xmin,xmax,Npar+1);
86  f->FixParameter(0,key);
87  for (Int_t i = 1; i <= Npar; i++) f->SetParameter(i,0);
88  return f;
89 }
90 //________________________________________________________________________________
91 TF1 *TPolynomial::MakePol(const Int_t N, const Char_t *X, TString type, Int_t i0) {
92  TString Func("");
93  if (! type.CompareTo("PL",TString::kIgnoreCase)) {// polynoms
94  Func = Form("[%i]",N); cout << Func << endl;
95  for (int n = N-1+i0; n>=i0; n--) {
96  TString temp;
97  if (n < N-1) temp = Form("%s*(%s)+[%i]",X,Func.Data(),n);
98  else temp = Form("%s*%s+[%i]",X,Func.Data(),n);
99  Func = temp; cout << Func << endl;
100  }
101  }
102  else {
103  TString T0("1"); Func = Form("[0]");
104  TString T1("");
105  TString T2("");
106  TString xx("");
107  if (N >= 1) {
108  if (! type.CompareTo("TCheb",TString::kIgnoreCase)) xx = Form("%s",X); // Tchebyshev : T_0 = 1; T_1 = x;
109  else xx = Form("(2*%s-1)",X); // Shifted Tchebyshev: S_0 = 1; S_1 = 2*x - 1
110  T1 = xx;
111  Func += Form("+[1]*%s",T1.Data()); cout << Func << endl;
112  for (int n = 2; n<=N; n++) {
113  T2 = Form("(2*%s*%s-%s)",xx.Data(),T1.Data(),T0.Data()); // T_n+1 = 2*x*T_n - T_n-1
114  // T2 = Form("(2*(2*%s-1)*%s-%s)",X,T1.Data(),T0.Data()); // S_n+1 = 2*(2*x-1)*S_n - S_n-1
115  cout << T0 << "\t" << T1 << "\t" << T2 << endl;
116  Func += Form("+[%i]*%s",n,T2.Data()); cout << Func << endl;
117  T0 = T1;
118  T1 = T2;
119  }
120  }
121  }
122  TF1 *fun = 0;
123  if (Func != "") {fun = new TF1(Form("%s%i",type.Data(),N),Func.Data()); cout << "Make " << fun->GetName() << endl;}
124  return fun;
125 }
126 //________________________________________________________________________________
127 void TPolynomial::GetFunc(TF1 *func) {
128  if (! func) return;
129  TString Func(func->GetTitle());
130  Int_t Npar = func->GetNpar();
131  for (Int_t p = 0; p < Npar; p++) {
132  TString par("");
133  par += func->GetParameter(p);
134  Func.ReplaceAll(Form("[%i]",p),par.Data());
135  }
136  cout << Func << endl;
137 }