Esempio n. 1
0
        private static void buildrbfmlayersmodellsqr(double[,] x,
            ref double[,] y,
            ref double[,] xc,
            double rval,
            ref double[] r,
            int n,
            ref int nc,
            int ny,
            int nlayers,
            nearestneighbor.kdtree centerstree,
            double epsort,
            double epserr,
            int maxits,
            double lambdav,
            ref int annz,
            ref double[,] w,
            ref int info,
            ref int iterationscount,
            ref int nmv)
        {
            linlsqr.linlsqrstate state = new linlsqr.linlsqrstate();
            linlsqr.linlsqrreport lsqrrep = new linlsqr.linlsqrreport();
            sparse.sparsematrix spa = new sparse.sparsematrix();
            double anorm = 0;
            double[] omega = new double[0];
            double[] xx = new double[0];
            double[] tmpy = new double[0];
            double[,] cx = new double[0,0];
            double yval = 0;
            int nec = 0;
            int[] centerstags = new int[0];
            int layer = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            double v = 0;
            double rmaxbefore = 0;
            double rmaxafter = 0;

            xc = new double[0,0];
            r = new double[0];
            nc = 0;
            annz = 0;
            w = new double[0,0];
            info = 0;
            iterationscount = 0;
            nmv = 0;

            alglib.ap.assert(nlayers>=0, "BuildRBFMLayersModelLSQR: invalid argument(NLayers<0)");
            alglib.ap.assert(n>=0, "BuildRBFMLayersModelLSQR: invalid argument(N<0)");
            alglib.ap.assert(mxnx>0 && mxnx<=3, "BuildRBFMLayersModelLSQR: internal error(invalid global const MxNX: either MxNX<=0 or MxNX>3)");
            annz = 0;
            if( n==0 || nlayers==0 )
            {
                info = 1;
                iterationscount = 0;
                nmv = 0;
                return;
            }
            nc = n*nlayers;
            xx = new double[mxnx];
            centerstags = new int[n];
            xc = new double[nc, mxnx];
            r = new double[nc];
            for(i=0; i<=nc-1; i++)
            {
                for(j=0; j<=mxnx-1; j++)
                {
                    xc[i,j] = x[i%n,j];
                }
            }
            for(i=0; i<=nc-1; i++)
            {
                r[i] = rval/Math.Pow(2, i/n);
            }
            for(i=0; i<=n-1; i++)
            {
                centerstags[i] = i;
            }
            nearestneighbor.kdtreebuildtagged(xc, centerstags, n, mxnx, 0, 2, centerstree);
            omega = new double[n];
            tmpy = new double[n];
            w = new double[nc, ny];
            info = -1;
            iterationscount = 0;
            nmv = 0;
            linlsqr.linlsqrcreate(n, n, state);
            linlsqr.linlsqrsetcond(state, epsort, epserr, maxits);
            linlsqr.linlsqrsetlambdai(state, 1.0E-6);
            
            //
            // calculate number of non-zero elements for sparse matrix
            //
            for(i=0; i<=n-1; i++)
            {
                for(j=0; j<=mxnx-1; j++)
                {
                    xx[j] = x[i,j];
                }
                annz = annz+nearestneighbor.kdtreequeryrnn(centerstree, xx, r[0]*rbfmlradius, true);
            }
            for(layer=0; layer<=nlayers-1; layer++)
            {
                
                //
                // Fill sparse matrix, calculate norm(A)
                //
                anorm = 0.0;
                sparse.sparsecreate(n, n, annz, spa);
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=mxnx-1; j++)
                    {
                        xx[j] = x[i,j];
                    }
                    nec = nearestneighbor.kdtreequeryrnn(centerstree, xx, r[layer*n]*rbfmlradius, true);
                    nearestneighbor.kdtreequeryresultsx(centerstree, ref cx);
                    nearestneighbor.kdtreequeryresultstags(centerstree, ref centerstags);
                    for(j=0; j<=nec-1; j++)
                    {
                        v = Math.Exp(-((math.sqr(xx[0]-cx[j,0])+math.sqr(xx[1]-cx[j,1])+math.sqr(xx[2]-cx[j,2]))/math.sqr(r[layer*n+centerstags[j]])));
                        sparse.sparseset(spa, i, centerstags[j], v);
                        anorm = anorm+math.sqr(v);
                    }
                }
                anorm = Math.Sqrt(anorm);
                sparse.sparseconverttocrs(spa);
                
                //
                // Calculate maximum residual before adding new layer.
                // This value is not used by algorithm, the only purpose is to make debugging easier.
                //
                rmaxbefore = 0.0;
                for(j=0; j<=n-1; j++)
                {
                    for(i=0; i<=ny-1; i++)
                    {
                        rmaxbefore = Math.Max(rmaxbefore, Math.Abs(y[j,i]));
                    }
                }
                
                //
                // Process NY dimensions of the target function
                //
                for(i=0; i<=ny-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        tmpy[j] = y[j,i];
                    }
                    
                    //
                    // calculate Omega for current layer
                    //
                    linlsqr.linlsqrsetlambdai(state, lambdav*anorm/n);
                    linlsqr.linlsqrsolvesparse(state, spa, tmpy);
                    linlsqr.linlsqrresults(state, ref omega, lsqrrep);
                    if( lsqrrep.terminationtype<=0 )
                    {
                        info = -4;
                        return;
                    }
                    
                    //
                    // calculate error for current layer
                    //
                    for(j=0; j<=n-1; j++)
                    {
                        yval = 0;
                        for(k=0; k<=mxnx-1; k++)
                        {
                            xx[k] = x[j,k];
                        }
                        nec = nearestneighbor.kdtreequeryrnn(centerstree, xx, r[layer*n]*rbffarradius, true);
                        nearestneighbor.kdtreequeryresultsx(centerstree, ref cx);
                        nearestneighbor.kdtreequeryresultstags(centerstree, ref centerstags);
                        for(k=0; k<=nec-1; k++)
                        {
                            yval = yval+omega[centerstags[k]]*Math.Exp(-((math.sqr(xx[0]-cx[k,0])+math.sqr(xx[1]-cx[k,1])+math.sqr(xx[2]-cx[k,2]))/math.sqr(r[layer*n+centerstags[k]])));
                        }
                        y[j,i] = y[j,i]-yval;
                    }
                    
                    //
                    // write Omega in out parameter W
                    //
                    for(j=0; j<=n-1; j++)
                    {
                        w[layer*n+j,i] = omega[j];
                    }
                    iterationscount = iterationscount+lsqrrep.iterationscount;
                    nmv = nmv+lsqrrep.nmv;
                }
                
                //
                // Calculate maximum residual before adding new layer.
                // This value is not used by algorithm, the only purpose is to make debugging easier.
                //
                rmaxafter = 0.0;
                for(j=0; j<=n-1; j++)
                {
                    for(i=0; i<=ny-1; i++)
                    {
                        rmaxafter = Math.Max(rmaxafter, Math.Abs(y[j,i]));
                    }
                }
            }
            info = 1;
        }
 public kdtree(nearestneighbor.kdtree obj)
 {
     _innerobj = obj;
 }
Esempio n. 3
0
        private static void buildrbfmodellsqr(double[,] x,
            ref double[,] y,
            double[,] xc,
            double[] r,
            int n,
            int nc,
            int ny,
            nearestneighbor.kdtree pointstree,
            nearestneighbor.kdtree centerstree,
            double epsort,
            double epserr,
            int maxits,
            ref int gnnz,
            ref int snnz,
            ref double[,] w,
            ref int info,
            ref int iterationscount,
            ref int nmv)
        {
            linlsqr.linlsqrstate state = new linlsqr.linlsqrstate();
            linlsqr.linlsqrreport lsqrrep = new linlsqr.linlsqrreport();
            sparse.sparsematrix spg = new sparse.sparsematrix();
            sparse.sparsematrix sps = new sparse.sparsematrix();
            int[] nearcenterscnt = new int[0];
            int[] nearpointscnt = new int[0];
            int[] skipnearpointscnt = new int[0];
            int[] farpointscnt = new int[0];
            int maxnearcenterscnt = 0;
            int maxnearpointscnt = 0;
            int maxfarpointscnt = 0;
            int sumnearcenterscnt = 0;
            int sumnearpointscnt = 0;
            int sumfarpointscnt = 0;
            double maxrad = 0;
            int[] pointstags = new int[0];
            int[] centerstags = new int[0];
            double[,] nearpoints = new double[0,0];
            double[,] nearcenters = new double[0,0];
            double[,] farpoints = new double[0,0];
            int tmpi = 0;
            int pointscnt = 0;
            int centerscnt = 0;
            double[] xcx = new double[0];
            double[] tmpy = new double[0];
            double[] tc = new double[0];
            double[] g = new double[0];
            double[] c = new double[0];
            int i = 0;
            int j = 0;
            int k = 0;
            int sind = 0;
            double[,] a = new double[0,0];
            double vv = 0;
            double vx = 0;
            double vy = 0;
            double vz = 0;
            double vr = 0;
            double gnorm2 = 0;
            double[] tmp0 = new double[0];
            double[] tmp1 = new double[0];
            double[] tmp2 = new double[0];
            double fx = 0;
            double[,] xx = new double[0,0];
            double[,] cx = new double[0,0];
            double mrad = 0;
            int i_ = 0;

            gnnz = 0;
            snnz = 0;
            w = new double[0,0];
            info = 0;
            iterationscount = 0;
            nmv = 0;

            
            //
            // Handle special cases: NC=0
            //
            if( nc==0 )
            {
                info = 1;
                iterationscount = 0;
                nmv = 0;
                return;
            }
            
            //
            // Prepare for general case, NC>0
            //
            xcx = new double[mxnx];
            pointstags = new int[n];
            centerstags = new int[nc];
            info = -1;
            iterationscount = 0;
            nmv = 0;
            
            //
            // This block prepares quantities used to compute approximate cardinal basis functions (ACBFs):
            // * NearCentersCnt[]   -   array[NC], whose elements store number of near centers used to build ACBF
            // * NearPointsCnt[]    -   array[NC], number of near points used to build ACBF
            // * FarPointsCnt[]     -   array[NC], number of far points (ones where ACBF is nonzero)
            // * MaxNearCentersCnt  -   max(NearCentersCnt)
            // * MaxNearPointsCnt   -   max(NearPointsCnt)
            // * SumNearCentersCnt  -   sum(NearCentersCnt)
            // * SumNearPointsCnt   -   sum(NearPointsCnt)
            // * SumFarPointsCnt    -   sum(FarPointsCnt)
            //
            nearcenterscnt = new int[nc];
            nearpointscnt = new int[nc];
            skipnearpointscnt = new int[nc];
            farpointscnt = new int[nc];
            maxnearcenterscnt = 0;
            maxnearpointscnt = 0;
            maxfarpointscnt = 0;
            sumnearcenterscnt = 0;
            sumnearpointscnt = 0;
            sumfarpointscnt = 0;
            for(i=0; i<=nc-1; i++)
            {
                for(j=0; j<=mxnx-1; j++)
                {
                    xcx[j] = xc[i,j];
                }
                
                //
                // Determine number of near centers and maximum radius of near centers
                //
                nearcenterscnt[i] = nearestneighbor.kdtreequeryrnn(centerstree, xcx, r[i]*rbfnearradius, true);
                nearestneighbor.kdtreequeryresultstags(centerstree, ref centerstags);
                maxrad = 0;
                for(j=0; j<=nearcenterscnt[i]-1; j++)
                {
                    maxrad = Math.Max(maxrad, Math.Abs(r[centerstags[j]]));
                }
                
                //
                // Determine number of near points (ones which used to build ACBF)
                // and skipped points (the most near points which are NOT used to build ACBF
                // and are NOT included in the near points count
                //
                skipnearpointscnt[i] = nearestneighbor.kdtreequeryrnn(pointstree, xcx, 0.1*r[i], true);
                nearpointscnt[i] = nearestneighbor.kdtreequeryrnn(pointstree, xcx, (r[i]+maxrad)*rbfnearradius, true)-skipnearpointscnt[i];
                alglib.ap.assert(nearpointscnt[i]>=0, "BuildRBFModelLSQR: internal error");
                
                //
                // Determine number of far points
                //
                farpointscnt[i] = nearestneighbor.kdtreequeryrnn(pointstree, xcx, Math.Max(r[i]*rbfnearradius+maxrad*rbffarradius, r[i]*rbffarradius), true);
                
                //
                // calculate sum and max, make some basic checks
                //
                alglib.ap.assert(nearcenterscnt[i]>0, "BuildRBFModelLSQR: internal error");
                maxnearcenterscnt = Math.Max(maxnearcenterscnt, nearcenterscnt[i]);
                maxnearpointscnt = Math.Max(maxnearpointscnt, nearpointscnt[i]);
                maxfarpointscnt = Math.Max(maxfarpointscnt, farpointscnt[i]);
                sumnearcenterscnt = sumnearcenterscnt+nearcenterscnt[i];
                sumnearpointscnt = sumnearpointscnt+nearpointscnt[i];
                sumfarpointscnt = sumfarpointscnt+farpointscnt[i];
            }
            snnz = sumnearcenterscnt;
            gnnz = sumfarpointscnt;
            alglib.ap.assert(maxnearcenterscnt>0, "BuildRBFModelLSQR: internal error");
            
            //
            // Allocate temporaries.
            //
            // NOTE: we want to avoid allocation of zero-size arrays, so we
            //       use max(desired_size,1) instead of desired_size when performing
            //       memory allocation.
            //
            a = new double[maxnearpointscnt+maxnearcenterscnt, maxnearcenterscnt];
            tmpy = new double[maxnearpointscnt+maxnearcenterscnt];
            g = new double[maxnearcenterscnt];
            c = new double[maxnearcenterscnt];
            nearcenters = new double[maxnearcenterscnt, mxnx];
            nearpoints = new double[Math.Max(maxnearpointscnt, 1), mxnx];
            farpoints = new double[Math.Max(maxfarpointscnt, 1), mxnx];
            
            //
            // fill matrix SpG
            //
            sparse.sparsecreate(n, nc, gnnz, spg);
            sparse.sparsecreate(nc, nc, snnz, sps);
            for(i=0; i<=nc-1; i++)
            {
                centerscnt = nearcenterscnt[i];
                
                //
                // main center
                //
                for(j=0; j<=mxnx-1; j++)
                {
                    xcx[j] = xc[i,j];
                }
                
                //
                // center's tree
                //
                tmpi = nearestneighbor.kdtreequeryknn(centerstree, xcx, centerscnt, true);
                alglib.ap.assert(tmpi==centerscnt, "BuildRBFModelLSQR: internal error");
                nearestneighbor.kdtreequeryresultsx(centerstree, ref cx);
                nearestneighbor.kdtreequeryresultstags(centerstree, ref centerstags);
                
                //
                // point's tree
                //
                mrad = 0;
                for(j=0; j<=centerscnt-1; j++)
                {
                    mrad = Math.Max(mrad, r[centerstags[j]]);
                }
                
                //
                // we need to be sure that 'CTree' contains
                // at least one side center
                //
                sparse.sparseset(sps, i, i, 1);
                c[0] = 1.0;
                for(j=1; j<=centerscnt-1; j++)
                {
                    c[j] = 0.0;
                }
                if( centerscnt>1 && nearpointscnt[i]>0 )
                {
                    
                    //
                    // first KDTree request for points
                    //
                    pointscnt = nearpointscnt[i];
                    tmpi = nearestneighbor.kdtreequeryknn(pointstree, xcx, skipnearpointscnt[i]+nearpointscnt[i], true);
                    alglib.ap.assert(tmpi==skipnearpointscnt[i]+nearpointscnt[i], "BuildRBFModelLSQR: internal error");
                    nearestneighbor.kdtreequeryresultsx(pointstree, ref xx);
                    sind = skipnearpointscnt[i];
                    for(j=0; j<=pointscnt-1; j++)
                    {
                        vx = xx[sind+j,0];
                        vy = xx[sind+j,1];
                        vz = xx[sind+j,2];
                        for(k=0; k<=centerscnt-1; k++)
                        {
                            vr = 0.0;
                            vv = vx-cx[k,0];
                            vr = vr+vv*vv;
                            vv = vy-cx[k,1];
                            vr = vr+vv*vv;
                            vv = vz-cx[k,2];
                            vr = vr+vv*vv;
                            vv = r[centerstags[k]];
                            a[j,k] = Math.Exp(-(vr/(vv*vv)));
                        }
                    }
                    for(j=0; j<=centerscnt-1; j++)
                    {
                        g[j] = Math.Exp(-((math.sqr(xcx[0]-cx[j,0])+math.sqr(xcx[1]-cx[j,1])+math.sqr(xcx[2]-cx[j,2]))/math.sqr(r[centerstags[j]])));
                    }
                    
                    //
                    // calculate the problem
                    //
                    gnorm2 = 0.0;
                    for(i_=0; i_<=centerscnt-1;i_++)
                    {
                        gnorm2 += g[i_]*g[i_];
                    }
                    for(j=0; j<=pointscnt-1; j++)
                    {
                        vv = 0.0;
                        for(i_=0; i_<=centerscnt-1;i_++)
                        {
                            vv += a[j,i_]*g[i_];
                        }
                        vv = vv/gnorm2;
                        tmpy[j] = -vv;
                        for(i_=0; i_<=centerscnt-1;i_++)
                        {
                            a[j,i_] = a[j,i_] - vv*g[i_];
                        }
                    }
                    for(j=pointscnt; j<=pointscnt+centerscnt-1; j++)
                    {
                        for(k=0; k<=centerscnt-1; k++)
                        {
                            a[j,k] = 0.0;
                        }
                        a[j,j-pointscnt] = 1.0E-6;
                        tmpy[j] = 0.0;
                    }
                    fbls.fblssolvels(ref a, ref tmpy, pointscnt+centerscnt, centerscnt, ref tmp0, ref tmp1, ref tmp2);
                    for(i_=0; i_<=centerscnt-1;i_++)
                    {
                        c[i_] = tmpy[i_];
                    }
                    vv = 0.0;
                    for(i_=0; i_<=centerscnt-1;i_++)
                    {
                        vv += g[i_]*c[i_];
                    }
                    vv = vv/gnorm2;
                    for(i_=0; i_<=centerscnt-1;i_++)
                    {
                        c[i_] = c[i_] - vv*g[i_];
                    }
                    vv = 1/gnorm2;
                    for(i_=0; i_<=centerscnt-1;i_++)
                    {
                        c[i_] = c[i_] + vv*g[i_];
                    }
                    for(j=0; j<=centerscnt-1; j++)
                    {
                        sparse.sparseset(sps, i, centerstags[j], c[j]);
                    }
                }
                
                //
                // second KDTree request for points
                //
                pointscnt = farpointscnt[i];
                tmpi = nearestneighbor.kdtreequeryknn(pointstree, xcx, pointscnt, true);
                alglib.ap.assert(tmpi==pointscnt, "BuildRBFModelLSQR: internal error");
                nearestneighbor.kdtreequeryresultsx(pointstree, ref xx);
                nearestneighbor.kdtreequeryresultstags(pointstree, ref pointstags);
                
                //
                //fill SpG matrix
                //
                for(j=0; j<=pointscnt-1; j++)
                {
                    fx = 0;
                    vx = xx[j,0];
                    vy = xx[j,1];
                    vz = xx[j,2];
                    for(k=0; k<=centerscnt-1; k++)
                    {
                        vr = 0.0;
                        vv = vx-cx[k,0];
                        vr = vr+vv*vv;
                        vv = vy-cx[k,1];
                        vr = vr+vv*vv;
                        vv = vz-cx[k,2];
                        vr = vr+vv*vv;
                        vv = r[centerstags[k]];
                        vv = vv*vv;
                        fx = fx+c[k]*Math.Exp(-(vr/vv));
                    }
                    sparse.sparseset(spg, pointstags[j], i, fx);
                }
            }
            sparse.sparseconverttocrs(spg);
            sparse.sparseconverttocrs(sps);
            
            //
            // solve by LSQR method
            //
            tmpy = new double[n];
            tc = new double[nc];
            w = new double[nc, ny];
            linlsqr.linlsqrcreate(n, nc, state);
            linlsqr.linlsqrsetcond(state, epsort, epserr, maxits);
            for(i=0; i<=ny-1; i++)
            {
                for(j=0; j<=n-1; j++)
                {
                    tmpy[j] = y[j,i];
                }
                linlsqr.linlsqrsolvesparse(state, spg, tmpy);
                linlsqr.linlsqrresults(state, ref c, lsqrrep);
                if( lsqrrep.terminationtype<=0 )
                {
                    info = -4;
                    return;
                }
                sparse.sparsemtv(sps, c, ref tc);
                for(j=0; j<=nc-1; j++)
                {
                    w[j,i] = tc[j];
                }
                iterationscount = iterationscount+lsqrrep.iterationscount;
                nmv = nmv+lsqrrep.nmv;
            }
            info = 1;
        }