mql5/Include/Math/Stat/Math.mqh

5518 lines
425 KiB
MQL5

2025-08-05 01:57:33 -04:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Math.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#define ERR_OK 0
#define ERR_ARGUMENTS_NAN 1
#define ERR_ARGUMENTS_INVALID 2
#define ERR_RESULT_INFINITE 3
#define ERR_NON_CONVERGENCE 4
//+------------------------------------------------------------------+
//| Nans |
//+------------------------------------------------------------------+
double QNaN =(double)"nan"; // QNaN
double QPOSINF=(double)"inf"; // +infinity 1.#INF
double QNEGINF=(double)"-inf"; // -infinity -1.#INF
//+------------------------------------------------------------------+
//| MathRandom |
//+------------------------------------------------------------------+
double MathRandomNonZero(void)
{
double rnd=0;
//--- except 0 and 1
while(rnd==0.0 || rnd==1.0)
rnd=MathRand()/32767.0;
//---
return(rnd);
}
//+------------------------------------------------------------------+
//| Computes 4 first moments of the values in array[] |
//+------------------------------------------------------------------+
bool MathMoments(const double &array[],double &mean,double &variance,double &skewness,double &kurtosis,const int start=0,const int count=WHOLE_ARRAY)
{
//--- initial values
mean=0.0;
variance=0.0;
skewness=0.0;
kurtosis=0.0;
//--- get data size
int size=ArraySize(array);
int data_count=0;
//--- set data count
if(count==WHOLE_ARRAY)
data_count=size;
else
data_count=count;
//--- check data range
if(data_count==0)
return(false);
if(start+data_count>size)
return(false);
//--- set indexes
int ind1=start;
int ind2=ind1+data_count-1;
//--- calculate mean
for(int i=ind1; i<=ind2; i++)
mean+=array[i];
mean=mean/data_count;
double S=0.0;
//---
if(data_count>1)
{
//--- calculate variance
for(int i=ind1; i<=ind2; i++)
variance+=MathPow(array[i]-mean,2);
variance=variance/(data_count-1);
S=MathSqrt(variance);
}
else
variance=QNaN;
//---
if(data_count>2 && S>0.0)
{
//--- calculate skewness
for(int i=ind1; i<=ind2; i++)
skewness+=MathPow(array[i]-mean,3);
skewness=skewness/(data_count*MathPow(S,3));
}
else
skewness=QNaN;
//---
if(data_count>3 && S>0.0)
{
//--- calculate kurtosis
for(int i=ind1; i<=ind2; i++)
kurtosis+=MathPow(array[i]-mean,4);
kurtosis=kurtosis/(data_count*MathPow(S,4));
kurtosis-=3;
}
else
kurtosis=QNaN;
//--- check values and return calculation result
if((!MathIsValidNumber(variance)) || (!MathIsValidNumber(skewness)) || (!MathIsValidNumber(kurtosis)))
return(false);
else
return(true);
}
#define M_1_SQRT_2PI 1/MathSqrt(2*M_PI)
double FactorialsTable[21]=
{
1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,
6227020800,87178291200,1307674368000,20922789888000,355687428096000,
6402373705728000,121645100408832000,2432902008176640000
};
//+------------------------------------------------------------------+
//| MathPowInt |
//+------------------------------------------------------------------+
double MathPowInt(const double x,const int power)
{
//--- check power
if(power==0)
return(1.0);
if(power<0)
return(0);
//--- calculate product
double val=x;
for(int i=2; i<=power; i++)
val*=x;
//--- return result
return(val);
}
//+------------------------------------------------------------------+
//| MathFactorial |
//+------------------------------------------------------------------+
double MathFactorial(const int n)
{
if(n<0)
return(0);
if(n<=20)
//--- use values from the factorials table
return(FactorialsTable[n]);
else
{
//--- calculate product starting from 20th element of factorials table
double val=FactorialsTable[20];
for(int i=21; i<=n; i++)
val*=i;
//--- return result
return(val);
}
}
//+------------------------------------------------------------------+
//| MathTrunc |
//+------------------------------------------------------------------+
double MathTrunc(const double x)
{
if(x>=0)
return(MathFloor(x));
else
return(MathCeil(x));
}
//+------------------------------------------------------------------+
//| MathRound |
//+------------------------------------------------------------------+
//| Round a double number to a given precision |
//+------------------------------------------------------------------+
double MathRound(const double x,const int digits)
{
if(!MathIsValidNumber(x))
return(QNaN);
if(x==0.0)
return(x);
if(digits>0)
{
double sign=1.0;
double xx=x;
if(xx<0.0)
{
xx=-xx;
sign=-1.0;
}
double pwr_factor=MathPow(10,digits);
double int_value=MathFloor(xx);
double res=(xx-int_value)*pwr_factor;
res=MathFloor(MathAbs(res)+0.5);
return(sign*(int_value+res/pwr_factor));
}
else
if(digits==0)
return MathRound(x);
//---
return(0);
}
//+------------------------------------------------------------------+
//| Comments from original FORTRAN code: |
//| https://www.netlib.org/specfun/gamma |
//| |
//| This routine calculates the GAMMA function for a real argument X.|
//| Computation is based on an algorithm outlined in reference 1. |
//| The program uses rational functions that approximate the GAMMA |
//| function to at least 20 significant decimal digits. Coefficients |
//| for the approximation over the interval (1,2) are unpublished. |
//| Those for the approximation for X .GE. 12 are from reference 2. |
//| |
//| References: |
//| 1. "An Overview of Software Development for Special Functions" |
//| W. J. Cody, Lecture Notes in Mathematics, 506, |
//| Numerical Analysis Dundee, 1975, G. A. Watson (ed.) |
//| Springer Verlag, Berlin, 1976. |
//| 2. Computer Approximations, Hart, Et. Al., Wiley and sons, |
//| New York, 1968. |
//| |
//| Authors: |
//| W. J. Cody and L. Stoltz, Applied Mathematics Division |
//| Argonne National Laboratory, Argonne, IL 60439 |
//+------------------------------------------------------------------+
double MathGamma(const double x)
{
//--- mathematical constants
const double logsqrt2pi=MathLog(MathSqrt(2*M_PI));
//--- machine dependent parameters
const double xminin=2.23e-308;
const double xbig=171.624;
double eps=2.22e-16;
//--- numerator and denominator coefficients for rational minimax
//--- approximation over (1,2)
const double p[8]=
{
-1.71618513886549492533811e+0, 2.47656508055759199108314e+1,
-3.79804256470945635097577e+2, 6.29331155312818442661052e+2,
8.66966202790413211295064e+2,-3.14512729688483675254357e+4,
-3.61444134186911729807069e+4, 6.64561438202405440627855e+4
};
const double q[8]=
{
-3.08402300119738975254353e+1, 3.15350626979604161529144e+2,
-1.01515636749021914166146e+3,-3.10777167157231109440444e+3,
2.25381184209801510330112e+4, 4.75584627752788110767815e+3,
-1.34659959864969306392456e+5,-1.15132259675553483497211e+5
};
//--- coefficients for minimax approximation over (12, inf)
const double c[7]=
{
-1.910444077728e-03, 8.4171387781295e-04,
-5.952379913043012e-04, 7.93650793500350248e-04,
-2.777777777777681622553e-03,8.333333333333333331554247e-02,
5.7083835261e-03
};
int parity=0;
double fact=1.0;
int n=0;
double y=x,y1,res,z,xnum=0,xden=0,ysq=0,sum=0;
if(y<=0.0)
{
//--- argument is negative
y=-x;
y1=MathTrunc(y);
res=y-y1;
if(res!=0.0)
{
if(y1!=MathTrunc(y1*0.5)*2.0)
parity=1;
fact=-M_PI/MathSin(M_PI*res);
y=y+1.0;
}
else
{
return(QPOSINF);
}
}
//--- argument is positive
if(y<eps)
{
//--- argument < eps
if(y>=xminin)
{
res=1.0/y;
}
else
{
return(QPOSINF);
}
}
else
if(y<12.0)
{
y1=y;
if(y<1.0)
{
//--- 0.0 < argument < 1.0
z = y;
y = y + 1.0;
}
else
{
//--- 1.0 < argument < 12.0, reduce argument if necessary
n = int(y) - 1;
y = y - double(n);
z = y - 1.0;
}
//--- evaluate approximation for 1.0 < argument < 2.0
xnum=0.0;
xden=1.0;
for(int i=0; i<8; i++)
{
xnum = (xnum + p[i]) * z;
xden = xden * z + q[i];
}
res=xnum/xden+1.0;
if(y1<y)
{
//--- adjust result for case 0.0 < argument < 1.0
res=res/y1;
}
else
if(y1>y)
{
//--- adjust result for case 2.0 < argument < 12.0
for(int i=0; i<n; i++)
{
res=res*y;
y=y+1.0;
}
}
}
else
{
//--- evaluate for argument <=12.0,
if(y<=xbig)
{
ysq=y*y;
sum=c[6];
for(int i=0; i<6; i++)
{
sum=sum/ysq+c[i];
}
sum = sum/y - y + logsqrt2pi;
sum = sum + (y-0.5)*MathLog(y);
res = MathExp(sum);
}
else
{
return(QPOSINF);
}
}
//--- final adjustments and return
if(parity==1)
res=-res;
if(fact!=1.0)
res=fact/res;
//--- return result
return(res);
}
//+------------------------------------------------------------------+
//| MathGammaLog |
//+------------------------------------------------------------------+
//| Comments from original FORTRAN code: |
//| https://www.netlib.org/specfun/algama |
//| |
//| This routine calculates the LOG(GAMMA) function for a positive |
//| real argument X. Computation is based on an algorithm outlined |
//| in references 1 and 2. The program uses rational functions that |
//| theoretically approximate LOG(GAMMA) to at least 18 significant |
//| decimal digits. The approximation for X > 12 is from reference |
//| 3, while approximations for X < 12.0 are similar to those in |
//| reference 1, but are unpublished. The accuracy achieved depends |
//| on the arithmetic system, the compiler, the intrinsic functions, |
//| and proper selection of the machine-dependent constants. |
//| |
//| References: |
//| 1) W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for |
//| the Natural Logarithm of the Gamma Function,' Math. Comp. 21, |
//| 1967, pp. 198-203. |
//| 2) K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May,|
//| 1969. |
//| 3) Hart, Et. Al., Computer Approximations, Wiley and sons, New |
//| York, 1968. |
//| Authors: W. J. Cody and L. Stoltz |
//| Argonne National Laboratory |
//| |
//| https://gcc.gnu.org/ml/fortran/2007-11/msg00061/gamma.diff |
//| For negative arguments (where netlib would return +Inf) |
//| we use the following identity: |
//| lgamma(y) = log(pi/(|y*sin(pi*y)|)) - lgamma(-y) |
//+------------------------------------------------------------------+
double MathGammaLog(const double x)
{
//--- mathematical constants
const double pnt68=0.6796875e0;
const double sqrtpi=0.9189385332046727417803297e0;
//--- machine dependent parameters
const double xbig=2.55E305;
const double xinf=1.79E308;
const double eps=2.22E-16;
const double frtbig=2.25E76;
//--- numerator and denominator coefficients for rational minimax
//--- approximation over (0.5,1.5)
const double d1=-5.772156649015328605195174e-1;
const double p1[8]=
{
4.945235359296727046734888e0,2.018112620856775083915565e2,
2.290838373831346393026739e3,1.131967205903380828685045e4,
2.855724635671635335736389e4,3.848496228443793359990269e4,
2.637748787624195437963534e4,7.225813979700288197698961e3
};
const double q1[8]=
{
6.748212550303777196073036e1,1.113332393857199323513008e3,
7.738757056935398733233834e3,2.763987074403340708898585e4,
5.499310206226157329794414e4,6.161122180066002127833352e4,
3.635127591501940507276287e4,8.785536302431013170870835e3
};
//--- numerator and denominator coefficients for rational minimax
//--- approximation over (1.5,4.0)
const double d2=4.227843350984671393993777e-1;
const double p2[8]=
{
4.974607845568932035012064e0,5.424138599891070494101986e2,
1.550693864978364947665077e4,1.847932904445632425417223e5,
1.088204769468828767498470e6,3.338152967987029735917223e6,
5.106661678927352456275255e6,3.074109054850539556250927e6
};
const double q2[8]=
{
1.830328399370592604055942e2,7.765049321445005871323047e3,
1.331903827966074194402448e5,1.136705821321969608938755e6,
5.267964117437946917577538e6,1.346701454311101692290052e7,
1.782736530353274213975932e7,9.533095591844353613395747e6
};
//--- numerator and denominator coefficients for rational minimax
//--- approximation over (4.0,12.0)
const double d4=1.791759469228055000094023e0;
const double p4[8]=
{
1.474502166059939948905062e4, 2.426813369486704502836312e6,
1.214755574045093227939592e8, 2.663432449630976949898078e9,
2.940378956634553899906876e10,1.702665737765398868392998e11,
4.926125793377430887588120e11,5.606251856223951465078242e11
};
const double q4[8]=
{
2.690530175870899333379843e3, 6.393885654300092398984238e5,
4.135599930241388052042842e7, 1.120872109616147941376570e9,
1.488613728678813811542398e10,1.016803586272438228077304e11,
3.417476345507377132798597e11,4.463158187419713286462081e11
};
//--- coefficients for minimax approximation over (12, inf)
const double c[7]=
{
-1.910444077728e-03, 8.4171387781295e-04,
-5.952379913043012e-04, 7.93650793500350248e-04,
-2.777777777777681622553e-03,8.333333333333333331554247e-02,
5.7083835261e-03
};
double y=x;
double res=0.0;
double corr=0;
double xm1,xm2,xm4,xden,xnum;
double ysq=0;
if((y>0 && y<=xbig))
{
if(y<=eps)
{
res=-MathLog(y);
}
else
{
if(y<=1.5)
{
//--- eps < x <= 1.5
if(y<pnt68)
{
corr= -MathLog(y);
xm1 = y;
}
else
{
corr=0.0;
xm1 =(y-0.5)-0.5;
}
if((y<=0.5 || y>=pnt68))
{
xden = 1.0;
xnum = 0;
for(int i=0; i<8; i++)
{
xnum = xnum*xm1 + p1[i];
xden = xden*xm1 + q1[i];
}
res=corr+(xm1 *(d1+xm1*(xnum/xden)));
}
else
{
xm2=(y-0.5)-0.5;
xden = 1.0;
xnum = 0.0;
for(int i=0; i<8; i++)
{
xnum=xnum*xm2+p2[i];
xden=xden*xm2+q2[i];
}
res=corr+xm2 *(d2+xm2*(xnum/xden));
}
}
else
{
if(y<=4.0)
{
//--- 1.5 < x .<= 4.0
xm2=y-2.0;
xden = 1.0;
xnum = 0.0;
for(int i=0; i<8; i++)
{
xnum = xnum*xm2 + p2[i];
xden = xden*xm2 + q2[i];
}
res=xm2 *(d2+xm2*(xnum/xden));
}
else
{
if(y<=12.0)
{
//--- 4.0 < x <= 12.0
xm4=y-4.0;
xden = -1.0;
xnum = 0.0;
for(int i=0; i<8; i++)
{
xnum = xnum*xm4 + p4[i];
xden = xden*xm4 + q4[i];
}
res=d4+xm4*(xnum/xden);
}
else
{
//--- evaluate for argument>=12.0,
res=0.0;
if(y<=frtbig)
{
res=c[6];
ysq=y*y;
for(int i=0; i<6; i++)
{
res=res/ysq+c[i];
}
}
res=res/y;
corr= MathLog(y);
res = res + sqrtpi - 0.5*corr;
res = res + y*(corr-1.0);
}
}
}
}
}
else
{
//--- return for bad arguments
//--- res=QPOSINF;
//--- for negative arguments (where netlib would return +Inf)
//--- we use the following identity:
//--- lgamma(y) = log(pi/(|y*sin(pi*y)|)) - lgamma(-y)
//--- https://gcc.gnu.org/ml/fortran/2007-11/msg00061/gamma.diff
if(y<0 && MathFloor(y)!=y)
{
//--- for abs(y) very close to zero, we use a series expansion to
//--- the first order in y to avoid overflow.
if(y>-1.e-100)
res=-2*MathLog(MathAbs(y))-MathGammaLog(-y);
else
res=MathLog(M_PI/MathAbs(y*MathSin(M_PI*y)))-MathGammaLog(-y);
}
else
{
//--- negative integer values
res=QPOSINF;
}
}
//--- return result
return(res);
}
//+------------------------------------------------------------------+
//| MathBeta |
//+------------------------------------------------------------------+
double MathBeta(const double a,const double b)
{
return MathExp(MathBetaLog(a,b));
}
//+------------------------------------------------------------------+
//| MathBetaLog |
//+------------------------------------------------------------------+
double MathBetaLog(const double a,const double b)
{
return(MathGammaLog(a)+MathGammaLog(b)-MathGammaLog(a+b));
}
//+------------------------------------------------------------------+
//| Incomplete beta function |
//+------------------------------------------------------------------+
//| The incomplete beta function ratio is the probability that a |
//| random variable from a beta distribution having parameters p |
//| and q will be less than or equal to x. |
//| |
//| Input: |
//| x : upper limit of integration. x must be in (0,1) inclusive. |
//| p : first beta distribution parameter. p must be>0.0. |
//| q : second beta distribution parameter. q must be>0.0. |
//| |
//| Returns the value of the incomplete Beta function ratio. |
//| |
//| Original FORTRAN77 version by KL Majumder, GP Bhattacharjee. |
//| C version by John Burkardt. |
//| |
//| Reference: |
//| |
//| KL Majumder, GP Bhattacharjee, |
//| Algorithm AS 63: The incomplete Beta Integral, |
//| Applied Statistics,.Volume 22, Number 3, 1973, pages 409-411. |
//+------------------------------------------------------------------+
double MathBetaIncomplete(const double x,const double p,const double q)
{
double acu=0.1E-16;
double pp,qq,xx;
int ifault=0;
double value=x;
//--- check the input arguments
if(p<=0.0 || q<=0.0)
{
ifault=1;
return(value);
}
//--- check x range
if(x<0.0 || 1.0<x)
{
ifault=2;
return(value);
}
//--- special cases
if(x==0.0 || x==1.0)
{
return(value);
}
//--- calc beta log
double beta_log=MathGammaLog(p)+MathGammaLog(q)-MathGammaLog(p+q);
//--- change tail if necessary and determine S
double psq= p+q;
double cx = 1.0-x;
int indx=0;
if(p<psq*x)
{
xx = cx;
cx = x;
pp = q;
qq = p;
indx=1;
}
else
{
xx = x;
pp = p;
qq = q;
indx=0;
}
value=1.0;
double term=1.0;
double ai=1.0;
int ns=(int)(qq+cx*psq);
//--- use the Soper reduction formula
double rx=xx/cx;
double temp=qq-ai;
if(ns==0.0)
{
rx=xx;
}
for(;;)
{
term=term*temp*rx/(pp+ai);
value= value+term;;
temp = MathAbs(term);
//---
if(temp<=acu && temp<=acu*value)
{
value=value*MathExp(pp*MathLog(xx)+(qq-1.0)*MathLog(cx)-beta_log)/pp;
if(indx)
{
value=1.0-value;
}
break;
}
ai=ai+1.0;
ns--;
if(0<=ns)
{
temp=qq-ai;
if(ns==0)
{
rx=xx;
}
}
else
{
temp= psq;
psq = psq+1.0;
}
}
//--- return result
return(value);
}
//+------------------------------------------------------------------+
//| Incomplete Gamma function |
//+------------------------------------------------------------------+
//| Inputs: |
//| x : value at which the c.d.f is to be computed |
//| alpha : parameter of the gamma function (>0) |
//+------------------------------------------------------------------+
//| Comment from original FORTRAN code: |
//| www.nist.gov/sites/default/files/documents/itl/sed/stspac.f |
//| ibid .../itl/sed/SED_Note_86-2-2.pdf |
//| |
//| CDFGAM Written by Charles p. Reeve, Statistical Engineering |
//| Division, National Bureau of Standards, Gaithersburg. |
//| |
//| Computing the cumulative distribution function of the Gamma |
//| distribution (also known as the Incomplete Gamma ratio) to a |
//| specified accuracy (truncation error in the infinite series). |
//| the algorithm, described in Ref. 2, is a modification of |
//| the algorithm of Ref. 1. Three features have been added: |
//| |
//| 1) A precise method of meeting the truncation accuracy, |
//| 2) Computation of the upper tail area by decrementing alpha |
//| when that method is more efficient, and |
//| 3) A constant uflo >= the underflow limit on the computer. |
//| |
//| References: |
//| |
//| 1) Lau, Chi-Leung, 'A Simple Series for the Incomplete Gamma |
//| Integral', Algorithm AS 147, Applied Statistics, vol. 29, |
//| No. 1, 1980, pp. 113-114. |
//| |
//| 2) Reeve, Charles p., 'An Algorithm for Computing the Gamma |
//| C.D.F. to a Specified Accuracy', Statistical Engineering |
//| Division,Note 86-2, October 1986. |
//+------------------------------------------------------------------+
double MathGammaIncomplete(double x,double alpha)
{
double eps=10e-20;
int iflag=0;
bool ll;
int imax=5000;
double uflo=1.0e-100;
double cdfx=0.0;
int k=0;
//--- check for validity of arguments alpha and eps
if(alpha<=uflo || eps<=uflo)
{
iflag=1;
return(QNaN);
}
iflag=0;
//--- check for special case of x
if(x<=0.0)
return(QNaN);
//--- evaluate the gamma p.d.f. and check for underflow
double dx=double(x);
double pdfl=double(alpha-1.0)*MathLog(dx)-dx-MathGammaLog(alpha);
if(pdfl<MathLog(uflo))
{
if(x>=alpha)
cdfx=1.0;
}
else
{
double p=alpha;
double u=MathExp(pdfl);
//--- determine whether to increment or decrement alpha (a.k.a. p)
ll=true;
if(x>=p)
{
k=int(p);
if(p<=double(k))
k=k-1;
double eta=p-double(k);
double bl=double((eta-1.0)*MathLog(dx)-dx-MathGammaLog(eta));
ll=bl>MathLog(eps);
}
//---
double epsx=eps/x;
//---
if(ll==true)
{
//--- increment p
for(int i=0; i<=imax; i++)
{
if(u<=epsx*(p-x))
{
return(cdfx);
}
u=x*u/p;
cdfx=cdfx+u;
p=p+1.0;
}
iflag=2;
}
else
{
//--- decrement p
for(int j=1; j<=k; j++)
{
p=p-1.0;
if(u<=epsx*(x-p))
break;
cdfx=cdfx+u;
u=p*u/x;
}
cdfx=1.0-cdfx;
}
}
//--- return result
return(cdfx);
}
//+------------------------------------------------------------------+
//| Computes the binomial coefficient C(n,k)=n!/(k!*(n-k)!) |
//|
//| The value is calculated in such a way as to avoid overflow and |
//| roundoff. The calculation is done in integer arithmetic. |
//| |
//| Parameters: |
//| Input, int N, K, are the values of N and K. |
//| Output: the number of combinations of N things taken K at a time.|
//| |
//| Author: John Burkardt |
//| |
//| Reference: |
//| ML Wolfson, HV Wright, |
//| Algorithm 160: Combinatorial of M Things Taken N at a Time, |
//| Communications of the ACM, Volume 6, N4, April 1963, page 161. |
//+------------------------------------------------------------------+
long MathBinomialCoefficient(const int n,const int k)
{
int mn,mx;
long value=0;
int n_k=n-k;
//---
if(k<n_k)
{
mn = k;
mx = n_k;
}
else
{
mn = n_k;
mx = k;
}
if(mn>0)
{
value=mx+1;
for(int i=2; i<=mn; i++)
value=(value*(mx+i))/i;
}
else
{
if(mn<0)
return(0);
if(mn==0)
return(1);
}
//---
return(value);
}
//+------------------------------------------------------------------+
//| MathBinomialCoefficientLog |
//+------------------------------------------------------------------+
double MathBinomialCoefficientLog(const int n,const int k)
{
int mn,mx;
long value=0;
int n_k=n-k;
//---
if(k<n_k)
{
mn = k;
mx = n_k;
}
else
{
mn = n_k;
mx = k;
}
if(mn>0)
{
value=mx+1;
for(int i=2; i<=mn; i++)
value=(value*(mx+i))/i;
}
else
{
if(mn<0)
return(QNEGINF);
if(mn==0)
return(0);
}
//---
return MathLog(value);
}
//+------------------------------------------------------------------+
//| Computes the logarithm of the Binomial coefficient. |
//| |
//| Log(C(n,k))=Log(n!/(k!*(n-k)!)) |
//| |
//| Parameters: |
//| Input, int n, k, are the values of n and k. |
//| Return value: the logarithm of C(n,k). |
//+------------------------------------------------------------------+
double MathBinomialCoefficientLog(const double n,const double k)
{
return(MathGammaLog(n+1)-MathGammaLog(k+1)-MathGammaLog(n-k+1));
}
//+------------------------------------------------------------------+
//| Computes the function Hypergeometric_2F2(a,b,c,d,z) using |
//| a Taylor method. |
//| |
//| Author : John Pearson |
//| Reference : MSc thesis "Computation of Hypergeometric Functions" |
//+------------------------------------------------------------------+
double MathHypergeometric2F2(const double a,const double b,const double c,const double d,const double z)
{
double a1=1.0;
double b1=1.0;
double tol=10E-10; // set tolerance
//--- direct summation
for(int j=1; j<=500; j++)
{
//--- update current term in terms of previous one
a1=(a+j-1)*(b+j-1)/(c+j-1)/(d+j-1)*z/j*a1;
//--- update sum of terms computed so far
b1=b1+a1;
//--- terminate summation if stopping criterion is satisfied
if(MathAbs(a1)/MathAbs(b1)<tol)
return(b1);
}
//--- unknown
return(QNaN);
}
//+------------------------------------------------------------------+
//| Returns log(0) depending on tail and log_mode arugments |
//+------------------------------------------------------------------+
double TailLog0(const bool tail,const bool log_mode)
{
if(tail==true)
{
if(log_mode==true)
return(QNEGINF);
else
return(0.0);
}
else
{
if(log_mode==true)
return(0.0);
else
return(1.0);
}
}
//+------------------------------------------------------------------+
//| Returns log(1) depending on tail and log_mode arugments |
//+------------------------------------------------------------------+
double TailLog1(const bool tail,const bool log_mode)
{
if(tail==true)
{
if(log_mode==true)
return(0.0);
else
return(1.0);
}
else
{
if(log_mode==true)
return(1.0);
else
return(0.0);
}
}
//+------------------------------------------------------------------+
//| Returns value depending on tail and log_mode arugments |
//+------------------------------------------------------------------+
double TailLogValue(const double value,const bool tail,const bool log_mode)
{
if(tail==true)
{
if(log_mode)
return MathLog(MathAbs(value));
else
return(value);
}
else
{
if(log_mode)
return MathLog(MathAbs(1.0-value));
else
return(1.0-value);
}
}
//+------------------------------------------------------------------+
//| Returns value depending on tail and log_mode arugments |
//+------------------------------------------------------------------+
double TailLogProbability(const double probability,const bool tail,const bool log_mode)
{
if(tail==true)
{
if(log_mode)
return MathExp(probability);
else
return(probability);
}
else
{
if(log_mode)
return(1.0-MathExp(probability));
else
return(1.0-probability);
}
}
//+------------------------------------------------------------------+
//| MathSequence |
//+------------------------------------------------------------------+
//| The function generates a sequence of double numbers |
//| with given starting and ending values and step. |
//| |
//| Arguments: |
//| from : Starting value of the sequence |
//| to : Last value of the sequence |
//| step : Step of the sequence |
//| result[] : Array for the sequence values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSequence(const double from,const double to,const double step,double &result[])
{
//--- check NaN
if(!MathIsValidNumber(from) || !MathIsValidNumber(to) || !MathIsValidNumber(step))
return(false);
if(to<from)
return(false);
//--- calculate number of elements and prepare output array
int count=1+int((to-from)/step);
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare sequence
for(int i=0; i<count; i++)
result[i]=from+i*step;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSequence |
//+------------------------------------------------------------------+
//| The function generates a sequence of integer numbers |
//| with given starting and ending values and step. |
//| |
//| Arguments: |
//| from : Starting value of the sequence |
//| to : Last value of the sequence |
//| step : Step of the sequence |
//| result[] : Array for the sequence values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSequence(const int from,const int to,const int step,int &result[])
{
if(to<from)
return(false);
//--- calculate number of elements and prepare output array
int count=1+int((to-from)/step);
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare sequence
for(int i=0; i<count; i++)
result[i]=from+i*step;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSequenceByCount |
//+------------------------------------------------------------------+
//| The function generates a sequence of double numbers |
//| with given starting and ending values and number of elements |
//| in the sequence. |
//| |
//| Arguments: |
//| from : Starting value of the sequence |
//| to : Last value of the sequence |
//| count : Number of elements in the sequence |
//| result[] : Array for sequence values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSequenceByCount(const double from,const double to,const int count,double &result[])
{
//--- check NaN
if(!MathIsValidNumber(from) || !MathIsValidNumber(to))
return(false);
if(to<from || count<=0)
return(false);
//--- prepare output array
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare sequence
double step=(count==1) ? 0 : ((to-from)/(count-1));
for(int i=0; i<count; i++)
result[i]=from+i*step;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSequenceByCount |
//+------------------------------------------------------------------+
//| The function generates a sequence of double numbers |
//| with given starting and ending values and number of elements |
//| in the sequence. |
//| |
//| Arguments: |
//| from : Starting value of the sequence |
//| to : Last value of the sequence |
//| count : Number of elements in the sequence |
//| result[] : Array for sequence values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSequenceByCount(const int from,const int to,const int count,int &result[])
{
if(to<from || count<=0)
return(false);
//--- prepare output array
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare sequence
int step=(count==1) ? 0 : ((to-from)/(count-1));
for(int i=0; i<count; i++)
result[i]=from+i*step;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathReplicate |
//+------------------------------------------------------------------+
//| The function replicates the sequence of double numbers |
//| from array[] with given times (count). |
//| |
//| Arguments: |
//| array[] : Array with values to replicate |
//| count : Number of elements in the sequence |
//| result[] : Array for sequence values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathReplicate(const double &array[],const int count,double &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
//--- check replicate count
if(count<=0)
return(false);
//--- prepare output array
int target_size=size*count;
if(ArraySize(result)<target_size)
if(ArrayResize(result,target_size)!=target_size)
return(false);
//--- replicate array elements
for(int i=0; i<count; i++)
ArrayCopy(result,array,i*size,0,WHOLE_ARRAY);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathReplicate |
//+------------------------------------------------------------------+
//| The function replicates the sequence of integer numbers |
//| from array[] with given times (count). |
//| |
//| Arguments: |
//| array[] : Array with values to replicate |
//| count : Number of elements in the sequence |
//| result[] : Array for sequence values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathReplicate(const int &array[],const int count,int &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
//--- check replicate count
if(count<=0)
return(false);
//--- prepare output array
int target_size=size*count;
if(ArraySize(result)<target_size)
if(ArrayResize(result,target_size)!=target_size)
return(false);
//--- replicate array elements
for(int i=0; i<count; i++)
ArrayCopy(result,array,i*size,0,WHOLE_ARRAY);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathReverse |
//+------------------------------------------------------------------+
//| The function reverses order of the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Array for reversed elements |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathReverse(const double &array[],double &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate elements of the reversed array
for(int i=0; i<size; i++)
{
int idx=size-1-i;
result[idx]=array[i];
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathReverse |
//+------------------------------------------------------------------+
//| The function reverses order of the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Array for reversed elements |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathReverse(const int &array[],int &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate elements of the reversed array
for(int i=0; i<size; i++)
{
int idx=size-1-i;
result[idx]=array[i];
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathReverse |
//+------------------------------------------------------------------+
//| The function reverses order of the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathReverse(double &array[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
int count=size/2;
for(int i=0; i<count; i++)
{
int idx=size-1-i;
//--- swap array[i] and array[size-1-i];
double t=array[i];
array[i]=array[idx];
array[idx]=t;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathReverse |
//+------------------------------------------------------------------+
//| The function reverses order of the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathReverse(int &array[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
int count=size/2;
for(int i=0; i<count; i++)
{
int idx=size-1-i;
//--- swap array[i] and array[size-1-i];
int t=array[i];
array[i]=array[idx];
array[idx]=t;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathIdentical |
//+------------------------------------------------------------------+
//| The function compares two arrays. |
//| |
//| Arguments: |
//| array1[] : First array |
//| array2[] : Second array |
//| |
//| Return value: true if the arrays are equal, otherwise false. |
//+------------------------------------------------------------------+
bool MathIdentical(const double &array1[],const double &array2[])
{
int size1=ArraySize(array1);
int size2=ArraySize(array1);
//--- check size of the arrays
if(size1!=size2)
return(false);
//--- check empty array case
if(size1==0)
return(false);
//--- check all array elements
for(int i=0; i<size1; i++)
{
if(array1[i]!=array2[i])
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathIdentical |
//+------------------------------------------------------------------+
//| The function compares two arrays. |
//| |
//| Arguments: |
//| array1[] : First array |
//| array2[] : Second array |
//| |
//| Return value: true if the arrays are equal, otherwise false. |
//+------------------------------------------------------------------+
bool MathIdentical(const int &array1[],const int &array2[])
{
int size1=ArraySize(array1);
int size2=ArraySize(array1);
//--- check size of the arrays
if(size1!=size2)
return(false);
//--- check empty array case
if(size1==0)
return(false);
//--- check all array elements
for(int i=0; i<size1; i++)
{
if(array1[i]!=array2[i])
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathUnique |
//+------------------------------------------------------------------+
//| The function extracts the unique values from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Array for unique values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathUnique(const double &array[],double &result[])
{
//--- check array size
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare additional array
bool checked[];
if(ArrayResize(checked,size)!=size)
return(false);
ArrayFill(checked,0,size,false);
//--- prepare result array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- find unique elements
int unique_count=0;
double value=0;
for(;;)
{
bool flag=false;
for(int i=unique_count; i<size; i++)
{
if(!flag && !checked[i])
{
value=array[i];
result[unique_count]=array[i];
unique_count++;
checked[i]=true;
flag=true;
}
else
if(flag && value==array[i])
checked[i]=true;
}
if(!flag)
break;
}
//--- resize target array
ArrayResize(result,unique_count);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathUnique |
//+------------------------------------------------------------------+
//| The function extracts the unique values from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Array for unique values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathUnique(const int &array[],int &result[])
{
//--- check array size
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare additional array
bool checked[];
if(ArrayResize(checked,size)!=size)
return(false);
ArrayFill(checked,0,size,false);
//--- prepare result array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- find unique elements
int unique_count=0;
int value=0;
for(;;)
{
bool flag=false;
for(int i=unique_count; i<size; i++)
{
if(!flag && !checked[i])
{
value=array[i];
result[unique_count]=array[i];
unique_count++;
checked[i]=true;
flag=true;
}
else
if(flag && value==array[i])
checked[i]=true;
}
if(!flag)
break;
}
//--- resize target array
ArrayResize(result,unique_count);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathQuickSortAscending |
//+------------------------------------------------------------------+
//| The function sorts array[] and indices[] simultaneously |
//| using QuickSort algorithm. After sorting the initial ordering |
//| of the elements is located in the indices[] array. |
//| |
//| Arguments: |
//| array : Array with values to sort |
//| indices : Targe array to sort |
//| first : First element index |
//| last : Last element index |
//| |
//| Return value: None |
//+------------------------------------------------------------------+
void MathQuickSortAscending(double &array[],int &indices[],int first,int last)
{
int i,j,t_int;
double p_double,t_double;
//--- check
if(first<0 || last<0)
return;
//--- sort
i=first;
j=last;
while(i<last)
{
//--- ">>1" is quick division by 2
p_double=array[(first+last)>>1];
while(i<j)
{
while(array[i]<p_double)
{
//--- control the output of the array bounds
if(i==ArraySize(array)-1)
break;
i++;
}
while(array[j]>p_double)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
//-- swap elements i and j
t_double=array[i];
array[i]=array[j];
array[j]=t_double;
//-- swap indices i and j
t_int=indices[i];
indices[i]=indices[j];
indices[j]=t_int;
i++;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(first<j)
MathQuickSortAscending(array,indices,first,j);
first=i;
j=last;
}
}
//+------------------------------------------------------------------+
//| MathQuickSortDescending |
//+------------------------------------------------------------------+
//| The function sorts array[] and indices[] simultaneously |
//| using QuickSort algorithm. After sorting the initial ordering |
//| of the elements is located in the indices[] array. |
//| |
//| Arguments: |
//| array : Array with values to sort |
//| indices : Targe array to sort |
//| first : First element index |
//| last : Last element index |
//| |
//| Return value: None |
//+------------------------------------------------------------------+
void MathQuickSortDescending(double &array[],int &indices[],int first,int last)
{
int i,j,t_int;
double p_double,t_double;
//--- check
if(first<0 || last<0)
return;
//--- sort
i=first;
j=last;
while(i<last)
{
//--- ">>1" is quick division by 2
p_double=array[(first+last)>>1];
while(i<j)
{
while(array[i]>p_double)
{
//--- control the output of the array bounds
if(i==ArraySize(array)-1)
break;
i++;
}
while(array[j]<p_double)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
//-- swap elements i and j
t_double=array[i];
array[i]=array[j];
array[j]=t_double;
//-- swap indices i and j
t_int=indices[i];
indices[i]=indices[j];
indices[j]=t_int;
i++;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(first<j)
MathQuickSortDescending(array,indices,first,j);
first=i;
j=last;
}
}
//+------------------------------------------------------------------+
//| MathQuickSort |
//+------------------------------------------------------------------+
//| The function sorts array[] and indices[] simultaneously |
//| using QuickSort algorithm. After sorting the initial ordering |
//| of the elements is located in the indices[] array. |
//| |
//| Arguments: |
//| array : Array with values to sort |
//| indices : Targe array to sort |
//| first : First element index |
//| last : Last element index |
//| mode : Sort direction (>0 ascending,otherwise descending) |
//| |
//| Return value: None |
//+------------------------------------------------------------------+
void MathQuickSort(double &array[],int &indices[],int first,int last,int mode)
{
if(mode>0)
MathQuickSortAscending(array,indices,first,last);
else
MathQuickSortDescending(array,indices,first,last);
}
//+------------------------------------------------------------------+
//| MathOrder |
//+------------------------------------------------------------------+
//| The function calculates the order of elements from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Array for sorted indices |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathOrder(const double &array[],int &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
//--- prepare temporary array
double tmp_array[];
ArrayCopy(tmp_array,array,0,0,WHOLE_ARRAY);
//--- prepare identical permutation
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=i+1;
//--- calculate order of numbers
MathQuickSortAscending(tmp_array,result,0,size-1);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathOrder |
//+------------------------------------------------------------------+
//| The function calculates the order of elements from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Array for sorted indices |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathOrder(const int &array[],int &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return(false);
//--- prepare temporary array
double tmp_array[];
if(ArrayResize(tmp_array,size)!=size)
return(false);
for(int i=0; i<size; i++)
tmp_array[i]=array[i];
//--- prepare identical permutation
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=i+1;
//--- calculate order of numbers
MathQuickSortAscending(tmp_array,result,0,size-1);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseNot |
//+------------------------------------------------------------------+
//| The function calculates NOT logical operation for elements |
//| of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseNot(const int &array[],int &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate ~array[i]
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=~array[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseNot |
//+------------------------------------------------------------------+
//| The function calculates NOT logical operation for elements |
//| of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseNot(int &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate ~array[i]
for(int i=0; i<size; i++)
array[i]=~array[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseAnd |
//+------------------------------------------------------------------+
//| The function calculates AND logical operation for elements |
//| of the array1[] and array2[]. |
//| |
//| Arguments: |
//| array1[] : First array with values |
//| array2[] : Second array with values |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseAnd(const int &array1[],const int &array2[],int &result[])
{
int size1=ArraySize(array1);
int size2=ArraySize(array2);
if(size1==0 || size2==0 || size1!=size2)
return(false);
//--- prepare target array and calculate array1&array2
if(ArraySize(result)<size1)
if(ArrayResize(result,size1)!=size1)
return(false);
for(int i=0; i<size1; i++)
result[i]=array1[i]&array2[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseOr |
//+------------------------------------------------------------------+
//| The function calculates OR logical operation for elements |
//| of the array1[] and array2[]. |
//| |
//| Arguments: |
//| array1[] : First array with values |
//| array2[] : Second array with values |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseOr(const int &array1[],const int &array2[],int &result[])
{
int size1=ArraySize(array1);
int size2=ArraySize(array2);
if(size1==0 || size2==0 || size1!=size2)
return(false);
//--- prepare target array and calculate array1|array2
if(ArraySize(result)<size1)
if(ArrayResize(result,size1)!=size1)
return(false);
for(int i=0; i<size1; i++)
result[i]=array1[i]|array2[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseXor |
//+------------------------------------------------------------------+
//| The function calculates XOR logical operation for elements |
//| of the array1[] and array2[]. |
//| |
//| Arguments: |
//| array1[] : First array with values |
//| array2[] : Second array with values |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseXor(const int &array1[],const int &array2[],int &result[])
{
int size1=ArraySize(array1);
int size2=ArraySize(array2);
if(size1==0 || size2==0 || size1!=size2)
return(false);
//--- prepare target array and calculate array1^array2
if(ArraySize(result)<size1)
if(ArrayResize(result,size1)!=size1)
return(false);
for(int i=0; i<size1; i++)
result[i]=array1[i]^array2[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseShiftL |
//+------------------------------------------------------------------+
//| The function calculates << logical operation for elements |
//| of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| n : Number of bits to shift |
//| result[] : Array for sorted indices |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseShiftL(const int &array[],const int n,int &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate array<<n
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=array[i]<<n;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseShiftL |
//+------------------------------------------------------------------+
//| The function calculates << logical operation for elements |
//| of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| n : Number of bits to shift |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseShiftL(int &array[],const int n)
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate array<<n
for(int i=0; i<size; i++)
array[i]=array[i]<<n;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseShiftR |
//+------------------------------------------------------------------+
//| The function calculates >> logical operation for elements |
//| of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| n : Number of bits to shift |
//| result[] : Array for sorted indices |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseShiftR(const int &array[],const int n,int &result[])
{
int size=ArraySize(array);
//---
if(size==0)
return(false);
//--- prepare target array and calculate array>>n
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=array[i]>>n;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathBitwiseShiftR |
//+------------------------------------------------------------------+
//| The function calculates >> logical operation for elements |
//| of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| n : Number of bits to shift |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathBitwiseShiftR(int &array[],const int n)
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate array>>n
for(int i=0; i<size; i++)
array[i]=array[i]>>n;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeSum |
//+------------------------------------------------------------------+
//| The function calculates cumulative sum of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with cumulative sum |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeSum(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate cumulative sum
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
double sum=0.0;
for(int i=0; i<size; i++)
{
//--- check value
if(!MathIsValidNumber(array[i]))
return(false);
sum+=array[i];
result[i]=sum;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeSum |
//+------------------------------------------------------------------+
//| The function calculates cumulative sum of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeSum(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate cumulative sum
double sum=0.0;
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]))
return(false);
sum+=array[i];
array[i]=sum;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeProduct |
//+------------------------------------------------------------------+
//| The function calculates cumulative product of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with cumulative product |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeProduct(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate cumulative product
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
double product=1.0;
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]))
return(false);
product*=array[i];
result[i]=product;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeProduct |
//+------------------------------------------------------------------+
//| The function calculates cumulative product of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeProduct(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate cumulative product
double product=1.0;
for(int i=0; i<size; i++)
{
//--- check value
if(!MathIsValidNumber(array[i]))
return(false);
product*=array[i];
array[i]=product;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeMin |
//+------------------------------------------------------------------+
//| The function calculates cumulative minimum of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with cumulative product |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeMin(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate cumulative min
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
double min=QPOSINF;
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]) || !MathIsValidNumber(min))
min+=array[i];
else
min=MathMin(min,array[i]);
result[i]=min;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeMin |
//+------------------------------------------------------------------+
//| The function calculates cumulative minimum of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeMin(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
double min=QPOSINF;
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]) || !MathIsValidNumber(min))
min+=array[i];
else
min=MathMin(min,array[i]);
array[i]=min;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeMax |
//+------------------------------------------------------------------+
//| The function calculates cumulative maximum of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with cumulative product |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeMax(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate cumulative max
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
double max=QNEGINF;
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]) || !MathIsValidNumber(max))
max+=array[i];
else
max=MathMax(max,array[i]);
result[i]=max;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeMax |
//+------------------------------------------------------------------+
//| The function calculates cumulative maximum of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeMax(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
double max=QNEGINF;
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]) || !MathIsValidNumber(max))
max+=array[i];
else
max=MathMax(max,array[i]);
array[i]=max;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSin |
//+------------------------------------------------------------------+
//| The function calculates sin(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSin(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathSin(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSin |
//+------------------------------------------------------------------+
//| The function calculates sin(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSin(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathSin(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCos |
//+------------------------------------------------------------------+
//| The function calculates cos(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCos(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathCos(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCos |
//+------------------------------------------------------------------+
//| The function calculates cos(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCos(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathCos(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTan |
//+------------------------------------------------------------------+
//| The function calculates tan(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathTan(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathTan(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTan |
//+------------------------------------------------------------------+
//| The function calculates tan(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathTan(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathTan(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArcsin |
//+------------------------------------------------------------------+
//| The function calculates Arcsin(x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArcsin(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathArcsin(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArcsin |
//+------------------------------------------------------------------+
//| The function calculates Arcsin(x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArcsin(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathArcsin(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArccos |
//+------------------------------------------------------------------+
//| The function calculates Arccos(x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArccos(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathArccos(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArccos |
//+------------------------------------------------------------------+
//| The function calculates Arccos(x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArccos(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathArccos(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArctan |
//+------------------------------------------------------------------+
//| The function calculates Arctan(x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArctan(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathArctan(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArctan |
//+------------------------------------------------------------------+
//| The function calculates Arctan(x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArctan(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathArctan(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSinPi |
//+------------------------------------------------------------------+
//| The function calculates sin(pi*x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSinPi(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathSin(M_PI*array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSinPi |
//+------------------------------------------------------------------+
//| The function calculates sin(pi*x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSinPi(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathSin(M_PI*array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCosPi |
//+------------------------------------------------------------------+
//| The function calculates cos(pi*x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCosPi(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathCos(M_PI*array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCosPi |
//+------------------------------------------------------------------+
//| The function calculates cos(pi*x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCosPi(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathCos(M_PI*array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTanPi |
//+------------------------------------------------------------------+
//| The function calculates tan(pi*x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathTanPi(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathTan(M_PI*array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTanPi |
//+------------------------------------------------------------------+
//| The function calculates tan(pi*x) for the elements |
//| from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathTanPi(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathTan(M_PI*array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathAbs |
//+------------------------------------------------------------------+
//| The function calculates abs(x) for the elements from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathAbs(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
result[i]=MathAbs(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathAbs |
//+------------------------------------------------------------------+
//| The function calculates abs(x) for the elements from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathAbs(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathAbs(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCeil |
//+------------------------------------------------------------------+
//| The function calculates integer numberic values closest from |
//| above for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCeil(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate Ceil(array[i])
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=MathCeil(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCeil |
//+------------------------------------------------------------------+
//| The function calculates integer numberic values closest from |
//| above for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCeil(double &array[])
{