コード例 #1
0
        public Vector <double>[] bvpsolver_zzz(Func <double, Vector <double>, Vector <double> > system,
                                               double ya, double yb,
                                               double xa, double xb,
                                               int N)
        {
            Vector <double>[] res;
            Vector <double>   y0;
            double            s_guess = (yb - ya) / (xb - xa), s_guess_pre = 0;
            double            fais = yb, fais_pre = 0, dfaids = 0;

            do
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess });

                // observer_pr ob_pr = this->write_targetFunc_end;
                res         = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                fais_pre    = fais;
                fais        = res[N - 1][0] - yb;
                dfaids      = (fais - fais_pre) / (s_guess - s_guess_pre);
                s_guess_pre = s_guess;
                s_guess     = s_guess - fais / dfaids;
                //count++;
            } while (fais > 0.001 * yb + 1e-6 || fais < -0.001 * yb - 1e-6);

            return(res);
        }
コード例 #2
0
        static void Main(string[] args)
        {
            int             N  = 1000000;
            Vector <double> y0 = Vector <double> .Build.Dense(new[] { -7.0 / 4.0, 55.0 / 8.0 });

            Func <double, Vector <double>, Vector <double> > der = DerivativeMaker();

            Vector <double>[] res = RungeKutta.FourthOrder(y0, 0, 10, N, der);

            double[] x = new double[N];
            double[] y = new double[N];
            for (int i = 0; i < N; i++)
            {
                double[] temp = res[i].ToArray();
                x[i] = temp[0];
                y[i] = temp[1];
            }

            //Test
            Console.WriteLine(y[N / 10]);                                           // gives 164,537981852489
            Console.WriteLine(Math.Exp(-1) + 3 * Math.Exp(4) - 5.0 / 2 + 23.0 / 8); //gives 164,537329540604, which is y(1)


            Console.ReadKey();
        }
コード例 #3
0
        static Vector <double>[] function_RungeKutta(double P, double R, double p, double c, double a, double k,
                                                     double t_first, double t_end, int N)
        {
            Vector <double> variables = Vector <double> .Build.Dense(new[] { P, R });

            Func <double, Vector <double>, Vector <double> > der = DerivativeMaker(p, c, a, k);

            Vector <double>[] res = RungeKutta.FourthOrder(variables, t_first, t_end, N, der);

            return(res);
        }
コード例 #4
0
        public double[,] SolveRK4(Vector <double> x0, double start, double end, int n, Func <double, Vector <double>, Vector <double> > func)
        {
            var answer = new double[n, 2];
            var res    = RungeKutta.FourthOrder(x0, start, end, n, func);

            for (var i = 0; i < n; i++)
            {
                var temp = res[i].ToArray();
                answer[i, 0] = temp[0];
                answer[i, 1] = temp[1];
            }

            return(answer);
        }
コード例 #5
0
ファイル: MathODE.cs プロジェクト: vlades7/text-to-equations
        public List <double[]> SolveODE(double[] y0, double startTime, double endTime, int n, Func <double, double[], double[]> func)
        {
            var y0Vector = Vector <double> .Build.DenseOfArray(y0);

            var result = RungeKutta.FourthOrder(y0Vector, startTime, endTime, n, (t, y) =>
            {
                var res = func(t, y.AsArray());
                return(Vector <double> .Build.DenseOfArray(res));
            });
            var resultList = new List <double[]>();

            for (var i = 0; i < n; i++)
            {
                var vector = result[i];
                resultList.Add(vector.AsArray());
            }

            return(resultList);
        }
コード例 #6
0
        public void RK4Test()
        {
            Func <double, double, double> ode = (t, y) => t + 2 * y * t;
            Func <double, double>         sol = (t) => 0.5 * (Math.Exp(t * t) - 1);
            double ratio    = double.NaN;
            double error    = 0;
            double oldError = 0;

            for (int k = 0; k < 4; k++)
            {
                double   y0  = 0;
                double[] y_t = RungeKutta.FourthOrder(y0, 0, 2, Convert.ToInt32(Math.Pow(2, k + 6)), ode);
                error = Math.Abs(sol(2) - y_t.Last());
                if (oldError != 0)
                {
                    ratio = Math.Log(oldError / error, 2);
                }
                oldError = error;
                Console.WriteLine(string.Format("{0}, {1}", error, ratio));
            }
            Assert.AreEqual(4, ratio, 0.01);// Check error convergence order
        }
コード例 #7
0
        static void Main(string[] args)
        {
            int             N  = 10000;
            Vector <double> y0 = Vector <double> .Build.Dense(new[] { -7.0 / 4.0, 55.0 / 8.0 });

            //Func<double, Vector<double>, Vector<double>> der = DerivativeMaker();

            Vector <double>[] res = RungeKutta.FourthOrder(y0, 0, 10, N, DerivativeMaker_zzz2);

            double[] t = Vector <double> .Build.Dense(N, i => i * 10.0 / N).ToArray();

            double[] x = new double[N];
            double[] y = new double[N];
            for (int i = 0; i < N; i++)
            {
                double[] temp = res[i].ToArray();
                x[i] = temp[0];
                y[i] = temp[1];
                //Console.WriteLine(t[i]);
            }

            var plt = new ScottPlot.Plot(800, 600);

            plt.PlotScatter(t, x, label: "x", markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));
            plt.PlotScatter(t, y, label: "y", markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));
            plt.Grid(false);
            plt.Legend(fontSize: 10);
            //plt.PlotSignal(new[,] { x, y });
            plt.SaveFig("quickstart.png");


            //Test
            Console.WriteLine(y[N / 10]);                                           // gives 164,537981852489
            Console.WriteLine(Math.Exp(-1) + 3 * Math.Exp(4) - 5.0 / 2 + 23.0 / 8); //gives 164,537329540604, which is y(1)

            Console.ReadKey();
        }
コード例 #8
0
        private void button_calc_Click_3(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)dataGridView1.DataSource;

            bendStiffener.max_k = (double)dt.Rows[0][1];
            bendStiffener.D1    = (double)dt.Rows[1][1];
            bendStiffener.d1    = (double)dt.Rows[2][1];
            bendStiffener.d2    = (double)dt.Rows[3][1];
            bendStiffener.L1    = (double)dt.Rows[4][1];
            bendStiffener.L2    = (double)dt.Rows[5][1];
            bendStiffener.L3    = (double)dt.Rows[6][1];
            bendStiffener.EIp   = (double)dt.Rows[7][1];
            bendStiffener.Es    = (double)dt.Rows[8][1];
            bendStiffener.F     = (double)dt.Rows[9][1];
            bendStiffener.q     = (double)dt.Rows[10][1];

            int N = 10000;

            //Vector<double>[] res = bendStiffener.bvpsolver_zzz(bendStiffener.Ode_to_solve, 0.0, bendStiffener.q, 0.0, 5.0, N);
            double[] x = Vector <double> .Build.Dense(N, i => i * 5.0 / N).ToArray();

            double[] y    = new double[N];
            double[] dydx = new double[N];

            //initialisation of plot
            formsPlot1.Reset();
            var plt = new ScottPlot.Plot(800, 600);

            //plt.PlotScatter(x, y, label: "y", markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));

            //plt.PlotSignal(new[,] { x, y });
            //plt.SaveFig("quickstart.png");

            double[] lineX = new double[] { 0, 5 };
            double[] lineY = new double[] { bendStiffener.max_k, bendStiffener.max_k };
            //formsPlot1.plt.PlotScatter(lineX, lineY, label: "Pass", lineWidth: 5, markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));

            //double[] max_pnt = new double[] { x[Array.IndexOf(dydx, dydx.Max())], dydx.Max() };

            //formsPlot1.plt.PlotPoint(max_pnt[0], max_pnt[1], color: Color.Magenta, markerSize: 15);
            //initialisation of plot
            //--------
            double ya = 0;
            double yb = bendStiffener.q;
            double xa = 0;
            double xb = 5;
            Func <double, Vector <double>, Vector <double> > system = bendStiffener.Ode_to_solve;

            Vector <double>[] res;
            Vector <double>   y0;

            //double s_guess = (yb - ya) / (xb - xa), s_guess_pre = 0;

            double fais = yb, fais_pre = 0, dfaids = 0, dfai, ds;
            //bool changeDirectionFlag = false;
            int countTimes = 1000;

            double[] faisLst = new double[countTimes];
            double[] sLst    = new double[countTimes];
            sLst = Vector <double> .Build.Dense(N, i => - 0.05 + i * 0.3 / countTimes).ToArray();

            for (int count = 0; count < countTimes; count++)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, sLst[count] });

                // observer_pr ob_pr = this->write_targetFunc_end;
                res      = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                fais_pre = fais;
                fais     = res[N - 1][0] - yb;
                ////dfaids = (fais - fais_pre) / (s_guess - s_guess_pre);
                //dfai = fais - fais_pre;
                //ds = s_guess - s_guess_pre;

                //s_guess_pre = s_guess;
                ////s_guess = s_guess - fais / dfaids;
                //s_guess = s_guess - fais * ds / dfai;
                ////s_guess = s_guess - fais / (fais - fais_pre) * (s_guess - s_guess_pre);

                faisLst[count] = fais;
                //sLst[count] = s_guess;
                formsPlot1.plt.PlotPoint(sLst[count], fais, color: Color.Magenta, markerSize: 15);
                //---------
                double[][] dydx2 = new double[countTimes][];
                for (int i = 0; i < N; i++)
                {
                    double[] temp = res[i].ToArray();
                    y[i]    = temp[0];
                    dydx[i] = temp[1];
                    //Console.WriteLine(t[i]);
                }
                dydx2[count] = (double[])dydx.Clone();

                //formsPlot1.plt.PlotScatter(x, dydx2[count], label: "dydx" + count.ToString(), lineWidth: 5, markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));
            }
            //formsPlot1.plt.PlotScatter(x, dydx, label: "dydx", lineWidth: 5, markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));
            formsPlot1.plt.PlotScatter(sLst, faisLst, label: "fais-s", lineWidth: 5, markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));
            //plt.PlotScatter(x, dydx, label: "dydx", markerShape: (MarkerShape)Enum.Parse(typeof(MarkerShape), "none"));
            formsPlot1.plt.Grid(true);
            formsPlot1.plt.Legend(fontSize: 20, location: legendLocation.lowerLeft);
            formsPlot1.Render();
        }
コード例 #9
0
        public Vector <double>[] bvpsolver_zzz(Func <double, Vector <double>, Vector <double> > system,
                                               double ya, double yb,
                                               double xa, double xb,
                                               int N)
        {
            //先求解方程得到初始斜率的估计值,再进行打靶法迭代。--zzz
            Vector <double>[] res;
            Vector <double>   y0;

            double s_guess, s_guess_pre;
            double fais, fais_pre;
            double dfai, ds;
            int    count = 0;

            //计算20组s_guess和fais,然后样条插值得到连续函数,再通过解方程,得到使fais=0的初始s_guess
            int M = 50;

            double[] sLst = Vector <double> .Build.Dense(M, i => yb / M *i).ToArray();

            double[] faisLst = new double[M];
            count = 0;
            while (count < M)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, sLst[count] });

                // observer_pr ob_pr = this->write_targetFunc_end;
                res            = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                faisLst[count] = res[N - 1][0] - yb;
                count++;
            }
            //样条插值得到连续函数
            var cubicSpl = CubicSpline.InterpolateNatural(sLst, faisLst);

            /*如果初始值离解太远,牛顿法会不收敛。故采用Mathnet包中的RobustNewtonRaphson
             * double s_cur = 0, s_next;
             * count = 0;
             * while (count < 1000)
             * {
             *  fais = cubicSpl.Interpolate(s_cur);
             *  dfaids = cubicSpl.Differentiate(s_cur);
             *  if (fais < 1e-5 && fais > -1e-5)
             *  {
             *      break;
             *  }
             *
             *  s_next = s_cur - fais / dfaids;
             *  s_cur = s_next;
             *  count += 1;
             * }*/

            //解方程fais=0,得到初始斜率s_guess。该法先尝试牛顿法,如失败会采用二分法(bisection)。
            s_guess = RobustNewtonRaphson.FindRoot(cubicSpl.Interpolate, cubicSpl.Differentiate, 0, yb, 1e-5);

            //利用解得的s_guess,构造s_guess_pre,目的是求导数dfai/ds。
            if (s_guess == 0)
            {
                s_guess_pre = 1e-2;
            }
            else
            {
                s_guess_pre = s_guess * 0.99;
            }
            //求s_guess_pre对应的fais_pre,目的是求导数dfai/ds。
            y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess_pre });

            res      = RungeKutta.FourthOrder(y0, xa, xb, N, system);
            fais_pre = res[N - 1][0] - yb;

            count = 0;
            while (count < 50)
            {
                y0 = Vector <double> .Build.DenseOfArray(new[] { ya, s_guess });

                res  = RungeKutta.FourthOrder(y0, xa, xb, N, system);
                fais = res[N - 1][0] - yb;

                dfai = fais - fais_pre;
                ds   = s_guess - s_guess_pre;
                if (fais < 1e-5 && fais > -1e-5)
                {
                    break;
                }

                fais_pre    = fais;
                s_guess_pre = s_guess;
                s_guess     = s_guess - fais * ds / dfai;
                count++;
            }

            return(res);
        }
コード例 #10
0
 /// <summary>
 /// Método Runge Kutta de Quarta ordem para equações diferenciais
 /// </summary>
 /// <param name="y0">Valor Inicial</param>
 /// <param name="start">Tempo Inicial</param>
 /// <param name="end">Tempo Final</param>
 /// <param name="dydx">Equação diferencial a ser calculada</param>
 /// <returns></returns>
 public double RungeKutta4(double y0, double start, double end, Func <double, double, double> dydx)
 {
     return(RungeKutta.FourthOrder(y0, start, end, 10, dydx)[9]);
 }
コード例 #11
0
ファイル: ODE.cs プロジェクト: KernelA/control-task
 public Vector <double>[] Integrate(IReadOnlyList <double> Control)
 {
     _params = Control;
     return(RungeKutta.FourthOrder(_x0, 0, _tMax, _sizeOfRes, OdeFunction));
 }