//+------------------------------------------------------------------+
//| ArrayEx.mq4 |
//| amba |
//| |
//+------------------------------------------------------------------+
#property copyright "amba"
#property link ""
#property library
#property stacksize 32767
/**/
#define MODE_QUICK3 0
#define MODE_QUICK3N 1
void Array.Sort(double &a[],int order[],int sort.mode=MODE_QUICK3)
{
if(sort.mode==MODE_QUICK3)
Array.Sort.Quick3(a,0,ArrayRange(a,0)-1,order);
//quicksort(a,0,ArrayRange(a,0)-1,order);
else if(sort.mode==MODE_QUICK3N)
Array.Sort.quicksort(a,0,ArrayRange(a,0)-1,order);
}
// http://www.sorting-algorithms.com/quick-sort-3-way
void Array.Sort.Quick3(double & a[][],int s, int n,int &order[])
{
if(n<=s) return(0);
// choose pivot
Array.Swap(a,n,(s+n+1)/2);
// 3-way partition
int i = s, k = s, p = n;
while (i < p)
{
int cmpr=Array.Compare(a,i,n,order);
if (cmpr<0) {Array.Swap(a,i,k); i++; k++;}
else if (cmpr==0) {p--; Array.Swap(a,i,p);}
else i++;
}
// move pivots to center
int m = MathMin(p-k,n-p+1);
int j1=k, j2=n-m+1;
while(j1<k+m && j2<n+1)
{
Array.Swap(a,j1,j2);
j1++;j2++;
}
// recursive sorts
Array.Sort.Quick3(a,s,k-1,order);
Array.Sort.Quick3(a,n-p+k+1,n,order);
}
void quicksort(double &a[][], int l, int r, int & order[])
{
int i = l-1, j = r;
if (r <= l) return;
// choose pivot
Array.Swap(a,l,(l+r+1)/2);
for (;;)
{
while (i < r) { i++; if(Array.Compare(a,r,i,order)<0) break; }
while (j > l) { j--; if(Array.Compare(a,r,j,order)<0) break; }
if (i >= j) break;
Array.Swap(a, i, j);
}
Array.Swap(a, i, r);
quicksort(a, l, i-1, order);
quicksort(a, i+1, r, order);
}
void Array.Swap(double & a[][],int i1, int i2)
{
if(i1==i2) return(0); //||MathMin(i1,i2)<0||MathMax(i1,i2)>ArrayRange(a,0)) return(0);
double prom=0;
for(int i=0;i<ArrayRange(a,1);i++)
{
prom=a[i1][i];
a[i1][i]=a[i2][i];
a[i2][i]=prom;
}
}
int Array.Compare(double & a[][],int i1, int i2,int &order[])
{
int col=0,sign=0;
for(int i=0;i<ArraySize(order);i++)
{
col=order[i];
if(col>0) sign=1;
if(col<0) sign=-1;
col=MathAbs(col)-1;
if (a[i1][col]>a[i2][col]) return(sign);
else if(a[i1][col]<a[i2][col]) return(-sign);
}
return(0);
}
void Array.Group(double &a[][],int groups[],int sums[],double &dest[][])
{
int ng=ArraySize(groups),ns=ArraySize(sums),nc=ng+ns;
if(ArraySize(a)==0
||ArrayDimension(a)!=2
||ArrayDimension(dest)!=2
||ArrayRange(a,1)<nc
||ArrayRange(dest,1)<nc)
return;
Array.Sort(a, groups);
int dest_cnt=1, currow=0, curcol=0;
ArrayResize(dest,dest_cnt);
ArrayInitialize(dest,0);
for(int i=0;i<ng;i++)
{
curcol=MathAbs(groups[i])-1;
dest[currow][i]=a[currow][curcol];
}
for(i=ng;i<nc;i++)
{
curcol=MathAbs(sums[(i-ng)])-1;
dest[currow][i]=a[currow][curcol];
}
for(int r=1;r<ArrayRange(a,0);r++)
{
if(Array.Compare(a,r-1,r,groups)!=0)
{
dest_cnt++;currow++;
ArrayResize(dest,dest_cnt);
for(i=0;i<ng;i++)
{
curcol=MathAbs(groups[i])-1;
dest[currow][i]=a[r][curcol];
}
}
for(i=ng;i<nc;i++)
{
curcol=MathAbs(sums[(i-ng)])-1;
dest[currow][i]+=a[r][curcol];
}
}
}
int Array.Select(double &a[][], double & filter[][], double & dest[][])
{
if(ArrayRange(a,1)!=ArrayRange(dest,1))
return(0);
ArrayResize(dest,0);
int col=0, rstart=0, rend=0;
bool equal=false;
for(int r=0;r<ArrayRange(a,0);r++)
{
equal=false;
for(int i=0;i<ArrayRange(filter,0);i++)
{
col=filter[i][0]-1;
if((a[r][col]<filter[i][1])||(a[r][col]>filter[i][2]))
{equal=false;break;}
else equal=true;
}
if(equal)
ArrayCopy(dest,a,ArraySize(dest),r*ArrayRange(a,1),ArrayRange(a,1));
}
}
// http://www.sorting-algorithms.com/static/QuicksortIsOptimal.pdf
void Array.Sort.quicksort(double & a[], int l, int r, int &order[])
{
int i = l-1, j = r, p = l-1, q = r;
if (r <= l) return;
// choose pivot
Array.Swap(a,l,(l+r+1)/2);
for (;;)
{
while (i<r) { i++; if(Array.Compare(a, i, r, order) >= 0) break; }
while (j>l) { j--; if(Array.Compare(a, r, j, order) >= 0) break; }
if (i >= j) break;
Array.Swap(a,i,j);
if (Array.Compare(a, i, r, order) == 0) { p++; Array.Swap(a, p, i); }
if (Array.Compare(a, r, j, order) == 0) { q--; Array.Swap(a, j, q); }
}
Array.Swap(a, i, r); j = i-1; i = i+1;
for (int k = l; k < p; k++, j--) Array.Swap(a, k, j);
for ( k = r-1; k > q; k--, i++) Array.Swap(a, i, k);
Array.Sort.quicksort(a, l, j, order);
Array.Sort.quicksort(a, i, r, order);
}
Comments