3#include "CLHEP/GenericFunctions/AbsFunction.hh"
4#include "CLHEP/GenericFunctions/AnalyticConvolution.hh"
5#include "CLHEP/GenericFunctions/Gaussian.hh"
6#include "CLHEP/GenericFunctions/Exponential.hh"
17 _lifetime ("Lifetime", 1.0, 0.0),
18 _frequency("Frequency", 0.0, 0.0),
19 _sigma ("
Sigma", 1.0, 0.0),
20 _offset ("Offset", 0.0),
27 _lifetime (right._lifetime),
28 _frequency (right._frequency),
29 _sigma (right._sigma),
30 _offset (right._offset),
71 static const double sqrtTwo = sqrt(2.0);
75 double x = argument-xoffset;
79 double expG=0.0, asymm=0.0;
82 expG = exp((xsigma*xsigma +2*tau*(x))/(2.0*tau*tau)) *
83 erfc((xsigma*xsigma+tau*(x))/(sqrtTwo*xsigma*tau))/(2.0*tau);
89 if (!std::isfinite(expG)) {
96 expG = exp((xsigma*xsigma +2*tau*(-x))/(2.0*tau*tau)) *
97 erfc((xsigma*xsigma+tau*(-x))/(sqrtTwo*xsigma*tau))/(2.0*tau);
103 if (!_finite(expG)) {
107 if (!std::isfinite(expG)) {
120 if (xsigma>6.0*tau) {
121 asymm = expG*(1/(1+tau*tau*freq*freq));
123 else if (xsigma==0.0) {
125 if (x>=0) asymm= (expG*cos(freq*x));
128 if (x>=0) asymm= (expG*sin(freq*x));
132 std::complex<double> z(freq*xsigma/sqrtTwo, (xsigma/tau-x/xsigma)/sqrtTwo);
135 asymm= 2.0*nwwerf(z).real()/tau/4.0*exp(-x*x/2.0/xsigma/xsigma);
138 asymm= 2.0*nwwerf(z).imag()/tau/4.0*exp(-x*x/2.0/xsigma/xsigma);
143 asymm= -2.0*nwwerf(std::conj(z)).real()/tau/4*exp(-x*x/2.0/xsigma/xsigma) +
144 exp(xsigma*xsigma/2 *(1/tau/tau - freq*freq) - x/tau)*(1./tau)*cos(freq*x - freq/tau*xsigma*xsigma);
147 asymm= +2.0*nwwerf(std::conj(z)).imag()/tau/4*exp(-x*x/2.0/xsigma/xsigma) +
148 exp(xsigma*xsigma/2 *(1/tau/tau - freq*freq) - x/tau)*(1./tau)*sin(freq*x - freq/tau*xsigma*xsigma);
155 double retVal = (expG+asymm)/2.0;
158 <<
"Warning in AnalyticConvolution: negative probablity"
162 << xsigma <<
' ' << tau <<
' ' << xoffset <<
' '
163 << freq <<
' '<< argument
166 std::cerr << retVal << std::endl;
169 else if (_type==
MIXED) {
170 double retVal = (expG-asymm)/2.0;
173 <<
"Warning in AnalyticConvolution: negative probablity"
177 << xsigma <<
' ' << tau <<
' ' << xoffset <<
' '
178 << freq <<
' ' << argument
181 std::cerr << retVal << std::endl;
189 <<
"Unknown sign parity. State is not allowed"
197double AnalyticConvolution::erfc(
double x)
const {
201 z = (x < 0) ? -x : x;
203 ans = t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
204 t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
205 t*(-0.82215223+t*0.17087277 ))) ))) )));
206 if ( x < 0 ) ans = 2.0 - ans;
210double AnalyticConvolution::pow(
double x,
int n)
const {
212 for(
int i=0;i<n;i++){
218std::complex<double> AnalyticConvolution::nwwerf(std::complex<double> z)
const {
219 std::complex<double> zh,r[38],s,t,v;
222 const double hf = z1/2;
223 const double z10 = 10;
224 const double c1 = 74/z10;
225 const double c2 = 83/z10;
226 const double c3 = z10/32;
227 const double c4 = 16/z10;
228 const double c = 1.12837916709551257;
229 const double p = pow(2.0*c4,33);
233 double xa=(x >= 0) ? x : -x;
234 double ya=(y >= 0) ? y : -y;
235 if(ya < c1 && xa < c2){
236 zh = std::complex<double>(ya+c4,xa);
237 r[37]= std::complex<double>(0,0);
239 for(
int n = 36;
n>0;
n--){
240 t=zh+
double(n)*std::conj(r[n+1]);
241 r[
n]=hf*t/std::norm(t);
244 s=std::complex<double>(0,0);
246 for(
int k=33; k>0; k--){
253 zh=std::complex<double>(ya,xa);
254 r[1]=std::complex<double>(0,0);
256 for(
int n=9;
n>0;
n--){
257 t=zh+
double(n)*std::conj(r[1]);
258 r[1]=hf*t/std::norm(t);
262 if(ya == 0) v= std::complex<double>(exp(-xa*xa),v.imag());
264 v=2.0*std::exp(std::complex<double>(-xa,-ya)*std::complex<double>(xa,ya))-v;
265 if(x > 0) v=std::conj(v);
268 if(x < 0) v=std::conj(v);
#define FUNCTION_OBJECT_IMP(classname)
virtual ~AnalyticConvolution()
AnalyticConvolution(Type=SMEARED_EXP)
virtual double operator()(double argument) const override
virtual double getValue() const