00001 #ifndef __BCMATH__H 00002 #define __BCMATH__H 00003 00004 /*! 00005 * \namespace BCMath 00006 * \brief Some useful mathematic functions. 00007 * \author Daniel Kollar 00008 * \author Kevin Kröninger 00009 * \author Jing Liu 00010 * \version 1.0 00011 * \date 08.2008 00012 * \detail A namespace which encapsulates some mathematical functions 00013 * necessary for BAT. 00014 */ 00015 00016 /* 00017 * Copyright (C) 2008, Daniel Kollar and Kevin Kroeninger. 00018 * All rights reserved. 00019 * 00020 * For the licensing terms see doc/COPYING. 00021 */ 00022 00023 // --------------------------------------------------------- 00024 00025 #define BCMATH_NFACT_ALIMIT 20 00026 00027 // --------------------------------------------------------- 00028 //#include <cstring> 00029 00030 namespace BCMath 00031 { 00032 00033 /** 00034 * Calculate the natural logarithm of a gaussian function with mean 00035 * and sigma. If norm=true (default is false) the result is 00036 * multiplied by the normalization constant, i.e. divided by 00037 * sqrt(2*Pi)*sigma. 00038 */ 00039 double LogGaus(double x, double mean = 0, double sigma = 1, bool norm = false); 00040 00041 /** 00042 * Calculate the natural logarithm of a poisson distribution. 00043 */ 00044 double LogPoisson(double x, double par); 00045 00046 /** 00047 * Calculates Binomial probability using approximations for 00048 * factorial calculations if calculation for number greater than 20 00049 * required using the BCMath::ApproxLogFact function. 00050 */ 00051 double ApproxBinomial(int n, int k, double p); 00052 00053 /** 00054 * Calculates natural logarithm of the Binomial probability using 00055 * approximations for factorial calculations if calculation for 00056 * number greater than 20 required using the BCMath::ApproxLogFact 00057 * function. 00058 */ 00059 double LogApproxBinomial(int n, int k, double p); 00060 00061 /** 00062 * Calculates natural logarithm of the Binomial factor "n over k" 00063 * using approximations for factorial calculations if calculation 00064 * for number greater than 20 required using the 00065 * BCMath::ApproxLogFact function. Even for large numbers the 00066 * calculation is performed precisely, if n-k < 5 00067 */ 00068 double LogBinomFactor(int n, int k); 00069 00070 /** 00071 * Calculates natural logarithm of the n-factorial (n!) using 00072 * Srinivasa Ramanujan approximation 00073 * log(n!) = n*log(n) - n + log(n*(1.+4.*n*(1.+2.*n)))/6. + log(PI)/2. 00074 * if n > 20. If n <= 20 it uses BCMath::LogFact to calculate it 00075 * exactly. 00076 */ 00077 double ApproxLogFact(double x); 00078 00079 /** 00080 * Calculates natural logarithm of the Binomial factor "n over k". 00081 */ 00082 double LogNoverK(int n, int k); 00083 00084 /** 00085 * Calculates natural logarithm of the n-factorial (n!) 00086 */ 00087 double LogFact(int n); 00088 00089 /** 00090 * Returns the "greater or equal" of two numbers 00091 */ 00092 inline int Max(int x, int y) 00093 { return x >= y ? x : y; } 00094 00095 inline double Max(double x, double y) 00096 { return x >= y ? x : y; } 00097 00098 /** 00099 * Returns the "less or equal" of two numbers 00100 */ 00101 inline int Min(int x, int y) 00102 { return x <= y ? x : y; } 00103 00104 inline double Min(double x, double y) 00105 { return x <= y ? x : y; } 00106 00107 /** 00108 * Returns the nearest integer of a double number. 00109 */ 00110 int Nint(double x); 00111 00112 /** 00113 * Returns the rms of an array. 00114 */ 00115 double rms(int n, const double * a); 00116 00117 /** 00118 * Calculates the logarithm of the non-relativistic Breit-Wigner 00119 * distribution. 00120 */ 00121 double LogBreitWignerNonRel(double x, double mean, double Gamma, bool norm = false); 00122 double LogBreitWignerRel(double x, double mean, double Gamma); 00123 00124 /** 00125 * Calculates the logarithm of chi square function: 00126 * chi2(double x; size_t n) 00127 */ 00128 double LogChi2(double x, int n); 00129 00130 /** 00131 * Calculates the logarithm of normalized voigtian function: 00132 * voigtian(double x, double sigma, double gamma) 00133 * 00134 * voigtian is a convolution of the following two functions: 00135 * gaussian(x) = 1/(sqrt(2*pi)*sigma) * exp(x*x/(2*sigma*sigma) 00136 * and 00137 * lorentz(x) = (1/pi)*(gamma/2) / (x*x + (gamma/2)*(gamma/2)) 00138 * 00139 * it is singly peaked at x=0. 00140 * The width of the peak is decided by sigma and gamma, 00141 * so they should be positive. 00142 */ 00143 double LogVoigtian(double x, double sigma, double gamma); 00144 00145 }; 00146 00147 // --------------------------------------------------------- 00148 00149 #endif 00150