Ejemplo n.º 1
0
        /*************************************************************************
        This function calculates values of the RBF model at the given point.

        This is general function which can be used for arbitrary NX (dimension  of 
        the space of arguments) and NY (dimension of the function itself). However
        when  you  have  NY=1  you  may  find more convenient to use RBFCalc2() or 
        RBFCalc3().

        This function returns 0.0 when model is not initialized.

        INPUT PARAMETERS:
            S       -   RBF model
            X       -   coordinates, array[NX].
                        X may have more than NX elements, in this case only 
                        leading NX will be used.

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

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfcalc(rbfmodel s,
            double[] x,
            ref double[] y)
        {
            y = new double[0];

            alglib.ap.assert(alglib.ap.len(x)>=s.nx, "RBFCalc: Length(X)<NX");
            alglib.ap.assert(apserv.isfinitevector(x, s.nx), "RBFCalc: X contains infinite or NaN values");
            rbfcalcbuf(s, x, ref y);
        }
Ejemplo n.º 2
0
        /*************************************************************************
        This function calculates values of the RBF model in the given point.

        This function should be used when we have NY=1 (scalar function) and  NX=2
        (2-dimensional space). If you have 3-dimensional space, use RBFCalc3(). If
        you have general situation (NX-dimensional space, NY-dimensional function)
        you should use general, less efficient implementation RBFCalc().

        If  you  want  to  calculate  function  values  many times, consider using 
        RBFGridCalc2(), which is far more efficient than many subsequent calls  to
        RBFCalc2().

        This function returns 0.0 when:
        * model is not initialized
        * NX<>2
         *NY<>1

        INPUT PARAMETERS:
            S       -   RBF model
            X0      -   first coordinate, finite number
            X1      -   second coordinate, finite number

        RESULT:
            value of the model or 0.0 (as defined above)

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static double rbfcalc2(rbfmodel s,
            double x0,
            double x1)
        {
            double result = 0;
            int i = 0;
            int j = 0;
            int lx = 0;
            int tg = 0;
            double d2 = 0;
            double t = 0;
            double bfcur = 0;
            double rcur = 0;

            alglib.ap.assert(math.isfinite(x0), "RBFCalc2: invalid value for X0 (X0 is Inf)!");
            alglib.ap.assert(math.isfinite(x1), "RBFCalc2: invalid value for X1 (X1 is Inf)!");
            if( s.ny!=1 || s.nx!=2 )
            {
                result = 0;
                return result;
            }
            result = s.v[0,0]*x0+s.v[0,1]*x1+s.v[0,mxnx];
            if( s.nc==0 )
            {
                return result;
            }
            apserv.rvectorsetlengthatleast(ref s.calcbufxcx, mxnx);
            for(i=0; i<=mxnx-1; i++)
            {
                s.calcbufxcx[i] = 0.0;
            }
            s.calcbufxcx[0] = x0;
            s.calcbufxcx[1] = x1;
            lx = nearestneighbor.kdtreequeryrnn(s.tree, s.calcbufxcx, s.rmax*rbffarradius, true);
            nearestneighbor.kdtreequeryresultsx(s.tree, ref s.calcbufx);
            nearestneighbor.kdtreequeryresultstags(s.tree, ref s.calcbuftags);
            for(i=0; i<=lx-1; i++)
            {
                tg = s.calcbuftags[i];
                d2 = math.sqr(x0-s.calcbufx[i,0])+math.sqr(x1-s.calcbufx[i,1]);
                rcur = s.wr[tg,0];
                bfcur = Math.Exp(-(d2/(rcur*rcur)));
                for(j=0; j<=s.nl-1; j++)
                {
                    result = result+bfcur*s.wr[tg,1+j];
                    rcur = 0.5*rcur;
                    t = bfcur*bfcur;
                    bfcur = t*t;
                }
            }
            return result;
        }
Ejemplo n.º 3
0
        /*************************************************************************
        This function calculates values of the RBF model in the given point.

        This function should be used when we have NY=1 (scalar function) and  NX=3
        (3-dimensional space). If you have 2-dimensional space, use RBFCalc2(). If
        you have general situation (NX-dimensional space, NY-dimensional function)
        you should use general, less efficient implementation RBFCalc().

        This function returns 0.0 when:
        * model is not initialized
        * NX<>3
         *NY<>1

        INPUT PARAMETERS:
            S       -   RBF model
            X0      -   first coordinate, finite number
            X1      -   second coordinate, finite number
            X2      -   third coordinate, finite number

        RESULT:
            value of the model or 0.0 (as defined above)

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static double rbfcalc3(rbfmodel s,
            double x0,
            double x1,
            double x2)
        {
            double result = 0;
            int i = 0;
            int j = 0;
            int lx = 0;
            int tg = 0;
            double t = 0;
            double rcur = 0;
            double bf = 0;

            alglib.ap.assert(math.isfinite(x0), "RBFCalc3: invalid value for X0 (X0 is Inf or NaN)!");
            alglib.ap.assert(math.isfinite(x1), "RBFCalc3: invalid value for X1 (X1 is Inf or NaN)!");
            alglib.ap.assert(math.isfinite(x2), "RBFCalc3: invalid value for X2 (X2 is Inf or NaN)!");
            if( s.ny!=1 || s.nx!=3 )
            {
                result = 0;
                return result;
            }
            result = s.v[0,0]*x0+s.v[0,1]*x1+s.v[0,2]*x2+s.v[0,mxnx];
            if( s.nc==0 )
            {
                return result;
            }
            
            //
            // calculating value for F(X)
            //
            apserv.rvectorsetlengthatleast(ref s.calcbufxcx, mxnx);
            for(i=0; i<=mxnx-1; i++)
            {
                s.calcbufxcx[i] = 0.0;
            }
            s.calcbufxcx[0] = x0;
            s.calcbufxcx[1] = x1;
            s.calcbufxcx[2] = x2;
            lx = nearestneighbor.kdtreequeryrnn(s.tree, s.calcbufxcx, s.rmax*rbffarradius, true);
            nearestneighbor.kdtreequeryresultsx(s.tree, ref s.calcbufx);
            nearestneighbor.kdtreequeryresultstags(s.tree, ref s.calcbuftags);
            for(i=0; i<=lx-1; i++)
            {
                tg = s.calcbuftags[i];
                rcur = s.wr[tg,0];
                bf = Math.Exp(-((math.sqr(x0-s.calcbufx[i,0])+math.sqr(x1-s.calcbufx[i,1])+math.sqr(x2-s.calcbufx[i,2]))/math.sqr(rcur)));
                for(j=0; j<=s.nl-1; j++)
                {
                    result = result+bf*s.wr[tg,1+j];
                    t = bf*bf;
                    bf = t*t;
                }
            }
            return result;
        }
Ejemplo n.º 4
0
        /*************************************************************************
        This function changes centers allocation algorithm to one which  allocates
        centers exactly at the dataset points (one input point = one center). This
        function won't have effect until next call to RBFBuildModel().

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        private static void rbfgridpoints(rbfmodel s)
        {
            s.gridtype = 2;
        }
        /*************************************************************************
        This function sets centers, defined by user.

        This function overrides results of the previous calls, i.e. multiple calls
        of this function will result in only the last set being added.

        INPUT PARAMETERS:
            S      -   RBF model, initialized by RBFCreate() call.
          CXY      -   centers, array[N,NX]. Centers must be distinct, 
                       non-distinct centers are not supported.
           NC      -   number of centers

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        private static void rbfgridspecial(rbfmodel s,
            double[,] cxy,
            int nc)
        {
            int i = 0;
            int j = 0;

            alglib.ap.assert(nc>0, "RBFGridSpecial: N<0");
            alglib.ap.assert(nc<=alglib.ap.rows(cxy), "RBFGridSpecial: Length(CXY)<NC");
            s.gridtype = 3;
            s.nc = nc;
            s.xc = new double[s.nc, mxnx];
            for(i=0; i<=s.nc-1; i++)
            {
                for(j=0; j<=mxnx-1; j++)
                {
                    s.xc[i,j] = 0;
                }
                for(j=0; j<=s.nx-1; j++)
                {
                    s.xc[i,j] = cxy[i,j];
                }
            }
        }
Ejemplo n.º 6
0
        /*************************************************************************
        This function "unpacks" RBF model by extracting its coefficients.

        INPUT PARAMETERS:
            S       -   RBF model

        OUTPUT PARAMETERS:
            NX      -   dimensionality of argument
            NY      -   dimensionality of the target function
            XWR     -   model information, array[NC,NX+NY+1].
                        One row of the array corresponds to one basis function:
                        * first NX columns  - coordinates of the center 
                        * next NY columns   - weights, one per dimension of the 
                                              function being modelled
                        * last column       - radius, same for all dimensions of
                                              the function being modelled
            NC      -   number of the centers
            V       -   polynomial  term , array[NY,NX+1]. One row per one 
                        dimension of the function being modelled. First NX 
                        elements are linear coefficients, V[NX] is equal to the 
                        constant part.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfunpack(rbfmodel s,
            ref int nx,
            ref int ny,
            ref double[,] xwr,
            ref int nc,
            ref double[,] v)
        {
            int i = 0;
            int j = 0;
            double rcur = 0;
            int i_ = 0;
            int i1_ = 0;

            nx = 0;
            ny = 0;
            xwr = new double[0,0];
            nc = 0;
            v = new double[0,0];

            nx = s.nx;
            ny = s.ny;
            nc = s.nc;
            
            //
            // Fill V
            //
            v = new double[s.ny, s.nx+1];
            for(i=0; i<=s.ny-1; i++)
            {
                for(i_=0; i_<=s.nx-1;i_++)
                {
                    v[i,i_] = s.v[i,i_];
                }
                v[i,s.nx] = s.v[i,mxnx];
            }
            
            //
            // Fill XWR and V
            //
            if( nc*s.nl>0 )
            {
                xwr = new double[s.nc*s.nl, s.nx+s.ny+1];
                for(i=0; i<=s.nc-1; i++)
                {
                    rcur = s.wr[i,0];
                    for(j=0; j<=s.nl-1; j++)
                    {
                        for(i_=0; i_<=s.nx-1;i_++)
                        {
                            xwr[i*s.nl+j,i_] = s.xc[i,i_];
                        }
                        i1_ = (1+j*s.ny) - (s.nx);
                        for(i_=s.nx; i_<=s.nx+s.ny-1;i_++)
                        {
                            xwr[i*s.nl+j,i_] = s.wr[i,i_+i1_];
                        }
                        xwr[i*s.nl+j,s.nx+s.ny] = rcur;
                        rcur = 0.5*rcur;
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /*************************************************************************
        Serializer: serialization

          -- ALGLIB --
             Copyright 02.02.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfserialize(alglib.serializer s,
            rbfmodel model)
        {
            
            //
            // Header
            //
            s.serialize_int(scodes.getrbfserializationcode());
            s.serialize_int(rbffirstversion);
            
            //
            // Data
            //
            s.serialize_int(model.nx);
            s.serialize_int(model.ny);
            s.serialize_int(model.nc);
            s.serialize_int(model.nl);
            nearestneighbor.kdtreeserialize(s, model.tree);
            apserv.serializerealmatrix(s, model.xc, -1, -1);
            apserv.serializerealmatrix(s, model.wr, -1, -1);
            s.serialize_double(model.rmax);
            apserv.serializerealmatrix(s, model.v, -1, -1);
        }
Ejemplo n.º 8
0
        /*************************************************************************
        This  function  sets  RBF interpolation algorithm. ALGLIB supports several
        RBF algorithms with different properties.

        This  algorithm is called RBF-ML. It builds  multilayer  RBF  model,  i.e.
        model with subsequently decreasing  radii,  which  allows  us  to  combine
        smoothness (due to  large radii of  the first layers) with  exactness (due
        to small radii of the last layers) and fast convergence.

        Internally RBF-ML uses many different  means  of acceleration, from sparse
        matrices  to  KD-trees,  which  results in algorithm whose working time is
        roughly proportional to N*log(N)*Density*RBase^2*NLayers,  where  N  is  a
        number of points, Density is an average density if points per unit of  the
        interpolation space, RBase is an initial radius, NLayers is  a  number  of
        layers.

        RBF-ML is good for following kinds of interpolation problems:
        1. "exact" problems (perfect fit) with well separated points
        2. least squares problems with arbitrary distribution of points (algorithm
           gives  perfect  fit  where it is possible, and resorts to least squares
           fit in the hard areas).
        3. noisy problems where  we  want  to  apply  some  controlled  amount  of
           smoothing.

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call
            RBase   -   RBase parameter, RBase>0
            NLayers -   NLayers parameter, NLayers>0, recommended value  to  start
                        with - about 5.
            LambdaV -   regularization value, can be useful when  solving  problem
                        in the least squares sense.  Optimal  lambda  is  problem-
                        dependent and require trial and error. In our  experience,
                        good lambda can be as large as 0.1, and you can use  0.001
                        as initial guess.
                        Default  value  - 0.01, which is used when LambdaV is  not
                        given.  You  can  specify  zero  value,  but  it  is   not
                        recommended to do so.

        TUNING ALGORITHM

        In order to use this algorithm you have to choose three parameters:
        * initial radius RBase
        * number of layers in the model NLayers
        * regularization coefficient LambdaV

        Initial radius is easy to choose - you can pick any number  several  times
        larger  than  the  average  distance between points. Algorithm won't break
        down if you choose radius which is too large (model construction time will
        increase, but model will be built correctly).

        Choose such number of layers that RLast=RBase/2^(NLayers-1)  (radius  used
        by  the  last  layer)  will  be  smaller than the typical distance between
        points.  In  case  model  error  is  too large, you can increase number of
        layers.  Having  more  layers  will make model construction and evaluation
        proportionally slower, but it will allow you to have model which precisely
        fits your data. From the other side, if you want to  suppress  noise,  you
        can DECREASE number of layers to make your model less flexible.

        Regularization coefficient LambdaV controls smoothness of  the  individual
        models built for each layer. We recommend you to use default value in case
        you don't want to tune this parameter,  because  having  non-zero  LambdaV
        accelerates and stabilizes internal iterative algorithm. In case you  want
        to suppress noise you can use  LambdaV  as  additional  parameter  (larger
        value = more smoothness) to tune.

        TYPICAL ERRORS

        1. Using  initial  radius  which is too large. Memory requirements  of the
           RBF-ML are roughly proportional to N*Density*RBase^2 (where Density  is
           an average density of points per unit of the interpolation  space).  In
           the extreme case of the very large RBase we will need O(N^2)  units  of
           memory - and many layers in order to decrease radius to some reasonably
           small value.

        2. Using too small number of layers - RBF models with large radius are not
           flexible enough to reproduce small variations in the  target  function.
           You  need  many  layers  with  different radii, from large to small, in
           order to have good model.

        3. Using  initial  radius  which  is  too  small.  You will get model with
           "holes" in the areas which are too far away from interpolation centers.
           However, algorithm will work correctly (and quickly) in this case.

        4. Using too many layers - you will get too large and too slow model. This
           model  will  perfectly  reproduce  your function, but maybe you will be
           able to achieve similar results with less layers (and less memory).
           
          -- ALGLIB --
             Copyright 02.03.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetalgomultilayer(rbfmodel s,
            double rbase,
            int nlayers,
            double lambdav)
        {
            alglib.ap.assert(math.isfinite(rbase), "RBFSetAlgoMultiLayer: RBase is infinite or NaN");
            alglib.ap.assert((double)(rbase)>(double)(0), "RBFSetAlgoMultiLayer: RBase<=0");
            alglib.ap.assert(nlayers>=0, "RBFSetAlgoMultiLayer: NLayers<0");
            alglib.ap.assert(math.isfinite(lambdav), "RBFSetAlgoMultiLayer: LambdaV is infinite or NAN");
            alglib.ap.assert((double)(lambdav)>=(double)(0), "RBFSetAlgoMultiLayer: LambdaV<0");
            s.radvalue = rbase;
            s.nlayers = nlayers;
            s.algorithmtype = 2;
            s.lambdav = lambdav;
        }
Ejemplo n.º 9
0
        /*************************************************************************
        This function sets linear term (model is a sum of radial  basis  functions
        plus linear polynomial). This function won't have effect until  next  call 
        to RBFBuildModel().

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetlinterm(rbfmodel s)
        {
            s.aterm = 1;
        }
Ejemplo n.º 10
0
        /*************************************************************************
        This function adds dataset.

        This function overrides results of the previous calls, i.e. multiple calls
        of this function will result in only the last set being added.

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call.
            XY      -   points, array[N,NX+NY]. One row corresponds to  one  point
                        in the dataset. First NX elements  are  coordinates,  next
                        NY elements are function values. Array may  be larger than 
                        specific,  in  this  case  only leading [N,NX+NY] elements 
                        will be used.
            N       -   number of points in the dataset

        After you've added dataset and (optionally) tuned algorithm  settings  you
        should call RBFBuildModel() in order to build a model for you.

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.
              

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetpoints(rbfmodel s,
            double[,] xy,
            int n)
        {
            int i = 0;
            int j = 0;

            alglib.ap.assert(n>0, "RBFSetPoints: N<0");
            alglib.ap.assert(alglib.ap.rows(xy)>=n, "RBFSetPoints: Rows(XY)<N");
            alglib.ap.assert(alglib.ap.cols(xy)>=s.nx+s.ny, "RBFSetPoints: Cols(XY)<NX+NY");
            s.n = n;
            s.x = new double[s.n, mxnx];
            s.y = new double[s.n, s.ny];
            for(i=0; i<=s.n-1; i++)
            {
                for(j=0; j<=mxnx-1; j++)
                {
                    s.x[i,j] = 0;
                }
                for(j=0; j<=s.nx-1; j++)
                {
                    s.x[i,j] = xy[i,j];
                }
                for(j=0; j<=s.ny-1; j++)
                {
                    s.y[i,j] = xy[i,j+s.nx];
                }
            }
        }
Ejemplo n.º 11
0
        /*************************************************************************
        This  function  sets  RBF interpolation algorithm. ALGLIB supports several
        RBF algorithms with different properties.

        This algorithm is called RBF-QNN and  it  is  good  for  point  sets  with
        following properties:
        a) all points are distinct
        b) all points are well separated.
        c) points  distribution  is  approximately  uniform.  There is no "contour
           lines", clusters of points, or other small-scale structures.

        Algorithm description:
        1) interpolation centers are allocated to data points
        2) interpolation radii are calculated as distances to the  nearest centers
           times Q coefficient (where Q is a value from [0.75,1.50]).
        3) after  performing (2) radii are transformed in order to avoid situation
           when single outlier has very large radius and  influences  many  points
           across all dataset. Transformation has following form:
               new_r[i] = min(r[i],Z*median(r[]))
           where r[i] is I-th radius, median()  is a median  radius across  entire
           dataset, Z is user-specified value which controls amount  of  deviation
           from median radius.

        When (a) is violated,  we  will  be unable to build RBF model. When (b) or
        (c) are violated, model will be built, but interpolation quality  will  be
        low. See http://www.alglib.net/interpolation/ for more information on this
        subject.

        This algorithm is used by default.

        Additional Q parameter controls smoothness properties of the RBF basis:
        * Q<0.75 will give perfectly conditioned basis,  but  terrible  smoothness
          properties (RBF interpolant will have sharp peaks around function values)
        * Q around 1.0 gives good balance between smoothness and condition number
        * Q>1.5 will lead to badly conditioned systems and slow convergence of the
          underlying linear solver (although smoothness will be very good)
        * Q>2.0 will effectively make optimizer useless because it won't  converge
          within reasonable amount of iterations. It is possible to set such large
          Q, but it is advised not to do so.

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call
            Q       -   Q parameter, Q>0, recommended value - 1.0
            Z       -   Z parameter, Z>0, recommended value - 5.0

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.


          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetalgoqnn(rbfmodel s,
            double q,
            double z)
        {
            alglib.ap.assert(math.isfinite(q), "RBFSetAlgoQNN: Q is infinite or NAN");
            alglib.ap.assert((double)(q)>(double)(0), "RBFSetAlgoQNN: Q<=0");
            rbfgridpoints(s);
            rbfradnn(s, q, z);
            s.algorithmtype = 1;
        }
Ejemplo n.º 12
0
        /*************************************************************************
        This function creates RBF  model  for  a  scalar (NY=1)  or  vector (NY>1)
        function in a NX-dimensional space (NX=2 or NX=3).

        Newly created model is empty. It can be used for interpolation right after
        creation, but it just returns zeros. You have to add points to the  model,
        tune interpolation settings, and then  call  model  construction  function
        RBFBuildModel() which will update model according to your specification.

        USAGE:
        1. User creates model with RBFCreate()
        2. User adds dataset with RBFSetPoints() (points do NOT have to  be  on  a
           regular grid)
        3. (OPTIONAL) User chooses polynomial term by calling:
           * RBFLinTerm() to set linear term
           * RBFConstTerm() to set constant term
           * RBFZeroTerm() to set zero term
           By default, linear term is used.
        4. User chooses specific RBF algorithm to use: either QNN (RBFSetAlgoQNN)
           or ML (RBFSetAlgoMultiLayer).
        5. User calls RBFBuildModel() function which rebuilds model  according  to
           the specification
        6. User may call RBFCalc() to calculate model value at the specified point,
           RBFGridCalc() to  calculate   model  values at the points of the regular
           grid. User may extract model coefficients with RBFUnpack() call.
           
        INPUT PARAMETERS:
            NX      -   dimension of the space, NX=2 or NX=3
            NY      -   function dimension, NY>=1

        OUTPUT PARAMETERS:
            S       -   RBF model (initially equals to zero)

        NOTE 1: memory requirements. RBF models require amount of memory  which is
                proportional  to  the  number  of data points. Memory is allocated 
                during model construction, but most of this memory is freed  after
                model coefficients are calculated.
                
                Some approximate estimates for N centers with default settings are
                given below:
                * about 250*N*(sizeof(double)+2*sizeof(int)) bytes  of  memory  is
                  needed during model construction stage.
                * about 15*N*sizeof(double) bytes is needed after model is built.
                For example, for N=100000 we may need 0.6 GB of memory  to  build
                model, but just about 0.012 GB to store it.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfcreate(int nx,
            int ny,
            rbfmodel s)
        {
            int i = 0;
            int j = 0;

            alglib.ap.assert(nx==2 || nx==3, "RBFCreate: NX<>2 and NX<>3");
            alglib.ap.assert(ny>=1, "RBFCreate: NY<1");
            s.nx = nx;
            s.ny = ny;
            s.nl = 0;
            s.nc = 0;
            s.v = new double[ny, mxnx+1];
            for(i=0; i<=ny-1; i++)
            {
                for(j=0; j<=mxnx; j++)
                {
                    s.v[i,j] = 0;
                }
            }
            s.n = 0;
            s.rmax = 0;
            s.gridtype = 2;
            s.fixrad = false;
            s.radvalue = 1;
            s.radzvalue = 5;
            s.aterm = 1;
            s.algorithmtype = 1;
            
            //
            // stopping criteria
            //
            s.epsort = eps;
            s.epserr = eps;
            s.maxits = 0;
        }
Ejemplo n.º 13
0
 public override alglib.apobject make_copy()
 {
     rbfmodel _result = new rbfmodel();
     _result.ny = ny;
     _result.nx = nx;
     _result.nc = nc;
     _result.nl = nl;
     _result.tree = (nearestneighbor.kdtree)tree.make_copy();
     _result.xc = (double[,])xc.Clone();
     _result.wr = (double[,])wr.Clone();
     _result.rmax = rmax;
     _result.v = (double[,])v.Clone();
     _result.gridtype = gridtype;
     _result.fixrad = fixrad;
     _result.lambdav = lambdav;
     _result.radvalue = radvalue;
     _result.radzvalue = radzvalue;
     _result.nlayers = nlayers;
     _result.aterm = aterm;
     _result.algorithmtype = algorithmtype;
     _result.epsort = epsort;
     _result.epserr = epserr;
     _result.maxits = maxits;
     _result.h = h;
     _result.n = n;
     _result.x = (double[,])x.Clone();
     _result.y = (double[,])y.Clone();
     _result.calcbufxcx = (double[])calcbufxcx.Clone();
     _result.calcbufx = (double[,])calcbufx.Clone();
     _result.calcbuftags = (int[])calcbuftags.Clone();
     return _result;
 }
        /*************************************************************************
        This function changes radii calculation algorithm to one which  makes  all
        radii equal to the same fixed value R. This  function  won't  have  effect
        until next call to RBFBuildModel().

        IMPORTANT: you should use this function with caution because too  large  R
        will make model fitting algorithm unstable, while too small  R  will  make
        perfect, but useless fit (it will be non-smooth, with sharp  peaks  around
        dataset points).

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call
            R       -   radius, R>0

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        private static void rbfradfixed(rbfmodel s,
            double r)
        {
            alglib.ap.assert(math.isfinite(r) && (double)(r)>(double)(0), "RBFRadFixed: R<=0, infinite or NAN");
            s.fixrad = true;
            s.radvalue = r;
        }
Ejemplo n.º 15
0
        /*************************************************************************
        This function calculates values of the RBF model at the given point.

        Same as RBFCalc(), but does not reallocate Y when in is large enough to 
        store function values.

        INPUT PARAMETERS:
            S       -   RBF model
            X       -   coordinates, array[NX].
                        X may have more than NX elements, in this case only 
                        leading NX will be used.
            Y       -   possibly preallocated array

        OUTPUT PARAMETERS:
            Y       -   function value, array[NY]. Y is not reallocated when it
                        is larger than NY.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfcalcbuf(rbfmodel s,
            double[] x,
            ref double[] y)
        {
            int i = 0;
            int j = 0;
            int k = 0;
            int lx = 0;
            int tg = 0;
            double t = 0;
            double rcur = 0;
            double bf = 0;

            alglib.ap.assert(alglib.ap.len(x)>=s.nx, "RBFCalcBuf: Length(X)<NX");
            alglib.ap.assert(apserv.isfinitevector(x, s.nx), "RBFCalcBuf: X contains infinite or NaN values");
            if( alglib.ap.len(y)<s.ny )
            {
                y = new double[s.ny];
            }
            for(i=0; i<=s.ny-1; i++)
            {
                y[i] = s.v[i,mxnx];
                for(j=0; j<=s.nx-1; j++)
                {
                    y[i] = y[i]+s.v[i,j]*x[j];
                }
            }
            if( s.nc==0 )
            {
                return;
            }
            apserv.rvectorsetlengthatleast(ref s.calcbufxcx, mxnx);
            for(i=0; i<=mxnx-1; i++)
            {
                s.calcbufxcx[i] = 0.0;
            }
            for(i=0; i<=s.nx-1; i++)
            {
                s.calcbufxcx[i] = x[i];
            }
            lx = nearestneighbor.kdtreequeryrnn(s.tree, s.calcbufxcx, s.rmax*rbffarradius, true);
            nearestneighbor.kdtreequeryresultsx(s.tree, ref s.calcbufx);
            nearestneighbor.kdtreequeryresultstags(s.tree, ref s.calcbuftags);
            for(i=0; i<=s.ny-1; i++)
            {
                for(j=0; j<=lx-1; j++)
                {
                    tg = s.calcbuftags[j];
                    rcur = s.wr[tg,0];
                    bf = Math.Exp(-((math.sqr(s.calcbufxcx[0]-s.calcbufx[j,0])+math.sqr(s.calcbufxcx[1]-s.calcbufx[j,1])+math.sqr(s.calcbufxcx[2]-s.calcbufx[j,2]))/math.sqr(rcur)));
                    for(k=0; k<=s.nl-1; k++)
                    {
                        y[i] = y[i]+bf*s.wr[tg,1+k*s.ny+i];
                        t = bf*bf;
                        bf = t*t;
                    }
                }
            }
        }
Ejemplo n.º 16
0
        /*************************************************************************
        This function sets constant term (model is a sum of radial basis functions
        plus constant).  This  function  won't  have  effect  until  next  call to 
        RBFBuildModel().

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetconstterm(rbfmodel s)
        {
            s.aterm = 2;
        }
Ejemplo n.º 17
0
        /*************************************************************************
        This function calculates values of the RBF model at the regular grid.

        Grid have N0*N1 points, with Point[I,J] = (X0[I], X1[J])

        This function returns 0.0 when:
        * model is not initialized
        * NX<>2
         *NY<>1

        INPUT PARAMETERS:
            S       -   RBF model
            X0      -   array of grid nodes, first coordinates, array[N0]
            N0      -   grid size (number of nodes) in the first dimension
            X1      -   array of grid nodes, second coordinates, array[N1]
            N1      -   grid size (number of nodes) in the second dimension

        OUTPUT PARAMETERS:
            Y       -   function values, array[N0,N1]. Y is out-variable and 
                        is reallocated by this function.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfgridcalc2(rbfmodel s,
            double[] x0,
            int n0,
            double[] x1,
            int n1,
            ref double[,] y)
        {
            double[] cpx0 = new double[0];
            double[] cpx1 = new double[0];
            int[] p01 = new int[0];
            int[] p11 = new int[0];
            int[] p2 = new int[0];
            double rlimit = 0;
            double xcnorm2 = 0;
            int hp01 = 0;
            double hcpx0 = 0;
            double xc0 = 0;
            double xc1 = 0;
            double omega = 0;
            double radius = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int d = 0;
            int i00 = 0;
            int i01 = 0;
            int i10 = 0;
            int i11 = 0;

            y = new double[0,0];

            alglib.ap.assert(n0>0, "RBFGridCalc2: invalid value for N0 (N0<=0)!");
            alglib.ap.assert(n1>0, "RBFGridCalc2: invalid value for N1 (N1<=0)!");
            alglib.ap.assert(alglib.ap.len(x0)>=n0, "RBFGridCalc2: Length(X0)<N0");
            alglib.ap.assert(alglib.ap.len(x1)>=n1, "RBFGridCalc2: Length(X1)<N1");
            alglib.ap.assert(apserv.isfinitevector(x0, n0), "RBFGridCalc2: X0 contains infinite or NaN values!");
            alglib.ap.assert(apserv.isfinitevector(x1, n1), "RBFGridCalc2: X1 contains infinite or NaN values!");
            y = new double[n0, n1];
            for(i=0; i<=n0-1; i++)
            {
                for(j=0; j<=n1-1; j++)
                {
                    y[i,j] = 0;
                }
            }
            if( (s.ny!=1 || s.nx!=2) || s.nc==0 )
            {
                return;
            }
            
            //
            //create and sort arrays
            //
            cpx0 = new double[n0];
            for(i=0; i<=n0-1; i++)
            {
                cpx0[i] = x0[i];
            }
            tsort.tagsort(ref cpx0, n0, ref p01, ref p2);
            cpx1 = new double[n1];
            for(i=0; i<=n1-1; i++)
            {
                cpx1[i] = x1[i];
            }
            tsort.tagsort(ref cpx1, n1, ref p11, ref p2);
            
            //
            //calculate function's value
            //
            for(i=0; i<=s.nc-1; i++)
            {
                radius = s.wr[i,0];
                for(d=0; d<=s.nl-1; d++)
                {
                    omega = s.wr[i,1+d];
                    rlimit = radius*rbffarradius;
                    
                    //
                    //search lower and upper indexes
                    //
                    i00 = tsort.lowerbound(cpx0, n0, s.xc[i,0]-rlimit);
                    i01 = tsort.upperbound(cpx0, n0, s.xc[i,0]+rlimit);
                    i10 = tsort.lowerbound(cpx1, n1, s.xc[i,1]-rlimit);
                    i11 = tsort.upperbound(cpx1, n1, s.xc[i,1]+rlimit);
                    xc0 = s.xc[i,0];
                    xc1 = s.xc[i,1];
                    for(j=i00; j<=i01-1; j++)
                    {
                        hcpx0 = cpx0[j];
                        hp01 = p01[j];
                        for(k=i10; k<=i11-1; k++)
                        {
                            xcnorm2 = math.sqr(hcpx0-xc0)+math.sqr(cpx1[k]-xc1);
                            if( (double)(xcnorm2)<=(double)(rlimit*rlimit) )
                            {
                                y[hp01,p11[k]] = y[hp01,p11[k]]+Math.Exp(-(xcnorm2/math.sqr(radius)))*omega;
                            }
                        }
                    }
                    radius = 0.5*radius;
                }
            }
            
            //
            //add linear term
            //
            for(i=0; i<=n0-1; i++)
            {
                for(j=0; j<=n1-1; j++)
                {
                    y[i,j] = y[i,j]+s.v[0,0]*x0[i]+s.v[0,1]*x1[j]+s.v[0,mxnx];
                }
            }
        }
Ejemplo n.º 18
0
        /*************************************************************************
        This  function  sets  zero  term (model is a sum of radial basis functions 
        without polynomial term). This function won't have effect until next  call
        to RBFBuildModel().

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetzeroterm(rbfmodel s)
        {
            s.aterm = 3;
        }
Ejemplo n.º 19
0
        /*************************************************************************
        Serializer: allocation

          -- ALGLIB --
             Copyright 02.02.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfalloc(alglib.serializer s,
            rbfmodel model)
        {
            
            //
            // Header
            //
            s.alloc_entry();
            s.alloc_entry();
            
            //
            // Data
            //
            s.alloc_entry();
            s.alloc_entry();
            s.alloc_entry();
            s.alloc_entry();
            nearestneighbor.kdtreealloc(s, model.tree);
            apserv.allocrealmatrix(s, model.xc, -1, -1);
            apserv.allocrealmatrix(s, model.wr, -1, -1);
            s.alloc_entry();
            apserv.allocrealmatrix(s, model.v, -1, -1);
        }
Ejemplo n.º 20
0
        /*************************************************************************
        This function sets stopping criteria of the underlying linear solver.

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call
            EpsOrt  -   orthogonality stopping criterion, EpsOrt>=0. Algorithm will
                        stop when ||A'*r||<=EpsOrt where A' is a transpose of  the 
                        system matrix, r is a residual vector.
                        Recommended value of EpsOrt is equal to 1E-6.
                        This criterion will stop algorithm when we have "bad fit"
                        situation, i.e. when we should stop in a point with large,
                        nonzero residual.
            EpsErr  -   residual stopping  criterion.  Algorithm  will  stop  when
                        ||r||<=EpsErr*||b||, where r is a residual vector, b is  a
                        right part of the system (function values).
                        Recommended value of EpsErr is equal to 1E-3 or 1E-6.
                        This  criterion  will  stop  algorithm  in  a  "good  fit" 
                        situation when we have near-zero residual near the desired
                        solution.
            MaxIts  -   this criterion will stop algorithm after MaxIts iterations.
                        It should be used for debugging purposes only!
                        Zero MaxIts means that no limit is placed on the number of
                        iterations.

        We  recommend  to  set  moderate  non-zero  values   EpsOrt   and   EpsErr 
        simultaneously. Values equal to 10E-6 are good to start with. In case  you
        need high performance and do not need high precision ,  you  may  decrease
        EpsErr down to 0.001. However, we do not recommend decreasing EpsOrt.

        As for MaxIts, we recommend to leave it zero unless you know what you do.

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfsetcond(rbfmodel s,
            double epsort,
            double epserr,
            int maxits)
        {
            alglib.ap.assert(math.isfinite(epsort) && (double)(epsort)>=(double)(0), "RBFSetCond: EpsOrt is negative, INF or NAN");
            alglib.ap.assert(math.isfinite(epserr) && (double)(epserr)>=(double)(0), "RBFSetCond: EpsB is negative, INF or NAN");
            alglib.ap.assert(maxits>=0, "RBFSetCond: MaxIts is negative");
            if( ((double)(epsort)==(double)(0) && (double)(epserr)==(double)(0)) && maxits==0 )
            {
                s.epsort = eps;
                s.epserr = eps;
                s.maxits = 0;
            }
            else
            {
                s.epsort = epsort;
                s.epserr = epserr;
                s.maxits = maxits;
            }
        }
Ejemplo n.º 21
0
        /*************************************************************************
        Serializer: unserialization

          -- ALGLIB --
             Copyright 02.02.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfunserialize(alglib.serializer s,
            rbfmodel model)
        {
            int i0 = 0;
            int i1 = 0;
            int nx = 0;
            int ny = 0;

            
            //
            // Header
            //
            i0 = s.unserialize_int();
            alglib.ap.assert(i0==scodes.getrbfserializationcode(), "RBFUnserialize: stream header corrupted");
            i1 = s.unserialize_int();
            alglib.ap.assert(i1==rbffirstversion, "RBFUnserialize: stream header corrupted");
            
            //
            // Unserialize primary model parameters, initialize model.
            //
            // It is necessary to call RBFCreate() because some internal fields
            // which are NOT unserialized will need initialization.
            //
            nx = s.unserialize_int();
            ny = s.unserialize_int();
            rbfcreate(nx, ny, model);
            model.nc = s.unserialize_int();
            model.nl = s.unserialize_int();
            nearestneighbor.kdtreeunserialize(s, model.tree);
            apserv.unserializerealmatrix(s, ref model.xc);
            apserv.unserializerealmatrix(s, ref model.wr);
            model.rmax = s.unserialize_double();
            apserv.unserializerealmatrix(s, ref model.v);
        }
Ejemplo n.º 22
0
        /*************************************************************************
        This   function  builds  RBF  model  and  returns  report  (contains  some 
        information which can be used for evaluation of the algorithm properties).

        Call to this function modifies RBF model by calculating its centers/radii/
        weights  and  saving  them  into  RBFModel  structure.  Initially RBFModel 
        contain zero coefficients, but after call to this function  we  will  have
        coefficients which were calculated in order to fit our dataset.

        After you called this function you can call RBFCalc(),  RBFGridCalc()  and
        other model calculation functions.

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call
            Rep     -   report:
                        * Rep.TerminationType:
                          * -5 - non-distinct basis function centers were detected,
                                 interpolation aborted
                          * -4 - nonconvergence of the internal SVD solver
                          *  1 - successful termination
                        Fields are used for debugging purposes:
                        * Rep.IterationsCount - iterations count of the LSQR solver
                        * Rep.NMV - number of matrix-vector products
                        * Rep.ARows - rows count for the system matrix
                        * Rep.ACols - columns count for the system matrix
                        * Rep.ANNZ - number of significantly non-zero elements
                          (elements above some algorithm-determined threshold)

        NOTE:  failure  to  build  model will leave current state of the structure
        unchanged.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void rbfbuildmodel(rbfmodel s,
            rbfreport rep)
        {
            nearestneighbor.kdtree tree = new nearestneighbor.kdtree();
            nearestneighbor.kdtree ctree = new nearestneighbor.kdtree();
            double[] dist = new double[0];
            double[] xcx = new double[0];
            double[,] a = new double[0,0];
            double[,] v = new double[0,0];
            double[,] omega = new double[0,0];
            double[] y = new double[0];
            double[,] residualy = new double[0,0];
            double[] radius = new double[0];
            double[,] xc = new double[0,0];
            double[] mnx = new double[0];
            double[] mxx = new double[0];
            double[] edge = new double[0];
            int[] mxsteps = new int[0];
            int nc = 0;
            double rmax = 0;
            int[] tags = new int[0];
            int[] ctags = new int[0];
            int i = 0;
            int j = 0;
            int k = 0;
            int k2 = 0;
            int snnz = 0;
            double[] tmp0 = new double[0];
            double[] tmp1 = new double[0];
            int layerscnt = 0;

            alglib.ap.assert(s.nx==2 || s.nx==3, "RBFBuildModel: S.NX<>2 or S.NX<>3!");
            
            //
            // Quick exit when we have no points
            //
            if( s.n==0 )
            {
                rep.terminationtype = 1;
                rep.iterationscount = 0;
                rep.nmv = 0;
                rep.arows = 0;
                rep.acols = 0;
                nearestneighbor.kdtreebuildtagged(s.xc, tags, 0, mxnx, 0, 2, s.tree);
                s.xc = new double[0, 0];
                s.wr = new double[0, 0];
                s.nc = 0;
                s.rmax = 0;
                s.v = new double[s.ny, mxnx+1];
                for(i=0; i<=s.ny-1; i++)
                {
                    for(j=0; j<=mxnx; j++)
                    {
                        s.v[i,j] = 0;
                    }
                }
                return;
            }
            
            //
            // General case, N>0
            //
            rep.annz = 0;
            rep.iterationscount = 0;
            rep.nmv = 0;
            xcx = new double[mxnx];
            
            //
            // First model in a sequence - linear model.
            // Residuals from linear regression are stored in the ResidualY variable
            // (used later to build RBF models).
            //
            residualy = new double[s.n, s.ny];
            for(i=0; i<=s.n-1; i++)
            {
                for(j=0; j<=s.ny-1; j++)
                {
                    residualy[i,j] = s.y[i,j];
                }
            }
            if( !buildlinearmodel(s.x, ref residualy, s.n, s.ny, s.aterm, ref v) )
            {
                rep.terminationtype = -5;
                return;
            }
            
            //
            // Handle special case: multilayer model with NLayers=0.
            // Quick exit.
            //
            if( s.algorithmtype==2 && s.nlayers==0 )
            {
                rep.terminationtype = 1;
                rep.iterationscount = 0;
                rep.nmv = 0;
                rep.arows = 0;
                rep.acols = 0;
                nearestneighbor.kdtreebuildtagged(s.xc, tags, 0, mxnx, 0, 2, s.tree);
                s.xc = new double[0, 0];
                s.wr = new double[0, 0];
                s.nc = 0;
                s.rmax = 0;
                s.v = new double[s.ny, mxnx+1];
                for(i=0; i<=s.ny-1; i++)
                {
                    for(j=0; j<=mxnx; j++)
                    {
                        s.v[i,j] = v[i,j];
                    }
                }
                return;
            }
            
            //
            // Second model in a sequence - RBF term.
            //
            // NOTE: assignments below are not necessary, but without them
            //       MSVC complains about unitialized variables.
            //
            nc = 0;
            rmax = 0;
            layerscnt = 0;
            if( s.algorithmtype==1 )
            {
                
                //
                // Add RBF model.
                // This model uses local KD-trees to speed-up nearest neighbor searches.
                //
                if( s.gridtype==1 )
                {
                    mxx = new double[s.nx];
                    mnx = new double[s.nx];
                    mxsteps = new int[s.nx];
                    edge = new double[s.nx];
                    for(i=0; i<=s.nx-1; i++)
                    {
                        mxx[i] = s.x[0,i];
                        mnx[i] = s.x[0,i];
                    }
                    for(i=0; i<=s.n-1; i++)
                    {
                        for(j=0; j<=s.nx-1; j++)
                        {
                            if( (double)(mxx[j])<(double)(s.x[i,j]) )
                            {
                                mxx[j] = s.x[i,j];
                            }
                            if( (double)(mnx[j])>(double)(s.x[i,j]) )
                            {
                                mnx[j] = s.x[i,j];
                            }
                        }
                    }
                    for(i=0; i<=s.nx-1; i++)
                    {
                        mxsteps[i] = (int)((mxx[i]-mnx[i])/(2*s.h))+1;
                        edge[i] = (mxx[i]+mnx[i])/2-s.h*mxsteps[i];
                    }
                    nc = 1;
                    for(i=0; i<=s.nx-1; i++)
                    {
                        mxsteps[i] = 2*mxsteps[i]+1;
                        nc = nc*mxsteps[i];
                    }
                    xc = new double[nc, mxnx];
                    if( s.nx==2 )
                    {
                        for(i=0; i<=mxsteps[0]-1; i++)
                        {
                            for(j=0; j<=mxsteps[1]-1; j++)
                            {
                                for(k2=0; k2<=mxnx-1; k2++)
                                {
                                    xc[i*mxsteps[1]+j,k2] = 0;
                                }
                                xc[i*mxsteps[1]+j,0] = edge[0]+s.h*i;
                                xc[i*mxsteps[1]+j,1] = edge[1]+s.h*j;
                            }
                        }
                    }
                    if( s.nx==3 )
                    {
                        for(i=0; i<=mxsteps[0]-1; i++)
                        {
                            for(j=0; j<=mxsteps[1]-1; j++)
                            {
                                for(k=0; k<=mxsteps[2]-1; k++)
                                {
                                    for(k2=0; k2<=mxnx-1; k2++)
                                    {
                                        xc[i*mxsteps[1]+j,k2] = 0;
                                    }
                                    xc[(i*mxsteps[1]+j)*mxsteps[2]+k,0] = edge[0]+s.h*i;
                                    xc[(i*mxsteps[1]+j)*mxsteps[2]+k,1] = edge[1]+s.h*j;
                                    xc[(i*mxsteps[1]+j)*mxsteps[2]+k,2] = edge[2]+s.h*k;
                                }
                            }
                        }
                    }
                }
                else
                {
                    if( s.gridtype==2 )
                    {
                        nc = s.n;
                        xc = new double[nc, mxnx];
                        for(i=0; i<=nc-1; i++)
                        {
                            for(j=0; j<=mxnx-1; j++)
                            {
                                xc[i,j] = s.x[i,j];
                            }
                        }
                    }
                    else
                    {
                        if( s.gridtype==3 )
                        {
                            nc = s.nc;
                            xc = new double[nc, mxnx];
                            for(i=0; i<=nc-1; i++)
                            {
                                for(j=0; j<=mxnx-1; j++)
                                {
                                    xc[i,j] = s.xc[i,j];
                                }
                            }
                        }
                        else
                        {
                            alglib.ap.assert(false, "RBFBuildModel: either S.GridType<1 or S.GridType>3!");
                        }
                    }
                }
                rmax = 0;
                radius = new double[nc];
                ctags = new int[nc];
                for(i=0; i<=nc-1; i++)
                {
                    ctags[i] = i;
                }
                nearestneighbor.kdtreebuildtagged(xc, ctags, nc, mxnx, 0, 2, ctree);
                if( s.fixrad )
                {
                    
                    //
                    // Fixed radius
                    //
                    for(i=0; i<=nc-1; i++)
                    {
                        radius[i] = s.radvalue;
                    }
                    rmax = radius[0];
                }
                else
                {
                    
                    //
                    // Dynamic radius
                    //
                    if( nc==0 )
                    {
                        rmax = 1;
                    }
                    else
                    {
                        if( nc==1 )
                        {
                            radius[0] = s.radvalue;
                            rmax = radius[0];
                        }
                        else
                        {
                            
                            //
                            // NC>1, calculate radii using distances to nearest neigbors
                            //
                            for(i=0; i<=nc-1; i++)
                            {
                                for(j=0; j<=mxnx-1; j++)
                                {
                                    xcx[j] = xc[i,j];
                                }
                                if( nearestneighbor.kdtreequeryknn(ctree, xcx, 1, false)>0 )
                                {
                                    nearestneighbor.kdtreequeryresultsdistances(ctree, ref dist);
                                    radius[i] = s.radvalue*dist[0];
                                }
                                else
                                {
                                    
                                    //
                                    // No neighbors found (it will happen when we have only one center).
                                    // Initialize radius with default value.
                                    //
                                    radius[i] = 1.0;
                                }
                            }
                            
                            //
                            // Apply filtering
                            //
                            apserv.rvectorsetlengthatleast(ref tmp0, nc);
                            for(i=0; i<=nc-1; i++)
                            {
                                tmp0[i] = radius[i];
                            }
                            tsort.tagsortfast(ref tmp0, ref tmp1, nc);
                            for(i=0; i<=nc-1; i++)
                            {
                                radius[i] = Math.Min(radius[i], s.radzvalue*tmp0[nc/2]);
                            }
                            
                            //
                            // Calculate RMax, check that all radii are non-zero
                            //
                            for(i=0; i<=nc-1; i++)
                            {
                                rmax = Math.Max(rmax, radius[i]);
                            }
                            for(i=0; i<=nc-1; i++)
                            {
                                if( (double)(radius[i])==(double)(0) )
                                {
                                    rep.terminationtype = -5;
                                    return;
                                }
                            }
                        }
                    }
                }
                apserv.ivectorsetlengthatleast(ref tags, s.n);
                for(i=0; i<=s.n-1; i++)
                {
                    tags[i] = i;
                }
                nearestneighbor.kdtreebuildtagged(s.x, tags, s.n, mxnx, 0, 2, tree);
                buildrbfmodellsqr(s.x, ref residualy, xc, radius, s.n, nc, s.ny, tree, ctree, s.epsort, s.epserr, s.maxits, ref rep.annz, ref snnz, ref omega, ref rep.terminationtype, ref rep.iterationscount, ref rep.nmv);
                layerscnt = 1;
            }
            else
            {
                if( s.algorithmtype==2 )
                {
                    rmax = s.radvalue;
                    buildrbfmlayersmodellsqr(s.x, ref residualy, ref xc, s.radvalue, ref radius, s.n, ref nc, s.ny, s.nlayers, ctree, 1.0E-6, 1.0E-6, 50, s.lambdav, ref rep.annz, ref omega, ref rep.terminationtype, ref rep.iterationscount, ref rep.nmv);
                    layerscnt = s.nlayers;
                }
                else
                {
                    alglib.ap.assert(false, "RBFBuildModel: internal error(AlgorithmType neither 1 nor 2)");
                }
            }
            if( rep.terminationtype<=0 )
            {
                return;
            }
            
            //
            // Model is built
            //
            s.nc = nc/layerscnt;
            s.rmax = rmax;
            s.nl = layerscnt;
            s.xc = new double[s.nc, mxnx];
            s.wr = new double[s.nc, 1+s.nl*s.ny];
            s.v = new double[s.ny, mxnx+1];
            for(i=0; i<=s.nc-1; i++)
            {
                for(j=0; j<=mxnx-1; j++)
                {
                    s.xc[i,j] = xc[i,j];
                }
            }
            apserv.ivectorsetlengthatleast(ref tags, s.nc);
            for(i=0; i<=s.nc-1; i++)
            {
                tags[i] = i;
            }
            nearestneighbor.kdtreebuildtagged(s.xc, tags, s.nc, mxnx, 0, 2, s.tree);
            for(i=0; i<=s.nc-1; i++)
            {
                s.wr[i,0] = radius[i];
                for(k=0; k<=layerscnt-1; k++)
                {
                    for(j=0; j<=s.ny-1; j++)
                    {
                        s.wr[i,1+k*s.ny+j] = omega[k*s.nc+i,j];
                    }
                }
            }
            for(i=0; i<=s.ny-1; i++)
            {
                for(j=0; j<=mxnx; j++)
                {
                    s.v[i,j] = v[i,j];
                }
            }
            rep.terminationtype = 1;
            rep.arows = s.n;
            rep.acols = s.nc;
        }
Ejemplo n.º 23
0
        /*************************************************************************
        This function changes radii  calculation  algorithm  to  one  which  makes
        radius for I-th node equal to R[i]=DistNN[i]*Q, where:
        * R[i] is a radius calculated by the algorithm
        * DistNN[i] is distance from I-th center to its nearest neighbor center
        * Q is a scale parameter, which should be within [0.75,1.50], with
          recommended value equal to 1.0
        * after performing radii calculation, radii are transformed  in  order  to
          avoid situation when single outlier has very large radius and influences
          many points across entire dataset. Transformation has following form:
               new_r[i] = min(r[i],Z*median(r[]))
           where r[i] is I-th radius, median()  is  a median  radius across entire
           dataset, Z is user-specified value which controls amount  of  deviation
           from median radius.

        This function won't have effect until next call to RBFBuildModel().

        The idea behind this algorithm is to choose radii corresponding  to  basis
        functions is such way that I-th radius is approximately equal to  distance
        from I-th center to its nearest neighbor. In this case  interactions  with
        distant points will be insignificant, and we  will  get  well  conditioned
        basis.

        Properties of this basis depend on the value of Q:
        * Q<0.75 will give perfectly conditioned basis,  but  terrible  smoothness
          properties (RBF interpolant will have sharp peaks around function values)
        * Q>1.5 will lead to badly conditioned systems and slow convergence of the
          underlying linear solver (although smoothness will be very good)
        * Q around 1.0 gives good balance between smoothness and condition number


        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call
            Q       -   radius coefficient, Q>0
            Z       -   z-parameter, Z>0
            
        Default value of Q is equal to 1.0
        Default value of Z is equal to 5.0

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        private static void rbfradnn(rbfmodel s,
            double q,
            double z)
        {
            alglib.ap.assert(math.isfinite(q) && (double)(q)>(double)(0), "RBFRadNN: Q<=0, infinite or NAN");
            alglib.ap.assert(math.isfinite(z) && (double)(z)>(double)(0), "RBFRadNN: Z<=0, infinite or NAN");
            s.fixrad = false;
            s.radvalue = q;
            s.radzvalue = z;
        }
        /*************************************************************************
        This function changes centers allocation algorithm to one which  allocates
        centers on a regular grid with step equal to H  in  all  dimensions.  This
        function won't have effect until next call to RBFBuildModel().

        Central  point  of  the  grid  is  located  exactly  in  the middle of the 
        bounding rectangle for our dataset. Grid countinues from the center to the
        bounds of the bounding rectangle, and makes one step beyond  bounds  (i.e. 
        leftmost/rightmost/topmost/... lines of the grid are located just  outside
        of the bounding rectangle).

        INPUT PARAMETERS:
            S       -   RBF model, initialized by RBFCreate() call.
            H       -   grid step, H>0

        NOTE: this   function  has   some   serialization-related  subtleties.  We
              recommend you to study serialization examples from ALGLIB  Reference
              Manual if you want to perform serialization of your models.

          -- ALGLIB --
             Copyright 13.12.2011 by Bochkanov Sergey
        *************************************************************************/
        private static void rbfgridregular(rbfmodel s,
            double h)
        {
            alglib.ap.assert(math.isfinite(h) && (double)(h)>(double)(0), "RBFGridRegular: H<0, INF or NAN");
            s.h = h;
            s.gridtype = 1;
        }