Files
All-MQL5-code/Include/Math/Stat/Math.mqh
T
2018-03-09 16:43:19 +01:00

5524 lines
424 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//+------------------------------------------------------------------+
//| Math.mqh |
//| Copyright 2016-2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016-2017, MetaQuotes Software Corp."
#property link "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);
}
//+------------------------------------------------------------------+
//| MathArctan2 |
//+------------------------------------------------------------------+
//| The function calculates polar angle of vector (x,y) |
//| in range [-pi, pi]. It uses signs to determine quadrant. |
//+------------------------------------------------------------------+
double MathArctan2(const double y,const double x)
{
if(x>0.0)
return MathArctan(y/x);
else
if(x<0.0)
{
if(y>0.0)
return(MathArctan(y/x)+M_PI);
else
return(MathArctan(y/x)-M_PI);
}
//--- case x==0.0
if(y>0.0)
return(M_PI_2);
else
if(y<0.0)
return(-M_PI_2);
else
return(QNaN);
}
//+------------------------------------------------------------------+
//| Comments from original FORTRAN code: |
//| http://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: |
//| http://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);
else
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);
else
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=(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=(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[])
{
int size=ArraySize(array);
if(size==0)
return(false);
for(int i=0; i<size; i++)
array[i]=MathCeil(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathFloor |
//+------------------------------------------------------------------+
//| The function calculates integer numberic values closest from |
//| below 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 MathFloor(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate Floor(array[i])
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
result[i]=MathFloor(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathFloor |
//+------------------------------------------------------------------+
//| The function calculates integer numberic values closest from |
//| below for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathFloor(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
for(int i=0; i<size; i++)
array[i]=MathFloor(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTrunc |
//+------------------------------------------------------------------+
//| The function calculates trunc(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 MathTrunc(const double &array[],double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- prepare target array and calculate Trunc(array[i])
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
for(int i=0; i<size; i++)
{
if(array[i]>=0)
result[i]=MathFloor(array[i]);
else
result[i]=MathCeil(array[i]);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTrunc |
//+------------------------------------------------------------------+
//| The function calculates trunc(x) for the elements from the array.|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathTrunc(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
for(int i=0; i<size; i++)
{
if(array[i]>=0)
array[i]=MathFloor(array[i]);
else
array[i]=MathCeil(array[i]);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSqrt |
//+------------------------------------------------------------------+
//| The function calculates sqrt(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 MathSqrt(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]=MathSqrt(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSqrt |
//+------------------------------------------------------------------+
//| The function calculates sqrt(x) for the elements from the array. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSqrt(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathSqrt(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathExp |
//+------------------------------------------------------------------+
//| The function calculates exp(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 MathExp(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]=MathExp(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathExp |
//+------------------------------------------------------------------+
//| The function calculates exp(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathExp(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathExp(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathPow |
//+------------------------------------------------------------------+
//| The function calculates Pow(x,power) 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 MathPow(const double &array[],const double power,double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- check NAN
if(!MathIsValidNumber(power))
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]=MathPow(array[i],power);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathPow |
//+------------------------------------------------------------------+
//| The function calculates Pow(x,power) for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathPow(double &array[],const double power)
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- check NAN
if(!MathIsValidNumber(power))
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathPow(array[i],power);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog |
//+------------------------------------------------------------------+
//| The function calculates log(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 MathLog(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]=MathLog(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog |
//+------------------------------------------------------------------+
//| The function calculates log(x) for the elements from the array[].|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathLog(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathLog(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog |
//+------------------------------------------------------------------+
//| The function calculates logarithm with the specified base |
//| 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 MathLog(const double &array[],const double base,double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- check NAN
if(!MathIsValidNumber(base))
return(false);
//--- check base
if(base==1.0 || base<=0.0)
return(false);
//--- prepare target array
if(ArraySize(result)<size)
if(ArrayResize(result,size)!=size)
return(false);
//--- calculate values
double factor=1.0/MathLog(base);
for(int i=0; i<size; i++)
result[i]=MathLog(array[i])*factor;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog |
//+------------------------------------------------------------------+
//| The function calculates logarithm with the specified base |
//| for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathLog(double &array[],const double base)
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- check NAN
if(!MathIsValidNumber(base))
return(false);
//--- check base
if(base==1.0 || base<=0.0)
return(false);
//--- calculate values
double factor=1.0/MathLog(base);
for(int i=0; i<size; i++)
array[i]=MathLog(array[i])*factor;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog2 |
//+------------------------------------------------------------------+
//| The function calculates logarithms on base 2 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 MathLog2(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
static const double factor=1.0/M_LN2;
for(int i=0; i<size; i++)
result[i]=MathLog(array[i])*factor;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog2 |
//+------------------------------------------------------------------+
//| The function calculates logarithms on base 2 for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathLog2(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
static const double factor=1.0/M_LN2;
for(int i=0; i<size; i++)
array[i]=MathLog(array[i])*factor;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog10 |
//+------------------------------------------------------------------+
//| The function calculates logarithm on base 10 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 MathLog10(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]=MathLog10(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog10 |
//+------------------------------------------------------------------+
//| The function calculates logarithm on base 10 for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathLog10(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathLog10(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArctan2 |
//+------------------------------------------------------------------+
//| The function calculates polar angles of vector (x[i],y[i]) |
//| in range [-pi, pi] for the elements from the x[] and y[] arrays. |
//| |
//| Arguments: |
//| x[] : Array with double values |
//| y[] : Array with double values |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArctan2(const double &y[],const double &x[],double &result[])
{
int size=ArraySize(x);
if(size==0 || ArraySize(y)!=size)
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]=MathArctan2(y[i],x[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathRound |
//+------------------------------------------------------------------+
//| The function calculates rounded values to a given precision |
//| for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| digits : Precision |
//| result[] : Output array with rounded values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathRound(const double &array[],int digits,double &result[])
{
int size=ArraySize(array);
if(size==0)
return(false);
if(digits<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]=MathRound(array[i],digits);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathRound |
//+------------------------------------------------------------------+
//| The function calculates rounded values to a given precision |
//| for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| digits : Precision |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathRound(double &array[],int digits)
{
int size=ArraySize(array);
if(size==0)
return(false);
if(digits<0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathRound(array[i],digits);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathDifference |
//+------------------------------------------------------------------+
//| The function calculates laggged differences of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| lag : Lag value |
//| result[] : Output array with calculated differences |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathDifference(const double &array[],const int lag,double &result[])
{
int size=ArraySize(array)-lag;
if(lag<1 || 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]=array[i+lag]-array[i];
//--- change array size for call with differences
if(ArrayResize(result,size)!=size)
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathDifference |
//+------------------------------------------------------------------+
//| The function calculates laggged differences of the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with integer values |
//| lag : Lag value |
//| result[] : Output array with calculated differences |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathDifference(const int &array[],const int lag,int &result[])
{
int size=ArraySize(array)-lag;
if(lag<1 || 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]=array[i+lag]-array[i];
//--- change array size for call with differences
if(ArrayResize(result,size)!=size)
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathDifference |
//+------------------------------------------------------------------+
//| The function calculates laggged and iterated differences |
//| of the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| lag : Lag value |
//| differences : Number of iterations |
//| result[] : Output array with calculated differences |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathDifference(const double &array[],const int lag,const int differences,double &result[])
{
int size=ArraySize(array);
//--- check parameters
if(size==0 || differences<0 || lag*differences>=size)
return(false);
//--- copy data from initial array
if(ArrayCopy(result,array,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- calculate iterated differences
for(int i=0; i<differences; i++)
{
if(!MathDifference(result,lag,result))
return false;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathDifference |
//+------------------------------------------------------------------+
//| The function calculates laggged and iterated differences |
//| of the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with integer values |
//| lag : Lag value |
//| differences : Number of iterations |
//| result[] : Output array with calculated differences |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathDifference(const int &array[],const int lag,const int differences,int &result[])
{
int size=ArraySize(array);
//--- check parameters
if(size==0 || differences<0 || lag*differences>=size)
return(false);
//--- copy data from initial array
if(ArrayCopy(result,array,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- calculate iterated differences
for(int i=0; i<differences; i++)
{
if(!MathDifference(result,lag,result))
return false;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| count : Number of elements to choose |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const double &array[],const int count,double &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return false;
//--- prepare target array and calculate values
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
for(int i=0; i<count; i++)
{
int ind=(int)(count-1)*MathRand()/32767;
result[i]=array[ind];
}
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[]. |
//| |
//| Arguments: |
//| array[] : Array with integer values |
//| count : Number of elements to choose |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const int &array[],const int count,int &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0)
return false;
//--- prepare target array and calculate values
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
for(int i=0; i<count; i++)
{
int ind=(int)(count-1)*MathRand()/32767;
result[i]=array[ind];
}
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[] with replacement. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| count : Number of elements to choose |
//| replace : If true, only unique values are placed to result[] |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const double &array[],const int count,const bool replace,double &result[])
{
//--- unique values not needed
if(!replace)
return MathSample(array,count,result);
int size=ArraySize(array);
if(size==0 || count>size)
return(false);
//--- prepare target array
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- unique values needed, prepare indices
int indices[];
MathSequenceByCount(0,count-1,count,indices);
int swaps=size/2;
int max_v=count-1;
for(int i=0; i<swaps; i++)
{
//--- select random indices and swap them
int ind1=(int)max_v*MathRand()/32767;
int ind2=(int)max_v*MathRand()/32767;
int t=indices[ind1];
indices[ind1]=indices[ind2];
indices[ind2]=t;
}
//--- select data according to indices
for(int i=0; i<count; i++)
result[i]=array[indices[i]];
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[] with replacement. |
//| |
//| Arguments: |
//| array[] : Array with integer values |
//| count : Number of elements to choose |
//| replace : If true, only unique values are placed to result[] |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const int &array[],const int count,const bool replace,int &result[])
{
//--- unique values not needed
if(!replace)
return MathSample(array,count,result);
int size=ArraySize(array);
if(size==0 || count>size)
return(false);
//--- prepare target array
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- unique values needed, prepare indices
int indices[];
MathSequenceByCount(0,count-1,count,indices);
int swaps=size/2;
int max_v=count-1;
for(int i=0; i<swaps; i++)
{
//--- select random indices and swap them
int ind1=(int)max_v*MathRand()/32767;
int ind2=(int)max_v*MathRand()/32767;
int t=indices[ind1];
indices[ind1]=indices[ind2];
indices[ind2]=t;
}
//--- select data according to indices
for(int i=0; i<count; i++)
result[i]=array[indices[i]];
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[] according to the given probabilities. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| probabilities[] : Array with probabilities |
//| count : Number of elements to choose |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const double &array[],double &probabilities[],const int count,double &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0 || size!=ArraySize(probabilities))
return(false);
if(count<=0)
return(false);
//--- probabilities
double prob[];
if(ArrayCopy(prob,probabilities,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- calculate sum and normalize probabilities
double sum=0;
for(int i=0; i<size; i++)
sum+=prob[i];
if(sum==0.0)
return(false);
sum=1.0/sum;
for(int i=0; i<size; i++)
prob[i]*=sum;
//--- prepare indices
int indices[];
if(ArrayResize(indices,size)!=size)
return(false);
for(int i=0; i<size; i++)
indices[i]=i;
//--- sort and prepare cumulative probabilities
MathQuickSortDescending(prob,indices,0,size-1);
for(int i=1; i<size; i++)
prob[i]+=prob[i-1];
//--- prepare target array and calculate values
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare random samples according to given probabilities
for(int i=0; i<count; i++)
{
double prb=MathRand()/32767.0;
for(int k=0; k<size; k++)
{
if(prb<=prob[k])
{
result[i]=array[indices[k]];
break;
}
}
}
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[] according to the given probabilities. |
//| |
//| Arguments: |
//| array[] : Array with integer values |
//| probabilities[] : Array with probabilities |
//| count : Number of elements to choose |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const int &array[],double &probabilities[],const int count,int &result[])
{
int size=ArraySize(array);
//--- check array size
if(size==0 || size!=ArraySize(probabilities))
return(false);
if(count<=0)
return(false);
//--- probabilities
double prob[];
if(ArrayCopy(prob,probabilities,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- calculate sum and normalize probabilities
double sum=0;
for(int i=0; i<size; i++)
sum+=prob[i];
if(sum==0.0)
return(false);
sum=1.0/sum;
for(int i=0; i<size; i++)
prob[i]*=sum;
//--- prepare indices
int indices[];
if(ArrayResize(indices,size)!=size)
return(false);
for(int i=0; i<size; i++)
indices[i]=i;
//--- sort and prepare cumulative probabilities
MathQuickSortDescending(prob,indices,0,size-1);
for(int i=1; i<size; i++)
prob[i]+=prob[i-1];
//--- prepare target array and calculate values
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare random samples according to given probabilities
for(int i=0; i<count; i++)
{
double prb=MathRand()/32767.0;
for(int k=0; k<size; k++)
{
if(prb<=prob[k])
{
result[i]=array[indices[k]];
break;
}
}
}
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[] according to the given probabilities. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| probabilities[] : Array with probabilities |
//| count : Number of elements to choose |
//| replace : If true,only unique values are taken to result |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const double &array[],double &probabilities[],const int count,const bool replace,double &result[])
{
if(!replace)
return MathSample(array,probabilities,count,result);
int size=ArraySize(array);
//--- check array size
if(size==0 || size!=ArraySize(probabilities))
return(false);
//--- return false if count>total samples
if(count<=0 || count>size)
return(false);
//--- probabilities
double prob[];
if(ArrayCopy(prob,probabilities,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- calculate sum and normalize probabilities
double sum=0;
for(int i=0; i<size; i++)
sum+=prob[i];
if(sum==0.0)
return(false);
sum=1.0/sum;
for(int i=0; i<size; i++)
prob[i]*=sum;
//--- prepare indices
int indices[];
if(ArrayResize(indices,size)!=size)
return(false);
for(int i=0; i<size; i++)
indices[i]=i;
//--- sort and prepare cumulative probabilities
MathQuickSortDescending(prob,indices,0,size-1);
for(int i=1; i<size; i++)
prob[i]+=prob[i-1];
//--- prepare array for taken values flag
bool taken_values[];
if(ArrayResize(taken_values,size)!=size)
return(false);
ArrayFill(taken_values,0,size,false);
//--- prepare target array and calculate values
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare random samples according to given probabilities
for(int i=0; i<count; i++)
{
double prb=MathRand()/32767.0;
for(int k=0; k<size; k++)
{
int ind=indices[k];
//--- check also if the value has been already taken
if(prb<=prob[k] && taken_values[ind]==false)
{
result[i]=array[ind];
taken_values[ind]=true;
break;
}
}
}
//---
return true;
}
//+------------------------------------------------------------------+
//| MathSample |
//+------------------------------------------------------------------+
//| The function takes a sample of the specified size from the |
//| elements of the array[] according to the given probabilities. |
//| |
//| Arguments: |
//| array[] : Array with integer values |
//| probabilities[] : Array with probabilities |
//| count : Number of elements to choose |
//| replace : If true,only unique values are taken to result |
//| result[] : Output array |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathSample(const int &array[],double &probabilities[],const int count,const bool replace,int &result[])
{
if(!replace)
return MathSample(array,probabilities,count,result);
int size=ArraySize(array);
//--- check array size
if(size==0 || size!=ArraySize(probabilities))
return(false);
//--- return false if count>total samples
if(count<=0 || count>size)
return(false);
//--- probabilities
double prob[];
if(ArrayCopy(prob,probabilities,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- calculate sum and normalize probabilities
double sum=0;
for(int i=0; i<size; i++)
sum+=prob[i];
if(sum==0.0)
return(false);
sum=1.0/sum;
for(int i=0; i<size; i++)
prob[i]*=sum;
//--- prepare indices
int indices[];
if(ArrayResize(indices,size)!=size)
return(false);
for(int i=0; i<size; i++)
indices[i]=i;
//--- sort and prepare cumulative probabilities
MathQuickSortDescending(prob,indices,0,size-1);
for(int i=1; i<size; i++)
prob[i]+=prob[i-1];
//--- prepare array for taken values flag
bool taken_values[];
if(ArrayResize(taken_values,size)!=size)
return(false);
ArrayFill(taken_values,0,size,false);
//--- prepare target array and calculate values
if(ArraySize(result)<count)
if(ArrayResize(result,count)!=count)
return(false);
//--- prepare random samples according to given probabilities
for(int i=0; i<count; i++)
{
double prb=MathRand()/32767.0;
for(int k=0; k<size; k++)
{
int ind=indices[k];
//--- check also if the value has been already taken
if(prb<=prob[k] && taken_values[ind]==false)
{
result[i]=array[ind];
taken_values[ind]=true;
break;
}
}
}
//---
return true;
}
//+------------------------------------------------------------------+
//| MathTukeySummary |
//+------------------------------------------------------------------+
//| The function calculates Tukey's five number summary. |
//| It consists of the five most important sample percentiles: |
//| 1) the sample minimum (smallest observation) |
//| 2) the lower quartile or first quartile (0.25 quantile) |
//| 3) the median (middle value) |
//| 4) the upper quartile or third quartile (0.75 quantile) |
//| 5) the sample maximum (largest observation) |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| removeNAN : Flag, if true, all NaN values will be removed |
//| minimum : Output variable for minimum value |
//| lower_hinge : Output variable for 0.25 quantile |
//| median : Output variable for median value |
//| upper_hinge : Output variable for 0.75 quantile |
//| maximum : Output variable for maximum value |
//| |
//| Return value: true if successful, otherwise false. |
//+------------------------------------------------------------------+
bool MathTukeySummary(const double &array[],const bool removeNAN,double &minimum,double &lower_hinge,double &median,double &upper_hinge,double &maximum)
{
//--- set default values
minimum=QNaN;
lower_hinge=QNaN;
median=QNaN;
upper_hinge=QNaN;
maximum=QNaN;
//--- check array size
int size=ArraySize(array);
if(size==0)
return(false);
double data[];
if(ArrayResize(data,size)!=size)
return(false);
int actual_values=0;
if(removeNAN==true)
{
//--- remove NAN values (copy non-NAN elements)
for(int i=0; i<size; i++)
{
if(MathIsValidNumber(array[i]))
{
data[actual_values]=array[i];
actual_values++;
}
}
//--- set actual size
ArrayResize(data,actual_values);
}
else
{
//--- check NAN and return if NAN found
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]))
return(false);
}
//--- otherwise copy data
if(ArrayCopy(data,array,0,0,WHOLE_ARRAY)!=size)
return(false);
}
//--- sort array
ArraySort(data);
int n=ArraySize(data);
if(n==0)
return(false);
//--- prepare indices
double n4=MathFloor((n+3)*0.5)*0.5;
double ind[5];
ind[0]=0;
ind[1]=n4-1;
ind[2]=0.5*(n+1)-1;
ind[3]=n-n4;
ind[4]=n-1;
//--- calculate values
minimum=0.5*(data[(int)MathFloor(ind[0])]+data[(int)MathCeil(ind[0])]);
lower_hinge=0.5*(data[(int)MathFloor(ind[1])]+data[(int)MathCeil(ind[1])]);
median=0.5*(data[(int)MathFloor(ind[2])]+data[(int)MathCeil(ind[2])]);
upper_hinge=0.5*(data[(int)MathFloor(ind[3])]+data[(int)MathCeil(ind[3])]);
maximum=0.5*(data[(int)MathFloor(ind[4])]+data[(int)MathCeil(ind[4])]);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Computes the minimum and maximum of the values in array[] |
//+------------------------------------------------------------------+
bool MathRange(const double &array[],double &min,double &max)
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- default values, find minimum and maximum values
min=array[0];
max=array[0];
for(int i=1; i<size; i++)
{
double value=array[i];
min=MathMin(min,value);
max=MathMax(max,value);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Computes the minimum value in array[] |
//+------------------------------------------------------------------+
double MathMin(const double &array[])
{
int size=ArraySize(array);
if(size==0)
return(QNaN);
double min_value=array[0];
for(int i=1; i<size; i++)
min_value=MathMin(min_value,array[i]);
//--- return minimum value
return(min_value);
}
//+------------------------------------------------------------------+
//| Computes the maximum value in array[] |
//+------------------------------------------------------------------+
double MathMax(const double &array[])
{
int size=ArraySize(array);
if(size==0)
return(QNaN);
double max_value=array[0];
for(int i=1; i<size; i++)
max_value=MathMax(max_value,array[i]);
//--- return maximum value
return(max_value);
}
//+------------------------------------------------------------------+
//| Computes the sum of the values in array[] |
//+------------------------------------------------------------------+
double MathSum(const double &array[])
{
int size=ArraySize(array);
if(size==0)
return(QNaN);
//--- calculate sum
double sum=0.0;
for(int i=0; i<size; i++)
sum+=array[i];
//--- return sum
return(sum);
}
//+------------------------------------------------------------------+
//| Computes the product of the values in array[] |
//+------------------------------------------------------------------+
double MathProduct(const double &array[])
{
int size=ArraySize(array);
if(size==0)
return(QNaN);
//--- calculate product
double product=1.0;
for(int i=0; i<size; i++)
product*=array[i];
//--- return product
return(product);
}
//+------------------------------------------------------------------+
//| Computes the standard deviation of the values in array[] |
//+------------------------------------------------------------------+
double MathStandardDeviation(const double &array[])
{
int size=ArraySize(array);
if(size<=1)
return(QNaN);
//--- calculate mean
double mean=0.0;
for(int i=0; i<size; i++)
mean+=array[i];
//--- average mean
mean=mean/size;
//--- calculate standard deviation
double sdev=0;
for(int i=0; i<size; i++)
sdev+=MathPow(array[i]-mean,2);
//--- return standard deviation
return MathSqrt(sdev/(size-1));
}
//+------------------------------------------------------------------+
//| Computes the average absolute deviation of the values in array[] |
//+------------------------------------------------------------------+
double MathAverageDeviation(const double &array[])
{
int size=ArraySize(array);
if(size<=1)
return(QNaN);
//--- calculate mean
double mean=0.0;
for(int i=0; i<size; i++)
mean+=array[i];
mean=mean/size;
//--- calculate average deviation
double adev=0;
for(int i=0; i<size; i++)
adev+=MathAbs(array[i]-mean);
adev=adev/size;
//--- return average deviation
return(adev);
}
//+------------------------------------------------------------------+
//| Computes the median value of the values in array[] |
//+------------------------------------------------------------------+
double MathMedian(double &array[])
{
int size=ArraySize(array);
//--- check data range
if(size==0)
return(QNaN);
//--- prepare sorted values
double sorted_values[];
if(ArrayCopy(sorted_values,array,0,0,WHOLE_ARRAY)!=size)
return(QNaN);
ArraySort(sorted_values);
//--- calculate median for odd and even cases
//--- data_count=odd
if(size%2==1)
return(sorted_values[size/2]);
else
//--- data_count=even
return(0.5*(sorted_values[(size-1)/2]+sorted_values[(size+1)/2]));
}
//+------------------------------------------------------------------+
//| Computes the mean value of the values in array[] |
//+------------------------------------------------------------------+
double MathMean(const double &array[])
{
int size=ArraySize(array);
//--- check data range
if(size<1)
return(QNaN); // need at least 1 observation
//--- calculate mean
double mean=0.0;
for(int i=0; i<size; i++)
mean+=array[i];
mean=mean/size;
//--- return mean
return(mean);
}
//+------------------------------------------------------------------+
//| Computes the variance of the values in array[] |
//+------------------------------------------------------------------+
double MathVariance(const double &array[])
{
int size=ArraySize(array);
//--- check data range
if(size<2)
return(QNaN); // need at least 2 observations
//--- calculate mean
double mean=0.0;
for(int i=0; i<size; i++)
mean+=array[i];
mean=mean/size;
//--- calculate variance
double variance=0;
for(int i=0; i<size; i++)
variance+=MathPow(array[i]-mean,2);
variance=variance/(size-1);
//--- return variance
return(variance);
}
//+------------------------------------------------------------------+
//| Computes the skewness of the values in array[] |
//+------------------------------------------------------------------+
double MathSkewness(const double &array[])
{
int size=ArraySize(array);
//--- check data range
if(size<3)
return(QNaN); // need at least 3 observations
//--- calculate mean
double mean=0.0;
for(int i=0; i<size; i++)
mean+=array[i];
mean=mean/size;
//--- calculate variance and skewness
double variance=0;
double skewness=0;
for(int i=0; i<size; i++)
{
double sqr_dev=MathPow(array[i]-mean,2);
skewness+=sqr_dev*(array[i]-mean);
variance+=sqr_dev;
}
variance=(variance)/(size-1);
double v3=MathPow(MathSqrt(variance),3);
//---
if(v3!=0)
{
skewness=skewness/(size*v3);
//--- return skewness
return(skewness);
}
else
return(QNaN);
}
//+------------------------------------------------------------------+
//| Computes the kurtosis of the values in array[] |
//+------------------------------------------------------------------+
double MathKurtosis(const double &array[])
{
int size=ArraySize(array);
//--- check data range
if(size<4)
return(QNaN); // need at least 4 observations
//--- calculate mean
double mean=0.0;
for(int i=0; i<size; i++)
mean+=array[i];
mean=mean/size;
//--- calculate variance and kurtosis
double variance=0;
double kurtosis=0;
for(int i=0; i<size; i++)
{
double sqr_dev=MathPow(array[i]-mean,2);
variance+=sqr_dev;
kurtosis+=sqr_dev*sqr_dev;
}
//--- calculate variance
variance=(variance)/(size-1);
double v4=MathPow(MathSqrt(variance),4);
if(v4!=0)
{
//--- calculate kurtosis
kurtosis=kurtosis/(size*v4);
kurtosis-=3;
//--- return kurtosis
return(kurtosis);
}
else
return(QNaN);
}
//+------------------------------------------------------------------+
//| MathLog1p |
//+------------------------------------------------------------------+
//| The function calculates log(1+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 MathLog1p(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]=MathLog1p(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathLog1p |
//+------------------------------------------------------------------+
//| The function calculates log(1+x) for the elements from the array.|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathLog1p(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathLog1p(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathExpm1 |
//+------------------------------------------------------------------+
//| The function calculates exp(x)-1 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 MathExpm1(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]=MathExpm1(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathExpm1 |
//+------------------------------------------------------------------+
//| The function calculates exp(x)-1 for the elements from the array.|
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathExpm1(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathExpm1(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSinh |
//+------------------------------------------------------------------+
//| The function calculates hyperbolic sine 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 MathSinh(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]=MathSinh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSinh |
//+------------------------------------------------------------------+
//| The function calculates hyperbolic sine for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSinh(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathSinh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCosh |
//+------------------------------------------------------------------+
//| The function calculates hyperbolic cosine 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 MathCosh(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]=MathCosh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCosh |
//+------------------------------------------------------------------+
//| The function calculates hyperbolic cosine for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCosh(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathCosh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTanh |
//+------------------------------------------------------------------+
//| The function calculates hyperbolic tangent 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 MathTanh(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]=MathTanh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathTanh |
//+------------------------------------------------------------------+
//| The function calculates hyperbolic tangent for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathTanh(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathTanh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArcsinh |
//+------------------------------------------------------------------+
//| The function calculates inverse hyperbolic sine 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 MathArcsinh(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]=MathArcsinh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArcsinh |
//+------------------------------------------------------------------+
//| The function calculates inverse hyperbolic sine for the elements |
//| from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArcsinh(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathArcsinh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArccosh |
//+------------------------------------------------------------------+
//| The function calculates inverse hyperbolic cosine 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 MathArccosh(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]=MathArccosh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArccosh |
//+------------------------------------------------------------------+
//| The function calculates inverse hyperbolic cosine for |
//| the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArccosh(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathArccosh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArctanh |
//+------------------------------------------------------------------+
//| The function calculates inverse hyperbolic tangent 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 MathArctanh(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]=MathArctanh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathArctanh |
//+------------------------------------------------------------------+
//| The function calculates inverse hyperbolic tangent for |
//| the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathArctanh(double &array[])
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathArctanh(array[i]);
//---
return(true);
}
//+------------------------------------------------------------------+
//| Rounds the value to the specified number of significant digits |
//+------------------------------------------------------------------+
double MathSignif(const double x,const int digits)
{
if(x==0)
return x;
int dig=digits;
if(dig>30)
return x;
else
if(dig<1)
dig=1;
double sign=1.0;
double xx=x;
if(xx<0.0)
{
sign=-sign;
xx=-xx;
}
//--- calculate log
double l10 = MathLog10(xx);
double e10 = (int)(dig-1-MathFloor(l10));
double value=0,pwr10;
if(e10>0)
{
pwr10=MathPow(10,e10);
value=MathFloor((xx*pwr10)+0.5)/pwr10;
}
else
{
pwr10=MathPow(10,-e10);
value=MathFloor((xx/pwr10)+0.5)*pwr10;
}
return(sign*value);
}
//+------------------------------------------------------------------+
//| MathSignif |
//+------------------------------------------------------------------+
//| The function calculates the rounded values (to the specified |
//| number of significant digits) for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| digits : Number of significant digits |
//| result[] : Output array with calculated values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSignif(const double &array[],int digits,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]=MathSignif(array[i],digits);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathSignif |
//+------------------------------------------------------------------+
//| The function calculates the rounded values (to the specified |
//| number of significant digits) for the elements from the array[]. |
//| |
//| Arguments: |
//| array[] : Array with double values |
//| digits : Number of significant digits |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathSignif(double &array[],int digits)
{
int size=ArraySize(array);
if(size==0)
return(false);
//--- calculate values
for(int i=0; i<size; i++)
array[i]=MathSignif(array[i],digits);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathRank |
//+------------------------------------------------------------------+
//| The function calculates tied ranks for the elements of the array.|
//| |
//| Arguments: |
//| array[] : Input array with double values |
//| rank[] : Output array with ranked values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
//| Code from ALGLIB numerical analysis and data processing library |
//+------------------------------------------------------------------+
bool MathRank(const double &array[],double &rank[])
{
int size=ArraySize(array);
if(size<1)
return(false);
if(size==1)
{
if(ArrayResize(rank,size)!=size)
return(false);
rank[0]=1;
return(true);
}
//--- prepare arrays
double values[];
int indices[];
if(ArrayCopy(values,array,0,0,WHOLE_ARRAY)!=size)
return(false);
if(!MathSequenceByCount(0,size,size,indices))
return(false);
if(ArrayResize(rank,size)!=size)
return(false);
//---
int i,j,k,t,tmpi;
double tmp;
//--- sort
if(size!=1)
{
i=2;
do
{
t=i;
while(t!=1)
{
k=t/2;
if(values[k-1]>=values[t-1])
t=1;
else
{
//--- swap
tmp=values[k-1];
values[k-1]=values[t-1];
values[t-1]=tmp;
tmpi=indices[k-1];
indices[k-1]=indices[t-1];
indices[t-1]=tmpi;
t=k;
}
}
i=i+1;
}
while(i<=size);
i=size-1;
do
{
//--- swap
tmp=values[i];
values[i]=values[0];
values[0]=tmp;
tmpi=indices[i];
indices[i]=indices[0];
indices[0]=tmpi;
t=1;
while(t!=0)
{
k=2*t;
if(k>i)
t=0;
else
{
if(k<i)
if(values[k]>values[k-1])
k++;
if(values[t-1]>=values[k-1])
t=0;
else
{
//--- swap
tmp=values[k-1];
values[k-1]=values[t-1];
values[t-1]=tmp;
tmpi=indices[k-1];
indices[k-1]=indices[t-1];
indices[t-1]=tmpi;
t=k;
}
}
}
i=i-1;
}
while(i>=1);
}
//--- compute tied ranks
i=0;
while(i<size)
{
j=i+1;
while(j<size)
{
//--- check
if(values[j]!=values[i])
break;
j=j+1;
}
for(k=i;k<j;k++)
values[k]=1+(i+j-1)*0.5;
i=j;
}
//--- set output values
for(i=0; i<size; i++)
rank[indices[i]]=values[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathRank |
//+------------------------------------------------------------------+
//| The function calculates tied ranks for the elements of the array.|
//| |
//| Arguments: |
//| array[] : Input array with integer values |
//| rank[] : Output array with ranked values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
//| Code from ALGLIB numerical analysis and data processing library |
//+------------------------------------------------------------------+
bool MathRank(const int &array[],double &rank[])
{
int size=ArraySize(array);
if(size<1)
return(false);
if(size==1)
{
if(ArrayResize(rank,size)!=size)
return(false);
rank[0]=1;
return(true);
}
//--- prepare arrays
double values[];
int indices[];
if(ArrayResize(values,size)!=size)
return(false);
for(int i=0; i<size; i++)
values[i]=array[i];
if(!MathSequenceByCount(0,size,size,indices))
return(false);
if(ArrayResize(rank,size)!=size)
return(false);
//---
int i,j,k,t,tmpi;
double tmp;
//--- sort
if(size!=1)
{
i=2;
do
{
t=i;
while(t!=1)
{
k=t/2;
if(values[k-1]>=values[t-1])
t=1;
else
{
//--- swap
tmp=values[k-1];
values[k-1]=values[t-1];
values[t-1]=tmp;
tmpi=indices[k-1];
indices[k-1]=indices[t-1];
indices[t-1]=tmpi;
t=k;
}
}
i=i+1;
}
while(i<=size);
i=size-1;
do
{
//--- swap
tmp=values[i];
values[i]=values[0];
values[0]=tmp;
tmpi=indices[i];
indices[i]=indices[0];
indices[0]=tmpi;
t=1;
while(t!=0)
{
k=2*t;
if(k>i)
t=0;
else
{
if(k<i)
if(values[k]>values[k-1])
k++;
if(values[t-1]>=values[k-1])
t=0;
else
{
//--- swap
tmp=values[k-1];
values[k-1]=values[t-1];
values[t-1]=tmp;
tmpi=indices[k-1];
indices[k-1]=indices[t-1];
indices[t-1]=tmpi;
t=k;
}
}
}
i=i-1;
}
while(i>=1);
}
//--- compute tied ranks
i=0;
while(i<size)
{
j=i+1;
while(j<size)
{
//--- check
if(values[j]!=values[i])
break;
j=j+1;
}
for(k=i;k<j;k++)
values[k]=1+(i+j-1)*0.5;
i=j;
}
//--- set output values
for(i=0; i<size; i++)
rank[indices[i]]=values[i];
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCorrelationPearson |
//+------------------------------------------------------------------+
//| The function calculates Pearson product-moment correlation |
//| coefficient. |
//| |
//| Arguments: |
//| array1[] : First array with double values |
//| array2[] : Second array with double values |
//| r : Variable for calculated value of the Pearson r |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
//| Code from ALGLIB numerical analysis and data processing library |
//+------------------------------------------------------------------+
bool MathCorrelationPearson(const double &array1[],const double &array2[],double &r)
{
r=QNaN;
int size=ArraySize(array1);
if(size<=1 || ArraySize(array2)!=size)
return(false);
//--- create variables
double xmean=0;
double ymean=0;
double v=1.0/(double)size;
double x0=array1[0];
double y0=array2[0];
double s=0;
double xv=0;
double yv=0;
double t1=0;
double t2=0;
bool samex=true;
bool samey=true;
//--- additonally we calculate SameX and SameY - flag variables which are set to true
//--- when all X[] (or Y[]) contain exactly same value.
//--- if at least one of them is true, we return zero
//--- (othwerwise we risk to get nonzero correlation because of roundoff).
for(int i=0; i<size; i++)
{
s=array1[i];
samex=samex && s==x0;
xmean+=s*v;
s=array2[i];
samey=samey && s==y0;
ymean+=s*v;
}
//--- check
if(samex || samey)
return(false);
//--- calculation
s=0;
for(int i=0; i<size; i++)
{
t1=array1[i]-xmean;
t2=array2[i]-ymean;
xv+=t1*t1;
yv+=t2*t2;
s+=t1*t2;
}
//--- check
if(xv==0 || yv==0)
return(false);
//---
r=s/MathSqrt(xv*yv);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCorrelationPearson |
//+------------------------------------------------------------------+
//| The function calculates Pearson product-moment correlation |
//| coefficient. |
//| |
//| Arguments: |
//| array1[] : First array with integer values |
//| array2[] : Second array with integer values |
//| r : Variable for calculated value of the Pearson r |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
//| Code from ALGLIB numerical analysis and data processing library |
//+------------------------------------------------------------------+
bool MathCorrelationPearson(const int &array1[],const int &array2[],double &r)
{
r=QNaN;
int size=ArraySize(array1);
if(size<=1 || ArraySize(array2)!=size)
return(false);
//--- create variables
double xmean=0;
double ymean=0;
double v=1.0/(double)size;
double x0=array1[0];
double y0=array2[0];
double s=0;
double xv=0;
double yv=0;
double t1=0;
double t2=0;
bool samex=true;
bool samey=true;
//--- additonally we calculate SameX and SameY - flag variables which are set to true
//--- when all X[] (or Y[]) contain exactly same value.
//--- if at least one of them is true, we return zero
//--- (othwerwise we risk to get nonzero correlation because of roundoff).
for(int i=0; i<size; i++)
{
s=array1[i];
samex=samex && s==x0;
xmean+=s*v;
s=array2[i];
samey=samey && s==y0;
ymean+=s*v;
}
//--- check
if(samex || samey)
return(false);
//--- calculation
s=0;
for(int i=0; i<size; i++)
{
t1=array1[i]-xmean;
t2=array2[i]-ymean;
xv+=t1*t1;
yv+=t2*t2;
s+=t1*t2;
}
//--- check
if(xv==0 || yv==0)
return(false);
//---
r=s/MathSqrt(xv*yv);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCorrelationSpearman |
//+------------------------------------------------------------------+
//| The function calculates Spearman correlation coefficient. |
//| |
//| Arguments: |
//| array1[] : First array with double values |
//| array2[] : Second array with double values |
//| r : Variable for calculated value of the Spearman r |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
//| Code from ALGLIB numerical analysis and data processing library |
//+------------------------------------------------------------------+
bool MathCorrelationSpearman(const double &array1[],const double &array2[],double &r)
{
r=QNaN;
int size=ArraySize(array1);
if(size<1 || ArraySize(array2)!=size)
return(false);
//--- calculate ranks
double rank_x[];
double rank_y[];
if(!MathRank(array1,rank_x))
return(false);
if(!MathRank(array2,rank_y))
return(false);
//---
return MathCorrelationPearson(rank_x,rank_y,r);
}
//+------------------------------------------------------------------+
//| MathCorrelationSpearman |
//+------------------------------------------------------------------+
//| The function calculates Spearman correlation coefficient. |
//| |
//| Arguments: |
//| array1[] : First array with integer values |
//| array2[] : Second array with integer values |
//| r : Variable for calculated value of the Spearman r |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
//| Code from ALGLIB numerical analysis and data processing library |
//+------------------------------------------------------------------+
bool MathCorrelationSpearman(const int &array1[],const int &array2[],double &r)
{
r=QNaN;
int size=ArraySize(array1);
if(size<1 || ArraySize(array2)!=size)
return(false);
//--- calculate ranks
double rank_x[];
double rank_y[];
if(!MathRank(array1,rank_x))
return(false);
if(!MathRank(array2,rank_y))
return(false);
//---
return MathCorrelationPearson(rank_x,rank_y,r);
}
//+------------------------------------------------------------------+
//| MathCorrelationKendall |
//+------------------------------------------------------------------+
//| The function calculates Kendall's tau correlation coefficient. |
//| |
//| Arguments: |
//| array1[] : First array with double values |
//| array2[] : Second array with double values |
//| tau : Variable for calculated value of the Kendall's tau |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCorrelationKendall(const double &array1[],const double &array2[],double &tau)
{
tau=QNaN;
int size=ArraySize(array1);
if(size==0 || ArraySize(array2)!=size)
return(false);
//---
int cnt1=0,cnt2=0,cnt=0;
//---
for(int i=0; i<size; i++)
{
for(int j=i+1; j<size; j++)
{
double delta1=array1[i]-array1[j];
double delta2=array2[i]-array2[j];
double delta=delta1*delta2;
if(delta==0)
{
if(delta1!=0)
cnt1++;
if(delta2!=0)
cnt2++;
}
else
{
cnt1++;
cnt2++;
if(delta>0.0)
cnt++;
else
cnt--;
}
}
}
//--- calculate Kendall tau
double den=cnt1*cnt2;
if(den==0)
return(false);
tau=cnt/MathSqrt(den);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCorrelationKendall |
//+------------------------------------------------------------------+
//| The function calculates Kendall's tau correlation coefficient. |
//| |
//| Arguments: |
//| array1[] : First array with integer values |
//| array2[] : Second array with integer values |
//| tau : Variable for calculated value of the Kendall's tau |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCorrelationKendall(const int &array1[],const int &array2[],double &tau)
{
tau=QNaN;
int size=ArraySize(array1);
if(size==0 || ArraySize(array2)!=size)
return(false);
//---
int cnt1=0,cnt2=0,cnt=0;
//---
for(int i=0; i<size; i++)
{
for(int j=i+1; j<size; j++)
{
double delta1=array1[i]-array1[j];
double delta2=array2[i]-array2[j];
double delta=delta1*delta2;
if(delta==0)
{
if(delta1!=0)
cnt1++;
if(delta2!=0)
cnt2++;
}
else
{
cnt1++;
cnt2++;
if(delta>0.0)
cnt++;
else
cnt--;
}
}
}
//--- calculate Kendall tau
double den=cnt1*cnt2;
if(den==0)
return(false);
tau=cnt/MathSqrt(den);
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathQuantile |
//+------------------------------------------------------------------+
//| The function produces sample quantiles corresponding to the |
//| given probabilities. The smallest observation corresponds |
//| to a probability of 0.0 and the largest to a probability of 1.0. |
//+------------------------------------------------------------------+
//| The function calculates estimates of underlying distribution |
//| quantiles based on one or two order statistics from the supplied |
//| elements in x at probabilities in probs. |
//| |
//| Reference: |
//| Hyndman, R. J. and Fan, Y. (1996) |
//| "Sample quantiles in statistical packages", |
//| American Statistician, vol.50, pp. 361365. |
//+------------------------------------------------------------------+
//| All sample quantiles are defined as weighted averages |
//| of consecutive order statistics. |
//| Sample quantiles of type i are defined by: |
//| Q[i](p) = (1 - gamma)*x[j] + gamma*x[j+1] |
//| |
//| The function MathQuantile calculates quantiles according to |
//| default type in R (type=7) |
//| p(k) = (k - 1)/(n - 1). |
//| In this case, p(k) = mode[F(x[k])]. This is used by S. |
//+------------------------------------------------------------------+
bool MathQuantile(const double &array[],const double &probs[],double &quantile[])
{
int size=ArraySize(array);
int size_p=ArraySize(probs);
if(size==0 || size_p==0)
return(false);
//--- check probability
for(int i=0; i<size_p; i++)
{
//--- check NaN
if(!MathIsValidNumber(probs[i]))
return(false);
//--- check probability range
if(probs[i]<0.0 || probs[i]>1.0)
return(false);
}
//--- prepare array with values
double x_values[];
if(ArrayCopy(x_values,array,0,0,WHOLE_ARRAY)!=size)
return(false);
//--- prepare output array
if(ArraySize(quantile)<size_p)
if(ArrayResize(quantile,size_p)!=size_p)
return(false);
double ind[];
int lo[];
int hi[];
ArrayResize(ind,size_p);
ArrayResize(lo,size_p);
ArrayResize(hi,size_p);
//--- calculate ranges
for(int i=0; i<size_p; i++)
{
ind[i]=(size-1)*probs[i];
lo[i]=(int)MathFloor(ind[i]);
hi[i]=(int)MathCeil(ind[i]);
}
//--- calculate quantiles
int indices[];
MathSequenceByCount(0,size-1,size,indices);
MathQuickSort(x_values,indices,0,size-1,1);
for(int i=0; i<size_p; i++)
{
quantile[i]=x_values[lo[i]];
if(ind[i]>lo[i])
{
double gamma=(ind[i]-lo[i]);
quantile[i]=(1.0-gamma)*quantile[i]+gamma*x_values[hi[i]];
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathProbabilityDensityEmpirical |
//+------------------------------------------------------------------+
//| The function calculates the empirical probability density |
//| function (pdf) for random values from array[]. |
//| |
//| Arguments: |
//| array[] : Array with random values |
//| count : Data count, total count pairs (x,pdf(x)) |
//| x[] : Output array for x values |
//| pdf[] : Output array for empirical pdf(x) values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathProbabilityDensityEmpirical(const double &array[],const int count,double &x[],double &pdf[])
{
if(count<=1)
return(false);
int size=ArraySize(array);
if(size==0)
return(false);
//--- check NaN values
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]))
return(false);
}
//--- prepare output arrays
if(ArraySize(x)<count)
if(ArrayResize(x,count)!=count)
return(false);
if(ArraySize(pdf)<count)
if(ArrayResize(pdf,count)!=count)
return(false);
//--- search for min,max and range
double minv=array[0];
double maxv=array[0];
for(int i=1; i<size; i++)
{
minv=MathMin(minv,array[i]);
maxv=MathMax(maxv,array[i]);
}
double range=maxv-minv;
if(range==0)
return(false);
//--- calculate probability density of the empirical distribution
for(int i=0; i<count; i++)
{
x[i]=minv+i*range/(count-1);
pdf[i]=0;
}
for(int i=0; i<size; i++)
{
double v=(array[i]-minv)/range;
int ind=int((v*(count-1)));
pdf[ind]++;
}
//--- normalize values
double dx=range/count;
double sum=0;
for(int i=0; i<count; i++)
sum+=pdf[i]*dx;
if(sum==0)
return(false);
double coef=1.0/sum;
for(int i=0; i<count; i++)
pdf[i]*=coef;
//---
return(true);
}
//+------------------------------------------------------------------+
//| MathCumulativeDistributionEmpirical |
//+------------------------------------------------------------------+
//| The function calculates the empirical cumulative distribution |
//| function (cdf) for random values from array[]. |
//| |
//| Arguments: |
//| array[] : Array with random values |
//| count : Data count, total count pairs (x,cdf(x)) |
//| x[] : Output array for x values |
//| cdf[] : Output array for empirical cdf(x) values |
//| |
//| Return value: true if successful, otherwise false |
//+------------------------------------------------------------------+
bool MathCumulativeDistributionEmpirical(const double &array[],const int count,double &x[],double &cdf[])
{
if(count<=1)
return(false);
int size=ArraySize(array);
if(size==0)
return(false);
//--- check NaN values
for(int i=0; i<size; i++)
{
if(!MathIsValidNumber(array[i]))
return(false);
}
//--- prepare output arrays
if(ArraySize(x)<count)
if(ArrayResize(x,count)!=count)
return(false);
if(ArraySize(cdf)<count)
if(ArrayResize(cdf,count)!=count)
return(false);
//--- search for min,max and range
double minv=array[0];
double maxv=array[0];
for(int i=1; i<size; i++)
{
minv=MathMin(minv,array[i]);
maxv=MathMax(maxv,array[i]);
}
double range=maxv-minv;
if(range==0)
return(false);
//--- calculate probability density of the empirical distribution
double pdf[];
if(ArrayResize(pdf,count)!=count)
return(false);
for(int i=0; i<count; i++)
{
x[i]=minv+i*range/(count-1);
pdf[i]=0;
}
for(int i=0; i<size; i++)
{
double v=(array[i]-minv)/range;
int ind=int((v*(count-1)));
pdf[ind]++;
}
//--- normalize values
double dx=range/count;
double sum=0;
for(int i=0; i<count; i++)
sum+=pdf[i]*dx;
if(sum==0)
return(false);
double coef=1.0/sum;
for(int i=0; i<count; i++)
pdf[i]*=coef;
//--- calculate cumulative distribution function
sum=0.0;
for(int i=0; i<count; i++)
{
sum+=pdf[i]*dx;
cdf[i]=sum;
}
//---
return(true);
}
//+------------------------------------------------------------------+