Author: amba
0 Views
0 Downloads
0 Favorites
ArrayEx
//+------------------------------------------------------------------+
//|                                                      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