public static void forwBackwCheck1DAlongD(ILArray <float> A, ILArray <fcomplex> Result, int p)
 {
     try {
         ILArray <fcomplex> B = fft(A, p);
         //double errMult = 1/(A.Dimensions.NumberOfElements * Math.Pow(10,A.Dimensions.NumberOfDimensions));
         float errMult = (float)Math.Pow(0.1f, A.Dimensions.NumberOfDimensions) / A.Dimensions.NumberOfElements;
         if (!A.IsScalar)
         {
             errMult /= (float)A.Dimensions[A.Dimensions.FirstNonSingleton()];
         }
         if (sumall(abs(subtract(Result, B))) * errMult > (double)MachineParameterFloat.eps)
         {
             throw new Exception("invalid value");
         }
         ILArray <float> ResultR = ifftsym(B, p);
         if (ILMath.sumall(ILMath.abs(ResultR - A)) * errMult > (double)ILMath.MachineParameterFloat.eps)
         {
             throw new Exception("invalid value");
         }
         B = ifft(B, p);
         if (ILMath.sumall(ILMath.abs(ILMath.tofcomplex(A) - B)) * errMult > (double)ILMath.MachineParameterFloat.eps)
         {
             throw new Exception("invalid value");
         }
     } catch (ILNumerics.Exceptions.ILArgumentException) {
         throw new Exception("unexpected exception was thrown -> error!");
     }
 }
 public static void forwBackwCheck2D(ILArray <double> A, ILArray <complex> Result)
 {
     try {
         ILArray <complex> B = fft2(A);
         //double errMult = 1/(A.Dimensions.NumberOfElements * Math.Pow(10,A.Dimensions.NumberOfDimensions));
         double errMult = Math.Pow(0.1, A.Dimensions.NumberOfDimensions) / A.Dimensions.NumberOfElements;
         if (!A.IsScalar)
         {
             errMult /= (double)A.Dimensions[A.Dimensions.FirstNonSingleton()];
         }
         if (sumall(abs(subtract(Result, B))) * errMult > (double)MachineParameterDouble.eps)
         {
             throw new Exception("invalid value");
         }
         ILArray <double> ResultR = ifft2sym(B);
         if (ILMath.sumall(ILMath.abs(ResultR - A)) * errMult > (double)ILMath.MachineParameterDouble.eps)
         {
             throw new Exception("invalid value");
         }
         B = ifft2(B);
         if (ILMath.sumall(ILMath.abs(ILMath.tocomplex(A) - B)) * errMult > (double)ILMath.MachineParameterDouble.eps)
         {
             throw new Exception("invalid value");
         }
     } catch (ILNumerics.Exceptions.ILArgumentException) {
         throw new Exception("unexpected exception was thrown -> error!");
     }
 }
Пример #3
0
        /// <summary>
        /// Multidimensional scaling/PCoA: transform distances to points in a coordinate system.
        /// </summary>
        /// <param name="input">A matrix of pairwise distances. Zero indicates identical objects.</param>
        /// <returns>A matrix, the columns of which are coordinates in the nth dimension.
        /// The rows are in the same order as the input.</returns>
        public static ILArray <double> Scale(ILArray <double> input)
        {
            int n = input.Length;

            ILArray <double> p = ILMath.eye <double>(n, n) - ILMath.repmat(1.0 / n, n, n);

            ILArray <double> a = -.5 * ILMath.multiplyElem(input, input);
            ILArray <double> b = ILMath.multiply(p, a, p);

            ILArray <complex> V = ILMath.empty <complex>();
            ILArray <complex> E = ILMath.eig((b + b.T) / 2, V);

            ILArray <int>    i = ILMath.empty <int>();
            ILArray <double> e = ILMath.sort(ILMath.diag(ILMath.real(E)), i);

            e = ILMath.flipud(e);
            i = ILMath.toint32(ILMath.flipud(ILMath.todouble(i)));

            ILArray <int> keep = ILMath.empty <int>();

            for (int j = 0; j < e.Length; j++)
            {
                if (e[j] > 0.000000001)
                {
                    keep.SetValue(j, keep.Length);
                }
            }

            ILArray <double> Y;

            if (ILMath.isempty(keep))
            {
                Y = ILMath.zeros(n, 1);
            }
            else
            {
                Y = ILMath.zeros <double>(V.S[0], keep.Length);
                for (int j = 0; j < keep.Length; j++)
                {
                    Y[ILMath.full, j] = ILMath.todouble(-V[ILMath.full, i[keep[j]]]);
                }
                Y = ILMath.multiply(Y, ILMath.diag(ILMath.sqrt(e[keep])));
            }

            ILArray <int> maxind = ILMath.empty <int>();

            ILMath.max(ILMath.abs(Y), maxind, 0);
            int              d       = Y.S[1];
            ILArray <int>    indices = maxind + ILMath.toint32(ILMath.array <int>(SteppedRange(0, n, (d - 1) * n)));
            ILArray <double> colsign = ILMath.sign(Y[indices]);

            for (int j = 0; j < Y.S[1]; j++)
            {
                Y[ILMath.full, j] = Y[ILMath.full, j] * colsign[j];
            }

            return(Y);
        }
 public static void forwBackwCheckNDmn(ILArray <float> A, ILArray <fcomplex> Result, ILArray <float> ResRA, ILArray <fcomplex> ResIA, int m, int n, int q)
 {
     try {
         int[] sizes = A.Dimensions.ToIntArray(3);
         sizes[0] = m; sizes[1] = n; sizes[2] = q;
         ILArray <fcomplex> B = fftn(A, sizes);
         //double errMult = 1/(A.Dimensions.NumberOfElements * Math.Pow(10,A.Dimensions.NumberOfDimensions));
         float errMult = (float)Math.Pow(0.1f, A.Dimensions.NumberOfDimensions) / A.Dimensions.NumberOfElements;
         if (!A.IsScalar)
         {
             errMult /= (float)A.Dimensions[A.Dimensions.FirstNonSingleton()];
         }
         if (m == 0 || n == 0 || q == 0)
         {
             if (!B.IsEmpty)
             {
                 throw new Exception("empty matrix should return empty!");
             }
         }
         else if (sumall(abs(subtract(Result, B))) * errMult > (double)MachineParameterFloat.eps)
         {
             throw new Exception("invalid value");
         }
         ILArray <float> ResultR = ifftnsym(B);
         if (m == 0 || n == 0 || q == 0)
         {
             if (!ResultR.IsEmpty)
             {
                 throw new Exception("empty matrix should return empty!");
             }
         }
         else if (ILMath.sumall(ILMath.abs(ResultR - ILMath.resize4Transform(A, sizes))) * errMult > (double)ILMath.MachineParameterFloat.eps)
         {
             throw new Exception("invalid value");
         }
         ILArray <fcomplex> ResultC = ifftn(tofcomplex(A), sizes);
         if (m == 0 || n == 0 || q == 0)
         {
             if (!B.IsEmpty)
             {
                 throw new Exception("empty matrix should return empty!");
             }
         }
         else if (ILMath.sumall(ILMath.abs(ResultC - ResIA)) * errMult > (double)ILMath.MachineParameterFloat.eps)
         {
             throw new Exception("invalid value");
         }
     } catch (ILNumerics.Exceptions.ILArgumentException) {
         throw new Exception("unexpected exception was thrown -> error!");
     }
 }
 public static void forwBackwCheck2Dmn(ILArray <double> A, ILArray <complex> Result, ILArray <double> ResRA, ILArray <complex> ResIA, int m, int n)
 {
     try {
         ILArray <complex> B     = fft2(A, m, n);
         int[]             sizes = A.Dimensions.ToIntArray();
         sizes[0] = m; sizes[1] = n;
         double errMult = Math.Pow(0.1, A.Dimensions.NumberOfDimensions) / A.Dimensions.NumberOfElements;
         if (!A.IsScalar)
         {
             errMult /= (double)A.Dimensions[A.Dimensions.FirstNonSingleton()];
         }
         if (m == 0 || n == 0)
         {
             if (!B.IsEmpty)
             {
                 throw new Exception("empty matrix should return empty!");
             }
         }
         else if (sumall(abs(subtract(Result, B))) * errMult > (double)MachineParameterDouble.eps)
         {
             throw new Exception("invalid value");
         }
         ILArray <double> ResultR = ifft2sym(B);
         if (m == 0 || n == 0)
         {
             if (!ResultR.IsEmpty)
             {
                 throw new Exception("empty matrix should return empty!");
             }
         }
         else if (ILMath.sumall(ILMath.abs(ResultR - ILMath.resize4Transform(A, sizes))) * errMult > (double)ILMath.MachineParameterDouble.eps)
         {
             throw new Exception("invalid value");
         }
         ILArray <complex> ResultC = ifft2(tocomplex(A), m, n);
         if (m == 0 || n == 0)
         {
             if (!ResultC.IsEmpty)
             {
                 throw new Exception("empty matrix should return empty!");
             }
         }
         else if (ILMath.sumall(ILMath.abs(ResIA - ResultC)) * errMult > (double)ILMath.MachineParameterDouble.eps)
         {
             throw new Exception("invalid value");
         }
     } catch (ILNumerics.Exceptions.ILArgumentException) {
         throw new Exception("unexpected exception was thrown -> error!");
     }
 }
Пример #6
0
        //public void Test_SimpleAsyncAlgorithmSample() {
        //    int errorCode = 0;
        //    try {
        //        SimpleAsyncSample sampleAlg = new SimpleAsyncSample(null, 2.0,50,ILMath.randn(3,2));
        //        sampleAlg.RunAsync();
        //        while (sampleAlg.State == ILAlgorithmRunningState.Running) {
        //            Info(sampleAlg.Progress * 100 + "\r");
        //            System.Threading.Thread.Sleep(300);
        //        }
        //        Info(sampleAlg.Result.result.ToString());
        //        //sampleAlg.Result;
        //        Success();
        //    } catch(Exception e) {
        //        Error(errorCode,e.Message);
        //    }
        //}


        public void Test_LDA()
        {
            int errorCode = 0;

            try {
                LDA lda = new LDA();
                lda.StateChanged    += new ILAlgorithmStateChangedEventHandler(lda_StateChanged);
                lda.ProgressChanged += new ILAlgorithmStateChangedEventHandler(lda_ProgressChanged);
                ILArray <double> X      = new ILArray <double>(new double[] { -2, -2, -3, -3, 2, 2, 3, 3 }, 2, 4);
                ILLogicalArray   labels = new ILLogicalArray(new byte[8] {
                    0, 1, 0, 1, 1, 0, 1, 0
                }, 2, 4);
                LDA.Hyperplane C = lda.TrainLDA(X, labels, 0.4);
                if (Object.ReferenceEquals(C, null))
                {
                    throw new Exception("LDA: result is null!");
                }
                if (!(C.w is ILArray <double>) || C.w.Dimensions[0] != 2)
                {
                    throw new Exception("LDA: Results C[0] should be ILArray<double> 2x1");
                }
                if (!(C.b is ILArray <double>) || !C.b.IsScalar)
                {
                    throw new Exception("LDA: Results C[1] should be ILArray<double> 2x1");
                }
                if (ILMath.abs(C.w[0] - -9.3750) > 1e-8)
                {
                    throw new Exception("LDA: invalid result: C.w(1) should be : -9.3750");
                }
                if (ILMath.abs(C.w[1] - -9.3750) > 1e-8)
                {
                    throw new Exception("LDA: invalid result: C.w(2) should be : -9.3750");
                }
                if (ILMath.abs(C.b.GetValue(0)) > 1e-8)
                {
                    throw new Exception("LDA: invalid result: C.b should be : 0.0!");
                }
                Success();
            } catch (Exception e) {
                Error(errorCode, e.Message);
            }
        }
Пример #7
0
 protected static ILArray <double> abs(ILArray <double> ilArray)
 {
     return(ILMath.abs(ilArray));
 }
Пример #8
0
        //% The main file for running the wind farm controll and wake simulation.
        // It is not completely done yet. Further updates will come
        // Currently there are only 4 turbines, for test purposes. But is should be
        // easily updated to a larger number of turbines.
        // Similarly there is a lot of room for speed optimizations, even though it
        // now runs slowly with only 4 turbines
        // 19/07-13 MS

        public static double[][] Simulation(WakeFarmControlConfig config)
        {
            var parm = new WindTurbineParameters();

            ILMatFile env;
            ILMatFile wt;

            ILArray <int>    idx;
            ILArray <double> ee;

            double           Ki;
            double           Kp;
            int              PC_MaxPit;
            int              PC_MinPit;
            double           VS_CtInSp;
            double           VS_RtGnSp;
            double           VS_Rgn2K;
            double           omega0;
            double           beta0;
            double           power0;
            ILArray <double> x;
            ILArray <double> u0;
            ILArray <double> u;
            ILArray <double> Mg_old;
            ILArray <double> P_ref;
            ILArray <double> Pa;
            ILArray <double> Power;
            ILArray <double> Ct;
            ILArray <double> P_ref_new;
            ILArray <double> v_nac;
            double           alpha;
            double           Mg_max_rate;
            ILArray <double> e;
            ILArray <double> Mg;
            ILArray <double> beta;
            ILArray <double> Cp;
            ILArray <double> Omega;
            ILArray <double> out_;

            if (config.NTurbines == 0)
            {
                return(null);
            }

            // Wind farm properties
            //turbine properties
            env             = wt = new ILMatFile(config.NREL5MW_MatFile);                                             //Load parameters from the NREL 5MW turbine
            parm.N          = config.NTurbines;                                                                       // number of turbines in farm
            parm.rho        = (double)env.GetArray <double>("env_rho");                                               //air density
            parm.radius     = ((double)(wt.GetArray <double>("wt_rotor_radius"))) * ILMath.ones(1, config.NTurbines); // rotor radius (NREL5MW)
            parm.rated      = 5e6 * ILMath.ones(1, config.NTurbines);                                                 //rated power (NREL5MW)
            parm.ratedSpeed = (double)wt.GetArray <double>("wt_rotor_ratedspeed");                                    //rated rotor speed

            idx = ILMath.empty <int>();
            ILMath.max(wt.GetArray <double>("wt_cp_table")[ILMath.full], idx);                                        //Find index for max Cp;
            parm.Cp = ILMath.ones(1, config.NTurbines) * wt.GetArray <double>("wt_cp_table").GetValue(idx.ToArray()); //Set power coefficent to maximum value in the cp table
            parm.Ct = ILMath.ones(1, config.NTurbines) * wt.GetArray <double>("wt_ct_table").GetValue(idx.ToArray()); //Set power coefficent to maximum value in the ct table

            // NOTE: controller parameters should be imported from the wt....struct in
            //Pitch control

            ee = 0;                                 //blade pitch integrator
            Ki = 0.008068634 * 360 / 2 / ILMath.pi; // integral gain (NREL5MW)
            Kp = 0.01882681 * 360 / 2 / ILMath.pi;  // proportional gain (NREL5MW)

            PC_MaxPit = 90;
            PC_MinPit = 0;

            //region control NREL
            VS_CtInSp = 70.16224;
            VS_RtGnSp = 121.6805;
            VS_Rgn2K  = 2.332287;


            // load initial wind data
            var wind = new ILMatFile(config.Wind_MatFile);

            //% Set initial conditions
            omega0 = 1.267; //Rotation speed
            beta0  = 0;     //Pitch

            var timeLine = (int)config.TimeLine();

            power0 = parm.rated.GetValue(0); //Power production
            x      = (omega0 * ILMath.ones(parm.N, 1)).Concat((wind.GetArray <double>("wind").GetValue(0, 1) * ILMath.ones(parm.N, 1)), 1);
            u0     = (beta0 * ILMath.ones(parm.N, 1)).Concat((power0 * ILMath.ones(parm.N, 1)), 1);
            u      = u0.C;
            Mg_old = u[ILMath.full, 1];
            P_ref  = ILMath.zeros(parm.N, (int)config.TimeLine()); //Initialize matrix to save the power production history for each turbine
            Pa     = P_ref.C;                                      //Initialize available power matrix
            Power  = P_ref.C;
            Ct     = parm.Ct.C;                                    //Initialize Ct - is this correct?
            Ct[timeLine - 1, ILMath.full] = Ct[0, ILMath.full];
            P_ref_new = power0 * ILMath.ones(config.NTurbines, 1);

            v_nac = ILMath.zeros(Ct.Size[1], timeLine);
            Mg    = ILMath.zeros(u.Size[0], timeLine);
            beta  = ILMath.zeros(u.Size[0], timeLine);
            Omega = ILMath.zeros(Ct.Size[1], timeLine);
            Cp    = ILMath.zeros(timeLine, parm.Cp.Size[1]);

            var turbineModel = new TurbineDrivetrainModel();

            //% Simulate wind farm operation
            //var timeLine = (int) config.TimeLine();
            for (var i = 2; i <= timeLine; i++) //At each sample time(DT) from Tstart to Tend
            {
                //Calculate the wake using the current Ct values
                {
                    ILArray <double> out_v_nac;
                    WakeCalculation.Calculate((Ct[i - 1 - 1, ILMath.full]), i, wind, out out_v_nac);
                    v_nac[ILMath.full, i - 1] = out_v_nac;
                }
                x[ILMath.full, 1] = v_nac[ILMath.full, i - 1];


                //Farm control
                //Calculate the power distribution references for each turbine
                if (config.EnablePowerDistribution)
                {
                    ILArray <double> out_Pa;
                    PowerDistributionControl.DistributePower(v_nac[ILMath.full, i - 1], config.Pdemand, Power[ILMath.full, i - 1 - 1], parm, out P_ref_new, out out_Pa);
                    Pa[ILMath.full, i - 1] = out_Pa;
                }

                //Hold  the demand for some seconds
                if (ILMath.mod(i, ILMath.round(config.PRefSampleTime / config.DT)) == 2) //???
                {
                    P_ref[ILMath.full, i - 1] = P_ref_new;
                }
                else
                {
                    if (config.PowerRefInterpolation)
                    {
                        alpha = 0.01;
                        P_ref[ILMath.full, i - 1] = (1 - alpha) * P_ref[ILMath.full, i - 1 - 1] + (alpha) * P_ref_new;
                    }
                    else
                    {
                        P_ref[ILMath.full, i - 1] = P_ref_new;
                    }
                }


                //Calculate control for each individual turbine - should be moved to the
                //turbine (drivetrain) model.

                //Torque controller
                for (var j = 1; j <= parm.N; j++)
                {
                    if ((x.GetValue(j - 1, 0) * 97 >= VS_RtGnSp) || (u.GetValue(j - 1, 0) >= 1))   // We are in region 3 - power is constant
                    {
                        u.SetValue(P_ref.GetValue(j - 1, i - 1) / x.GetValue(j - 1, 0), j - 1, 1);
                    }
                    else if (x.GetValue(j - 1, 0) * 97 <= VS_CtInSp)                            //! We are in region 1 - torque is zero
                    {
                        u.SetValue(0.0, j - 1, 1);
                    }
                    else                                                         //! We are in region 2 - optimal torque is proportional to the square of the generator speed
                    {
                        u.SetValue(97 * VS_Rgn2K * x.GetValue(j - 1, 0) * x.GetValue(j - 1, 0) * Math.Pow(97, 2), j - 1, 1);
                    }
                }

                //Rate limit torque change
                //  u(:,2) - Mg_old;
                Mg_max_rate       = 1e6 * config.DT;
                u[ILMath.full, 1] = ILMath.sign(u[ILMath.full, 1] - Mg_old) * ILMath.min(ILMath.abs(u[ILMath.full, 1] - Mg_old), Mg_max_rate) + Mg_old;

                //Pitch controller
                e  = 97 * (omega0 * ILMath.ones(parm.N, 1) - x[ILMath.full, 0]);
                ee = ee - config.DT * e;
                ee = ILMath.min(ILMath.max(ee, PC_MinPit / Ki), PC_MaxPit / Ki);

                u[ILMath.full, 0] = -Kp * config.DT * e + Ki * ee;
                for (var j = 1; j <= parm.N; j++)
                {
                    u.SetValue(Math.Min(Math.Max(u.GetValue(j - 1, 0), PC_MinPit), PC_MaxPit), j - 1, 0);
                }

                if (!config.EnableTurbineDynamics)
                {
                    u = u0;
                }

                Mg[ILMath.full, i - 1] = u[ILMath.full, 1];
                Mg_old = Mg[ILMath.full, i - 1];
                beta[ILMath.full, i - 1] = u[ILMath.full, 0]; //Set pitch


                //Turbine dynamics - can be simplified
                if (config.EnableTurbineDynamics)
                {
                    for (var j = 1; j <= parm.N; j++)
                    {
                        double out_x;
                        double out_Ct;
                        double out_Cp;
                        turbineModel.Model(x[j - 1, ILMath.full], u[j - 1, ILMath.full], wt, env, config.DT, out out_x, out out_Ct, out out_Cp);
                        x.SetValue(out_x, j - 1, 0);
                        Ct.SetValue(out_Ct, i - 1, j - 1);
                        Cp.SetValue(out_Cp, i - 1, j - 1);
                    }
                }
                else
                {
                    Ct[i - 1, ILMath.full] = parm.Ct;
                    Cp[i - 1, ILMath.full] = parm.Cp;
                    x[ILMath.full, 0]      = parm.ratedSpeed;//Rotational speed
                }

                Omega[ILMath.full, i - 1] = x[ILMath.full, 0];
                Power[ILMath.full, i - 1] = Omega[ILMath.full, i - 1] * Mg[ILMath.full, i - 1];
            }

            //% Save output data
            out_ = (config.DT * (ILMath.counter(0, 1, config.TimeLine())));
            out_ = out_.Concat(v_nac.T, 1);
            out_ = out_.Concat(Omega.T, 1);
            out_ = out_.Concat(beta.T, 1);
            out_ = out_.Concat(P_ref.T, 1);
            out_ = out_.Concat(Ct, 1);
            out_ = out_.Concat(Cp, 1);
            out_ = out_.Concat(Pa.T, 1);
            out_ = out_.Concat(Mg.T, 1);
            out_ = out_.Concat(Power.T, 1);

            //Ttotal power demand
            var l = config.NTurbines * 3 + 1;
            var r = l + config.NTurbines - 1;

            out_ = out_.Concat(ILMath.sum(out_[ILMath.full, ILMath.r(l, r)], 1) / 1e6, 1);    // P_ref sum

            l = config.NTurbines * 6 + 1;
            r = l + config.NTurbines - 1;

            out_ = out_.Concat(ILMath.sum(out_[ILMath.full, ILMath.r(l, r)], 1) / 1e6, 1);    // Pa sum. 'Power Demand'
            out_ = out_.Concat(ILMath.sum(Power).T / 1e6, 1);                                 // 'Actual Production'

            //Ttotal power demand
            out_ = out_.Concat(ILMath.sum(P_ref.T, 1), 1);              // 'Demand'
            out_ = out_.Concat(ILMath.sum(Pa.T, 1), 1);                 // 'Available'
            out_ = out_.Concat(ILMath.sum(Mg * Omega).T, 1);            // 'Actual'

            //Total power produced
            out_ = out_.Concat((Mg * Omega).T, 1);

            var out_doubleArray = new double[out_.Size[0]][];

            for (int i = 0; i <= out_doubleArray.GetLength(0) - 1; i++)
            {
                out_doubleArray[i] = new double[out_.Size[1]];
                for (int j = 0; j <= out_doubleArray[i].GetLength(0) - 1; j++)
                {
                    out_doubleArray[i][j] = out_.GetValue(i, j);
                }
            }
            return(out_doubleArray);
        }
Пример #9
0
        //Finalval is the result of the look up of Lambda and Beta in the CP map.
        //The function uses a bilinear interpolation method, and has been developed
        //to replace interpn in an embedded matlab environment
        public void Interpolate(double Beta, double Lambda, ILArray <double> table2, ILArray <double> Betavec2, ILArray <double> Lambdavec2, out double Finalval)
        {
            ILArray <int>    Bt;
            int              B1;
            int              B2;
            ILArray <int>    Lt;
            int              L1;
            int              L2;
            ILArray <double> Yvals;
            ILArray <double> Yintervals;

            //Setting up persistent variables

            //Function initialization

            //The first time the function is run, it stores supplied map as a persistent
            //variable.
            if (_persistentCt == null)// Is only run once
            {
                _persistentCt           = new PersistentVariables();
                _persistentCt.Table     = table2.C;
                _persistentCt.Betavec   = Betavec2.C;
                _persistentCt.Lambdavec = Lambdavec2.C;
            }

            //Step 1, finding two adjecent indexes of the BetaVec, which contain the
            //supplied beta value

            Bt = ILMath.empty <int>();
            ILMath.min(ILMath.abs(_persistentCt.Betavec - Beta), Bt); //Finding index 1
            B1 = Bt.GetValue(0);                                      //Necessary specification in embedded
            //matlab

            if (Beta > _persistentCt.Betavec.GetValue(B1))    //Finding index 2
            {
                if (B1 == (_persistentCt.Betavec.Length - 1)) //testing if endpoint-extrapolation
                {
                    B2 = B1;                                  //should be used
                    B1 = B1 - 1;
                }
                else
                {
                    B2 = B1 + 1;
                }
            }
            else
            {
                if (B1 == 0)
                {
                    B1 = 1;
                    B2 = 0;
                }
                else
                {
                    B2 = B1 - 1;
                }
            }

            //Step 2, finding two adjecent indexes of the LambdaVec, which contain the
            //supplied Lambda value
            Lt = ILMath.empty <int>();
            ILMath.min(ILMath.abs(_persistentCt.Lambdavec - Lambda), Lt);
            L1 = Lt.GetValue(0);
            if (Lambda > _persistentCt.Lambdavec.GetValue(L1)) //Need to work out of indexes
            {
                if (L1 == (_persistentCt.Lambdavec.Length - 1))
                {
                    L2 = L1;
                    L1 = L1 - 1;
                }
                else
                {
                    L2 = L1 + 1;
                }
            }
            else
            {
                if (L1 == 0)
                {
                    L1 = 1;
                    L2 = 0;
                }
                else
                {
                    L2 = L1 - 1;
                }
            }

            //Step 3
            //Finding the four indexed values by means of the indexes
            Yvals = new double[, ] {
                { _persistentCt.Table.GetValue(B1, L1), _persistentCt.Table.GetValue(B2, L1) },
                { _persistentCt.Table.GetValue(B1, L2), _persistentCt.Table.GetValue(B2, L2) }
            };

            //Step 4
            //Making two sets of linear interpolations by using the different lambda values
            Yintervals = ILMath.array(new double[] {
                ((Yvals.GetValue(0, 1) - Yvals.GetValue(0, 0))
                 / (_persistentCt.Lambdavec.GetValue(L2) - _persistentCt.Lambdavec.GetValue(L1))
                 * (Lambda - _persistentCt.Lambdavec.GetValue(L1))
                 + Yvals.GetValue(0, 0)),
                ((Yvals.GetValue(1, 1) - Yvals.GetValue(1, 0))
                 / (_persistentCt.Lambdavec.GetValue(L2) - _persistentCt.Lambdavec.GetValue(L1))
                 * (Lambda - _persistentCt.Lambdavec.GetValue(L1))
                 + Yvals.GetValue(1, 0))
            },
                                      2, 1);

            //Step 5
            //Making the final linear interpolation on the results obtained in
            //stepp 4
            Finalval = ((Yintervals.GetValue(1) - Yintervals.GetValue(0)) / (_persistentCt.Betavec.GetValue(B2) - _persistentCt.Betavec.GetValue(B1)))
                       * (Beta - _persistentCt.Betavec.GetValue(B1))
                       + Yintervals.GetValue(0);
        }