Esempio n. 1
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Construction of linear conjugate gradient solver.

        State parameter passed using "var" semantics (i.e. previous state  is  NOT
        erased). When it is already initialized, we can reause prevously allocated
        memory.

        INPUT PARAMETERS:
            X       -   initial solution
            B       -   right part
            N       -   system size
            State   -   structure; may be preallocated, if we want to reuse memory

        OUTPUT PARAMETERS:
            State   -   structure which is used by FBLSCGIteration() to store
                        algorithm state between subsequent calls.

        NOTE: no error checking is done; caller must check all parameters, prevent
              overflows, and so on.

          -- ALGLIB --
             Copyright 22.10.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void fblscgcreate(double[] x,
            double[] b,
            int n,
            fblslincgstate state)
        {
            int i_ = 0;

            if( ap.len(state.b)<n )
            {
                state.b = new double[n];
            }
            if( ap.len(state.rk)<n )
            {
                state.rk = new double[n];
            }
            if( ap.len(state.rk1)<n )
            {
                state.rk1 = new double[n];
            }
            if( ap.len(state.xk)<n )
            {
                state.xk = new double[n];
            }
            if( ap.len(state.xk1)<n )
            {
                state.xk1 = new double[n];
            }
            if( ap.len(state.pk)<n )
            {
                state.pk = new double[n];
            }
            if( ap.len(state.pk1)<n )
            {
                state.pk1 = new double[n];
            }
            if( ap.len(state.tmp2)<n )
            {
                state.tmp2 = new double[n];
            }
            if( ap.len(state.x)<n )
            {
                state.x = new double[n];
            }
            if( ap.len(state.ax)<n )
            {
                state.ax = new double[n];
            }
            state.n = n;
            for(i_=0; i_<=n-1;i_++)
            {
                state.xk[i_] = x[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.b[i_] = b[i_];
            }
            state.rstate.ia = new int[1+1];
            state.rstate.ra = new double[6+1];
            state.rstate.stage = -1;
        }
Esempio n. 2
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Linear CG solver, function relying on reverse communication to calculate
        matrix-vector products.

        See comments for FBLSLinCGState structure for more info.

          -- ALGLIB --
             Copyright 22.10.2009 by Bochkanov Sergey
        *************************************************************************/
        public static bool fblscgiteration(fblslincgstate state)
        {
            bool result = new bool();
            int n = 0;
            int k = 0;
            double rk2 = 0;
            double rk12 = 0;
            double pap = 0;
            double s = 0;
            double betak = 0;
            double v1 = 0;
            double v2 = 0;
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstate.stage>=0 )
            {
                n = state.rstate.ia[0];
                k = state.rstate.ia[1];
                rk2 = state.rstate.ra[0];
                rk12 = state.rstate.ra[1];
                pap = state.rstate.ra[2];
                s = state.rstate.ra[3];
                betak = state.rstate.ra[4];
                v1 = state.rstate.ra[5];
                v2 = state.rstate.ra[6];
            }
            else
            {
                n = -983;
                k = -989;
                rk2 = -834;
                rk12 = 900;
                pap = -287;
                s = 364;
                betak = 214;
                v1 = -338;
                v2 = -686;
            }
            if( state.rstate.stage==0 )
            {
                goto lbl_0;
            }
            if( state.rstate.stage==1 )
            {
                goto lbl_1;
            }
            if( state.rstate.stage==2 )
            {
                goto lbl_2;
            }
            
            //
            // Routine body
            //
            
            //
            // prepare locals
            //
            n = state.n;
            
            //
            // Test for special case: B=0
            //
            v1 = 0.0;
            for(i_=0; i_<=n-1;i_++)
            {
                v1 += state.b[i_]*state.b[i_];
            }
            if( (double)(v1)==(double)(0) )
            {
                for(k=0; k<=n-1; k++)
                {
                    state.xk[k] = 0;
                }
                result = false;
                return result;
            }
            
            //
            // r(0) = b-A*x(0)
            // RK2 = r(0)'*r(0)
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xk[i_];
            }
            state.rstate.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk[i_] = state.b[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk[i_] = state.rk[i_] - state.ax[i_];
            }
            rk2 = 0.0;
            for(i_=0; i_<=n-1;i_++)
            {
                rk2 += state.rk[i_]*state.rk[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.pk[i_] = state.rk[i_];
            }
            state.e1 = Math.Sqrt(rk2);
            
            //
            // Cycle
            //
            k = 0;
        lbl_3:
            if( k>n-1 )
            {
                goto lbl_5;
            }
            
            //
            // Calculate A*p(k) - store in State.Tmp2
            // and p(k)'*A*p(k)  - store in PAP
            //
            // If PAP=0, break (iteration is over)
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.pk[i_];
            }
            state.rstate.stage = 1;
            goto lbl_rcomm;
        lbl_1:
            for(i_=0; i_<=n-1;i_++)
            {
                state.tmp2[i_] = state.ax[i_];
            }
            pap = state.xax;
            if( !math.isfinite(pap) )
            {
                goto lbl_5;
            }
            if( (double)(pap)<=(double)(0) )
            {
                goto lbl_5;
            }
            
            //
            // S = (r(k)'*r(k))/(p(k)'*A*p(k))
            //
            s = rk2/pap;
            
            //
            // x(k+1) = x(k) + S*p(k)
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.xk1[i_] = state.xk[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.xk1[i_] = state.xk1[i_] + s*state.pk[i_];
            }
            
            //
            // r(k+1) = r(k) - S*A*p(k)
            // RK12 = r(k+1)'*r(k+1)
            //
            // Break if r(k+1) small enough (when compared to r(k))
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk1[i_] = state.rk[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk1[i_] = state.rk1[i_] - s*state.tmp2[i_];
            }
            rk12 = 0.0;
            for(i_=0; i_<=n-1;i_++)
            {
                rk12 += state.rk1[i_]*state.rk1[i_];
            }
            if( (double)(Math.Sqrt(rk12))<=(double)(100*math.machineepsilon*state.e1) )
            {
                
                //
                // X(k) = x(k+1) before exit -
                // - because we expect to find solution at x(k)
                //
                for(i_=0; i_<=n-1;i_++)
                {
                    state.xk[i_] = state.xk1[i_];
                }
                goto lbl_5;
            }
            
            //
            // BetaK = RK12/RK2
            // p(k+1) = r(k+1)+betak*p(k)
            //
            // NOTE: we expect that BetaK won't overflow because of
            // "Sqrt(RK12)<=100*MachineEpsilon*E1" test above.
            //
            betak = rk12/rk2;
            for(i_=0; i_<=n-1;i_++)
            {
                state.pk1[i_] = state.rk1[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.pk1[i_] = state.pk1[i_] + betak*state.pk[i_];
            }
            
            //
            // r(k) := r(k+1)
            // x(k) := x(k+1)
            // p(k) := p(k+1)
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk[i_] = state.rk1[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.xk[i_] = state.xk1[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.pk[i_] = state.pk1[i_];
            }
            rk2 = rk12;
            k = k+1;
            goto lbl_3;
        lbl_5:
            
            //
            // Calculate E2
            //
            for(i_=0; i_<=n-1;i_++)
            {
                state.x[i_] = state.xk[i_];
            }
            state.rstate.stage = 2;
            goto lbl_rcomm;
        lbl_2:
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk[i_] = state.b[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.rk[i_] = state.rk[i_] - state.ax[i_];
            }
            v1 = 0.0;
            for(i_=0; i_<=n-1;i_++)
            {
                v1 += state.rk[i_]*state.rk[i_];
            }
            state.e2 = Math.Sqrt(v1);
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstate.ia[0] = n;
            state.rstate.ia[1] = k;
            state.rstate.ra[0] = rk2;
            state.rstate.ra[1] = rk12;
            state.rstate.ra[2] = pap;
            state.rstate.ra[3] = s;
            state.rstate.ra[4] = betak;
            state.rstate.ra[5] = v1;
            state.rstate.ra[6] = v2;
            return result;
        }
Esempio n. 3
0
 public override alglib.apobject make_copy()
 {
     fblslincgstate _result = new fblslincgstate();
     _result.e1 = e1;
     _result.e2 = e2;
     _result.x = (double[])x.Clone();
     _result.ax = (double[])ax.Clone();
     _result.xax = xax;
     _result.n = n;
     _result.rk = (double[])rk.Clone();
     _result.rk1 = (double[])rk1.Clone();
     _result.xk = (double[])xk.Clone();
     _result.xk1 = (double[])xk1.Clone();
     _result.pk = (double[])pk.Clone();
     _result.pk1 = (double[])pk1.Clone();
     _result.b = (double[])b.Clone();
     _result.rstate = (rcommstate)rstate.make_copy();
     _result.tmp2 = (double[])tmp2.Clone();
     return _result;
 }