/*************************************************************************
        *  This subroutine calculates the value of the bilinear or bicubic spline  at
        *  the given point X.
        *
        *  Input parameters:
        *   C   -   coefficients table.
        *           Built by BuildBilinearSpline or BuildBicubicSpline.
        *   X, Y-   point
        *
        *  Result:
        *   S(x,y)
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static double spline2dcalc(ref spline2dinterpolant c,
                                          double x,
                                          double y)
        {
            double result = 0;
            double v      = 0;
            double vx     = 0;
            double vy     = 0;
            double vxy    = 0;

            spline2ddiff(ref c, x, y, ref v, ref vx, ref vy, ref vxy);
            result = v;
            return(result);
        }
        /*************************************************************************
        *  This subroutine makes the copy of the spline model.
        *
        *  Input parameters:
        *   C   -   spline interpolant
        *
        *  Output parameters:
        *   CC  -   spline copy
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 29.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dcopy(ref spline2dinterpolant c,
                                        ref spline2dinterpolant cc)
        {
            int n  = 0;
            int i_ = 0;

            System.Diagnostics.Debug.Assert(c.k == 1 | c.k == 3, "Spline2DCopy: incorrect C!");
            cc.k = c.k;
            n    = (int)Math.Round(c.c[0]);
            cc.c = new double[n];
            for (i_ = 0; i_ <= n - 1; i_++)
            {
                cc.c[i_] = c.c[i_];
            }
        }
        /*************************************************************************
        *  Unserialization of the spline interpolant
        *
        *  INPUT PARAMETERS:
        *   RA  -   array of real numbers which contains interpolant,
        *
        *  OUTPUT PARAMETERS:
        *   B   -   spline interpolant
        *
        *  -- ALGLIB --
        *    Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dunserialize(ref double[] ra,
                                               ref spline2dinterpolant c)
        {
            int clen = 0;
            int i_   = 0;
            int i1_  = 0;

            System.Diagnostics.Debug.Assert((int)Math.Round(ra[1]) == spline2dvnum, "Spline2DUnserialize: corrupted array!");
            c.k  = (int)Math.Round(ra[2]);
            clen = (int)Math.Round(ra[3]);
            c.c  = new double[clen];
            i1_  = (3) - (0);
            for (i_ = 0; i_ <= clen - 1; i_++)
            {
                c.c[i_] = ra[i_ + i1_];
            }
        }
        /*************************************************************************
        *  This subroutine performs linear transformation of the spline.
        *
        *  Input parameters:
        *   C   -   spline interpolant.
        *   A, B-   transformation coefficients: S2(x,y) = A*S(x,y) + B
        *
        *  Output parameters:
        *   C   -   transformed spline
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 30.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dlintransf(ref spline2dinterpolant c,
                                             double a,
                                             double b)
        {
            int i = 0;
            int j = 0;
            int n = 0;
            int m = 0;

            double[] x = new double[0];
            double[] y = new double[0];
            double[,] f = new double[0, 0];
            int typec = 0;

            typec = (int)Math.Round(c.c[1]);
            System.Diagnostics.Debug.Assert(typec == -3 | typec == -1, "Spline2DLinTransXY: incorrect C!");
            n = (int)Math.Round(c.c[2]);
            m = (int)Math.Round(c.c[3]);
            x = new double[n - 1 + 1];
            y = new double[m - 1 + 1];
            f = new double[m - 1 + 1, n - 1 + 1];
            for (j = 0; j <= n - 1; j++)
            {
                x[j] = c.c[4 + j];
            }
            for (i = 0; i <= m - 1; i++)
            {
                y[i] = c.c[4 + n + i];
            }
            for (i = 0; i <= m - 1; i++)
            {
                for (j = 0; j <= n - 1; j++)
                {
                    f[i, j] = a * c.c[4 + n + m + i * n + j] + b;
                }
            }
            if (typec == -3)
            {
                spline2dbuildbicubic(x, y, f, m, n, ref c);
            }
            if (typec == -1)
            {
                spline2dbuildbilinear(x, y, f, m, n, ref c);
            }
        }
        /*************************************************************************
        *  Serialization of the spline interpolant
        *
        *  INPUT PARAMETERS:
        *   B   -   spline interpolant
        *
        *  OUTPUT PARAMETERS:
        *   RA      -   array of real numbers which contains interpolant,
        *               array[0..RLen-1]
        *   RLen    -   RA lenght
        *
        *  -- ALGLIB --
        *    Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dserialize(ref spline2dinterpolant c,
                                             ref double[] ra,
                                             ref int ralen)
        {
            int clen = 0;
            int i_   = 0;
            int i1_  = 0;

            System.Diagnostics.Debug.Assert(c.k == 1 | c.k == 3, "Spline2DSerialize: incorrect C!");
            clen  = (int)Math.Round(c.c[0]);
            ralen = 3 + clen;
            ra    = new double[ralen];
            ra[0] = ralen;
            ra[1] = spline2dvnum;
            ra[2] = c.k;
            i1_   = (0) - (3);
            for (i_ = 3; i_ <= 3 + clen - 1; i_++)
            {
                ra[i_] = c.c[i_ + i1_];
            }
        }
示例#6
0
        /*************************************************************************
        This subroutine builds bicubic vector-valued spline.

        Input parameters:
            X   -   spline abscissas, array[0..N-1]
            Y   -   spline ordinates, array[0..M-1]
            F   -   function values, array[0..M*N*D-1]:
                    * first D elements store D values at (X[0],Y[0])
                    * next D elements store D values at (X[1],Y[0])
                    * general form - D function values at (X[i],Y[j]) are stored
                      at F[D*(J*N+I)...D*(J*N+I)+D-1].
            M,N -   grid size, M>=2, N>=2
            D   -   vector dimension, D>=1

        Output parameters:
            C   -   spline interpolant

          -- ALGLIB PROJECT --
             Copyright 16.04.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dbuildbicubicv(double[] x,
            int n,
            double[] y,
            int m,
            double[] f,
            int d,
            spline2dinterpolant c)
        {
            double[,] tf = new double[0,0];
            double[,] dx = new double[0,0];
            double[,] dy = new double[0,0];
            double[,] dxy = new double[0,0];
            double t = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int di = 0;

            f = (double[])f.Clone();

            alglib.ap.assert(n>=2, "Spline2DBuildBicubicV: N is less than 2");
            alglib.ap.assert(m>=2, "Spline2DBuildBicubicV: M is less than 2");
            alglib.ap.assert(d>=1, "Spline2DBuildBicubicV: invalid argument D (D<1)");
            alglib.ap.assert(alglib.ap.len(x)>=n && alglib.ap.len(y)>=m, "Spline2DBuildBicubicV: length of X or Y is too short (Length(X/Y)<N/M)");
            alglib.ap.assert(apserv.isfinitevector(x, n) && apserv.isfinitevector(y, m), "Spline2DBuildBicubicV: X or Y contains NaN or Infinite value");
            k = n*m*d;
            alglib.ap.assert(alglib.ap.len(f)>=k, "Spline2DBuildBicubicV: length of F is too short (Length(F)<N*M*D)");
            alglib.ap.assert(apserv.isfinitevector(f, k), "Spline2DBuildBicubicV: F contains NaN or Infinite value");
            
            //
            // Fill interpolant:
            //  F[0]...F[N*M*D-1]:
            //      f(i,j) table. f(0,0), f(0, 1), f(0,2) and so on...
            //  F[N*M*D]...F[2*N*M*D-1]:
            //      df(i,j)/dx table.
            //  F[2*N*M*D]...F[3*N*M*D-1]:
            //      df(i,j)/dy table.
            //  F[3*N*M*D]...F[4*N*M*D-1]:
            //      d2f(i,j)/dxdy table.
            //
            c.k = 3;
            c.d = d;
            c.n = n;
            c.m = m;
            c.stype = -3;
            k = 4*k;
            c.x = new double[c.n];
            c.y = new double[c.m];
            c.f = new double[k];
            tf = new double[c.m, c.n];
            for(i=0; i<=c.n-1; i++)
            {
                c.x[i] = x[i];
            }
            for(i=0; i<=c.m-1; i++)
            {
                c.y[i] = y[i];
            }
            
            //
            // Sort points
            //
            for(j=0; j<=c.n-1; j++)
            {
                k = j;
                for(i=j+1; i<=c.n-1; i++)
                {
                    if( (double)(c.x[i])<(double)(c.x[k]) )
                    {
                        k = i;
                    }
                }
                if( k!=j )
                {
                    for(i=0; i<=c.m-1; i++)
                    {
                        for(di=0; di<=c.d-1; di++)
                        {
                            t = f[c.d*(i*c.n+j)+di];
                            f[c.d*(i*c.n+j)+di] = f[c.d*(i*c.n+k)+di];
                            f[c.d*(i*c.n+k)+di] = t;
                        }
                    }
                    t = c.x[j];
                    c.x[j] = c.x[k];
                    c.x[k] = t;
                }
            }
            for(i=0; i<=c.m-1; i++)
            {
                k = i;
                for(j=i+1; j<=c.m-1; j++)
                {
                    if( (double)(c.y[j])<(double)(c.y[k]) )
                    {
                        k = j;
                    }
                }
                if( k!=i )
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        for(di=0; di<=c.d-1; di++)
                        {
                            t = f[c.d*(i*c.n+j)+di];
                            f[c.d*(i*c.n+j)+di] = f[c.d*(k*c.n+j)+di];
                            f[c.d*(k*c.n+j)+di] = t;
                        }
                    }
                    t = c.y[i];
                    c.y[i] = c.y[k];
                    c.y[k] = t;
                }
            }
            for(di=0; di<=c.d-1; di++)
            {
                for(i=0; i<=c.m-1; i++)
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        tf[i,j] = f[c.d*(i*c.n+j)+di];
                    }
                }
                bicubiccalcderivatives(tf, c.x, c.y, c.m, c.n, ref dx, ref dy, ref dxy);
                for(i=0; i<=c.m-1; i++)
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        k = c.d*(i*c.n+j)+di;
                        c.f[k] = tf[i,j];
                        c.f[c.n*c.m*c.d+k] = dx[i,j];
                        c.f[2*c.n*c.m*c.d+k] = dy[i,j];
                        c.f[3*c.n*c.m*c.d+k] = dxy[i,j];
                    }
                }
            }
        }
示例#7
0
            /*************************************************************************
            This subroutine builds bicubic spline coefficients table.

            Input parameters:
                X   -   spline abscissas, array[0..N-1]
                Y   -   spline ordinates, array[0..M-1]
                F   -   function values, array[0..M-1,0..N-1]
                M,N -   grid size, M>=2, N>=2

            Output parameters:
                C   -   spline interpolant

              -- ALGLIB PROJECT --
                 Copyright 05.07.2007 by Bochkanov Sergey
            *************************************************************************/
            public static void spline2dbuildbicubic(double[] x,
                double[] y,
                double[,] f,
                int m,
                int n,
                spline2dinterpolant c) {
                int i = 0;
                int j = 0;
                int k = 0;
                int tblsize = 0;
                int shift = 0;
                double t = 0;
                double[,] dx = new double[0, 0];
                double[,] dy = new double[0, 0];
                double[,] dxy = new double[0, 0];

                x = (double[])x.Clone();
                y = (double[])y.Clone();
                f = (double[,])f.Clone();

                ap.assert(n >= 2 & m >= 2, "BuildBicubicSpline: N<2 or M<2!");

                //
                // Sort points
                //
                for(j = 0; j <= n - 1; j++) {
                    k = j;
                    for(i = j + 1; i <= n - 1; i++) {
                        if((double)(x[i]) < (double)(x[k])) {
                            k = i;
                        }
                    }
                    if(k != j) {
                        for(i = 0; i <= m - 1; i++) {
                            t = f[i, j];
                            f[i, j] = f[i, k];
                            f[i, k] = t;
                        }
                        t = x[j];
                        x[j] = x[k];
                        x[k] = t;
                    }
                }
                for(i = 0; i <= m - 1; i++) {
                    k = i;
                    for(j = i + 1; j <= m - 1; j++) {
                        if((double)(y[j]) < (double)(y[k])) {
                            k = j;
                        }
                    }
                    if(k != i) {
                        for(j = 0; j <= n - 1; j++) {
                            t = f[i, j];
                            f[i, j] = f[k, j];
                            f[k, j] = t;
                        }
                        t = y[i];
                        y[i] = y[k];
                        y[k] = t;
                    }
                }

                //
                // Fill C:
                //  C[0]            -   length(C)
                //  C[1]            -   type(C):
                //                      -1 = bilinear interpolant
                //                           (see BuildBilinearInterpolant)
                //                      -3 = general cubic spline
                //  C[2]:
                //      N (x count)
                //  C[3]:
                //      M (y count)
                //  C[4]...C[4+N-1]:
                //      x[i], i = 0...N-1
                //  C[4+N]...C[4+N+M-1]:
                //      y[i], i = 0...M-1
                //  C[4+N+M]...C[4+N+M+(N*M-1)]:
                //      f(i,j) table. f(0,0), f(0, 1), f(0,2) and so on...
                //  C[4+N+M+N*M]...C[4+N+M+(2*N*M-1)]:
                //      df(i,j)/dx table.
                //  C[4+N+M+2*N*M]...C[4+N+M+(3*N*M-1)]:
                //      df(i,j)/dy table.
                //  C[4+N+M+3*N*M]...C[4+N+M+(4*N*M-1)]:
                //      d2f(i,j)/dxdy table.
                //
                c.k = 3;
                tblsize = 4 + n + m + 4 * n * m;
                c.c = new double[tblsize - 1 + 1];
                c.c[0] = tblsize;
                c.c[1] = -3;
                c.c[2] = n;
                c.c[3] = m;
                for(i = 0; i <= n - 1; i++) {
                    c.c[4 + i] = x[i];
                }
                for(i = 0; i <= m - 1; i++) {
                    c.c[4 + n + i] = y[i];
                }
                bicubiccalcderivatives(f, x, y, m, n, ref dx, ref dy, ref dxy);
                for(i = 0; i <= m - 1; i++) {
                    for(j = 0; j <= n - 1; j++) {
                        shift = i * n + j;
                        c.c[4 + n + m + shift] = f[i, j];
                        c.c[4 + n + m + n * m + shift] = dx[i, j];
                        c.c[4 + n + m + 2 * n * m + shift] = dy[i, j];
                        c.c[4 + n + m + 3 * n * m + shift] = dxy[i, j];
                    }
                }
            }
        /*************************************************************************
        *  This subroutine unpacks two-dimensional spline into the coefficients table
        *
        *  Input parameters:
        *   C   -   spline interpolant.
        *
        *  Result:
        *   M, N-   grid size (x-axis and y-axis)
        *   Tbl -   coefficients table, unpacked format,
        *           [0..(N-1)*(M-1)-1, 0..19].
        *           For I = 0...M-2, J=0..N-2:
        *               K =  I*(N-1)+J
        *               Tbl[K,0] = X[j]
        *               Tbl[K,1] = X[j+1]
        *               Tbl[K,2] = Y[i]
        *               Tbl[K,3] = Y[i+1]
        *               Tbl[K,4] = C00
        *               Tbl[K,5] = C01
        *               Tbl[K,6] = C02
        *               Tbl[K,7] = C03
        *               Tbl[K,8] = C10
        *               Tbl[K,9] = C11
        *               ...
        *               Tbl[K,19] = C33
        *           On each grid square spline is equals to:
        *               S(x) = SUM(c[i,j]*(x^i)*(y^j), i=0..3, j=0..3)
        *               t = x-x[j]
        *               u = y-y[i]
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 29.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dunpack(ref spline2dinterpolant c,
                                          ref int m,
                                          ref int n,
                                          ref double[,] tbl)
        {
            int    i     = 0;
            int    j     = 0;
            int    ci    = 0;
            int    cj    = 0;
            int    k     = 0;
            int    p     = 0;
            int    shift = 0;
            int    s1    = 0;
            int    s2    = 0;
            int    s3    = 0;
            int    s4    = 0;
            int    sf    = 0;
            int    sfx   = 0;
            int    sfy   = 0;
            int    sfxy  = 0;
            double y1    = 0;
            double y2    = 0;
            double y3    = 0;
            double y4    = 0;
            double dt    = 0;
            double du    = 0;

            System.Diagnostics.Debug.Assert((int)Math.Round(c.c[1]) == -3 | (int)Math.Round(c.c[1]) == -1, "SplineUnpack2D: incorrect C!");
            n   = (int)Math.Round(c.c[2]);
            m   = (int)Math.Round(c.c[3]);
            tbl = new double[(n - 1) * (m - 1) - 1 + 1, 19 + 1];

            //
            // Fill
            //
            for (i = 0; i <= m - 2; i++)
            {
                for (j = 0; j <= n - 2; j++)
                {
                    p         = i * (n - 1) + j;
                    tbl[p, 0] = c.c[4 + j];
                    tbl[p, 1] = c.c[4 + j + 1];
                    tbl[p, 2] = c.c[4 + n + i];
                    tbl[p, 3] = c.c[4 + n + i + 1];
                    dt        = 1 / (tbl[p, 1] - tbl[p, 0]);
                    du        = 1 / (tbl[p, 3] - tbl[p, 2]);

                    //
                    // Bilinear interpolation
                    //
                    if ((int)Math.Round(c.c[1]) == -1)
                    {
                        for (k = 4; k <= 19; k++)
                        {
                            tbl[p, k] = 0;
                        }
                        shift                 = 4 + n + m;
                        y1                    = c.c[shift + n * i + j];
                        y2                    = c.c[shift + n * i + (j + 1)];
                        y3                    = c.c[shift + n * (i + 1) + (j + 1)];
                        y4                    = c.c[shift + n * (i + 1) + j];
                        tbl[p, 4]             = y1;
                        tbl[p, 4 + 1 * 4 + 0] = y2 - y1;
                        tbl[p, 4 + 0 * 4 + 1] = y4 - y1;
                        tbl[p, 4 + 1 * 4 + 1] = y3 - y2 - y4 + y1;
                    }

                    //
                    // Bicubic interpolation
                    //
                    if ((int)Math.Round(c.c[1]) == -3)
                    {
                        sf   = 4 + n + m;
                        sfx  = 4 + n + m + n * m;
                        sfy  = 4 + n + m + 2 * n * m;
                        sfxy = 4 + n + m + 3 * n * m;
                        s1   = n * i + j;
                        s2   = n * i + (j + 1);
                        s3   = n * (i + 1) + (j + 1);
                        s4   = n * (i + 1) + j;
                        tbl[p, 4 + 0 * 4 + 0] = +(1 * c.c[sf + s1]);
                        tbl[p, 4 + 0 * 4 + 1] = +(1 * c.c[sfy + s1] / du);
                        tbl[p, 4 + 0 * 4 + 2] = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s4] - 2 * c.c[sfy + s1] / du - 1 * c.c[sfy + s4] / du;
                        tbl[p, 4 + 0 * 4 + 3] = +(2 * c.c[sf + s1]) - 2 * c.c[sf + s4] + 1 * c.c[sfy + s1] / du + 1 * c.c[sfy + s4] / du;
                        tbl[p, 4 + 1 * 4 + 0] = +(1 * c.c[sfx + s1] / dt);
                        tbl[p, 4 + 1 * 4 + 1] = +(1 * c.c[sfxy + s1] / (dt * du));
                        tbl[p, 4 + 1 * 4 + 2] = -(3 * c.c[sfx + s1] / dt) + 3 * c.c[sfx + s4] / dt - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                        tbl[p, 4 + 1 * 4 + 3] = +(2 * c.c[sfx + s1] / dt) - 2 * c.c[sfx + s4] / dt + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                        tbl[p, 4 + 2 * 4 + 0] = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s2] - 2 * c.c[sfx + s1] / dt - 1 * c.c[sfx + s2] / dt;
                        tbl[p, 4 + 2 * 4 + 1] = -(3 * c.c[sfy + s1] / du) + 3 * c.c[sfy + s2] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du);
                        tbl[p, 4 + 2 * 4 + 2] = +(9 * c.c[sf + s1]) - 9 * c.c[sf + s2] + 9 * c.c[sf + s3] - 9 * c.c[sf + s4] + 6 * c.c[sfx + s1] / dt + 3 * c.c[sfx + s2] / dt - 3 * c.c[sfx + s3] / dt - 6 * c.c[sfx + s4] / dt + 6 * c.c[sfy + s1] / du - 6 * c.c[sfy + s2] / du - 3 * c.c[sfy + s3] / du + 3 * c.c[sfy + s4] / du + 4 * c.c[sfxy + s1] / (dt * du) + 2 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 2 * c.c[sfxy + s4] / (dt * du);
                        tbl[p, 4 + 2 * 4 + 3] = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 4 * c.c[sfx + s1] / dt - 2 * c.c[sfx + s2] / dt + 2 * c.c[sfx + s3] / dt + 4 * c.c[sfx + s4] / dt - 3 * c.c[sfy + s1] / du + 3 * c.c[sfy + s2] / du + 3 * c.c[sfy + s3] / du - 3 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 2 * c.c[sfxy + s4] / (dt * du);
                        tbl[p, 4 + 3 * 4 + 0] = +(2 * c.c[sf + s1]) - 2 * c.c[sf + s2] + 1 * c.c[sfx + s1] / dt + 1 * c.c[sfx + s2] / dt;
                        tbl[p, 4 + 3 * 4 + 1] = +(2 * c.c[sfy + s1] / du) - 2 * c.c[sfy + s2] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du);
                        tbl[p, 4 + 3 * 4 + 2] = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 3 * c.c[sfx + s1] / dt - 3 * c.c[sfx + s2] / dt + 3 * c.c[sfx + s3] / dt + 3 * c.c[sfx + s4] / dt - 4 * c.c[sfy + s1] / du + 4 * c.c[sfy + s2] / du + 2 * c.c[sfy + s3] / du - 2 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 2 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                        tbl[p, 4 + 3 * 4 + 3] = +(4 * c.c[sf + s1]) - 4 * c.c[sf + s2] + 4 * c.c[sf + s3] - 4 * c.c[sf + s4] + 2 * c.c[sfx + s1] / dt + 2 * c.c[sfx + s2] / dt - 2 * c.c[sfx + s3] / dt - 2 * c.c[sfx + s4] / dt + 2 * c.c[sfy + s1] / du - 2 * c.c[sfy + s2] / du - 2 * c.c[sfy + s3] / du + 2 * c.c[sfy + s4] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                    }

                    //
                    // Rescale Cij
                    //
                    for (ci = 0; ci <= 3; ci++)
                    {
                        for (cj = 0; cj <= 3; cj++)
                        {
                            tbl[p, 4 + ci * 4 + cj] = tbl[p, 4 + ci * 4 + cj] * Math.Pow(dt, ci) * Math.Pow(du, cj);
                        }
                    }
                }
            }
        }
        /*************************************************************************
        *  This subroutine calculates the value of the bilinear or bicubic spline  at
        *  the given point X and its derivatives.
        *
        *  Input parameters:
        *   C   -   spline interpolant.
        *   X, Y-   point
        *
        *  Output parameters:
        *   F   -   S(x,y)
        *   FX  -   dS(x,y)/dX
        *   FY  -   dS(x,y)/dY
        *   FXY -   d2S(x,y)/dXdY
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2ddiff(ref spline2dinterpolant c,
                                        double x,
                                        double y,
                                        ref double f,
                                        ref double fx,
                                        ref double fy,
                                        ref double fxy)
        {
            int    n      = 0;
            int    m      = 0;
            double t      = 0;
            double dt     = 0;
            double u      = 0;
            double du     = 0;
            int    ix     = 0;
            int    iy     = 0;
            int    l      = 0;
            int    r      = 0;
            int    h      = 0;
            int    shift1 = 0;
            int    s1     = 0;
            int    s2     = 0;
            int    s3     = 0;
            int    s4     = 0;
            int    sf     = 0;
            int    sfx    = 0;
            int    sfy    = 0;
            int    sfxy   = 0;
            double y1     = 0;
            double y2     = 0;
            double y3     = 0;
            double y4     = 0;
            double v      = 0;
            double t0     = 0;
            double t1     = 0;
            double t2     = 0;
            double t3     = 0;
            double u0     = 0;
            double u1     = 0;
            double u2     = 0;
            double u3     = 0;

            System.Diagnostics.Debug.Assert((int)Math.Round(c.c[1]) == -1 | (int)Math.Round(c.c[1]) == -3, "Spline2DDiff: incorrect C!");
            n = (int)Math.Round(c.c[2]);
            m = (int)Math.Round(c.c[3]);

            //
            // Binary search in the [ x[0], ..., x[n-2] ] (x[n-1] is not included)
            //
            l = 4;
            r = 4 + n - 2 + 1;
            while (l != r - 1)
            {
                h = (l + r) / 2;
                if ((double)(c.c[h]) >= (double)(x))
                {
                    r = h;
                }
                else
                {
                    l = h;
                }
            }
            t  = (x - c.c[l]) / (c.c[l + 1] - c.c[l]);
            dt = 1.0 / (c.c[l + 1] - c.c[l]);
            ix = l - 4;

            //
            // Binary search in the [ y[0], ..., y[m-2] ] (y[m-1] is not included)
            //
            l = 4 + n;
            r = 4 + n + (m - 2) + 1;
            while (l != r - 1)
            {
                h = (l + r) / 2;
                if ((double)(c.c[h]) >= (double)(y))
                {
                    r = h;
                }
                else
                {
                    l = h;
                }
            }
            u  = (y - c.c[l]) / (c.c[l + 1] - c.c[l]);
            du = 1.0 / (c.c[l + 1] - c.c[l]);
            iy = l - (4 + n);

            //
            // Prepare F, dF/dX, dF/dY, d2F/dXdY
            //
            f   = 0;
            fx  = 0;
            fy  = 0;
            fxy = 0;

            //
            // Bilinear interpolation
            //
            if ((int)Math.Round(c.c[1]) == -1)
            {
                shift1 = 4 + n + m;
                y1     = c.c[shift1 + n * iy + ix];
                y2     = c.c[shift1 + n * iy + (ix + 1)];
                y3     = c.c[shift1 + n * (iy + 1) + (ix + 1)];
                y4     = c.c[shift1 + n * (iy + 1) + ix];
                f      = (1 - t) * (1 - u) * y1 + t * (1 - u) * y2 + t * u * y3 + (1 - t) * u * y4;
                fx     = (-((1 - u) * y1) + (1 - u) * y2 + u * y3 - u * y4) * dt;
                fy     = (-((1 - t) * y1) - t * y2 + t * y3 + (1 - t) * y4) * du;
                fxy    = (y1 - y2 + y3 - y4) * du * dt;
                return;
            }

            //
            // Bicubic interpolation
            //
            if ((int)Math.Round(c.c[1]) == -3)
            {
                //
                // Prepare info
                //
                t0   = 1;
                t1   = t;
                t2   = AP.Math.Sqr(t);
                t3   = t * t2;
                u0   = 1;
                u1   = u;
                u2   = AP.Math.Sqr(u);
                u3   = u * u2;
                sf   = 4 + n + m;
                sfx  = 4 + n + m + n * m;
                sfy  = 4 + n + m + 2 * n * m;
                sfxy = 4 + n + m + 3 * n * m;
                s1   = n * iy + ix;
                s2   = n * iy + (ix + 1);
                s3   = n * (iy + 1) + (ix + 1);
                s4   = n * (iy + 1) + ix;

                //
                // Calculate
                //
                v   = +(1 * c.c[sf + s1]);
                f   = f + v * t0 * u0;
                v   = +(1 * c.c[sfy + s1] / du);
                f   = f + v * t0 * u1;
                fy  = fy + 1 * v * t0 * u0 * du;
                v   = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s4] - 2 * c.c[sfy + s1] / du - 1 * c.c[sfy + s4] / du;
                f   = f + v * t0 * u2;
                fy  = fy + 2 * v * t0 * u1 * du;
                v   = +(2 * c.c[sf + s1]) - 2 * c.c[sf + s4] + 1 * c.c[sfy + s1] / du + 1 * c.c[sfy + s4] / du;
                f   = f + v * t0 * u3;
                fy  = fy + 3 * v * t0 * u2 * du;
                v   = +(1 * c.c[sfx + s1] / dt);
                f   = f + v * t1 * u0;
                fx  = fx + 1 * v * t0 * u0 * dt;
                v   = +(1 * c.c[sfxy + s1] / (dt * du));
                f   = f + v * t1 * u1;
                fx  = fx + 1 * v * t0 * u1 * dt;
                fy  = fy + 1 * v * t1 * u0 * du;
                fxy = fxy + 1 * v * t0 * u0 * dt * du;
                v   = -(3 * c.c[sfx + s1] / dt) + 3 * c.c[sfx + s4] / dt - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                f   = f + v * t1 * u2;
                fx  = fx + 1 * v * t0 * u2 * dt;
                fy  = fy + 2 * v * t1 * u1 * du;
                fxy = fxy + 2 * v * t0 * u1 * dt * du;
                v   = +(2 * c.c[sfx + s1] / dt) - 2 * c.c[sfx + s4] / dt + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                f   = f + v * t1 * u3;
                fx  = fx + 1 * v * t0 * u3 * dt;
                fy  = fy + 3 * v * t1 * u2 * du;
                fxy = fxy + 3 * v * t0 * u2 * dt * du;
                v   = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s2] - 2 * c.c[sfx + s1] / dt - 1 * c.c[sfx + s2] / dt;
                f   = f + v * t2 * u0;
                fx  = fx + 2 * v * t1 * u0 * dt;
                v   = -(3 * c.c[sfy + s1] / du) + 3 * c.c[sfy + s2] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du);
                f   = f + v * t2 * u1;
                fx  = fx + 2 * v * t1 * u1 * dt;
                fy  = fy + 1 * v * t2 * u0 * du;
                fxy = fxy + 2 * v * t1 * u0 * dt * du;
                v   = +(9 * c.c[sf + s1]) - 9 * c.c[sf + s2] + 9 * c.c[sf + s3] - 9 * c.c[sf + s4] + 6 * c.c[sfx + s1] / dt + 3 * c.c[sfx + s2] / dt - 3 * c.c[sfx + s3] / dt - 6 * c.c[sfx + s4] / dt + 6 * c.c[sfy + s1] / du - 6 * c.c[sfy + s2] / du - 3 * c.c[sfy + s3] / du + 3 * c.c[sfy + s4] / du + 4 * c.c[sfxy + s1] / (dt * du) + 2 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 2 * c.c[sfxy + s4] / (dt * du);
                f   = f + v * t2 * u2;
                fx  = fx + 2 * v * t1 * u2 * dt;
                fy  = fy + 2 * v * t2 * u1 * du;
                fxy = fxy + 4 * v * t1 * u1 * dt * du;
                v   = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 4 * c.c[sfx + s1] / dt - 2 * c.c[sfx + s2] / dt + 2 * c.c[sfx + s3] / dt + 4 * c.c[sfx + s4] / dt - 3 * c.c[sfy + s1] / du + 3 * c.c[sfy + s2] / du + 3 * c.c[sfy + s3] / du - 3 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 2 * c.c[sfxy + s4] / (dt * du);
                f   = f + v * t2 * u3;
                fx  = fx + 2 * v * t1 * u3 * dt;
                fy  = fy + 3 * v * t2 * u2 * du;
                fxy = fxy + 6 * v * t1 * u2 * dt * du;
                v   = +(2 * c.c[sf + s1]) - 2 * c.c[sf + s2] + 1 * c.c[sfx + s1] / dt + 1 * c.c[sfx + s2] / dt;
                f   = f + v * t3 * u0;
                fx  = fx + 3 * v * t2 * u0 * dt;
                v   = +(2 * c.c[sfy + s1] / du) - 2 * c.c[sfy + s2] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du);
                f   = f + v * t3 * u1;
                fx  = fx + 3 * v * t2 * u1 * dt;
                fy  = fy + 1 * v * t3 * u0 * du;
                fxy = fxy + 3 * v * t2 * u0 * dt * du;
                v   = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 3 * c.c[sfx + s1] / dt - 3 * c.c[sfx + s2] / dt + 3 * c.c[sfx + s3] / dt + 3 * c.c[sfx + s4] / dt - 4 * c.c[sfy + s1] / du + 4 * c.c[sfy + s2] / du + 2 * c.c[sfy + s3] / du - 2 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 2 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                f   = f + v * t3 * u2;
                fx  = fx + 3 * v * t2 * u2 * dt;
                fy  = fy + 2 * v * t3 * u1 * du;
                fxy = fxy + 6 * v * t2 * u1 * dt * du;
                v   = +(4 * c.c[sf + s1]) - 4 * c.c[sf + s2] + 4 * c.c[sf + s3] - 4 * c.c[sf + s4] + 2 * c.c[sfx + s1] / dt + 2 * c.c[sfx + s2] / dt - 2 * c.c[sfx + s3] / dt - 2 * c.c[sfx + s4] / dt + 2 * c.c[sfy + s1] / du - 2 * c.c[sfy + s2] / du - 2 * c.c[sfy + s3] / du + 2 * c.c[sfy + s4] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                f   = f + v * t3 * u3;
                fx  = fx + 3 * v * t2 * u3 * dt;
                fy  = fy + 3 * v * t3 * u2 * du;
                fxy = fxy + 9 * v * t2 * u2 * dt * du;
                return;
            }
        }
示例#10
0
        /*************************************************************************
        This subroutine was deprecated in ALGLIB 3.6.0

        We recommend you to switch  to  Spline2DUnpackV(),  which is more flexible
        and accepts its arguments in more convenient order.

          -- ALGLIB PROJECT --
             Copyright 29.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dunpack(spline2dinterpolant c,
            ref int m,
            ref int n,
            ref double[,] tbl)
        {
            int k = 0;
            int p = 0;
            int ci = 0;
            int cj = 0;
            int s1 = 0;
            int s2 = 0;
            int s3 = 0;
            int s4 = 0;
            int sfx = 0;
            int sfy = 0;
            int sfxy = 0;
            double y1 = 0;
            double y2 = 0;
            double y3 = 0;
            double y4 = 0;
            double dt = 0;
            double du = 0;
            int i = 0;
            int j = 0;

            m = 0;
            n = 0;
            tbl = new double[0,0];

            alglib.ap.assert(c.stype==-3 || c.stype==-1, "Spline2DUnpack: incorrect C (incorrect parameter C.SType)");
            if( c.d!=1 )
            {
                n = 0;
                m = 0;
                return;
            }
            n = c.n;
            m = c.m;
            tbl = new double[(n-1)*(m-1), 20];
            sfx = n*m;
            sfy = 2*n*m;
            sfxy = 3*n*m;
            
            //
            // Fill
            //
            for(i=0; i<=m-2; i++)
            {
                for(j=0; j<=n-2; j++)
                {
                    p = i*(n-1)+j;
                    tbl[p,0] = c.x[j];
                    tbl[p,1] = c.x[j+1];
                    tbl[p,2] = c.y[i];
                    tbl[p,3] = c.y[i+1];
                    dt = 1/(tbl[p,1]-tbl[p,0]);
                    du = 1/(tbl[p,3]-tbl[p,2]);
                    
                    //
                    // Bilinear interpolation
                    //
                    if( c.stype==-1 )
                    {
                        for(k=4; k<=19; k++)
                        {
                            tbl[p,k] = 0;
                        }
                        y1 = c.f[n*i+j];
                        y2 = c.f[n*i+(j+1)];
                        y3 = c.f[n*(i+1)+(j+1)];
                        y4 = c.f[n*(i+1)+j];
                        tbl[p,4] = y1;
                        tbl[p,4+1*4+0] = y2-y1;
                        tbl[p,4+0*4+1] = y4-y1;
                        tbl[p,4+1*4+1] = y3-y2-y4+y1;
                    }
                    
                    //
                    // Bicubic interpolation
                    //
                    if( c.stype==-3 )
                    {
                        s1 = n*i+j;
                        s2 = n*i+(j+1);
                        s3 = n*(i+1)+(j+1);
                        s4 = n*(i+1)+j;
                        tbl[p,4+0*4+0] = c.f[s1];
                        tbl[p,4+0*4+1] = c.f[sfy+s1]/du;
                        tbl[p,4+0*4+2] = -(3*c.f[s1])+3*c.f[s4]-2*c.f[sfy+s1]/du-c.f[sfy+s4]/du;
                        tbl[p,4+0*4+3] = 2*c.f[s1]-2*c.f[s4]+c.f[sfy+s1]/du+c.f[sfy+s4]/du;
                        tbl[p,4+1*4+0] = c.f[sfx+s1]/dt;
                        tbl[p,4+1*4+1] = c.f[sfxy+s1]/(dt*du);
                        tbl[p,4+1*4+2] = -(3*c.f[sfx+s1]/dt)+3*c.f[sfx+s4]/dt-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s4]/(dt*du);
                        tbl[p,4+1*4+3] = 2*c.f[sfx+s1]/dt-2*c.f[sfx+s4]/dt+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s4]/(dt*du);
                        tbl[p,4+2*4+0] = -(3*c.f[s1])+3*c.f[s2]-2*c.f[sfx+s1]/dt-c.f[sfx+s2]/dt;
                        tbl[p,4+2*4+1] = -(3*c.f[sfy+s1]/du)+3*c.f[sfy+s2]/du-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s2]/(dt*du);
                        tbl[p,4+2*4+2] = 9*c.f[s1]-9*c.f[s2]+9*c.f[s3]-9*c.f[s4]+6*c.f[sfx+s1]/dt+3*c.f[sfx+s2]/dt-3*c.f[sfx+s3]/dt-6*c.f[sfx+s4]/dt+6*c.f[sfy+s1]/du-6*c.f[sfy+s2]/du-3*c.f[sfy+s3]/du+3*c.f[sfy+s4]/du+4*c.f[sfxy+s1]/(dt*du)+2*c.f[sfxy+s2]/(dt*du)+c.f[sfxy+s3]/(dt*du)+2*c.f[sfxy+s4]/(dt*du);
                        tbl[p,4+2*4+3] = -(6*c.f[s1])+6*c.f[s2]-6*c.f[s3]+6*c.f[s4]-4*c.f[sfx+s1]/dt-2*c.f[sfx+s2]/dt+2*c.f[sfx+s3]/dt+4*c.f[sfx+s4]/dt-3*c.f[sfy+s1]/du+3*c.f[sfy+s2]/du+3*c.f[sfy+s3]/du-3*c.f[sfy+s4]/du-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s2]/(dt*du)-c.f[sfxy+s3]/(dt*du)-2*c.f[sfxy+s4]/(dt*du);
                        tbl[p,4+3*4+0] = 2*c.f[s1]-2*c.f[s2]+c.f[sfx+s1]/dt+c.f[sfx+s2]/dt;
                        tbl[p,4+3*4+1] = 2*c.f[sfy+s1]/du-2*c.f[sfy+s2]/du+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s2]/(dt*du);
                        tbl[p,4+3*4+2] = -(6*c.f[s1])+6*c.f[s2]-6*c.f[s3]+6*c.f[s4]-3*c.f[sfx+s1]/dt-3*c.f[sfx+s2]/dt+3*c.f[sfx+s3]/dt+3*c.f[sfx+s4]/dt-4*c.f[sfy+s1]/du+4*c.f[sfy+s2]/du+2*c.f[sfy+s3]/du-2*c.f[sfy+s4]/du-2*c.f[sfxy+s1]/(dt*du)-2*c.f[sfxy+s2]/(dt*du)-c.f[sfxy+s3]/(dt*du)-c.f[sfxy+s4]/(dt*du);
                        tbl[p,4+3*4+3] = 4*c.f[s1]-4*c.f[s2]+4*c.f[s3]-4*c.f[s4]+2*c.f[sfx+s1]/dt+2*c.f[sfx+s2]/dt-2*c.f[sfx+s3]/dt-2*c.f[sfx+s4]/dt+2*c.f[sfy+s1]/du-2*c.f[sfy+s2]/du-2*c.f[sfy+s3]/du+2*c.f[sfy+s4]/du+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s2]/(dt*du)+c.f[sfxy+s3]/(dt*du)+c.f[sfxy+s4]/(dt*du);
                    }
                    
                    //
                    // Rescale Cij
                    //
                    for(ci=0; ci<=3; ci++)
                    {
                        for(cj=0; cj<=3; cj++)
                        {
                            tbl[p,4+ci*4+cj] = tbl[p,4+ci*4+cj]*Math.Pow(dt, ci)*Math.Pow(du, cj);
                        }
                    }
                }
            }
        }
示例#11
0
        /*************************************************************************
        This subroutine was deprecated in ALGLIB 3.6.0

        We recommend you to switch  to  Spline2DBuildBilinearV(),  which  is  more
        flexible and accepts its arguments in more convenient order.

          -- ALGLIB PROJECT --
             Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dbuildbilinear(double[] x,
            double[] y,
            double[,] f,
            int m,
            int n,
            spline2dinterpolant c)
        {
            double t = 0;
            int i = 0;
            int j = 0;
            int k = 0;

            alglib.ap.assert(n>=2, "Spline2DBuildBilinear: N<2");
            alglib.ap.assert(m>=2, "Spline2DBuildBilinear: M<2");
            alglib.ap.assert(alglib.ap.len(x)>=n && alglib.ap.len(y)>=m, "Spline2DBuildBilinear: length of X or Y is too short (Length(X/Y)<N/M)");
            alglib.ap.assert(apserv.isfinitevector(x, n) && apserv.isfinitevector(y, m), "Spline2DBuildBilinear: X or Y contains NaN or Infinite value");
            alglib.ap.assert(alglib.ap.rows(f)>=m && alglib.ap.cols(f)>=n, "Spline2DBuildBilinear: size of F is too small (rows(F)<M or cols(F)<N)");
            alglib.ap.assert(apserv.apservisfinitematrix(f, m, n), "Spline2DBuildBilinear: F contains NaN or Infinite value");
            
            //
            // Fill interpolant
            //
            c.k = 1;
            c.n = n;
            c.m = m;
            c.d = 1;
            c.stype = -1;
            c.x = new double[c.n];
            c.y = new double[c.m];
            c.f = new double[c.n*c.m];
            for(i=0; i<=c.n-1; i++)
            {
                c.x[i] = x[i];
            }
            for(i=0; i<=c.m-1; i++)
            {
                c.y[i] = y[i];
            }
            for(i=0; i<=c.m-1; i++)
            {
                for(j=0; j<=c.n-1; j++)
                {
                    c.f[i*c.n+j] = f[i,j];
                }
            }
            
            //
            // Sort points
            //
            for(j=0; j<=c.n-1; j++)
            {
                k = j;
                for(i=j+1; i<=c.n-1; i++)
                {
                    if( (double)(c.x[i])<(double)(c.x[k]) )
                    {
                        k = i;
                    }
                }
                if( k!=j )
                {
                    for(i=0; i<=c.m-1; i++)
                    {
                        t = c.f[i*c.n+j];
                        c.f[i*c.n+j] = c.f[i*c.n+k];
                        c.f[i*c.n+k] = t;
                    }
                    t = c.x[j];
                    c.x[j] = c.x[k];
                    c.x[k] = t;
                }
            }
            for(i=0; i<=c.m-1; i++)
            {
                k = i;
                for(j=i+1; j<=c.m-1; j++)
                {
                    if( (double)(c.y[j])<(double)(c.y[k]) )
                    {
                        k = j;
                    }
                }
                if( k!=i )
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        t = c.f[i*c.n+j];
                        c.f[i*c.n+j] = c.f[k*c.n+j];
                        c.f[k*c.n+j] = t;
                    }
                    t = c.y[i];
                    c.y[i] = c.y[k];
                    c.y[k] = t;
                }
            }
        }
示例#12
0
 public override alglib.apobject make_copy()
 {
     spline2dinterpolant _result = new spline2dinterpolant();
     _result.k = k;
     _result.stype = stype;
     _result.n = n;
     _result.m = m;
     _result.d = d;
     _result.x = (double[])x.Clone();
     _result.y = (double[])y.Clone();
     _result.f = (double[])f.Clone();
     return _result;
 }
示例#13
0
            /*************************************************************************
            This subroutine makes the copy of the spline model.

            Input parameters:
                C   -   spline interpolant

            Output parameters:
                CC  -   spline copy

              -- ALGLIB PROJECT --
                 Copyright 29.06.2007 by Bochkanov Sergey
            *************************************************************************/
            public static void spline2dcopy(spline2dinterpolant c,
                spline2dinterpolant cc) {
                int n = 0;
                int i_ = 0;

                ap.assert(c.k == 1 | c.k == 3, "Spline2DCopy: incorrect C!");
                cc.k = c.k;
                n = (int)Math.Round(c.c[0]);
                cc.c = new double[n];
                for(i_ = 0; i_ <= n - 1; i_++) {
                    cc.c[i_] = c.c[i_];
                }
            }
示例#14
0
            /*************************************************************************
            This subroutine performs linear transformation of the spline.

            Input parameters:
                C   -   spline interpolant.
                A, B-   transformation coefficients: S2(x,y) = A*S(x,y) + B
            
            Output parameters:
                C   -   transformed spline

              -- ALGLIB PROJECT --
                 Copyright 30.06.2007 by Bochkanov Sergey
            *************************************************************************/
            public static void spline2dlintransf(spline2dinterpolant c,
                double a,
                double b) {
                int i = 0;
                int j = 0;
                int n = 0;
                int m = 0;
                double[] x = new double[0];
                double[] y = new double[0];
                double[,] f = new double[0, 0];
                int typec = 0;

                typec = (int)Math.Round(c.c[1]);
                ap.assert(typec == -3 | typec == -1, "Spline2DLinTransXY: incorrect C!");
                n = (int)Math.Round(c.c[2]);
                m = (int)Math.Round(c.c[3]);
                x = new double[n - 1 + 1];
                y = new double[m - 1 + 1];
                f = new double[m - 1 + 1, n - 1 + 1];
                for(j = 0; j <= n - 1; j++) {
                    x[j] = c.c[4 + j];
                }
                for(i = 0; i <= m - 1; i++) {
                    y[i] = c.c[4 + n + i];
                }
                for(i = 0; i <= m - 1; i++) {
                    for(j = 0; j <= n - 1; j++) {
                        f[i, j] = a * c.c[4 + n + m + i * n + j] + b;
                    }
                }
                if(typec == -3) {
                    spline2dbuildbicubic(x, y, f, m, n, c);
                }
                if(typec == -1) {
                    spline2dbuildbilinear(x, y, f, m, n, c);
                }
            }
示例#15
0
            /*************************************************************************
            This subroutine performs linear transformation of the spline argument.

            Input parameters:
                C       -   spline interpolant
                AX, BX  -   transformation coefficients: x = A*t + B
                AY, BY  -   transformation coefficients: y = A*u + B
            Result:
                C   -   transformed spline

              -- ALGLIB PROJECT --
                 Copyright 30.06.2007 by Bochkanov Sergey
            *************************************************************************/
            public static void spline2dlintransxy(spline2dinterpolant c,
                double ax,
                double bx,
                double ay,
                double by) {
                int i = 0;
                int j = 0;
                int n = 0;
                int m = 0;
                double v = 0;
                double[] x = new double[0];
                double[] y = new double[0];
                double[,] f = new double[0, 0];
                int typec = 0;

                typec = (int)Math.Round(c.c[1]);
                ap.assert(typec == -3 | typec == -1, "Spline2DLinTransXY: incorrect C!");
                n = (int)Math.Round(c.c[2]);
                m = (int)Math.Round(c.c[3]);
                x = new double[n - 1 + 1];
                y = new double[m - 1 + 1];
                f = new double[m - 1 + 1, n - 1 + 1];
                for(j = 0; j <= n - 1; j++) {
                    x[j] = c.c[4 + j];
                }
                for(i = 0; i <= m - 1; i++) {
                    y[i] = c.c[4 + n + i];
                }
                for(i = 0; i <= m - 1; i++) {
                    for(j = 0; j <= n - 1; j++) {
                        f[i, j] = c.c[4 + n + m + i * n + j];
                    }
                }

                //
                // Special case: AX=0 or AY=0
                //
                if((double)(ax) == (double)(0)) {
                    for(i = 0; i <= m - 1; i++) {
                        v = spline2dcalc(c, bx, y[i]);
                        for(j = 0; j <= n - 1; j++) {
                            f[i, j] = v;
                        }
                    }
                    if(typec == -3) {
                        spline2dbuildbicubic(x, y, f, m, n, c);
                    }
                    if(typec == -1) {
                        spline2dbuildbilinear(x, y, f, m, n, c);
                    }
                    ax = 1;
                    bx = 0;
                }
                if((double)(ay) == (double)(0)) {
                    for(j = 0; j <= n - 1; j++) {
                        v = spline2dcalc(c, x[j], by);
                        for(i = 0; i <= m - 1; i++) {
                            f[i, j] = v;
                        }
                    }
                    if(typec == -3) {
                        spline2dbuildbicubic(x, y, f, m, n, c);
                    }
                    if(typec == -1) {
                        spline2dbuildbilinear(x, y, f, m, n, c);
                    }
                    ay = 1;
                    by = 0;
                }

                //
                // General case: AX<>0, AY<>0
                // Unpack, scale and pack again.
                //
                for(j = 0; j <= n - 1; j++) {
                    x[j] = (x[j] - bx) / ax;
                }
                for(i = 0; i <= m - 1; i++) {
                    y[i] = (y[i] - by) / ay;
                }
                if(typec == -3) {
                    spline2dbuildbicubic(x, y, f, m, n, c);
                }
                if(typec == -1) {
                    spline2dbuildbilinear(x, y, f, m, n, c);
                }
            }
示例#16
0
            /*************************************************************************
            This subroutine unpacks two-dimensional spline into the coefficients table

            Input parameters:
                C   -   spline interpolant.

            Result:
                M, N-   grid size (x-axis and y-axis)
                Tbl -   coefficients table, unpacked format,
                        [0..(N-1)*(M-1)-1, 0..19].
                        For I = 0...M-2, J=0..N-2:
                            K =  I*(N-1)+J
                            Tbl[K,0] = X[j]
                            Tbl[K,1] = X[j+1]
                            Tbl[K,2] = Y[i]
                            Tbl[K,3] = Y[i+1]
                            Tbl[K,4] = C00
                            Tbl[K,5] = C01
                            Tbl[K,6] = C02
                            Tbl[K,7] = C03
                            Tbl[K,8] = C10
                            Tbl[K,9] = C11
                            ...
                            Tbl[K,19] = C33
                        On each grid square spline is equals to:
                            S(x) = SUM(c[i,j]*(x^i)*(y^j), i=0..3, j=0..3)
                            t = x-x[j]
                            u = y-y[i]

              -- ALGLIB PROJECT --
                 Copyright 29.06.2007 by Bochkanov Sergey
            *************************************************************************/
            public static void spline2dunpack(spline2dinterpolant c,
                ref int m,
                ref int n,
                ref double[,] tbl) {
                int i = 0;
                int j = 0;
                int ci = 0;
                int cj = 0;
                int k = 0;
                int p = 0;
                int shift = 0;
                int s1 = 0;
                int s2 = 0;
                int s3 = 0;
                int s4 = 0;
                int sf = 0;
                int sfx = 0;
                int sfy = 0;
                int sfxy = 0;
                double y1 = 0;
                double y2 = 0;
                double y3 = 0;
                double y4 = 0;
                double dt = 0;
                double du = 0;

                m = 0;
                n = 0;
                tbl = new double[0, 0];

                ap.assert((int)Math.Round(c.c[1]) == -3 | (int)Math.Round(c.c[1]) == -1, "SplineUnpack2D: incorrect C!");
                n = (int)Math.Round(c.c[2]);
                m = (int)Math.Round(c.c[3]);
                tbl = new double[(n - 1) * (m - 1) - 1 + 1, 19 + 1];

                //
                // Fill
                //
                for(i = 0; i <= m - 2; i++) {
                    for(j = 0; j <= n - 2; j++) {
                        p = i * (n - 1) + j;
                        tbl[p, 0] = c.c[4 + j];
                        tbl[p, 1] = c.c[4 + j + 1];
                        tbl[p, 2] = c.c[4 + n + i];
                        tbl[p, 3] = c.c[4 + n + i + 1];
                        dt = 1 / (tbl[p, 1] - tbl[p, 0]);
                        du = 1 / (tbl[p, 3] - tbl[p, 2]);

                        //
                        // Bilinear interpolation
                        //
                        if((int)Math.Round(c.c[1]) == -1) {
                            for(k = 4; k <= 19; k++) {
                                tbl[p, k] = 0;
                            }
                            shift = 4 + n + m;
                            y1 = c.c[shift + n * i + j];
                            y2 = c.c[shift + n * i + (j + 1)];
                            y3 = c.c[shift + n * (i + 1) + (j + 1)];
                            y4 = c.c[shift + n * (i + 1) + j];
                            tbl[p, 4] = y1;
                            tbl[p, 4 + 1 * 4 + 0] = y2 - y1;
                            tbl[p, 4 + 0 * 4 + 1] = y4 - y1;
                            tbl[p, 4 + 1 * 4 + 1] = y3 - y2 - y4 + y1;
                        }

                        //
                        // Bicubic interpolation
                        //
                        if((int)Math.Round(c.c[1]) == -3) {
                            sf = 4 + n + m;
                            sfx = 4 + n + m + n * m;
                            sfy = 4 + n + m + 2 * n * m;
                            sfxy = 4 + n + m + 3 * n * m;
                            s1 = n * i + j;
                            s2 = n * i + (j + 1);
                            s3 = n * (i + 1) + (j + 1);
                            s4 = n * (i + 1) + j;
                            tbl[p, 4 + 0 * 4 + 0] = 1 * c.c[sf + s1];
                            tbl[p, 4 + 0 * 4 + 1] = 1 * c.c[sfy + s1] / du;
                            tbl[p, 4 + 0 * 4 + 2] = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s4] - 2 * c.c[sfy + s1] / du - 1 * c.c[sfy + s4] / du;
                            tbl[p, 4 + 0 * 4 + 3] = 2 * c.c[sf + s1] - 2 * c.c[sf + s4] + 1 * c.c[sfy + s1] / du + 1 * c.c[sfy + s4] / du;
                            tbl[p, 4 + 1 * 4 + 0] = 1 * c.c[sfx + s1] / dt;
                            tbl[p, 4 + 1 * 4 + 1] = 1 * c.c[sfxy + s1] / (dt * du);
                            tbl[p, 4 + 1 * 4 + 2] = -(3 * c.c[sfx + s1] / dt) + 3 * c.c[sfx + s4] / dt - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                            tbl[p, 4 + 1 * 4 + 3] = 2 * c.c[sfx + s1] / dt - 2 * c.c[sfx + s4] / dt + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                            tbl[p, 4 + 2 * 4 + 0] = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s2] - 2 * c.c[sfx + s1] / dt - 1 * c.c[sfx + s2] / dt;
                            tbl[p, 4 + 2 * 4 + 1] = -(3 * c.c[sfy + s1] / du) + 3 * c.c[sfy + s2] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du);
                            tbl[p, 4 + 2 * 4 + 2] = 9 * c.c[sf + s1] - 9 * c.c[sf + s2] + 9 * c.c[sf + s3] - 9 * c.c[sf + s4] + 6 * c.c[sfx + s1] / dt + 3 * c.c[sfx + s2] / dt - 3 * c.c[sfx + s3] / dt - 6 * c.c[sfx + s4] / dt + 6 * c.c[sfy + s1] / du - 6 * c.c[sfy + s2] / du - 3 * c.c[sfy + s3] / du + 3 * c.c[sfy + s4] / du + 4 * c.c[sfxy + s1] / (dt * du) + 2 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 2 * c.c[sfxy + s4] / (dt * du);
                            tbl[p, 4 + 2 * 4 + 3] = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 4 * c.c[sfx + s1] / dt - 2 * c.c[sfx + s2] / dt + 2 * c.c[sfx + s3] / dt + 4 * c.c[sfx + s4] / dt - 3 * c.c[sfy + s1] / du + 3 * c.c[sfy + s2] / du + 3 * c.c[sfy + s3] / du - 3 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 2 * c.c[sfxy + s4] / (dt * du);
                            tbl[p, 4 + 3 * 4 + 0] = 2 * c.c[sf + s1] - 2 * c.c[sf + s2] + 1 * c.c[sfx + s1] / dt + 1 * c.c[sfx + s2] / dt;
                            tbl[p, 4 + 3 * 4 + 1] = 2 * c.c[sfy + s1] / du - 2 * c.c[sfy + s2] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du);
                            tbl[p, 4 + 3 * 4 + 2] = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 3 * c.c[sfx + s1] / dt - 3 * c.c[sfx + s2] / dt + 3 * c.c[sfx + s3] / dt + 3 * c.c[sfx + s4] / dt - 4 * c.c[sfy + s1] / du + 4 * c.c[sfy + s2] / du + 2 * c.c[sfy + s3] / du - 2 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 2 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                            tbl[p, 4 + 3 * 4 + 3] = 4 * c.c[sf + s1] - 4 * c.c[sf + s2] + 4 * c.c[sf + s3] - 4 * c.c[sf + s4] + 2 * c.c[sfx + s1] / dt + 2 * c.c[sfx + s2] / dt - 2 * c.c[sfx + s3] / dt - 2 * c.c[sfx + s4] / dt + 2 * c.c[sfy + s1] / du - 2 * c.c[sfy + s2] / du - 2 * c.c[sfy + s3] / du + 2 * c.c[sfy + s4] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                        }

                        //
                        // Rescale Cij
                        //
                        for(ci = 0; ci <= 3; ci++) {
                            for(cj = 0; cj <= 3; cj++) {
                                tbl[p, 4 + ci * 4 + cj] = tbl[p, 4 + ci * 4 + cj] * Math.Pow(dt, ci) * Math.Pow(du, cj);
                            }
                        }
                    }
                }
            }
示例#17
0
            /*************************************************************************
            This subroutine calculates the value of the bilinear or bicubic spline  at
            the given point X and its derivatives.

            Input parameters:
                C   -   spline interpolant.
                X, Y-   point

            Output parameters:
                F   -   S(x,y)
                FX  -   dS(x,y)/dX
                FY  -   dS(x,y)/dY
                FXY -   d2S(x,y)/dXdY

              -- ALGLIB PROJECT --
                 Copyright 05.07.2007 by Bochkanov Sergey
            *************************************************************************/
            public static void spline2ddiff(spline2dinterpolant c,
                double x,
                double y,
                ref double f,
                ref double fx,
                ref double fy,
                ref double fxy) {
                int n = 0;
                int m = 0;
                double t = 0;
                double dt = 0;
                double u = 0;
                double du = 0;
                int ix = 0;
                int iy = 0;
                int l = 0;
                int r = 0;
                int h = 0;
                int shift1 = 0;
                int s1 = 0;
                int s2 = 0;
                int s3 = 0;
                int s4 = 0;
                int sf = 0;
                int sfx = 0;
                int sfy = 0;
                int sfxy = 0;
                double y1 = 0;
                double y2 = 0;
                double y3 = 0;
                double y4 = 0;
                double v = 0;
                double t0 = 0;
                double t1 = 0;
                double t2 = 0;
                double t3 = 0;
                double u0 = 0;
                double u1 = 0;
                double u2 = 0;
                double u3 = 0;

                f = 0;
                fx = 0;
                fy = 0;
                fxy = 0;

                ap.assert((int)Math.Round(c.c[1]) == -1 | (int)Math.Round(c.c[1]) == -3, "Spline2DDiff: incorrect C!");
                n = (int)Math.Round(c.c[2]);
                m = (int)Math.Round(c.c[3]);

                //
                // Binary search in the [ x[0], ..., x[n-2] ] (x[n-1] is not included)
                //
                l = 4;
                r = 4 + n - 2 + 1;
                while(l != r - 1) {
                    h = (l + r) / 2;
                    if((double)(c.c[h]) >= (double)(x)) {
                        r = h;
                    } else {
                        l = h;
                    }
                }
                t = (x - c.c[l]) / (c.c[l + 1] - c.c[l]);
                dt = 1.0 / (c.c[l + 1] - c.c[l]);
                ix = l - 4;

                //
                // Binary search in the [ y[0], ..., y[m-2] ] (y[m-1] is not included)
                //
                l = 4 + n;
                r = 4 + n + (m - 2) + 1;
                while(l != r - 1) {
                    h = (l + r) / 2;
                    if((double)(c.c[h]) >= (double)(y)) {
                        r = h;
                    } else {
                        l = h;
                    }
                }
                u = (y - c.c[l]) / (c.c[l + 1] - c.c[l]);
                du = 1.0 / (c.c[l + 1] - c.c[l]);
                iy = l - (4 + n);

                //
                // Prepare F, dF/dX, dF/dY, d2F/dXdY
                //
                f = 0;
                fx = 0;
                fy = 0;
                fxy = 0;

                //
                // Bilinear interpolation
                //
                if((int)Math.Round(c.c[1]) == -1) {
                    shift1 = 4 + n + m;
                    y1 = c.c[shift1 + n * iy + ix];
                    y2 = c.c[shift1 + n * iy + (ix + 1)];
                    y3 = c.c[shift1 + n * (iy + 1) + (ix + 1)];
                    y4 = c.c[shift1 + n * (iy + 1) + ix];
                    f = (1 - t) * (1 - u) * y1 + t * (1 - u) * y2 + t * u * y3 + (1 - t) * u * y4;
                    fx = (-((1 - u) * y1) + (1 - u) * y2 + u * y3 - u * y4) * dt;
                    fy = (-((1 - t) * y1) - t * y2 + t * y3 + (1 - t) * y4) * du;
                    fxy = (y1 - y2 + y3 - y4) * du * dt;
                    return;
                }

                //
                // Bicubic interpolation
                //
                if((int)Math.Round(c.c[1]) == -3) {

                    //
                    // Prepare info
                    //
                    t0 = 1;
                    t1 = t;
                    t2 = math.sqr(t);
                    t3 = t * t2;
                    u0 = 1;
                    u1 = u;
                    u2 = math.sqr(u);
                    u3 = u * u2;
                    sf = 4 + n + m;
                    sfx = 4 + n + m + n * m;
                    sfy = 4 + n + m + 2 * n * m;
                    sfxy = 4 + n + m + 3 * n * m;
                    s1 = n * iy + ix;
                    s2 = n * iy + (ix + 1);
                    s3 = n * (iy + 1) + (ix + 1);
                    s4 = n * (iy + 1) + ix;

                    //
                    // Calculate
                    //
                    v = 1 * c.c[sf + s1];
                    f = f + v * t0 * u0;
                    v = 1 * c.c[sfy + s1] / du;
                    f = f + v * t0 * u1;
                    fy = fy + 1 * v * t0 * u0 * du;
                    v = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s4] - 2 * c.c[sfy + s1] / du - 1 * c.c[sfy + s4] / du;
                    f = f + v * t0 * u2;
                    fy = fy + 2 * v * t0 * u1 * du;
                    v = 2 * c.c[sf + s1] - 2 * c.c[sf + s4] + 1 * c.c[sfy + s1] / du + 1 * c.c[sfy + s4] / du;
                    f = f + v * t0 * u3;
                    fy = fy + 3 * v * t0 * u2 * du;
                    v = 1 * c.c[sfx + s1] / dt;
                    f = f + v * t1 * u0;
                    fx = fx + 1 * v * t0 * u0 * dt;
                    v = 1 * c.c[sfxy + s1] / (dt * du);
                    f = f + v * t1 * u1;
                    fx = fx + 1 * v * t0 * u1 * dt;
                    fy = fy + 1 * v * t1 * u0 * du;
                    fxy = fxy + 1 * v * t0 * u0 * dt * du;
                    v = -(3 * c.c[sfx + s1] / dt) + 3 * c.c[sfx + s4] / dt - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                    f = f + v * t1 * u2;
                    fx = fx + 1 * v * t0 * u2 * dt;
                    fy = fy + 2 * v * t1 * u1 * du;
                    fxy = fxy + 2 * v * t0 * u1 * dt * du;
                    v = 2 * c.c[sfx + s1] / dt - 2 * c.c[sfx + s4] / dt + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                    f = f + v * t1 * u3;
                    fx = fx + 1 * v * t0 * u3 * dt;
                    fy = fy + 3 * v * t1 * u2 * du;
                    fxy = fxy + 3 * v * t0 * u2 * dt * du;
                    v = -(3 * c.c[sf + s1]) + 3 * c.c[sf + s2] - 2 * c.c[sfx + s1] / dt - 1 * c.c[sfx + s2] / dt;
                    f = f + v * t2 * u0;
                    fx = fx + 2 * v * t1 * u0 * dt;
                    v = -(3 * c.c[sfy + s1] / du) + 3 * c.c[sfy + s2] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du);
                    f = f + v * t2 * u1;
                    fx = fx + 2 * v * t1 * u1 * dt;
                    fy = fy + 1 * v * t2 * u0 * du;
                    fxy = fxy + 2 * v * t1 * u0 * dt * du;
                    v = 9 * c.c[sf + s1] - 9 * c.c[sf + s2] + 9 * c.c[sf + s3] - 9 * c.c[sf + s4] + 6 * c.c[sfx + s1] / dt + 3 * c.c[sfx + s2] / dt - 3 * c.c[sfx + s3] / dt - 6 * c.c[sfx + s4] / dt + 6 * c.c[sfy + s1] / du - 6 * c.c[sfy + s2] / du - 3 * c.c[sfy + s3] / du + 3 * c.c[sfy + s4] / du + 4 * c.c[sfxy + s1] / (dt * du) + 2 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 2 * c.c[sfxy + s4] / (dt * du);
                    f = f + v * t2 * u2;
                    fx = fx + 2 * v * t1 * u2 * dt;
                    fy = fy + 2 * v * t2 * u1 * du;
                    fxy = fxy + 4 * v * t1 * u1 * dt * du;
                    v = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 4 * c.c[sfx + s1] / dt - 2 * c.c[sfx + s2] / dt + 2 * c.c[sfx + s3] / dt + 4 * c.c[sfx + s4] / dt - 3 * c.c[sfy + s1] / du + 3 * c.c[sfy + s2] / du + 3 * c.c[sfy + s3] / du - 3 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 1 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 2 * c.c[sfxy + s4] / (dt * du);
                    f = f + v * t2 * u3;
                    fx = fx + 2 * v * t1 * u3 * dt;
                    fy = fy + 3 * v * t2 * u2 * du;
                    fxy = fxy + 6 * v * t1 * u2 * dt * du;
                    v = 2 * c.c[sf + s1] - 2 * c.c[sf + s2] + 1 * c.c[sfx + s1] / dt + 1 * c.c[sfx + s2] / dt;
                    f = f + v * t3 * u0;
                    fx = fx + 3 * v * t2 * u0 * dt;
                    v = 2 * c.c[sfy + s1] / du - 2 * c.c[sfy + s2] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du);
                    f = f + v * t3 * u1;
                    fx = fx + 3 * v * t2 * u1 * dt;
                    fy = fy + 1 * v * t3 * u0 * du;
                    fxy = fxy + 3 * v * t2 * u0 * dt * du;
                    v = -(6 * c.c[sf + s1]) + 6 * c.c[sf + s2] - 6 * c.c[sf + s3] + 6 * c.c[sf + s4] - 3 * c.c[sfx + s1] / dt - 3 * c.c[sfx + s2] / dt + 3 * c.c[sfx + s3] / dt + 3 * c.c[sfx + s4] / dt - 4 * c.c[sfy + s1] / du + 4 * c.c[sfy + s2] / du + 2 * c.c[sfy + s3] / du - 2 * c.c[sfy + s4] / du - 2 * c.c[sfxy + s1] / (dt * du) - 2 * c.c[sfxy + s2] / (dt * du) - 1 * c.c[sfxy + s3] / (dt * du) - 1 * c.c[sfxy + s4] / (dt * du);
                    f = f + v * t3 * u2;
                    fx = fx + 3 * v * t2 * u2 * dt;
                    fy = fy + 2 * v * t3 * u1 * du;
                    fxy = fxy + 6 * v * t2 * u1 * dt * du;
                    v = 4 * c.c[sf + s1] - 4 * c.c[sf + s2] + 4 * c.c[sf + s3] - 4 * c.c[sf + s4] + 2 * c.c[sfx + s1] / dt + 2 * c.c[sfx + s2] / dt - 2 * c.c[sfx + s3] / dt - 2 * c.c[sfx + s4] / dt + 2 * c.c[sfy + s1] / du - 2 * c.c[sfy + s2] / du - 2 * c.c[sfy + s3] / du + 2 * c.c[sfy + s4] / du + 1 * c.c[sfxy + s1] / (dt * du) + 1 * c.c[sfxy + s2] / (dt * du) + 1 * c.c[sfxy + s3] / (dt * du) + 1 * c.c[sfxy + s4] / (dt * du);
                    f = f + v * t3 * u3;
                    fx = fx + 3 * v * t2 * u3 * dt;
                    fy = fy + 3 * v * t3 * u2 * du;
                    fxy = fxy + 9 * v * t2 * u2 * dt * du;
                    return;
                }
            }
示例#18
0
            /*************************************************************************
            This subroutine calculates the value of the bilinear or bicubic spline  at
            the given point X.

            Input parameters:
                C   -   coefficients table.
                        Built by BuildBilinearSpline or BuildBicubicSpline.
                X, Y-   point

            Result:
                S(x,y)

              -- ALGLIB PROJECT --
                 Copyright 05.07.2007 by Bochkanov Sergey
            *************************************************************************/
            public static double spline2dcalc(spline2dinterpolant c,
                double x,
                double y) {
                double result = 0;
                double v = 0;
                double vx = 0;
                double vy = 0;
                double vxy = 0;

                spline2ddiff(c, x, y, ref v, ref vx, ref vy, ref vxy);
                result = v;
                return result;
            }
示例#19
0
        /*************************************************************************
        This subroutine calculates bilinear or bicubic vector-valued spline at the
        given point (X,Y).

        INPUT PARAMETERS:
            C   -   spline interpolant.
            X, Y-   point
            F   -   output buffer, possibly preallocated array. In case array size
                    is large enough to store result, it is not reallocated.  Array
                    which is too short will be reallocated

        OUTPUT PARAMETERS:
            F   -   array[D] (or larger) which stores function values

          -- ALGLIB PROJECT --
             Copyright 16.04.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dcalcvbuf(spline2dinterpolant c,
            double x,
            double y,
            ref double[] f)
        {
            double t = 0;
            double dt = 0;
            double u = 0;
            double du = 0;
            int ix = 0;
            int iy = 0;
            int l = 0;
            int r = 0;
            int h = 0;
            int s1 = 0;
            int s2 = 0;
            int s3 = 0;
            int s4 = 0;
            int sfx = 0;
            int sfy = 0;
            int sfxy = 0;
            double y1 = 0;
            double y2 = 0;
            double y3 = 0;
            double y4 = 0;
            double v = 0;
            double t0 = 0;
            double t1 = 0;
            double t2 = 0;
            double t3 = 0;
            double u0 = 0;
            double u1 = 0;
            double u2 = 0;
            double u3 = 0;
            int i = 0;

            alglib.ap.assert(c.stype==-1 || c.stype==-3, "Spline2DCalcVBuf: incorrect C (incorrect parameter C.SType)");
            alglib.ap.assert(math.isfinite(x) && math.isfinite(y), "Spline2DCalcVBuf: either X=NaN/Infinite or Y=NaN/Infinite");
            apserv.rvectorsetlengthatleast(ref f, c.d);
            
            //
            // Binary search in the [ x[0], ..., x[n-2] ] (x[n-1] is not included)
            //
            l = 0;
            r = c.n-1;
            while( l!=r-1 )
            {
                h = (l+r)/2;
                if( (double)(c.x[h])>=(double)(x) )
                {
                    r = h;
                }
                else
                {
                    l = h;
                }
            }
            t = (x-c.x[l])/(c.x[l+1]-c.x[l]);
            dt = 1.0/(c.x[l+1]-c.x[l]);
            ix = l;
            
            //
            // Binary search in the [ y[0], ..., y[m-2] ] (y[m-1] is not included)
            //
            l = 0;
            r = c.m-1;
            while( l!=r-1 )
            {
                h = (l+r)/2;
                if( (double)(c.y[h])>=(double)(y) )
                {
                    r = h;
                }
                else
                {
                    l = h;
                }
            }
            u = (y-c.y[l])/(c.y[l+1]-c.y[l]);
            du = 1.0/(c.y[l+1]-c.y[l]);
            iy = l;
            
            //
            // Bilinear interpolation
            //
            if( c.stype==-1 )
            {
                for(i=0; i<=c.d-1; i++)
                {
                    y1 = c.f[c.d*(c.n*iy+ix)+i];
                    y2 = c.f[c.d*(c.n*iy+(ix+1))+i];
                    y3 = c.f[c.d*(c.n*(iy+1)+(ix+1))+i];
                    y4 = c.f[c.d*(c.n*(iy+1)+ix)+i];
                    f[i] = (1-t)*(1-u)*y1+t*(1-u)*y2+t*u*y3+(1-t)*u*y4;
                }
                return;
            }
            
            //
            // Bicubic interpolation
            //
            if( c.stype==-3 )
            {
                
                //
                // Prepare info
                //
                t0 = 1;
                t1 = t;
                t2 = math.sqr(t);
                t3 = t*t2;
                u0 = 1;
                u1 = u;
                u2 = math.sqr(u);
                u3 = u*u2;
                sfx = c.n*c.m*c.d;
                sfy = 2*c.n*c.m*c.d;
                sfxy = 3*c.n*c.m*c.d;
                for(i=0; i<=c.d-1; i++)
                {
                    
                    //
                    // Prepare F, dF/dX, dF/dY, d2F/dXdY
                    //
                    f[i] = 0;
                    s1 = c.d*(c.n*iy+ix)+i;
                    s2 = c.d*(c.n*iy+(ix+1))+i;
                    s3 = c.d*(c.n*(iy+1)+(ix+1))+i;
                    s4 = c.d*(c.n*(iy+1)+ix)+i;
                    
                    //
                    // Calculate
                    //
                    v = c.f[s1];
                    f[i] = f[i]+v*t0*u0;
                    v = c.f[sfy+s1]/du;
                    f[i] = f[i]+v*t0*u1;
                    v = -(3*c.f[s1])+3*c.f[s4]-2*c.f[sfy+s1]/du-c.f[sfy+s4]/du;
                    f[i] = f[i]+v*t0*u2;
                    v = 2*c.f[s1]-2*c.f[s4]+c.f[sfy+s1]/du+c.f[sfy+s4]/du;
                    f[i] = f[i]+v*t0*u3;
                    v = c.f[sfx+s1]/dt;
                    f[i] = f[i]+v*t1*u0;
                    v = c.f[sfxy+s1]/(dt*du);
                    f[i] = f[i]+v*t1*u1;
                    v = -(3*c.f[sfx+s1]/dt)+3*c.f[sfx+s4]/dt-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s4]/(dt*du);
                    f[i] = f[i]+v*t1*u2;
                    v = 2*c.f[sfx+s1]/dt-2*c.f[sfx+s4]/dt+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s4]/(dt*du);
                    f[i] = f[i]+v*t1*u3;
                    v = -(3*c.f[s1])+3*c.f[s2]-2*c.f[sfx+s1]/dt-c.f[sfx+s2]/dt;
                    f[i] = f[i]+v*t2*u0;
                    v = -(3*c.f[sfy+s1]/du)+3*c.f[sfy+s2]/du-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s2]/(dt*du);
                    f[i] = f[i]+v*t2*u1;
                    v = 9*c.f[s1]-9*c.f[s2]+9*c.f[s3]-9*c.f[s4]+6*c.f[sfx+s1]/dt+3*c.f[sfx+s2]/dt-3*c.f[sfx+s3]/dt-6*c.f[sfx+s4]/dt+6*c.f[sfy+s1]/du-6*c.f[sfy+s2]/du-3*c.f[sfy+s3]/du+3*c.f[sfy+s4]/du+4*c.f[sfxy+s1]/(dt*du)+2*c.f[sfxy+s2]/(dt*du)+c.f[sfxy+s3]/(dt*du)+2*c.f[sfxy+s4]/(dt*du);
                    f[i] = f[i]+v*t2*u2;
                    v = -(6*c.f[s1])+6*c.f[s2]-6*c.f[s3]+6*c.f[s4]-4*c.f[sfx+s1]/dt-2*c.f[sfx+s2]/dt+2*c.f[sfx+s3]/dt+4*c.f[sfx+s4]/dt-3*c.f[sfy+s1]/du+3*c.f[sfy+s2]/du+3*c.f[sfy+s3]/du-3*c.f[sfy+s4]/du-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s2]/(dt*du)-c.f[sfxy+s3]/(dt*du)-2*c.f[sfxy+s4]/(dt*du);
                    f[i] = f[i]+v*t2*u3;
                    v = 2*c.f[s1]-2*c.f[s2]+c.f[sfx+s1]/dt+c.f[sfx+s2]/dt;
                    f[i] = f[i]+v*t3*u0;
                    v = 2*c.f[sfy+s1]/du-2*c.f[sfy+s2]/du+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s2]/(dt*du);
                    f[i] = f[i]+v*t3*u1;
                    v = -(6*c.f[s1])+6*c.f[s2]-6*c.f[s3]+6*c.f[s4]-3*c.f[sfx+s1]/dt-3*c.f[sfx+s2]/dt+3*c.f[sfx+s3]/dt+3*c.f[sfx+s4]/dt-4*c.f[sfy+s1]/du+4*c.f[sfy+s2]/du+2*c.f[sfy+s3]/du-2*c.f[sfy+s4]/du-2*c.f[sfxy+s1]/(dt*du)-2*c.f[sfxy+s2]/(dt*du)-c.f[sfxy+s3]/(dt*du)-c.f[sfxy+s4]/(dt*du);
                    f[i] = f[i]+v*t3*u2;
                    v = 4*c.f[s1]-4*c.f[s2]+4*c.f[s3]-4*c.f[s4]+2*c.f[sfx+s1]/dt+2*c.f[sfx+s2]/dt-2*c.f[sfx+s3]/dt-2*c.f[sfx+s4]/dt+2*c.f[sfy+s1]/du-2*c.f[sfy+s2]/du-2*c.f[sfy+s3]/du+2*c.f[sfy+s4]/du+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s2]/(dt*du)+c.f[sfxy+s3]/(dt*du)+c.f[sfxy+s4]/(dt*du);
                    f[i] = f[i]+v*t3*u3;
                }
                return;
            }
        }
示例#20
0
        /*************************************************************************
        This subroutine calculates bilinear or bicubic vector-valued spline at the
        given point (X,Y).

        INPUT PARAMETERS:
            C   -   spline interpolant.
            X, Y-   point

        OUTPUT PARAMETERS:
            F   -   array[D] which stores function values.  F is out-parameter and
                    it  is  reallocated  after  call to this function. In case you
                    want  to    reuse  previously  allocated  F,   you   may   use
                    Spline2DCalcVBuf(),  which  reallocates  F only when it is too
                    small.

          -- ALGLIB PROJECT --
             Copyright 16.04.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dcalcv(spline2dinterpolant c,
            double x,
            double y,
            ref double[] f)
        {
            f = new double[0];

            alglib.ap.assert(c.stype==-1 || c.stype==-3, "Spline2DCalcV: incorrect C (incorrect parameter C.SType)");
            alglib.ap.assert(math.isfinite(x) && math.isfinite(y), "Spline2DCalcV: either X=NaN/Infinite or Y=NaN/Infinite");
            f = new double[c.d];
            spline2dcalcvbuf(c, x, y, ref f);
        }
示例#21
0
        /*************************************************************************
        This subroutine calculates the value of the bilinear or bicubic spline  at
        the given point X.

        Input parameters:
            C   -   coefficients table.
                    Built by BuildBilinearSpline or BuildBicubicSpline.
            X, Y-   point

        Result:
            S(x,y)

          -- ALGLIB PROJECT --
             Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static double spline2dcalc(spline2dinterpolant c,
            double x,
            double y)
        {
            double result = 0;
            double v = 0;
            double vx = 0;
            double vy = 0;
            double vxy = 0;

            alglib.ap.assert(c.stype==-1 || c.stype==-3, "Spline2DCalc: incorrect C (incorrect parameter C.SType)");
            alglib.ap.assert(math.isfinite(x) && math.isfinite(y), "Spline2DCalc: X or Y contains NaN or Infinite value");
            if( c.d!=1 )
            {
                result = 0;
                return result;
            }
            spline2ddiff(c, x, y, ref v, ref vx, ref vy, ref vxy);
            result = v;
            return result;
        }
示例#22
0
        /*************************************************************************
        This subroutine was deprecated in ALGLIB 3.6.0

        We recommend you to switch  to  Spline2DBuildBicubicV(),  which  is  more
        flexible and accepts its arguments in more convenient order.

          -- ALGLIB PROJECT --
             Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dbuildbicubic(double[] x,
            double[] y,
            double[,] f,
            int m,
            int n,
            spline2dinterpolant c)
        {
            int sfx = 0;
            int sfy = 0;
            int sfxy = 0;
            double[,] dx = new double[0,0];
            double[,] dy = new double[0,0];
            double[,] dxy = new double[0,0];
            double t = 0;
            int i = 0;
            int j = 0;
            int k = 0;

            f = (double[,])f.Clone();

            alglib.ap.assert(n>=2, "Spline2DBuildBicubicSpline: N<2");
            alglib.ap.assert(m>=2, "Spline2DBuildBicubicSpline: M<2");
            alglib.ap.assert(alglib.ap.len(x)>=n && alglib.ap.len(y)>=m, "Spline2DBuildBicubic: length of X or Y is too short (Length(X/Y)<N/M)");
            alglib.ap.assert(apserv.isfinitevector(x, n) && apserv.isfinitevector(y, m), "Spline2DBuildBicubic: X or Y contains NaN or Infinite value");
            alglib.ap.assert(alglib.ap.rows(f)>=m && alglib.ap.cols(f)>=n, "Spline2DBuildBicubic: size of F is too small (rows(F)<M or cols(F)<N)");
            alglib.ap.assert(apserv.apservisfinitematrix(f, m, n), "Spline2DBuildBicubic: F contains NaN or Infinite value");
            
            //
            // Fill interpolant:
            //  F[0]...F[N*M-1]:
            //      f(i,j) table. f(0,0), f(0, 1), f(0,2) and so on...
            //  F[N*M]...F[2*N*M-1]:
            //      df(i,j)/dx table.
            //  F[2*N*M]...F[3*N*M-1]:
            //      df(i,j)/dy table.
            //  F[3*N*M]...F[4*N*M-1]:
            //      d2f(i,j)/dxdy table.
            //
            c.k = 3;
            c.d = 1;
            c.n = n;
            c.m = m;
            c.stype = -3;
            sfx = c.n*c.m;
            sfy = 2*c.n*c.m;
            sfxy = 3*c.n*c.m;
            c.x = new double[c.n];
            c.y = new double[c.m];
            c.f = new double[4*c.n*c.m];
            for(i=0; i<=c.n-1; i++)
            {
                c.x[i] = x[i];
            }
            for(i=0; i<=c.m-1; i++)
            {
                c.y[i] = y[i];
            }
            
            //
            // Sort points
            //
            for(j=0; j<=c.n-1; j++)
            {
                k = j;
                for(i=j+1; i<=c.n-1; i++)
                {
                    if( (double)(c.x[i])<(double)(c.x[k]) )
                    {
                        k = i;
                    }
                }
                if( k!=j )
                {
                    for(i=0; i<=c.m-1; i++)
                    {
                        t = f[i,j];
                        f[i,j] = f[i,k];
                        f[i,k] = t;
                    }
                    t = c.x[j];
                    c.x[j] = c.x[k];
                    c.x[k] = t;
                }
            }
            for(i=0; i<=c.m-1; i++)
            {
                k = i;
                for(j=i+1; j<=c.m-1; j++)
                {
                    if( (double)(c.y[j])<(double)(c.y[k]) )
                    {
                        k = j;
                    }
                }
                if( k!=i )
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        t = f[i,j];
                        f[i,j] = f[k,j];
                        f[k,j] = t;
                    }
                    t = c.y[i];
                    c.y[i] = c.y[k];
                    c.y[k] = t;
                }
            }
            bicubiccalcderivatives(f, c.x, c.y, c.m, c.n, ref dx, ref dy, ref dxy);
            for(i=0; i<=c.m-1; i++)
            {
                for(j=0; j<=c.n-1; j++)
                {
                    k = i*c.n+j;
                    c.f[k] = f[i,j];
                    c.f[sfx+k] = dx[i,j];
                    c.f[sfy+k] = dy[i,j];
                    c.f[sfxy+k] = dxy[i,j];
                }
            }
        }
示例#23
0
        /*************************************************************************
        This subroutine calculates the value of the bilinear or bicubic spline  at
        the given point X and its derivatives.

        Input parameters:
            C   -   spline interpolant.
            X, Y-   point

        Output parameters:
            F   -   S(x,y)
            FX  -   dS(x,y)/dX
            FY  -   dS(x,y)/dY
            FXY -   d2S(x,y)/dXdY

          -- ALGLIB PROJECT --
             Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2ddiff(spline2dinterpolant c,
            double x,
            double y,
            ref double f,
            ref double fx,
            ref double fy,
            ref double fxy)
        {
            double t = 0;
            double dt = 0;
            double u = 0;
            double du = 0;
            int ix = 0;
            int iy = 0;
            int l = 0;
            int r = 0;
            int h = 0;
            int s1 = 0;
            int s2 = 0;
            int s3 = 0;
            int s4 = 0;
            int sfx = 0;
            int sfy = 0;
            int sfxy = 0;
            double y1 = 0;
            double y2 = 0;
            double y3 = 0;
            double y4 = 0;
            double v = 0;
            double t0 = 0;
            double t1 = 0;
            double t2 = 0;
            double t3 = 0;
            double u0 = 0;
            double u1 = 0;
            double u2 = 0;
            double u3 = 0;

            f = 0;
            fx = 0;
            fy = 0;
            fxy = 0;

            alglib.ap.assert(c.stype==-1 || c.stype==-3, "Spline2DDiff: incorrect C (incorrect parameter C.SType)");
            alglib.ap.assert(math.isfinite(x) && math.isfinite(y), "Spline2DDiff: X or Y contains NaN or Infinite value");
            
            //
            // Prepare F, dF/dX, dF/dY, d2F/dXdY
            //
            f = 0;
            fx = 0;
            fy = 0;
            fxy = 0;
            if( c.d!=1 )
            {
                return;
            }
            
            //
            // Binary search in the [ x[0], ..., x[n-2] ] (x[n-1] is not included)
            //
            l = 0;
            r = c.n-1;
            while( l!=r-1 )
            {
                h = (l+r)/2;
                if( (double)(c.x[h])>=(double)(x) )
                {
                    r = h;
                }
                else
                {
                    l = h;
                }
            }
            t = (x-c.x[l])/(c.x[l+1]-c.x[l]);
            dt = 1.0/(c.x[l+1]-c.x[l]);
            ix = l;
            
            //
            // Binary search in the [ y[0], ..., y[m-2] ] (y[m-1] is not included)
            //
            l = 0;
            r = c.m-1;
            while( l!=r-1 )
            {
                h = (l+r)/2;
                if( (double)(c.y[h])>=(double)(y) )
                {
                    r = h;
                }
                else
                {
                    l = h;
                }
            }
            u = (y-c.y[l])/(c.y[l+1]-c.y[l]);
            du = 1.0/(c.y[l+1]-c.y[l]);
            iy = l;
            
            //
            // Bilinear interpolation
            //
            if( c.stype==-1 )
            {
                y1 = c.f[c.n*iy+ix];
                y2 = c.f[c.n*iy+(ix+1)];
                y3 = c.f[c.n*(iy+1)+(ix+1)];
                y4 = c.f[c.n*(iy+1)+ix];
                f = (1-t)*(1-u)*y1+t*(1-u)*y2+t*u*y3+(1-t)*u*y4;
                fx = (-((1-u)*y1)+(1-u)*y2+u*y3-u*y4)*dt;
                fy = (-((1-t)*y1)-t*y2+t*y3+(1-t)*y4)*du;
                fxy = (y1-y2+y3-y4)*du*dt;
                return;
            }
            
            //
            // Bicubic interpolation
            //
            if( c.stype==-3 )
            {
                
                //
                // Prepare info
                //
                t0 = 1;
                t1 = t;
                t2 = math.sqr(t);
                t3 = t*t2;
                u0 = 1;
                u1 = u;
                u2 = math.sqr(u);
                u3 = u*u2;
                sfx = c.n*c.m;
                sfy = 2*c.n*c.m;
                sfxy = 3*c.n*c.m;
                s1 = c.n*iy+ix;
                s2 = c.n*iy+(ix+1);
                s3 = c.n*(iy+1)+(ix+1);
                s4 = c.n*(iy+1)+ix;
                
                //
                // Calculate
                //
                v = c.f[s1];
                f = f+v*t0*u0;
                v = c.f[sfy+s1]/du;
                f = f+v*t0*u1;
                fy = fy+v*t0*u0*du;
                v = -(3*c.f[s1])+3*c.f[s4]-2*c.f[sfy+s1]/du-c.f[sfy+s4]/du;
                f = f+v*t0*u2;
                fy = fy+2*v*t0*u1*du;
                v = 2*c.f[s1]-2*c.f[s4]+c.f[sfy+s1]/du+c.f[sfy+s4]/du;
                f = f+v*t0*u3;
                fy = fy+3*v*t0*u2*du;
                v = c.f[sfx+s1]/dt;
                f = f+v*t1*u0;
                fx = fx+v*t0*u0*dt;
                v = c.f[sfxy+s1]/(dt*du);
                f = f+v*t1*u1;
                fx = fx+v*t0*u1*dt;
                fy = fy+v*t1*u0*du;
                fxy = fxy+v*t0*u0*dt*du;
                v = -(3*c.f[sfx+s1]/dt)+3*c.f[sfx+s4]/dt-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s4]/(dt*du);
                f = f+v*t1*u2;
                fx = fx+v*t0*u2*dt;
                fy = fy+2*v*t1*u1*du;
                fxy = fxy+2*v*t0*u1*dt*du;
                v = 2*c.f[sfx+s1]/dt-2*c.f[sfx+s4]/dt+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s4]/(dt*du);
                f = f+v*t1*u3;
                fx = fx+v*t0*u3*dt;
                fy = fy+3*v*t1*u2*du;
                fxy = fxy+3*v*t0*u2*dt*du;
                v = -(3*c.f[s1])+3*c.f[s2]-2*c.f[sfx+s1]/dt-c.f[sfx+s2]/dt;
                f = f+v*t2*u0;
                fx = fx+2*v*t1*u0*dt;
                v = -(3*c.f[sfy+s1]/du)+3*c.f[sfy+s2]/du-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s2]/(dt*du);
                f = f+v*t2*u1;
                fx = fx+2*v*t1*u1*dt;
                fy = fy+v*t2*u0*du;
                fxy = fxy+2*v*t1*u0*dt*du;
                v = 9*c.f[s1]-9*c.f[s2]+9*c.f[s3]-9*c.f[s4]+6*c.f[sfx+s1]/dt+3*c.f[sfx+s2]/dt-3*c.f[sfx+s3]/dt-6*c.f[sfx+s4]/dt+6*c.f[sfy+s1]/du-6*c.f[sfy+s2]/du-3*c.f[sfy+s3]/du+3*c.f[sfy+s4]/du+4*c.f[sfxy+s1]/(dt*du)+2*c.f[sfxy+s2]/(dt*du)+c.f[sfxy+s3]/(dt*du)+2*c.f[sfxy+s4]/(dt*du);
                f = f+v*t2*u2;
                fx = fx+2*v*t1*u2*dt;
                fy = fy+2*v*t2*u1*du;
                fxy = fxy+4*v*t1*u1*dt*du;
                v = -(6*c.f[s1])+6*c.f[s2]-6*c.f[s3]+6*c.f[s4]-4*c.f[sfx+s1]/dt-2*c.f[sfx+s2]/dt+2*c.f[sfx+s3]/dt+4*c.f[sfx+s4]/dt-3*c.f[sfy+s1]/du+3*c.f[sfy+s2]/du+3*c.f[sfy+s3]/du-3*c.f[sfy+s4]/du-2*c.f[sfxy+s1]/(dt*du)-c.f[sfxy+s2]/(dt*du)-c.f[sfxy+s3]/(dt*du)-2*c.f[sfxy+s4]/(dt*du);
                f = f+v*t2*u3;
                fx = fx+2*v*t1*u3*dt;
                fy = fy+3*v*t2*u2*du;
                fxy = fxy+6*v*t1*u2*dt*du;
                v = 2*c.f[s1]-2*c.f[s2]+c.f[sfx+s1]/dt+c.f[sfx+s2]/dt;
                f = f+v*t3*u0;
                fx = fx+3*v*t2*u0*dt;
                v = 2*c.f[sfy+s1]/du-2*c.f[sfy+s2]/du+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s2]/(dt*du);
                f = f+v*t3*u1;
                fx = fx+3*v*t2*u1*dt;
                fy = fy+v*t3*u0*du;
                fxy = fxy+3*v*t2*u0*dt*du;
                v = -(6*c.f[s1])+6*c.f[s2]-6*c.f[s3]+6*c.f[s4]-3*c.f[sfx+s1]/dt-3*c.f[sfx+s2]/dt+3*c.f[sfx+s3]/dt+3*c.f[sfx+s4]/dt-4*c.f[sfy+s1]/du+4*c.f[sfy+s2]/du+2*c.f[sfy+s3]/du-2*c.f[sfy+s4]/du-2*c.f[sfxy+s1]/(dt*du)-2*c.f[sfxy+s2]/(dt*du)-c.f[sfxy+s3]/(dt*du)-c.f[sfxy+s4]/(dt*du);
                f = f+v*t3*u2;
                fx = fx+3*v*t2*u2*dt;
                fy = fy+2*v*t3*u1*du;
                fxy = fxy+6*v*t2*u1*dt*du;
                v = 4*c.f[s1]-4*c.f[s2]+4*c.f[s3]-4*c.f[s4]+2*c.f[sfx+s1]/dt+2*c.f[sfx+s2]/dt-2*c.f[sfx+s3]/dt-2*c.f[sfx+s4]/dt+2*c.f[sfy+s1]/du-2*c.f[sfy+s2]/du-2*c.f[sfy+s3]/du+2*c.f[sfy+s4]/du+c.f[sfxy+s1]/(dt*du)+c.f[sfxy+s2]/(dt*du)+c.f[sfxy+s3]/(dt*du)+c.f[sfxy+s4]/(dt*du);
                f = f+v*t3*u3;
                fx = fx+3*v*t2*u3*dt;
                fy = fy+3*v*t3*u2*du;
                fxy = fxy+9*v*t2*u2*dt*du;
                return;
            }
        }
示例#24
0
        /*************************************************************************
        Serialization of the spline interpolant

        INPUT PARAMETERS:
            B   -   spline interpolant

        OUTPUT PARAMETERS:
            RA      -   array of real numbers which contains interpolant,
                        array[0..RLen-1]
            RLen    -   RA lenght

          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dserialize(ref spline2dinterpolant c,
            ref double[] ra,
            ref int ralen)
        {
            int clen = 0;
            int i_ = 0;
            int i1_ = 0;

            System.Diagnostics.Debug.Assert(c.k==1 | c.k==3, "Spline2DSerialize: incorrect C!");
            clen = (int)Math.Round(c.c[0]);
            ralen = 3+clen;
            ra = new double[ralen];
            ra[0] = ralen;
            ra[1] = spline2dvnum;
            ra[2] = c.k;
            i1_ = (0) - (3);
            for(i_=3; i_<=3+clen-1;i_++)
            {
                ra[i_] = c.c[i_+i1_];
            }
        }
示例#25
0
        /*************************************************************************
        This subroutine performs linear transformation of the spline argument.

        Input parameters:
            C       -   spline interpolant
            AX, BX  -   transformation coefficients: x = A*t + B
            AY, BY  -   transformation coefficients: y = A*u + B
        Result:
            C   -   transformed spline

          -- ALGLIB PROJECT --
             Copyright 30.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dlintransxy(spline2dinterpolant c,
            double ax,
            double bx,
            double ay,
            double by)
        {
            double[] x = new double[0];
            double[] y = new double[0];
            double[] f = new double[0];
            double[] v = new double[0];
            int i = 0;
            int j = 0;
            int k = 0;

            alglib.ap.assert(c.stype==-3 || c.stype==-1, "Spline2DLinTransXY: incorrect C (incorrect parameter C.SType)");
            alglib.ap.assert(math.isfinite(ax), "Spline2DLinTransXY: AX is infinite or NaN");
            alglib.ap.assert(math.isfinite(bx), "Spline2DLinTransXY: BX is infinite or NaN");
            alglib.ap.assert(math.isfinite(ay), "Spline2DLinTransXY: AY is infinite or NaN");
            alglib.ap.assert(math.isfinite(by), "Spline2DLinTransXY: BY is infinite or NaN");
            x = new double[c.n];
            y = new double[c.m];
            f = new double[c.m*c.n*c.d];
            for(j=0; j<=c.n-1; j++)
            {
                x[j] = c.x[j];
            }
            for(i=0; i<=c.m-1; i++)
            {
                y[i] = c.y[i];
            }
            for(i=0; i<=c.m-1; i++)
            {
                for(j=0; j<=c.n-1; j++)
                {
                    for(k=0; k<=c.d-1; k++)
                    {
                        f[c.d*(i*c.n+j)+k] = c.f[c.d*(i*c.n+j)+k];
                    }
                }
            }
            
            //
            // Handle different combinations of AX/AY
            //
            if( (double)(ax)==(double)(0) && (double)(ay)!=(double)(0) )
            {
                for(i=0; i<=c.m-1; i++)
                {
                    spline2dcalcvbuf(c, bx, y[i], ref v);
                    y[i] = (y[i]-by)/ay;
                    for(j=0; j<=c.n-1; j++)
                    {
                        for(k=0; k<=c.d-1; k++)
                        {
                            f[c.d*(i*c.n+j)+k] = v[k];
                        }
                    }
                }
            }
            if( (double)(ax)!=(double)(0) && (double)(ay)==(double)(0) )
            {
                for(j=0; j<=c.n-1; j++)
                {
                    spline2dcalcvbuf(c, x[j], by, ref v);
                    x[j] = (x[j]-bx)/ax;
                    for(i=0; i<=c.m-1; i++)
                    {
                        for(k=0; k<=c.d-1; k++)
                        {
                            f[c.d*(i*c.n+j)+k] = v[k];
                        }
                    }
                }
            }
            if( (double)(ax)!=(double)(0) && (double)(ay)!=(double)(0) )
            {
                for(j=0; j<=c.n-1; j++)
                {
                    x[j] = (x[j]-bx)/ax;
                }
                for(i=0; i<=c.m-1; i++)
                {
                    y[i] = (y[i]-by)/ay;
                }
            }
            if( (double)(ax)==(double)(0) && (double)(ay)==(double)(0) )
            {
                spline2dcalcvbuf(c, bx, by, ref v);
                for(i=0; i<=c.m-1; i++)
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        for(k=0; k<=c.d-1; k++)
                        {
                            f[c.d*(i*c.n+j)+k] = v[k];
                        }
                    }
                }
            }
            
            //
            // Rebuild spline
            //
            if( c.stype==-3 )
            {
                spline2dbuildbicubicv(x, c.n, y, c.m, f, c.d, c);
            }
            if( c.stype==-1 )
            {
                spline2dbuildbilinearv(x, c.n, y, c.m, f, c.d, c);
            }
        }
示例#26
0
        /*************************************************************************
        *  This subroutine builds bilinear spline coefficients table.
        *
        *  Input parameters:
        *   X   -   spline abscissas, array[0..N-1]
        *   Y   -   spline ordinates, array[0..M-1]
        *   F   -   function values, array[0..M-1,0..N-1]
        *   M,N -   grid size, M>=2, N>=2
        *
        *  Output parameters:
        *   C   -   spline interpolant
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dbuildbilinear(double[] x,
                                                 double[] y,
                                                 double[,] f,
                                                 int m,
                                                 int n,
                                                 ref spline2dinterpolant c)
        {
            int    i       = 0;
            int    j       = 0;
            int    k       = 0;
            int    tblsize = 0;
            int    shift   = 0;
            double t       = 0;

            double[,] dx  = new double[0, 0];
            double[,] dy  = new double[0, 0];
            double[,] dxy = new double[0, 0];

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            f = (double[, ])f.Clone();

            System.Diagnostics.Debug.Assert(n >= 2 & m >= 2, "Spline2DBuildBilinear: N<2 or M<2!");

            //
            // Sort points
            //
            for (j = 0; j <= n - 1; j++)
            {
                k = j;
                for (i = j + 1; i <= n - 1; i++)
                {
                    if ((double)(x[i]) < (double)(x[k]))
                    {
                        k = i;
                    }
                }
                if (k != j)
                {
                    for (i = 0; i <= m - 1; i++)
                    {
                        t       = f[i, j];
                        f[i, j] = f[i, k];
                        f[i, k] = t;
                    }
                    t    = x[j];
                    x[j] = x[k];
                    x[k] = t;
                }
            }
            for (i = 0; i <= m - 1; i++)
            {
                k = i;
                for (j = i + 1; j <= m - 1; j++)
                {
                    if ((double)(y[j]) < (double)(y[k]))
                    {
                        k = j;
                    }
                }
                if (k != i)
                {
                    for (j = 0; j <= n - 1; j++)
                    {
                        t       = f[i, j];
                        f[i, j] = f[k, j];
                        f[k, j] = t;
                    }
                    t    = y[i];
                    y[i] = y[k];
                    y[k] = t;
                }
            }

            //
            // Fill C:
            //  C[0]            -   length(C)
            //  C[1]            -   type(C):
            //                      -1 = bilinear interpolant
            //                      -3 = general cubic spline
            //                           (see BuildBicubicSpline)
            //  C[2]:
            //      N (x count)
            //  C[3]:
            //      M (y count)
            //  C[4]...C[4+N-1]:
            //      x[i], i = 0...N-1
            //  C[4+N]...C[4+N+M-1]:
            //      y[i], i = 0...M-1
            //  C[4+N+M]...C[4+N+M+(N*M-1)]:
            //      f(i,j) table. f(0,0), f(0, 1), f(0,2) and so on...
            //
            c.k     = 1;
            tblsize = 4 + n + m + n * m;
            c.c     = new double[tblsize - 1 + 1];
            c.c[0]  = tblsize;
            c.c[1]  = -1;
            c.c[2]  = n;
            c.c[3]  = m;
            for (i = 0; i <= n - 1; i++)
            {
                c.c[4 + i] = x[i];
            }
            for (i = 0; i <= m - 1; i++)
            {
                c.c[4 + n + i] = y[i];
            }
            for (i = 0; i <= m - 1; i++)
            {
                for (j = 0; j <= n - 1; j++)
                {
                    shift = i * n + j;
                    c.c[4 + n + m + shift] = f[i, j];
                }
            }
        }
示例#27
0
        /*************************************************************************
        This subroutine makes the copy of the spline model.

        Input parameters:
            C   -   spline interpolant

        Output parameters:
            CC  -   spline copy

          -- ALGLIB PROJECT --
             Copyright 29.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dcopy(ref spline2dinterpolant c,
            ref spline2dinterpolant cc)
        {
            int n = 0;
            int i_ = 0;

            System.Diagnostics.Debug.Assert(c.k==1 | c.k==3, "Spline2DCopy: incorrect C!");
            cc.k = c.k;
            n = (int)Math.Round(c.c[0]);
            cc.c = new double[n];
            for(i_=0; i_<=n-1;i_++)
            {
                cc.c[i_] = c.c[i_];
            }
        }
示例#28
0
        /*************************************************************************
        *  This subroutine performs linear transformation of the spline argument.
        *
        *  Input parameters:
        *   C       -   spline interpolant
        *   AX, BX  -   transformation coefficients: x = A*t + B
        *   AY, BY  -   transformation coefficients: y = A*u + B
        *  Result:
        *   C   -   transformed spline
        *
        *  -- ALGLIB PROJECT --
        *    Copyright 30.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dlintransxy(ref spline2dinterpolant c,
                                              double ax,
                                              double bx,
                                              double ay,
                                              double by)
        {
            int    i = 0;
            int    j = 0;
            int    n = 0;
            int    m = 0;
            double v = 0;

            double[] x = new double[0];
            double[] y = new double[0];
            double[,] f = new double[0, 0];
            int typec = 0;

            typec = (int)Math.Round(c.c[1]);
            System.Diagnostics.Debug.Assert(typec == -3 | typec == -1, "Spline2DLinTransXY: incorrect C!");
            n = (int)Math.Round(c.c[2]);
            m = (int)Math.Round(c.c[3]);
            x = new double[n - 1 + 1];
            y = new double[m - 1 + 1];
            f = new double[m - 1 + 1, n - 1 + 1];
            for (j = 0; j <= n - 1; j++)
            {
                x[j] = c.c[4 + j];
            }
            for (i = 0; i <= m - 1; i++)
            {
                y[i] = c.c[4 + n + i];
            }
            for (i = 0; i <= m - 1; i++)
            {
                for (j = 0; j <= n - 1; j++)
                {
                    f[i, j] = c.c[4 + n + m + i * n + j];
                }
            }

            //
            // Special case: AX=0 or AY=0
            //
            if ((double)(ax) == (double)(0))
            {
                for (i = 0; i <= m - 1; i++)
                {
                    v = spline2dcalc(ref c, bx, y[i]);
                    for (j = 0; j <= n - 1; j++)
                    {
                        f[i, j] = v;
                    }
                }
                if (typec == -3)
                {
                    spline2dbuildbicubic(x, y, f, m, n, ref c);
                }
                if (typec == -1)
                {
                    spline2dbuildbilinear(x, y, f, m, n, ref c);
                }
                ax = 1;
                bx = 0;
            }
            if ((double)(ay) == (double)(0))
            {
                for (j = 0; j <= n - 1; j++)
                {
                    v = spline2dcalc(ref c, x[j], by);
                    for (i = 0; i <= m - 1; i++)
                    {
                        f[i, j] = v;
                    }
                }
                if (typec == -3)
                {
                    spline2dbuildbicubic(x, y, f, m, n, ref c);
                }
                if (typec == -1)
                {
                    spline2dbuildbilinear(x, y, f, m, n, ref c);
                }
                ay = 1;
                by = 0;
            }

            //
            // General case: AX<>0, AY<>0
            // Unpack, scale and pack again.
            //
            for (j = 0; j <= n - 1; j++)
            {
                x[j] = (x[j] - bx) / ax;
            }
            for (i = 0; i <= m - 1; i++)
            {
                y[i] = (y[i] - by) / ay;
            }
            if (typec == -3)
            {
                spline2dbuildbicubic(x, y, f, m, n, ref c);
            }
            if (typec == -1)
            {
                spline2dbuildbilinear(x, y, f, m, n, ref c);
            }
        }
示例#29
0
        /*************************************************************************
        This subroutine builds bilinear vector-valued spline.

        Input parameters:
            X   -   spline abscissas, array[0..N-1]
            Y   -   spline ordinates, array[0..M-1]
            F   -   function values, array[0..M*N*D-1]:
                    * first D elements store D values at (X[0],Y[0])
                    * next D elements store D values at (X[1],Y[0])
                    * general form - D function values at (X[i],Y[j]) are stored
                      at F[D*(J*N+I)...D*(J*N+I)+D-1].
            M,N -   grid size, M>=2, N>=2
            D   -   vector dimension, D>=1

        Output parameters:
            C   -   spline interpolant

          -- ALGLIB PROJECT --
             Copyright 16.04.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dbuildbilinearv(double[] x,
            int n,
            double[] y,
            int m,
            double[] f,
            int d,
            spline2dinterpolant c)
        {
            double t = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int i0 = 0;

            alglib.ap.assert(n>=2, "Spline2DBuildBilinearV: N is less then 2");
            alglib.ap.assert(m>=2, "Spline2DBuildBilinearV: M is less then 2");
            alglib.ap.assert(d>=1, "Spline2DBuildBilinearV: invalid argument D (D<1)");
            alglib.ap.assert(alglib.ap.len(x)>=n && alglib.ap.len(y)>=m, "Spline2DBuildBilinearV: length of X or Y is too short (Length(X/Y)<N/M)");
            alglib.ap.assert(apserv.isfinitevector(x, n) && apserv.isfinitevector(y, m), "Spline2DBuildBilinearV: X or Y contains NaN or Infinite value");
            k = n*m*d;
            alglib.ap.assert(alglib.ap.len(f)>=k, "Spline2DBuildBilinearV: length of F is too short (Length(F)<N*M*D)");
            alglib.ap.assert(apserv.isfinitevector(f, k), "Spline2DBuildBilinearV: F contains NaN or Infinite value");
            
            //
            // Fill interpolant
            //
            c.k = 1;
            c.n = n;
            c.m = m;
            c.d = d;
            c.stype = -1;
            c.x = new double[c.n];
            c.y = new double[c.m];
            c.f = new double[k];
            for(i=0; i<=c.n-1; i++)
            {
                c.x[i] = x[i];
            }
            for(i=0; i<=c.m-1; i++)
            {
                c.y[i] = y[i];
            }
            for(i=0; i<=k-1; i++)
            {
                c.f[i] = f[i];
            }
            
            //
            // Sort points
            //
            for(j=0; j<=c.n-1; j++)
            {
                k = j;
                for(i=j+1; i<=c.n-1; i++)
                {
                    if( (double)(c.x[i])<(double)(c.x[k]) )
                    {
                        k = i;
                    }
                }
                if( k!=j )
                {
                    for(i=0; i<=c.m-1; i++)
                    {
                        for(i0=0; i0<=c.d-1; i0++)
                        {
                            t = c.f[c.d*(i*c.n+j)+i0];
                            c.f[c.d*(i*c.n+j)+i0] = c.f[c.d*(i*c.n+k)+i0];
                            c.f[c.d*(i*c.n+k)+i0] = t;
                        }
                    }
                    t = c.x[j];
                    c.x[j] = c.x[k];
                    c.x[k] = t;
                }
            }
            for(i=0; i<=c.m-1; i++)
            {
                k = i;
                for(j=i+1; j<=c.m-1; j++)
                {
                    if( (double)(c.y[j])<(double)(c.y[k]) )
                    {
                        k = j;
                    }
                }
                if( k!=i )
                {
                    for(j=0; j<=c.n-1; j++)
                    {
                        for(i0=0; i0<=c.d-1; i0++)
                        {
                            t = c.f[c.d*(i*c.n+j)+i0];
                            c.f[c.d*(i*c.n+j)+i0] = c.f[c.d*(k*c.n+j)+i0];
                            c.f[c.d*(k*c.n+j)+i0] = t;
                        }
                    }
                    t = c.y[i];
                    c.y[i] = c.y[k];
                    c.y[k] = t;
                }
            }
        }
示例#30
0
        /*************************************************************************
        This subroutine performs linear transformation of the spline.

        Input parameters:
            C   -   spline interpolant.
            A, B-   transformation coefficients: S2(x,y) = A*S(x,y) + B
            
        Output parameters:
            C   -   transformed spline

          -- ALGLIB PROJECT --
             Copyright 30.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dlintransf(spline2dinterpolant c,
            double a,
            double b)
        {
            double[] x = new double[0];
            double[] y = new double[0];
            double[] f = new double[0];
            int i = 0;
            int j = 0;

            alglib.ap.assert(c.stype==-3 || c.stype==-1, "Spline2DLinTransF: incorrect C (incorrect parameter C.SType)");
            x = new double[c.n];
            y = new double[c.m];
            f = new double[c.m*c.n*c.d];
            for(j=0; j<=c.n-1; j++)
            {
                x[j] = c.x[j];
            }
            for(i=0; i<=c.m-1; i++)
            {
                y[i] = c.y[i];
            }
            for(i=0; i<=c.m*c.n*c.d-1; i++)
            {
                f[i] = a*c.f[i]+b;
            }
            if( c.stype==-3 )
            {
                spline2dbuildbicubicv(x, c.n, y, c.m, f, c.d, c);
            }
            if( c.stype==-1 )
            {
                spline2dbuildbilinearv(x, c.n, y, c.m, f, c.d, c);
            }
        }
示例#31
0
        /*************************************************************************
        Unserialization of the spline interpolant

        INPUT PARAMETERS:
            RA  -   array of real numbers which contains interpolant,

        OUTPUT PARAMETERS:
            B   -   spline interpolant

          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dunserialize(ref double[] ra,
            ref spline2dinterpolant c)
        {
            int clen = 0;
            int i_ = 0;
            int i1_ = 0;

            System.Diagnostics.Debug.Assert((int)Math.Round(ra[1])==spline2dvnum, "Spline2DUnserialize: corrupted array!");
            c.k = (int)Math.Round(ra[2]);
            clen = (int)Math.Round(ra[3]);
            c.c = new double[clen];
            i1_ = (3) - (0);
            for(i_=0; i_<=clen-1;i_++)
            {
                c.c[i_] = ra[i_+i1_];
            }
        }
示例#32
0
        /*************************************************************************
        This subroutine makes the copy of the spline model.

        Input parameters:
            C   -   spline interpolant

        Output parameters:
            CC  -   spline copy

          -- ALGLIB PROJECT --
             Copyright 29.06.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dcopy(spline2dinterpolant c,
            spline2dinterpolant cc)
        {
            int tblsize = 0;
            int i_ = 0;

            alglib.ap.assert(c.k==1 || c.k==3, "Spline2DCopy: incorrect C (incorrect parameter C.K)");
            cc.k = c.k;
            cc.n = c.n;
            cc.m = c.m;
            cc.d = c.d;
            cc.stype = c.stype;
            tblsize = -1;
            if( c.stype==-3 )
            {
                tblsize = 4*c.n*c.m*c.d;
            }
            if( c.stype==-1 )
            {
                tblsize = c.n*c.m*c.d;
            }
            alglib.ap.assert(tblsize>0, "Spline2DCopy: internal error");
            cc.x = new double[cc.n];
            cc.y = new double[cc.m];
            cc.f = new double[tblsize];
            for(i_=0; i_<=cc.n-1;i_++)
            {
                cc.x[i_] = c.x[i_];
            }
            for(i_=0; i_<=cc.m-1;i_++)
            {
                cc.y[i_] = c.y[i_];
            }
            for(i_=0; i_<=tblsize-1;i_++)
            {
                cc.f[i_] = c.f[i_];
            }
        }
示例#33
0
        /*************************************************************************
        This subroutine builds bilinear spline coefficients table.

        Input parameters:
            X   -   spline abscissas, array[0..N-1]
            Y   -   spline ordinates, array[0..M-1]
            F   -   function values, array[0..M-1,0..N-1]
            M,N -   grid size, M>=2, N>=2

        Output parameters:
            C   -   spline interpolant

          -- ALGLIB PROJECT --
             Copyright 05.07.2007 by Bochkanov Sergey
        *************************************************************************/
        public static void spline2dbuildbilinear(double[] x,
            double[] y,
            double[,] f,
            int m,
            int n,
            ref spline2dinterpolant c)
        {
            int i = 0;
            int j = 0;
            int k = 0;
            int tblsize = 0;
            int shift = 0;
            double t = 0;
            double[,] dx = new double[0,0];
            double[,] dy = new double[0,0];
            double[,] dxy = new double[0,0];

            x = (double[])x.Clone();
            y = (double[])y.Clone();
            f = (double[,])f.Clone();

            System.Diagnostics.Debug.Assert(n>=2 & m>=2, "Spline2DBuildBilinear: N<2 or M<2!");
            
            //
            // Sort points
            //
            for(j=0; j<=n-1; j++)
            {
                k = j;
                for(i=j+1; i<=n-1; i++)
                {
                    if( (double)(x[i])<(double)(x[k]) )
                    {
                        k = i;
                    }
                }
                if( k!=j )
                {
                    for(i=0; i<=m-1; i++)
                    {
                        t = f[i,j];
                        f[i,j] = f[i,k];
                        f[i,k] = t;
                    }
                    t = x[j];
                    x[j] = x[k];
                    x[k] = t;
                }
            }
            for(i=0; i<=m-1; i++)
            {
                k = i;
                for(j=i+1; j<=m-1; j++)
                {
                    if( (double)(y[j])<(double)(y[k]) )
                    {
                        k = j;
                    }
                }
                if( k!=i )
                {
                    for(j=0; j<=n-1; j++)
                    {
                        t = f[i,j];
                        f[i,j] = f[k,j];
                        f[k,j] = t;
                    }
                    t = y[i];
                    y[i] = y[k];
                    y[k] = t;
                }
            }
            
            //
            // Fill C:
            //  C[0]            -   length(C)
            //  C[1]            -   type(C):
            //                      -1 = bilinear interpolant
            //                      -3 = general cubic spline
            //                           (see BuildBicubicSpline)
            //  C[2]:
            //      N (x count)
            //  C[3]:
            //      M (y count)
            //  C[4]...C[4+N-1]:
            //      x[i], i = 0...N-1
            //  C[4+N]...C[4+N+M-1]:
            //      y[i], i = 0...M-1
            //  C[4+N+M]...C[4+N+M+(N*M-1)]:
            //      f(i,j) table. f(0,0), f(0, 1), f(0,2) and so on...
            //
            c.k = 1;
            tblsize = 4+n+m+n*m;
            c.c = new double[tblsize-1+1];
            c.c[0] = tblsize;
            c.c[1] = -1;
            c.c[2] = n;
            c.c[3] = m;
            for(i=0; i<=n-1; i++)
            {
                c.c[4+i] = x[i];
            }
            for(i=0; i<=m-1; i++)
            {
                c.c[4+n+i] = y[i];
            }
            for(i=0; i<=m-1; i++)
            {
                for(j=0; j<=n-1; j++)
                {
                    shift = i*n+j;
                    c.c[4+n+m+shift] = f[i,j];
                }
            }
        }