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