Ejemplo n.º 1
0
        /*************************************************************************
        Unpack testing
        *************************************************************************/
        private static bool testunpack(spline1d.spline1dinterpolant c,
            double[] x)
        {
            bool result = new bool();
            int i = 0;
            int n = 0;
            double err = 0;
            double t = 0;
            double v1 = 0;
            double v2 = 0;
            int pass = 0;
            int passcount = 0;
            double[,] tbl = new double[0,0];

            passcount = 20;
            err = 0;
            spline1d.spline1dunpack(c, ref n, ref tbl);
            for(i=0; i<=n-2; i++)
            {
                for(pass=1; pass<=passcount; pass++)
                {
                    t = math.randomreal()*(tbl[i,1]-tbl[i,0]);
                    v1 = tbl[i,2]+t*tbl[i,3]+math.sqr(t)*tbl[i,4]+t*math.sqr(t)*tbl[i,5];
                    v2 = spline1d.spline1dcalc(c, tbl[i,0]+t);
                    err = Math.Max(err, Math.Abs(v1-v2));
                }
            }
            for(i=0; i<=n-2; i++)
            {
                err = Math.Max(err, Math.Abs(x[i]-tbl[i,0]));
            }
            for(i=0; i<=n-2; i++)
            {
                err = Math.Max(err, Math.Abs(x[i+1]-tbl[i,1]));
            }
            result = (double)(err)<(double)(100*math.machineepsilon);
            return result;
        }
Ejemplo n.º 2
0
        /*************************************************************************
        Unset spline, i.e. initialize it with random garbage
        *************************************************************************/
        private static void unsetspline1d(spline1d.spline1dinterpolant c)
        {
            double[] x = new double[0];
            double[] y = new double[0];
            double[] d = new double[0];

            x = new double[2];
            y = new double[2];
            d = new double[2];
            x[0] = -1;
            y[0] = math.randomreal();
            d[0] = math.randomreal();
            x[1] = 1;
            y[1] = math.randomreal();
            d[1] = math.randomreal();
            spline1d.spline1dbuildhermite(x, y, d, 2, c);
        }
Ejemplo n.º 3
0
 public spline1dinterpolant(spline1d.spline1dinterpolant obj)
 {
     _innerobj = obj;
 }
Ejemplo n.º 4
0
        /*************************************************************************
        Lipschitz constants for spline inself, first and second derivatives.
        *************************************************************************/
        private static void lconst(double a,
            double b,
            spline1d.spline1dinterpolant c,
            double lstep,
            ref double l0,
            ref double l1,
            ref double l2)
        {
            double t = 0;
            double vl = 0;
            double vm = 0;
            double vr = 0;
            double prevf = 0;
            double prevd = 0;
            double prevd2 = 0;
            double f = 0;
            double d = 0;
            double d2 = 0;

            l0 = 0;
            l1 = 0;
            l2 = 0;

            l0 = 0;
            l1 = 0;
            l2 = 0;
            t = a-0.1;
            vl = spline1d.spline1dcalc(c, t-2*lstep);
            vm = spline1d.spline1dcalc(c, t-lstep);
            vr = spline1d.spline1dcalc(c, t);
            f = vm;
            d = (vr-vl)/(2*lstep);
            d2 = (vr-2*vm+vl)/math.sqr(lstep);
            while( (double)(t)<=(double)(b+0.1) )
            {
                prevf = f;
                prevd = d;
                prevd2 = d2;
                vl = vm;
                vm = vr;
                vr = spline1d.spline1dcalc(c, t+lstep);
                f = vm;
                d = (vr-vl)/(2*lstep);
                d2 = (vr-2*vm+vl)/math.sqr(lstep);
                l0 = Math.Max(l0, Math.Abs((f-prevf)/lstep));
                l1 = Math.Max(l1, Math.Abs((d-prevd)/lstep));
                l2 = Math.Max(l2, Math.Abs((d2-prevd2)/lstep));
                t = t+lstep;
            }
        }
Ejemplo n.º 5
0
        /*************************************************************************
        Least squares fitting by Hermite spline.

        This subroutine is "lightweight" alternative for more complex and feature-
        rich Spline1DFitHermiteWC().  See Spline1DFitHermiteWC()  description  for
        more information about subroutine parameters (we don't duplicate  it  here
        because of length).

          -- ALGLIB PROJECT --
             Copyright 18.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline1dfithermite(double[] x,
            double[] y,
            int n,
            int m,
            ref int info,
            spline1d.spline1dinterpolant s,
            spline1dfitreport rep)
        {
            int i = 0;
            double[] w = new double[0];
            double[] xc = new double[0];
            double[] yc = new double[0];
            int[] dc = new int[0];

            info = 0;

            alglib.ap.assert(n>=1, "Spline1DFitHermite: N<1!");
            alglib.ap.assert(m>=4, "Spline1DFitHermite: M<4!");
            alglib.ap.assert(m%2==0, "Spline1DFitHermite: M is odd!");
            alglib.ap.assert(alglib.ap.len(x)>=n, "Spline1DFitHermite: Length(X)<N!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "Spline1DFitHermite: Length(Y)<N!");
            alglib.ap.assert(apserv.isfinitevector(x, n), "Spline1DFitHermite: X contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "Spline1DFitHermite: Y contains infinite or NAN values!");
            w = new double[n];
            for(i=0; i<=n-1; i++)
            {
                w[i] = 1;
            }
            spline1dfithermitewc(x, y, w, n, xc, yc, dc, 0, m, ref info, s, rep);
        }
Ejemplo n.º 6
0
        /*************************************************************************
        Internal spline fitting subroutine

          -- ALGLIB PROJECT --
             Copyright 08.09.2009 by Bochkanov Sergey
        *************************************************************************/
        private static void spline1dfitinternal(int st,
            double[] x,
            double[] y,
            double[] w,
            int n,
            double[] xc,
            double[] yc,
            int[] dc,
            int k,
            int m,
            ref int info,
            spline1d.spline1dinterpolant s,
            spline1dfitreport rep)
        {
            double[,] fmatrix = new double[0,0];
            double[,] cmatrix = new double[0,0];
            double[] y2 = new double[0];
            double[] w2 = new double[0];
            double[] sx = new double[0];
            double[] sy = new double[0];
            double[] sd = new double[0];
            double[] tmp = new double[0];
            double[] xoriginal = new double[0];
            double[] yoriginal = new double[0];
            lsfitreport lrep = new lsfitreport();
            double v0 = 0;
            double v1 = 0;
            double v2 = 0;
            double mx = 0;
            spline1d.spline1dinterpolant s2 = new spline1d.spline1dinterpolant();
            int i = 0;
            int j = 0;
            int relcnt = 0;
            double xa = 0;
            double xb = 0;
            double sa = 0;
            double sb = 0;
            double bl = 0;
            double br = 0;
            double decay = 0;
            int i_ = 0;

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            w = (double[])w.Clone();
            xc = (double[])xc.Clone();
            yc = (double[])yc.Clone();
            info = 0;

            alglib.ap.assert(st==0 || st==1, "Spline1DFit: internal error!");
            if( st==0 && m<4 )
            {
                info = -1;
                return;
            }
            if( st==1 && m<4 )
            {
                info = -1;
                return;
            }
            if( (n<1 || k<0) || k>=m )
            {
                info = -1;
                return;
            }
            for(i=0; i<=k-1; i++)
            {
                info = 0;
                if( dc[i]<0 )
                {
                    info = -1;
                }
                if( dc[i]>1 )
                {
                    info = -1;
                }
                if( info<0 )
                {
                    return;
                }
            }
            if( st==1 && m%2!=0 )
            {
                
                //
                // Hermite fitter must have even number of basis functions
                //
                info = -2;
                return;
            }
            
            //
            // weight decay for correct handling of task which becomes
            // degenerate after constraints are applied
            //
            decay = 10000*math.machineepsilon;
            
            //
            // Scale X, Y, XC, YC
            //
            lsfitscalexy(ref x, ref y, ref w, n, ref xc, ref yc, dc, k, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);
            
            //
            // allocate space, initialize:
            // * SX     -   grid for basis functions
            // * SY     -   values of basis functions at grid points
            // * FMatrix-   values of basis functions at X[]
            // * CMatrix-   values (derivatives) of basis functions at XC[]
            //
            y2 = new double[n+m];
            w2 = new double[n+m];
            fmatrix = new double[n+m, m];
            if( k>0 )
            {
                cmatrix = new double[k, m+1];
            }
            if( st==0 )
            {
                
                //
                // allocate space for cubic spline
                //
                sx = new double[m-2];
                sy = new double[m-2];
                for(j=0; j<=m-2-1; j++)
                {
                    sx[j] = (double)(2*j)/(double)(m-2-1)-1;
                }
            }
            if( st==1 )
            {
                
                //
                // allocate space for Hermite spline
                //
                sx = new double[m/2];
                sy = new double[m/2];
                sd = new double[m/2];
                for(j=0; j<=m/2-1; j++)
                {
                    sx[j] = (double)(2*j)/(double)(m/2-1)-1;
                }
            }
            
            //
            // Prepare design and constraints matrices:
            // * fill constraints matrix
            // * fill first N rows of design matrix with values
            // * fill next M rows of design matrix with regularizing term
            // * append M zeros to Y
            // * append M elements, mean(abs(W)) each, to W
            //
            for(j=0; j<=m-1; j++)
            {
                
                //
                // prepare Jth basis function
                //
                if( st==0 )
                {
                    
                    //
                    // cubic spline basis
                    //
                    for(i=0; i<=m-2-1; i++)
                    {
                        sy[i] = 0;
                    }
                    bl = 0;
                    br = 0;
                    if( j<m-2 )
                    {
                        sy[j] = 1;
                    }
                    if( j==m-2 )
                    {
                        bl = 1;
                    }
                    if( j==m-1 )
                    {
                        br = 1;
                    }
                    spline1d.spline1dbuildcubic(sx, sy, m-2, 1, bl, 1, br, s2);
                }
                if( st==1 )
                {
                    
                    //
                    // Hermite basis
                    //
                    for(i=0; i<=m/2-1; i++)
                    {
                        sy[i] = 0;
                        sd[i] = 0;
                    }
                    if( j%2==0 )
                    {
                        sy[j/2] = 1;
                    }
                    else
                    {
                        sd[j/2] = 1;
                    }
                    spline1d.spline1dbuildhermite(sx, sy, sd, m/2, s2);
                }
                
                //
                // values at X[], XC[]
                //
                for(i=0; i<=n-1; i++)
                {
                    fmatrix[i,j] = spline1d.spline1dcalc(s2, x[i]);
                }
                for(i=0; i<=k-1; i++)
                {
                    alglib.ap.assert(dc[i]>=0 && dc[i]<=2, "Spline1DFit: internal error!");
                    spline1d.spline1ddiff(s2, xc[i], ref v0, ref v1, ref v2);
                    if( dc[i]==0 )
                    {
                        cmatrix[i,j] = v0;
                    }
                    if( dc[i]==1 )
                    {
                        cmatrix[i,j] = v1;
                    }
                    if( dc[i]==2 )
                    {
                        cmatrix[i,j] = v2;
                    }
                }
            }
            for(i=0; i<=k-1; i++)
            {
                cmatrix[i,m] = yc[i];
            }
            for(i=0; i<=m-1; i++)
            {
                for(j=0; j<=m-1; j++)
                {
                    if( i==j )
                    {
                        fmatrix[n+i,j] = decay;
                    }
                    else
                    {
                        fmatrix[n+i,j] = 0;
                    }
                }
            }
            y2 = new double[n+m];
            w2 = new double[n+m];
            for(i_=0; i_<=n-1;i_++)
            {
                y2[i_] = y[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                w2[i_] = w[i_];
            }
            mx = 0;
            for(i=0; i<=n-1; i++)
            {
                mx = mx+Math.Abs(w[i]);
            }
            mx = mx/n;
            for(i=0; i<=m-1; i++)
            {
                y2[n+i] = 0;
                w2[n+i] = mx;
            }
            
            //
            // Solve constrained task
            //
            if( k>0 )
            {
                
                //
                // solve using regularization
                //
                lsfitlinearwc(y2, w2, fmatrix, cmatrix, n+m, m, k, ref info, ref tmp, lrep);
            }
            else
            {
                
                //
                // no constraints, no regularization needed
                //
                lsfitlinearwc(y, w, fmatrix, cmatrix, n, m, k, ref info, ref tmp, lrep);
            }
            if( info<0 )
            {
                return;
            }
            
            //
            // Generate spline and scale it
            //
            if( st==0 )
            {
                
                //
                // cubic spline basis
                //
                for(i_=0; i_<=m-2-1;i_++)
                {
                    sy[i_] = tmp[i_];
                }
                spline1d.spline1dbuildcubic(sx, sy, m-2, 1, tmp[m-2], 1, tmp[m-1], s);
            }
            if( st==1 )
            {
                
                //
                // Hermite basis
                //
                for(i=0; i<=m/2-1; i++)
                {
                    sy[i] = tmp[2*i];
                    sd[i] = tmp[2*i+1];
                }
                spline1d.spline1dbuildhermite(sx, sy, sd, m/2, s);
            }
            spline1d.spline1dlintransx(s, 2/(xb-xa), -((xa+xb)/(xb-xa)));
            spline1d.spline1dlintransy(s, sb-sa, sa);
            
            //
            // Scale absolute errors obtained from LSFitLinearW.
            // Relative error should be calculated separately
            // (because of shifting/scaling of the task)
            //
            rep.taskrcond = lrep.taskrcond;
            rep.rmserror = lrep.rmserror*(sb-sa);
            rep.avgerror = lrep.avgerror*(sb-sa);
            rep.maxerror = lrep.maxerror*(sb-sa);
            rep.avgrelerror = 0;
            relcnt = 0;
            for(i=0; i<=n-1; i++)
            {
                if( (double)(yoriginal[i])!=(double)(0) )
                {
                    rep.avgrelerror = rep.avgrelerror+Math.Abs(spline1d.spline1dcalc(s, xoriginal[i])-yoriginal[i])/Math.Abs(yoriginal[i]);
                    relcnt = relcnt+1;
                }
            }
            if( relcnt!=0 )
            {
                rep.avgrelerror = rep.avgrelerror/relcnt;
            }
        }
Ejemplo n.º 7
0
        /*************************************************************************
        Weighted fitting by penalized cubic spline.

        Equidistant grid with M nodes on [min(x,xc),max(x,xc)] is  used  to  build
        basis functions. Basis functions are cubic splines with  natural  boundary
        conditions. Problem is regularized by  adding non-linearity penalty to the
        usual least squares penalty function:

            S(x) = arg min { LS + P }, where
            LS   = SUM { w[i]^2*(y[i] - S(x[i]))^2 } - least squares penalty
            P    = C*10^rho*integral{ S''(x)^2*dx } - non-linearity penalty
            rho  - tunable constant given by user
            C    - automatically determined scale parameter,
                   makes penalty invariant with respect to scaling of X, Y, W.

        INPUT PARAMETERS:
            X   -   points, array[0..N-1].
            Y   -   function values, array[0..N-1].
            W   -   weights, array[0..N-1]
                    Each summand in square  sum  of  approximation deviations from
                    given  values  is  multiplied  by  the square of corresponding
                    weight. Fill it by 1's if you don't  want  to  solve  weighted
                    problem.
            N   -   number of points (optional):
                    * N>0
                    * if given, only first N elements of X/Y/W are processed
                    * if not given, automatically determined from X/Y/W sizes
            M   -   number of basis functions ( = number_of_nodes), M>=4.
            Rho -   regularization  constant  passed   by   user.   It   penalizes
                    nonlinearity in the regression spline. It  is  logarithmically
                    scaled,  i.e.  actual  value  of  regularization  constant  is
                    calculated as 10^Rho. It is automatically scaled so that:
                    * Rho=2.0 corresponds to moderate amount of nonlinearity
                    * generally, it should be somewhere in the [-8.0,+8.0]
                    If you do not want to penalize nonlineary,
                    pass small Rho. Values as low as -15 should work.

        OUTPUT PARAMETERS:
            Info-   same format as in LSFitLinearWC() subroutine.
                    * Info>0    task is solved
                    * Info<=0   an error occured:
                                -4 means inconvergence of internal SVD or
                                   Cholesky decomposition; problem may be
                                   too ill-conditioned (very rare)
            S   -   spline interpolant.
            Rep -   Following fields are set:
                    * RMSError      rms error on the (X,Y).
                    * AvgError      average error on the (X,Y).
                    * AvgRelError   average relative error on the non-zero Y
                    * MaxError      maximum error
                                    NON-WEIGHTED ERRORS ARE CALCULATED

        IMPORTANT:
            this subroitine doesn't calculate task's condition number for K<>0.

        NOTE 1: additional nodes are added to the spline outside  of  the  fitting
        interval to force linearity when x<min(x,xc) or x>max(x,xc).  It  is  done
        for consistency - we penalize non-linearity  at [min(x,xc),max(x,xc)],  so
        it is natural to force linearity outside of this interval.

        NOTE 2: function automatically sorts points,  so  caller may pass unsorted
        array.

          -- ALGLIB PROJECT --
             Copyright 19.10.2010 by Bochkanov Sergey
        *************************************************************************/
        public static void spline1dfitpenalizedw(double[] x,
            double[] y,
            double[] w,
            int n,
            int m,
            double rho,
            ref int info,
            spline1d.spline1dinterpolant s,
            spline1dfitreport rep)
        {
            int i = 0;
            int j = 0;
            int b = 0;
            double v = 0;
            double relcnt = 0;
            double xa = 0;
            double xb = 0;
            double sa = 0;
            double sb = 0;
            double[] xoriginal = new double[0];
            double[] yoriginal = new double[0];
            double pdecay = 0;
            double tdecay = 0;
            double[,] fmatrix = new double[0,0];
            double[] fcolumn = new double[0];
            double[] y2 = new double[0];
            double[] w2 = new double[0];
            double[] xc = new double[0];
            double[] yc = new double[0];
            int[] dc = new int[0];
            double fdmax = 0;
            double admax = 0;
            double[,] amatrix = new double[0,0];
            double[,] d2matrix = new double[0,0];
            double fa = 0;
            double ga = 0;
            double fb = 0;
            double gb = 0;
            double lambdav = 0;
            double[] bx = new double[0];
            double[] by = new double[0];
            double[] bd1 = new double[0];
            double[] bd2 = new double[0];
            double[] tx = new double[0];
            double[] ty = new double[0];
            double[] td = new double[0];
            spline1d.spline1dinterpolant bs = new spline1d.spline1dinterpolant();
            double[,] nmatrix = new double[0,0];
            double[] rightpart = new double[0];
            fbls.fblslincgstate cgstate = new fbls.fblslincgstate();
            double[] c = new double[0];
            double[] tmp0 = new double[0];
            int i_ = 0;
            int i1_ = 0;

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            w = (double[])w.Clone();
            info = 0;

            alglib.ap.assert(n>=1, "Spline1DFitPenalizedW: N<1!");
            alglib.ap.assert(m>=4, "Spline1DFitPenalizedW: M<4!");
            alglib.ap.assert(alglib.ap.len(x)>=n, "Spline1DFitPenalizedW: Length(X)<N!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "Spline1DFitPenalizedW: Length(Y)<N!");
            alglib.ap.assert(alglib.ap.len(w)>=n, "Spline1DFitPenalizedW: Length(W)<N!");
            alglib.ap.assert(apserv.isfinitevector(x, n), "Spline1DFitPenalizedW: X contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "Spline1DFitPenalizedW: Y contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(w, n), "Spline1DFitPenalizedW: Y contains infinite or NAN values!");
            alglib.ap.assert(math.isfinite(rho), "Spline1DFitPenalizedW: Rho is infinite!");
            
            //
            // Prepare LambdaV
            //
            v = -(Math.Log(math.machineepsilon)/Math.Log(10));
            if( (double)(rho)<(double)(-v) )
            {
                rho = -v;
            }
            if( (double)(rho)>(double)(v) )
            {
                rho = v;
            }
            lambdav = Math.Pow(10, rho);
            
            //
            // Sort X, Y, W
            //
            spline1d.heapsortdpoints(ref x, ref y, ref w, n);
            
            //
            // Scale X, Y, XC, YC
            //
            lsfitscalexy(ref x, ref y, ref w, n, ref xc, ref yc, dc, 0, ref xa, ref xb, ref sa, ref sb, ref xoriginal, ref yoriginal);
            
            //
            // Allocate space
            //
            fmatrix = new double[n, m];
            amatrix = new double[m, m];
            d2matrix = new double[m, m];
            bx = new double[m];
            by = new double[m];
            fcolumn = new double[n];
            nmatrix = new double[m, m];
            rightpart = new double[m];
            tmp0 = new double[Math.Max(m, n)];
            c = new double[m];
            
            //
            // Fill:
            // * FMatrix by values of basis functions
            // * TmpAMatrix by second derivatives of I-th function at J-th point
            // * CMatrix by constraints
            //
            fdmax = 0;
            for(b=0; b<=m-1; b++)
            {
                
                //
                // Prepare I-th basis function
                //
                for(j=0; j<=m-1; j++)
                {
                    bx[j] = (double)(2*j)/(double)(m-1)-1;
                    by[j] = 0;
                }
                by[b] = 1;
                spline1d.spline1dgriddiff2cubic(bx, by, m, 2, 0.0, 2, 0.0, ref bd1, ref bd2);
                spline1d.spline1dbuildcubic(bx, by, m, 2, 0.0, 2, 0.0, bs);
                
                //
                // Calculate B-th column of FMatrix
                // Update FDMax (maximum column norm)
                //
                spline1d.spline1dconvcubic(bx, by, m, 2, 0.0, 2, 0.0, x, n, ref fcolumn);
                for(i_=0; i_<=n-1;i_++)
                {
                    fmatrix[i_,b] = fcolumn[i_];
                }
                v = 0;
                for(i=0; i<=n-1; i++)
                {
                    v = v+math.sqr(w[i]*fcolumn[i]);
                }
                fdmax = Math.Max(fdmax, v);
                
                //
                // Fill temporary with second derivatives of basis function
                //
                for(i_=0; i_<=m-1;i_++)
                {
                    d2matrix[b,i_] = bd2[i_];
                }
            }
            
            //
            // * calculate penalty matrix A
            // * calculate max of diagonal elements of A
            // * calculate PDecay - coefficient before penalty matrix
            //
            for(i=0; i<=m-1; i++)
            {
                for(j=i; j<=m-1; j++)
                {
                    
                    //
                    // calculate integral(B_i''*B_j'') where B_i and B_j are
                    // i-th and j-th basis splines.
                    // B_i and B_j are piecewise linear functions.
                    //
                    v = 0;
                    for(b=0; b<=m-2; b++)
                    {
                        fa = d2matrix[i,b];
                        fb = d2matrix[i,b+1];
                        ga = d2matrix[j,b];
                        gb = d2matrix[j,b+1];
                        v = v+(bx[b+1]-bx[b])*(fa*ga+(fa*(gb-ga)+ga*(fb-fa))/2+(fb-fa)*(gb-ga)/3);
                    }
                    amatrix[i,j] = v;
                    amatrix[j,i] = v;
                }
            }
            admax = 0;
            for(i=0; i<=m-1; i++)
            {
                admax = Math.Max(admax, Math.Abs(amatrix[i,i]));
            }
            pdecay = lambdav*fdmax/admax;
            
            //
            // Calculate TDecay for Tikhonov regularization
            //
            tdecay = fdmax*(1+pdecay)*10*math.machineepsilon;
            
            //
            // Prepare system
            //
            // NOTE: FMatrix is spoiled during this process
            //
            for(i=0; i<=n-1; i++)
            {
                v = w[i];
                for(i_=0; i_<=m-1;i_++)
                {
                    fmatrix[i,i_] = v*fmatrix[i,i_];
                }
            }
            ablas.rmatrixgemm(m, m, n, 1.0, fmatrix, 0, 0, 1, fmatrix, 0, 0, 0, 0.0, nmatrix, 0, 0);
            for(i=0; i<=m-1; i++)
            {
                for(j=0; j<=m-1; j++)
                {
                    nmatrix[i,j] = nmatrix[i,j]+pdecay*amatrix[i,j];
                }
            }
            for(i=0; i<=m-1; i++)
            {
                nmatrix[i,i] = nmatrix[i,i]+tdecay;
            }
            for(i=0; i<=m-1; i++)
            {
                rightpart[i] = 0;
            }
            for(i=0; i<=n-1; i++)
            {
                v = y[i]*w[i];
                for(i_=0; i_<=m-1;i_++)
                {
                    rightpart[i_] = rightpart[i_] + v*fmatrix[i,i_];
                }
            }
            
            //
            // Solve system
            //
            if( !trfac.spdmatrixcholesky(ref nmatrix, m, true) )
            {
                info = -4;
                return;
            }
            fbls.fblscholeskysolve(nmatrix, 1.0, m, true, ref rightpart, ref tmp0);
            for(i_=0; i_<=m-1;i_++)
            {
                c[i_] = rightpart[i_];
            }
            
            //
            // add nodes to force linearity outside of the fitting interval
            //
            spline1d.spline1dgriddiffcubic(bx, c, m, 2, 0.0, 2, 0.0, ref bd1);
            tx = new double[m+2];
            ty = new double[m+2];
            td = new double[m+2];
            i1_ = (0) - (1);
            for(i_=1; i_<=m;i_++)
            {
                tx[i_] = bx[i_+i1_];
            }
            i1_ = (0) - (1);
            for(i_=1; i_<=m;i_++)
            {
                ty[i_] = rightpart[i_+i1_];
            }
            i1_ = (0) - (1);
            for(i_=1; i_<=m;i_++)
            {
                td[i_] = bd1[i_+i1_];
            }
            tx[0] = tx[1]-(tx[2]-tx[1]);
            ty[0] = ty[1]-td[1]*(tx[2]-tx[1]);
            td[0] = td[1];
            tx[m+1] = tx[m]+(tx[m]-tx[m-1]);
            ty[m+1] = ty[m]+td[m]*(tx[m]-tx[m-1]);
            td[m+1] = td[m];
            spline1d.spline1dbuildhermite(tx, ty, td, m+2, s);
            spline1d.spline1dlintransx(s, 2/(xb-xa), -((xa+xb)/(xb-xa)));
            spline1d.spline1dlintransy(s, sb-sa, sa);
            info = 1;
            
            //
            // Fill report
            //
            rep.rmserror = 0;
            rep.avgerror = 0;
            rep.avgrelerror = 0;
            rep.maxerror = 0;
            relcnt = 0;
            spline1d.spline1dconvcubic(bx, rightpart, m, 2, 0.0, 2, 0.0, x, n, ref fcolumn);
            for(i=0; i<=n-1; i++)
            {
                v = (sb-sa)*fcolumn[i]+sa;
                rep.rmserror = rep.rmserror+math.sqr(v-yoriginal[i]);
                rep.avgerror = rep.avgerror+Math.Abs(v-yoriginal[i]);
                if( (double)(yoriginal[i])!=(double)(0) )
                {
                    rep.avgrelerror = rep.avgrelerror+Math.Abs(v-yoriginal[i])/Math.Abs(yoriginal[i]);
                    relcnt = relcnt+1;
                }
                rep.maxerror = Math.Max(rep.maxerror, Math.Abs(v-yoriginal[i]));
            }
            rep.rmserror = Math.Sqrt(rep.rmserror/n);
            rep.avgerror = rep.avgerror/n;
            if( (double)(relcnt)!=(double)(0) )
            {
                rep.avgrelerror = rep.avgrelerror/relcnt;
            }
        }
Ejemplo n.º 8
0
        /*************************************************************************
        Weighted  fitting  by Hermite spline,  with constraints on function values
        or first derivatives.

        Equidistant grid with M nodes on [min(x,xc),max(x,xc)] is  used  to  build
        basis functions. Basis functions are Hermite splines.  Small  regularizing
        term is used when solving constrained tasks (to improve stability).

        Task is linear, so linear least squares solver is used. Complexity of this
        computational scheme is O(N*M^2), mostly dominated by least squares solver

        SEE ALSO
            Spline1DFitCubicWC()    -   fitting by Cubic splines (less flexible,
                                        more smooth)
            Spline1DFitHermite()    -   "lightweight" Hermite fitting, without
                                        invididual weights and constraints

        INPUT PARAMETERS:
            X   -   points, array[0..N-1].
            Y   -   function values, array[0..N-1].
            W   -   weights, array[0..N-1]
                    Each summand in square  sum  of  approximation deviations from
                    given  values  is  multiplied  by  the square of corresponding
                    weight. Fill it by 1's if you don't  want  to  solve  weighted
                    task.
            N   -   number of points (optional):
                    * N>0
                    * if given, only first N elements of X/Y/W are processed
                    * if not given, automatically determined from X/Y/W sizes
            XC  -   points where spline values/derivatives are constrained,
                    array[0..K-1].
            YC  -   values of constraints, array[0..K-1]
            DC  -   array[0..K-1], types of constraints:
                    * DC[i]=0   means that S(XC[i])=YC[i]
                    * DC[i]=1   means that S'(XC[i])=YC[i]
                    SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS
            K   -   number of constraints (optional):
                    * 0<=K<M.
                    * K=0 means no constraints (XC/YC/DC are not used)
                    * if given, only first K elements of XC/YC/DC are used
                    * if not given, automatically determined from XC/YC/DC
            M   -   number of basis functions (= 2 * number of nodes),
                    M>=4,
                    M IS EVEN!

        OUTPUT PARAMETERS:
            Info-   same format as in LSFitLinearW() subroutine:
                    * Info>0    task is solved
                    * Info<=0   an error occured:
                                -4 means inconvergence of internal SVD
                                -3 means inconsistent constraints
                                -2 means odd M was passed (which is not supported)
                                -1 means another errors in parameters passed
                                   (N<=0, for example)
            S   -   spline interpolant.
            Rep -   report, same format as in LSFitLinearW() subroutine.
                    Following fields are set:
                    * RMSError      rms error on the (X,Y).
                    * AvgError      average error on the (X,Y).
                    * AvgRelError   average relative error on the non-zero Y
                    * MaxError      maximum error
                                    NON-WEIGHTED ERRORS ARE CALCULATED

        IMPORTANT:
            this subroitine doesn't calculate task's condition number for K<>0.

        IMPORTANT:
            this subroitine supports only even M's


        ORDER OF POINTS

        Subroutine automatically sorts points, so caller may pass unsorted array.

        SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES:

        Setting constraints can lead  to undesired  results,  like ill-conditioned
        behavior, or inconsistency being detected. From the other side,  it allows
        us to improve quality of the fit. Here we summarize  our  experience  with
        constrained regression splines:
        * excessive constraints can be inconsistent. Splines are  piecewise  cubic
          functions, and it is easy to create an example, where  large  number  of
          constraints  concentrated  in  small  area will result in inconsistency.
          Just because spline is not flexible enough to satisfy all of  them.  And
          same constraints spread across the  [min(x),max(x)]  will  be  perfectly
          consistent.
        * the more evenly constraints are spread across [min(x),max(x)],  the more
          chances that they will be consistent
        * the  greater  is  M (given  fixed  constraints),  the  more chances that
          constraints will be consistent
        * in the general case, consistency of constraints is NOT GUARANTEED.
        * in the several special cases, however, we can guarantee consistency.
        * one of this cases is  M>=4  and   constraints  on   the  function  value
          (AND/OR its derivative) at the interval boundaries.
        * another special case is M>=4  and  ONE  constraint on the function value
          (OR, BUT NOT AND, derivative) anywhere in [min(x),max(x)]

        Our final recommendation is to use constraints  WHEN  AND  ONLY  when  you
        can't solve your task without them. Anything beyond  special  cases  given
        above is not guaranteed and may result in inconsistency.

          -- ALGLIB PROJECT --
             Copyright 18.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline1dfithermitewc(double[] x,
            double[] y,
            double[] w,
            int n,
            double[] xc,
            double[] yc,
            int[] dc,
            int k,
            int m,
            ref int info,
            spline1d.spline1dinterpolant s,
            spline1dfitreport rep)
        {
            int i = 0;

            info = 0;

            alglib.ap.assert(n>=1, "Spline1DFitHermiteWC: N<1!");
            alglib.ap.assert(m>=4, "Spline1DFitHermiteWC: M<4!");
            alglib.ap.assert(m%2==0, "Spline1DFitHermiteWC: M is odd!");
            alglib.ap.assert(k>=0, "Spline1DFitHermiteWC: K<0!");
            alglib.ap.assert(k<m, "Spline1DFitHermiteWC: K>=M!");
            alglib.ap.assert(alglib.ap.len(x)>=n, "Spline1DFitHermiteWC: Length(X)<N!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "Spline1DFitHermiteWC: Length(Y)<N!");
            alglib.ap.assert(alglib.ap.len(w)>=n, "Spline1DFitHermiteWC: Length(W)<N!");
            alglib.ap.assert(alglib.ap.len(xc)>=k, "Spline1DFitHermiteWC: Length(XC)<K!");
            alglib.ap.assert(alglib.ap.len(yc)>=k, "Spline1DFitHermiteWC: Length(YC)<K!");
            alglib.ap.assert(alglib.ap.len(dc)>=k, "Spline1DFitHermiteWC: Length(DC)<K!");
            alglib.ap.assert(apserv.isfinitevector(x, n), "Spline1DFitHermiteWC: X contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "Spline1DFitHermiteWC: Y contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(w, n), "Spline1DFitHermiteWC: Y contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(xc, k), "Spline1DFitHermiteWC: X contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(yc, k), "Spline1DFitHermiteWC: Y contains infinite or NAN values!");
            for(i=0; i<=k-1; i++)
            {
                alglib.ap.assert(dc[i]==0 || dc[i]==1, "Spline1DFitHermiteWC: DC[i] is neither 0 or 1!");
            }
            spline1dfitinternal(1, x, y, w, n, xc, yc, dc, k, m, ref info, s, rep);
        }
Ejemplo n.º 9
0
        /*************************************************************************
        Fitting by penalized cubic spline.

        Equidistant grid with M nodes on [min(x,xc),max(x,xc)] is  used  to  build
        basis functions. Basis functions are cubic splines with  natural  boundary
        conditions. Problem is regularized by  adding non-linearity penalty to the
        usual least squares penalty function:

            S(x) = arg min { LS + P }, where
            LS   = SUM { w[i]^2*(y[i] - S(x[i]))^2 } - least squares penalty
            P    = C*10^rho*integral{ S''(x)^2*dx } - non-linearity penalty
            rho  - tunable constant given by user
            C    - automatically determined scale parameter,
                   makes penalty invariant with respect to scaling of X, Y, W.

        INPUT PARAMETERS:
            X   -   points, array[0..N-1].
            Y   -   function values, array[0..N-1].
            N   -   number of points (optional):
                    * N>0
                    * if given, only first N elements of X/Y are processed
                    * if not given, automatically determined from X/Y sizes
            M   -   number of basis functions ( = number_of_nodes), M>=4.
            Rho -   regularization  constant  passed   by   user.   It   penalizes
                    nonlinearity in the regression spline. It  is  logarithmically
                    scaled,  i.e.  actual  value  of  regularization  constant  is
                    calculated as 10^Rho. It is automatically scaled so that:
                    * Rho=2.0 corresponds to moderate amount of nonlinearity
                    * generally, it should be somewhere in the [-8.0,+8.0]
                    If you do not want to penalize nonlineary,
                    pass small Rho. Values as low as -15 should work.

        OUTPUT PARAMETERS:
            Info-   same format as in LSFitLinearWC() subroutine.
                    * Info>0    task is solved
                    * Info<=0   an error occured:
                                -4 means inconvergence of internal SVD or
                                   Cholesky decomposition; problem may be
                                   too ill-conditioned (very rare)
            S   -   spline interpolant.
            Rep -   Following fields are set:
                    * RMSError      rms error on the (X,Y).
                    * AvgError      average error on the (X,Y).
                    * AvgRelError   average relative error on the non-zero Y
                    * MaxError      maximum error
                                    NON-WEIGHTED ERRORS ARE CALCULATED

        IMPORTANT:
            this subroitine doesn't calculate task's condition number for K<>0.

        NOTE 1: additional nodes are added to the spline outside  of  the  fitting
        interval to force linearity when x<min(x,xc) or x>max(x,xc).  It  is  done
        for consistency - we penalize non-linearity  at [min(x,xc),max(x,xc)],  so
        it is natural to force linearity outside of this interval.

        NOTE 2: function automatically sorts points,  so  caller may pass unsorted
        array.

          -- ALGLIB PROJECT --
             Copyright 18.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline1dfitpenalized(double[] x,
            double[] y,
            int n,
            int m,
            double rho,
            ref int info,
            spline1d.spline1dinterpolant s,
            spline1dfitreport rep)
        {
            double[] w = new double[0];
            int i = 0;

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            info = 0;

            alglib.ap.assert(n>=1, "Spline1DFitPenalized: N<1!");
            alglib.ap.assert(m>=4, "Spline1DFitPenalized: M<4!");
            alglib.ap.assert(alglib.ap.len(x)>=n, "Spline1DFitPenalized: Length(X)<N!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "Spline1DFitPenalized: Length(Y)<N!");
            alglib.ap.assert(apserv.isfinitevector(x, n), "Spline1DFitPenalized: X contains infinite or NAN values!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "Spline1DFitPenalized: Y contains infinite or NAN values!");
            alglib.ap.assert(math.isfinite(rho), "Spline1DFitPenalized: Rho is infinite!");
            w = new double[n];
            for(i=0; i<=n-1; i++)
            {
                w[i] = 1;
            }
            spline1dfitpenalizedw(x, y, w, n, m, rho, ref info, s, rep);
        }
Ejemplo n.º 10
0
 /*************************************************************************
 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code.
 *************************************************************************/
 public static void _pexec_spline1dfithermite(double[] x,
     double[] y,
     int n,
     int m,
     ref int info,
     spline1d.spline1dinterpolant s,
     spline1dfitreport rep)
 {
     spline1dfithermite(x,y,n,m,ref info,s,rep);
 }
Ejemplo n.º 11
0
 /*************************************************************************
 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code.
 *************************************************************************/
 public static void _pexec_spline1dfithermitewc(double[] x,
     double[] y,
     double[] w,
     int n,
     double[] xc,
     double[] yc,
     int[] dc,
     int k,
     int m,
     ref int info,
     spline1d.spline1dinterpolant s,
     spline1dfitreport rep)
 {
     spline1dfithermitewc(x,y,w,n,xc,yc,dc,k,m,ref info,s,rep);
 }
Ejemplo n.º 12
0
 /*************************************************************************
 Single-threaded stub. HPC ALGLIB replaces it by multithreaded code.
 *************************************************************************/
 public static void _pexec_spline1dfitpenalizedw(double[] x,
     double[] y,
     double[] w,
     int n,
     int m,
     double rho,
     ref int info,
     spline1d.spline1dinterpolant s,
     spline1dfitreport rep)
 {
     spline1dfitpenalizedw(x,y,w,n,m,rho,ref info,s,rep);
 }
Ejemplo n.º 13
0
 public spline1dfitreport(spline1d.spline1dfitreport obj)
 {
     _innerobj = obj;
 }