File indexing completed on 2026-08-06 09:38:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef ThePEG_Math_H
0010 #define ThePEG_Math_H
0011
0012 #include <cmath>
0013
0014 namespace ThePEG {
0015
0016
0017
0018 namespace Math {
0019
0020
0021
0022
0023
0024 struct MathType {};
0025
0026
0027
0028 double exp1m(double x);
0029
0030
0031
0032 double log1m(double);
0033
0034
0035 double powi(double x, int p);
0036
0037
0038 inline double pIntegrate(double p, double xl, double xu) {
0039 return p == -1.0? log(xu/xl): (pow(xu, p + 1.0) - pow(xl, p + 1.0))/(p + 1.0);
0040 }
0041
0042
0043 inline double pIntegrate(int p, double xl, double xu) {
0044 return p == -1? log(xu/xl): (powi(xu, p + 1) - powi(xl, p + 1))/double(p + 1);
0045 }
0046
0047
0048
0049
0050 inline double pXIntegrate(double e, double xl, double dx) {
0051 return e == 0.0? log1m(-dx/xl): -pow(xl, e)*exp1m(e*log1m(-dx/xl))/e;
0052 }
0053
0054
0055 inline double pGenerate(double p, double xl, double xu, double rnd) {
0056 return p == -1.0? xl*pow(xu/xl, rnd):
0057 pow((1.0 - rnd)*pow(xl, p + 1.0) + rnd*pow(xu, p + 1.0), 1.0/(1.0 + p));
0058 }
0059
0060
0061 inline double pGenerate(int p, double xl, double xu, double rnd) {
0062 return p == -1? xl*pow(xu/xl, rnd):
0063 pow((1.0 - rnd)*powi(xl, p + 1) + rnd*powi(xu, p + 1), 1.0/double(1 + p));
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073 inline double pXGenerate(double e, double xl, double dx, double rnd) {
0074 return e == 0.0? -xl*exp1m(rnd*log1m(-dx/xl)):
0075 -exp1m(log1m(rnd*exp1m(e*log1m(-dx/xl)))/e)*xl;
0076 }
0077
0078
0079 template <typename FloatType>
0080 inline double relativeError(FloatType x, FloatType y) {
0081 return ( x == y ? 0.0 : double((x - y)/(abs(x) + abs(y))) );
0082 }
0083
0084
0085 template <typename T>
0086 inline T absmin(const T & x, const T & y) {
0087 return abs(x) < abs(y)? x: y;
0088 }
0089
0090
0091 template <typename T>
0092 inline T absmax(const T & x, const T & y) {
0093 return abs(x) > abs(y)? x: y;
0094 }
0095
0096
0097
0098
0099 template <typename T, typename U>
0100 inline T sign(T x, U y) {
0101 return y > U()? abs(x): -abs(x);
0102 }
0103
0104
0105
0106
0107
0108
0109 template <int N, bool Inv>
0110 struct Power: public MathType {};
0111
0112
0113
0114
0115 template <int N>
0116 struct Power<N,false> {
0117
0118 static double pow(double x) { return x*Power<N-1,false>::pow(x); }
0119 };
0120
0121
0122
0123
0124 template <int N>
0125 struct Power<N,true> {
0126
0127 static double pow(double x) { return Power<N+1,true>::pow(x)/x; }
0128 };
0129
0130
0131
0132
0133 template <>
0134 struct Power<0,true> {
0135
0136 static double pow(double) { return 1.0; }
0137 };
0138
0139
0140
0141
0142 template <>
0143 struct Power<0,false> {
0144
0145 static double pow(double) { return 1.0; }
0146 };
0147
0148
0149
0150
0151 template <int N>
0152 inline double Pow(double x) { return Power<N, (N < 0)>::pow(x); }
0153
0154
0155
0156
0157 namespace Functions {
0158
0159
0160 template <int N>
0161 struct PowX: public MathType {
0162
0163
0164 static double primitive(double x) {
0165 return Pow<N+1>(x)/double(N+1);
0166 }
0167
0168
0169 static double integrate(double x0, double x1) {
0170 return primitive(x1) - primitive(x0);
0171 }
0172
0173
0174
0175 static double generate(double x0, double x1, double R) {
0176 return pow(primitive(x0) + R*integrate(x0, x1), 1.0/double(N+1));
0177 }
0178
0179 };
0180
0181
0182
0183
0184
0185
0186 template <>
0187 inline double PowX<1>::generate(double x0, double x1, double R) {
0188 return std::sqrt(x0*x0 + R*(x1*x1 - x0*x0));
0189 }
0190
0191
0192
0193
0194 template <>
0195 inline double PowX<0>::generate(double x0, double x1, double R) {
0196 return x0 + R*(x1 - x0);
0197 }
0198
0199
0200
0201
0202 template<>
0203 inline double PowX<-1>::primitive(double x) {
0204 return log(x);
0205 }
0206
0207
0208
0209
0210 template <>
0211 inline double PowX<-1>::integrate(double x0, double x1) {
0212 return log(x1/x0);
0213 }
0214
0215
0216
0217
0218 template <>
0219 inline double PowX<-1>::generate(double x0, double x1, double R) {
0220 return x0*pow(x1/x0, R);
0221 }
0222
0223
0224
0225
0226 template <>
0227 inline double PowX<-2>::generate(double x0, double x1, double R) {
0228 return x0*x1/(x1 - R*(x1 - x0));
0229 }
0230
0231
0232
0233
0234 template <>
0235 inline double PowX<-3>::generate(double x0, double x1, double R) {
0236 return x0*x1/std::sqrt(x1*x1 - R*(x1*x1 - x0*x0));
0237 }
0238
0239
0240
0241
0242
0243
0244
0245 template <int N>
0246 struct Pow1mX: public MathType {
0247
0248
0249 static double primitive(double x) {
0250 return -PowX<N>::primitive(1.0 - x);
0251 }
0252
0253
0254 static double integrate(double x0, double x1) {
0255 return PowX<N>::integrate(1.0 - x1, 1.0 - x0);
0256 }
0257
0258
0259
0260 static double generate(double x0, double x1, double R) {
0261 return 1.0 - PowX<N>::generate(1.0 - x1, 1.0 - x0, R);
0262 }
0263
0264 };
0265
0266
0267 struct InvX1mX: public MathType {
0268
0269
0270 static double primitive(double x) {
0271 return log(x/(1.0 - x));
0272 }
0273
0274
0275 static double integrate(double x0, double x1) {
0276 return log(x1*(1.0 - x0)/(x0*(1.0 - x1)));
0277 }
0278
0279
0280
0281 static double generate(double x0, double x1, double R) {
0282 double r = pow(x1*(1.0 - x0)/(x0*(1.0 - x1)), R)*x0/(1.0 - x0);
0283 return r/(1.0 + r);
0284 }
0285
0286 };
0287
0288
0289 struct ExpX: public MathType {
0290
0291
0292 static double primitive(double x) {
0293 return exp(x);
0294 }
0295
0296
0297 static double integrate(double x0, double x1) {
0298 return exp(x1) - exp(x0);
0299 }
0300
0301
0302
0303 static double generate(double x0, double x1, double R) {
0304 return log(exp(x0) + R*(exp(x1) - exp(x0)));
0305 }
0306
0307 };
0308
0309
0310
0311 template <int N, int D>
0312 struct FracPowX: public MathType {
0313
0314
0315 static double primitive(double x) {
0316 double r = double(N)/double(D) + 1.0;
0317 return pow(x, r)/r;
0318 }
0319
0320
0321 static double integrate(double x0, double x1) {
0322 return primitive(x1) - primitive(x0);
0323 }
0324
0325
0326
0327 static double generate(double x0, double x1, double R) {
0328 double r = double(N)/double(D) + 1.0;
0329 return pow(primitive(x0) + R*integrate(x0, x1), 1.0/r);
0330 }
0331
0332 };
0333
0334 }
0335
0336 }
0337
0338 }
0339
0340 #endif