ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ChebyshevApproximation.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ChebyshevApproximation.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 
30 #include "G4PhysicalConstants.hh"
31 
32 // Constructor for initialisation of the class data members.
33 // It creates the array fChebyshevCof[0,...,fNumber-1], fNumber = n ;
34 // which consists of Chebyshev coefficients describing the function
35 // pointed by pFunction. The values a and b fix the interval of validity
36 // of the Chebyshev approximation.
37 
39  G4int n,
40  G4double a,
41  G4double b )
42  : fFunction(pFunction), fNumber(n),
43  fChebyshevCof(new G4double[fNumber]),
44  fMean(0.5*(b+a)), fDiff(0.5*(b-a))
45 {
46  G4int i=0, j=0 ;
47  G4double rootSum=0.0, cofj=0.0 ;
48  G4double* tempFunction = new G4double[fNumber] ;
49  G4double weight = 2.0/fNumber ;
50  G4double cof = 0.5*weight*pi ; // pi/n
51 
52  for (i=0;i<fNumber;i++)
53  {
54  rootSum = std::cos(cof*(i+0.5)) ;
55  tempFunction[i]= fFunction(rootSum*fDiff+fMean) ;
56  }
57  for (j=0;j<fNumber;j++)
58  {
59  cofj = cof*j ;
60  rootSum = 0.0 ;
61 
62  for (i=0;i<fNumber;i++)
63  {
64  rootSum += tempFunction[i]*std::cos(cofj*(i+0.5)) ;
65  }
66  fChebyshevCof[j] = weight*rootSum ;
67  }
68  delete[] tempFunction ;
69 }
70 
71 // --------------------------------------------------------------------
72 //
73 // Constructor for creation of Chebyshev coefficients for mx-derivative
74 // from pFunction. The value of mx ! MUST BE ! < nx , because the result
75 // array of fChebyshevCof will be of (nx-mx) size. The values a and b
76 // fix the interval of validity of the Chebyshev approximation.
77 
79 G4ChebyshevApproximation( function pFunction,
80  G4int nx, G4int mx,
81  G4double a, G4double b )
82  : fFunction(pFunction), fNumber(nx),
83  fChebyshevCof(new G4double[fNumber]),
84  fMean(0.5*(b+a)), fDiff(0.5*(b-a))
85 {
86  if(nx <= mx)
87  {
88  G4Exception("G4ChebyshevApproximation::G4ChebyshevApproximation()",
89  "InvalidCall", FatalException, "Invalid arguments !") ;
90  }
91  G4int i=0, j=0 ;
92  G4double rootSum = 0.0, cofj=0.0;
93  G4double* tempFunction = new G4double[fNumber] ;
94  G4double weight = 2.0/fNumber ;
95  G4double cof = 0.5*weight*pi ; // pi/nx
96 
97  for (i=0;i<fNumber;i++)
98  {
99  rootSum = std::cos(cof*(i+0.5)) ;
100  tempFunction[i] = fFunction(rootSum*fDiff+fMean) ;
101  }
102  for (j=0;j<fNumber;j++)
103  {
104  cofj = cof*j ;
105  rootSum = 0.0 ;
106 
107  for (i=0;i<fNumber;i++)
108  {
109  rootSum += tempFunction[i]*std::cos(cofj*(i+0.5)) ;
110  }
111  fChebyshevCof[j] = weight*rootSum ; // corresponds to pFunction
112  }
113  // Chebyshev coefficients for (mx)-derivative of pFunction
114 
115  for(i=1;i<=mx;i++)
116  {
117  DerivativeChebyshevCof(tempFunction) ;
118  fNumber-- ;
119  for(j=0;j<fNumber;j++)
120  {
121  fChebyshevCof[j] = tempFunction[j] ; // corresponds to (i)-derivative
122  }
123  }
124  delete[] tempFunction ; // delete of dynamically allocated tempFunction
125 }
126 
127 // ------------------------------------------------------
128 //
129 // Constructor for creation of Chebyshev coefficients for integral
130 // from pFunction.
131 
133  G4double a,
134  G4double b,
135  G4int n )
136  : fFunction(pFunction), fNumber(n),
137  fChebyshevCof(new G4double[fNumber]),
138  fMean(0.5*(b+a)), fDiff(0.5*(b-a))
139 {
140  G4int i=0, j=0;
141  G4double rootSum=0.0, cofj=0.0;
142  G4double* tempFunction = new G4double[fNumber] ;
143  G4double weight = 2.0/fNumber;
144  G4double cof = 0.5*weight*pi ; // pi/n
145 
146  for (i=0;i<fNumber;i++)
147  {
148  rootSum = std::cos(cof*(i+0.5)) ;
149  tempFunction[i]= fFunction(rootSum*fDiff+fMean) ;
150  }
151  for (j=0;j<fNumber;j++)
152  {
153  cofj = cof*j ;
154  rootSum = 0.0 ;
155 
156  for (i=0;i<fNumber;i++)
157  {
158  rootSum += tempFunction[i]*std::cos(cofj*(i+0.5)) ;
159  }
160  fChebyshevCof[j] = weight*rootSum ; // corresponds to pFunction
161  }
162  // Chebyshev coefficients for integral of pFunction
163 
164  IntegralChebyshevCof(tempFunction) ;
165  for(j=0;j<fNumber;j++)
166  {
167  fChebyshevCof[j] = tempFunction[j] ; // corresponds to integral
168  }
169  delete[] tempFunction ; // delete of dynamically allocated tempFunction
170 }
171 
172 
173 
174 // ---------------------------------------------------------------
175 //
176 // Destructor deletes the array of Chebyshev coefficients
177 
179 {
180  delete[] fChebyshevCof ;
181 }
182 
183 // ---------------------------------------------------------------
184 //
185 // Access function for Chebyshev coefficients
186 //
187 
188 
189 G4double
191 {
192  if(number < 0 && number >= fNumber)
193  {
194  G4Exception("G4ChebyshevApproximation::GetChebyshevCof()",
195  "InvalidCall", FatalException, "Argument out of range !") ;
196  }
197  return fChebyshevCof[number] ;
198 }
199 
200 // --------------------------------------------------------------
201 //
202 // Evaluate the value of fFunction at the point x via the Chebyshev coefficients
203 // fChebyshevCof[0,...,fNumber-1]
204 
205 G4double
207 {
208  G4double evaluate = 0.0, evaluate2 = 0.0, temp = 0.0,
209  xReduced = 0.0, xReduced2 = 0.0 ;
210 
211  if ((x-fMean+fDiff)*(x-fMean-fDiff) > 0.0)
212  {
213  G4Exception("G4ChebyshevApproximation::ChebyshevEvaluation()",
214  "InvalidCall", FatalException, "Invalid argument !") ;
215  }
216  xReduced = (x-fMean)/fDiff ;
217  xReduced2 = 2.0*xReduced ;
218  for (G4int i=fNumber-1;i>=1;i--)
219  {
220  temp = evaluate ;
221  evaluate = xReduced2*evaluate - evaluate2 + fChebyshevCof[i] ;
222  evaluate2 = temp ;
223  }
224  return xReduced*evaluate - evaluate2 + 0.5*fChebyshevCof[0] ;
225 }
226 
227 // ------------------------------------------------------------------
228 //
229 // Returns the array derCof[0,...,fNumber-2], the Chebyshev coefficients of the
230 // derivative of the function whose coefficients are fChebyshevCof
231 
232 void
234 {
235  G4double cof = 1.0/fDiff ;
236  derCof[fNumber-1] = 0.0 ;
237  derCof[fNumber-2] = 2*(fNumber-1)*fChebyshevCof[fNumber-1] ;
238  for(G4int i=fNumber-3;i>=0;i--)
239  {
240  derCof[i] = derCof[i+2] + 2*(i+1)*fChebyshevCof[i+1] ;
241  }
242  for(G4int j=0;j<fNumber;j++)
243  {
244  derCof[j] *= cof ;
245  }
246 }
247 
248 // ------------------------------------------------------------------------
249 //
250 // This function produces the array integralCof[0,...,fNumber-1] , the Chebyshev
251 // coefficients of the integral of the function whose coefficients are
252 // fChebyshevCof[]. The constant of integration is set so that the integral
253 // vanishes at the point (fMean - fDiff), i.e. at the begining of the interval of
254 // validity (we start the integration from this point).
255 //
256 
257 void
259 {
260  G4double cof = 0.5*fDiff, sum = 0.0, factor = 1.0 ;
261  for(G4int i=1;i<fNumber-1;i++)
262  {
263  integralCof[i] = cof*(fChebyshevCof[i-1] - fChebyshevCof[i+1])/i ;
264  sum += factor*integralCof[i] ;
265  factor = -factor ;
266  }
267  integralCof[fNumber-1] = cof*fChebyshevCof[fNumber-2]/(fNumber-1) ;
268  sum += factor*integralCof[fNumber-1] ;
269  integralCof[0] = 2.0*sum ; // set the constant of integration
270 }