void tagsort(ap::real_1d_array& a,
     int n,
     ap::integer_1d_array& p1,
     ap::integer_1d_array& p2)
{
    int i;
    int j;
    int k;
    int t;
    double tmp;
    int tmpi;
    ap::integer_1d_array pv;
    ap::integer_1d_array vp;
    int lv;
    int lp;
    int rv;
    int rp;

    
    //
    // Special cases
    //
    if( n<=0 )
    {
        return;
    }
    if( n==1 )
    {
        p1.setbounds(0, 0);
        p2.setbounds(0, 0);
        p1(0) = 0;
        p2(0) = 0;
        return;
    }
    
    //
    // General case, N>1: prepare permutations table P1
    //
    p1.setbounds(0, n-1);
    for(i = 0; i <= n-1; i++)
    {
        p1(i) = i;
    }
    
    //
    // General case, N>1: sort, update P1
    //
    tagsortfasti(a, p1, n);
    
    //
    // General case, N>1: fill permutations table P2
    //
    // To fill P2 we maintain two arrays:
    // * PV, Position(Value). PV[i] contains position of I-th key at the moment
    // * VP, Value(Position). VP[i] contains key which has position I at the moment
    //
    // At each step we making permutation of two items:
    //   Left, which is given by position/value pair LP/LV
    //   and Right, which is given by RP/RV
    // and updating PV[] and VP[] correspondingly.
    //
    pv.setbounds(0, n-1);
    vp.setbounds(0, n-1);
    p2.setbounds(0, n-1);
    for(i = 0; i <= n-1; i++)
    {
        pv(i) = i;
        vp(i) = i;
    }
    for(i = 0; i <= n-1; i++)
    {
        
        //
        // calculate LP, LV, RP, RV
        //
        lp = i;
        lv = vp(lp);
        rv = p1(i);
        rp = pv(rv);
        
        //
        // Fill P2
        //
        p2(i) = rp;
        
        //
        // update PV and VP
        //
        vp(lp) = rv;
        vp(rp) = lv;
        pv(lv) = rp;
        pv(rv) = lp;
    }
}
Exemple #2
0
/*************************************************************************
Makes weak split on attribute
*************************************************************************/
static void dfweakspliti(ap::real_1d_array& x,
     ap::integer_1d_array& y,
     int n,
     int nclasses,
     int& info,
     double& threshold,
     double& e)
{
    int i;
    int neq;
    int nless;
    int ngreater;

    tagsortfasti(x, y, n);
    if( n%2==1 )
    {
        
        //
        // odd number of elements
        //
        threshold = x(n/2);
    }
    else
    {
        
        //
        // even number of elements.
        //
        // if two closest to the middle of the array are equal,
        // we will select one of them (to avoid possible problems with
        // floating point errors).
        // we will select halfsum otherwise.
        //
        if( ap::fp_eq(x(n/2-1),x(n/2)) )
        {
            threshold = x(n/2-1);
        }
        else
        {
            threshold = 0.5*(x(n/2-1)+x(n/2));
        }
    }
    neq = 0;
    nless = 0;
    ngreater = 0;
    for(i = 0; i <= n-1; i++)
    {
        if( ap::fp_less(x(i),threshold) )
        {
            nless = nless+1;
        }
        if( ap::fp_eq(x(i),threshold) )
        {
            neq = neq+1;
        }
        if( ap::fp_greater(x(i),threshold) )
        {
            ngreater = ngreater+1;
        }
    }
    if( nless==0&&ngreater==0 )
    {
        info = -3;
    }
    else
    {
        if( neq!=0 )
        {
            if( nless<ngreater )
            {
                threshold = 0.5*(x(nless+neq-1)+x(nless+neq));
            }
            else
            {
                threshold = 0.5*(x(nless-1)+x(nless));
            }
        }
        info = 1;
        e = 0;
    }
}
Exemple #3
0
/*************************************************************************
Makes split on attribute
*************************************************************************/
static void dfsplitc(ap::real_1d_array& x,
     ap::integer_1d_array& c,
     ap::integer_1d_array& cntbuf,
     int n,
     int nc,
     int flags,
     int& info,
     double& threshold,
     double& e)
{
    int i;
    int neq;
    int nless;
    int ngreater;
    int q;
    int qmin;
    int qmax;
    int qcnt;
    double cursplit;
    int nleft;
    double v;
    double cure;
    double w;
    double sl;
    double sr;

    tagsortfasti(x, c, n);
    e = ap::maxrealnumber;
    threshold = 0.5*(x(0)+x(n-1));
    info = -3;
    if( flags/dfusestrongsplits%2==0 )
    {
        
        //
        // weak splits, split at half
        //
        qcnt = 2;
        qmin = 1;
        qmax = 1;
    }
    else
    {
        
        //
        // strong splits: choose best quartile
        //
        qcnt = 4;
        qmin = 1;
        qmax = 3;
    }
    for(q = qmin; q <= qmax; q++)
    {
        cursplit = x(n*q/qcnt);
        neq = 0;
        nless = 0;
        ngreater = 0;
        for(i = 0; i <= n-1; i++)
        {
            if( ap::fp_less(x(i),cursplit) )
            {
                nless = nless+1;
            }
            if( ap::fp_eq(x(i),cursplit) )
            {
                neq = neq+1;
            }
            if( ap::fp_greater(x(i),cursplit) )
            {
                ngreater = ngreater+1;
            }
        }
        ap::ap_error::make_assertion(neq!=0, "DFSplitR: NEq=0, something strange!!!");
        if( nless!=0||ngreater!=0 )
        {
            
            //
            // set threshold between two partitions, with
            // some tweaking to avoid problems with floating point
            // arithmetics.
            //
            // The problem is that when you calculates C = 0.5*(A+B) there
            // can be no C which lies strictly between A and B (for example,
            // there is no floating point number which is
            // greater than 1 and less than 1+eps). In such situations
            // we choose right side as theshold (remember that
            // points which lie on threshold falls to the right side).
            //
            if( nless<ngreater )
            {
                cursplit = 0.5*(x(nless+neq-1)+x(nless+neq));
                nleft = nless+neq;
                if( ap::fp_less_eq(cursplit,x(nless+neq-1)) )
                {
                    cursplit = x(nless+neq);
                }
            }
            else
            {
                cursplit = 0.5*(x(nless-1)+x(nless));
                nleft = nless;
                if( ap::fp_less_eq(cursplit,x(nless-1)) )
                {
                    cursplit = x(nless);
                }
            }
            info = 1;
            cure = 0;
            for(i = 0; i <= 2*nc-1; i++)
            {
                cntbuf(i) = 0;
            }
            for(i = 0; i <= nleft-1; i++)
            {
                cntbuf(c(i)) = cntbuf(c(i))+1;
            }
            for(i = nleft; i <= n-1; i++)
            {
                cntbuf(nc+c(i)) = cntbuf(nc+c(i))+1;
            }
            sl = nleft;
            sr = n-nleft;
            v = 0;
            for(i = 0; i <= nc-1; i++)
            {
                w = cntbuf(i);
                v = v+w*ap::sqr(w/sl-1);
                v = v+(sl-w)*ap::sqr(w/sl);
                w = cntbuf(nc+i);
                v = v+w*ap::sqr(w/sr-1);
                v = v+(sr-w)*ap::sqr(w/sr);
            }
            cure = sqrt(v/(nc*n));
            if( ap::fp_less(cure,e) )
            {
                threshold = cursplit;
                e = cure;
            }
        }
    }
}
/*************************************************************************
Rational barycentric interpolation without poles

The subroutine constructs the rational interpolating function without real
poles. It should be noted that the barycentric weights of the  interpolant
constructed are independent of the values of the given function.

Input parameters:
    X   -   interpolation nodes, array[0..N-1].
    N   -   number of nodes, N>0.
    D   -   order of the interpolation scheme, 0 <= D <= N-1.

Output parameters:
    W   -   array of the barycentric weights which  can  be  used  in  the
            BarycentricInterpolate subroutine. Array[0..N-1]

Note:
    this algorithm always succeeds and calculates the weights  with  close
    to machine precision.

  -- ALGLIB PROJECT --
     Copyright 17.06.2007 by Bochkanov Sergey
*************************************************************************/
void buildfloaterhormannrationalinterpolant(ap::real_1d_array x,
     int n,
     int d,
     ap::real_1d_array& w)
{
    double s0;
    double s;
    double v;
    int i;
    int j;
    int k;
    ap::integer_1d_array perm;
    ap::real_1d_array wtemp;

    ap::ap_error::make_assertion(n>0, "BuildRationalInterpolantWithoutPoles: N<=0!");
    ap::ap_error::make_assertion(d>=0&&d<=n, "BuildRationalInterpolantWithoutPoles: incorrect D!");
    
    //
    // Prepare
    //
    w.setbounds(0, n-1);
    s0 = 1;
    for(k = 1; k <= d; k++)
    {
        s0 = -s0;
    }
    perm.setbounds(0, n-1);
    for(i = 0; i <= n-1; i++)
    {
        perm(i) = i;
    }
    tagsortfasti(x, perm, n);
    
    //
    // Calculate Wk
    //
    for(k = 0; k <= n-1; k++)
    {
        
        //
        // Wk
        //
        s = 0;
        for(i = ap::maxint(k-d, 0); i <= ap::minint(k, n-1-d); i++)
        {
            v = 1;
            for(j = i; j <= i+d; j++)
            {
                if( j!=k )
                {
                    v = v/fabs(x(k)-x(j));
                }
            }
            s = s+v;
        }
        w(k) = s0*s;
        
        //
        // Next S0
        //
        s0 = -s0;
    }
    
    //
    // Reorder W
    //
    wtemp.setbounds(0, n-1);
    ap::vmove(&wtemp(0), &w(0), ap::vlen(0,n-1));
    for(i = 0; i <= n-1; i++)
    {
        w(perm(i)) = wtemp(i);
    }
}