예제 #1
0
        public static double[] Newtone(DoubleMultiDimFunction[] F, DoubleMultiDimFunction[,] J,
                                       double[] x0, double eps,
                                       out List <PointF[]> lines, bool silent)
        {
            if (F.GetLength(0) > 2)
            {
                throw new NotImplementedException("Multidimensional case is not implemented yet");
            }
            if (F.GetLength(0) != J.GetLength(0))
            {
                throw new ArgumentException("Sizes of J and F are not correct");
            }

            List <PointF> nodes = new List <PointF>();

            lines = new List <PointF[]>();

            DoubleMultiDimFunction[,] _F =
                new DoubleMultiDimFunction[F.GetLength(0), 1];

            for (int i = 0; i < F.GetLength(0); i++)
            {
                _F[i, 0] = F[i];
            }

            double[] x_old, x = x0;

            double[,] J1AtPt = new double[J.GetLength(0), J.GetLength(1)];

            int stepsMaden = 0;

            nodes.Add(new PointF((float)x0[0], (float)x0[1]));

            do
            {
                x_old  = (double[])x.Clone();
                J1AtPt = ValAtPt(J, x);
                double delta = det(J1AtPt);

                double t_for_swap = J1AtPt[0, 0];
                J1AtPt[0, 0] = J1AtPt[1, 1] / delta;
                J1AtPt[0, 1] = -J1AtPt[0, 1] / delta;
                J1AtPt[1, 0] = -J1AtPt[1, 0] / delta;
                J1AtPt[1, 1] = t_for_swap / delta;

                double[,] tmp_x = MulAb(J1AtPt, ValAtPt(_F, x));
                for (int i = 0; i < x.GetLength(0); i++)
                {
                    x[i] -= tmp_x[i, 0];
                }


                nodes.Add(new PointF((float)x[0], (float)x[1]));

                stepsMaden++;

                if (stepsMaden % 100 == 0)
                {
                    if (silent)
                    {
                        lines.Add(nodes.ToArray());
                        return(new double[] { double.NaN, double.NaN });
                    }

                    if (MessageBox.Show("Performed " + stepsMaden.ToString()
                                        + " steps, continue?", "Разошлось наверно?",
                                        MessageBoxButtons.OKCancel, MessageBoxIcon.Question,
                                        MessageBoxDefaultButton.Button1) != DialogResult.OK)
                    {
                        lines.Add(nodes.ToArray());
                        return(new double[] { double.NaN, double.NaN });
                    }
                }
            } while (ro(x, x_old) >= eps);

            lines.Add(nodes.ToArray());

            return(x);
        }
예제 #2
0
        private void buttonSolve_Click(object sender, EventArgs e)
        {
            double x0, y0;
            double eps;
            bool   speedUp;

            #region get parameters from form
            errorProvider.Clear();

            try { eps = float.Parse(textE.Text); }
            catch (FormatException) {
                errorProvider.SetError(textE, "Wrong float number");
                return;
            }
            if (eps < 0)
            {
                errorProvider.SetError(textE, "Has to be > 0");
                return;
            }

            speedUp = checkSpeedUp.Checked;
            #endregion

            double[]        res   = new double[] { double.NaN, double.NaN };
            DekartForm      dForm = null;
            List <PointF[]> lines = null;

            switch (selectedSolMeth)
            {
                #region Method Simple Iteration

            case SolutionMethod.StillPoint:

                try { x0 = float.Parse(textX0.Text); }
                catch (FormatException) { errorProvider.SetError(textX0, "Wrong float number"); return; }

                try { y0 = float.Parse(textY0.Text); }
                catch (FormatException) { errorProvider.SetError(textY0, "Wrong float number"); return; }

                dForm               = new DekartForm(200, 200, 200, 300);
                dForm.Size          = new Size(750, 600);
                dForm.Use_IsVisible = false;

                dForm.AddGraphic(f1x, f1yS, -5f, 5f, DrawModes.DrawLines, Color.Green);
                dForm.AddGraphic(f2xS, f2y, -5f, 5f, DrawModes.DrawLines, Color.Blue);
                res = FindSysRoot.StillPointMethod(
                    new double[] { x0, y0 },
                    new DoubleFunction[] { g1S, g2S },
                    eps, out lines, speedUp, false);
                break;
                #endregion

                #region Method Newtone

            case SolutionMethod.Newtone:

                try { x0 = float.Parse(textX0.Text); }
                catch (FormatException) { errorProvider.SetError(textX0, "Wrong float number"); return; }

                try { y0 = float.Parse(textY0.Text); }
                catch (FormatException) { errorProvider.SetError(textY0, "Wrong float number"); return; }

                dForm               = new DekartForm(100, 100, 300, 300);
                dForm.Size          = new Size(750, 600);
                dForm.Use_IsVisible = false;

                dForm.AddGraphic(f1x, f1y, -5f, 5f, DrawModes.DrawLines, Color.Green);
                dForm.AddGraphic(f2x, f2y, -5f, 5f, DrawModes.DrawLines, Color.Blue);

                DoubleMultiDimFunction[,] J = new DoubleMultiDimFunction[2, 2];
                J[0, 0] = df1x;
                J[0, 1] = df1y;
                J[1, 0] = df2x;
                J[1, 1] = df2y;

                DoubleMultiDimFunction[] F = new DoubleMultiDimFunction[2];
                F[0] = f1;
                F[1] = f2;

                res = FindSysRoot.Newtone(F, J,
                                          new double[] { x0, y0 }, eps, out lines, false);
                break;

                #endregion

            default:
                return;
            }

            #region Print results

            if (lines != null)
            {
                foreach (PointF[] pts in lines)
                {
                    dForm.AddPolygon(Color.Red, DrawModes.DrawLines, pts);
                }
            }
            dForm.Show();
            dForm.Update2();

            listRoots.Items.Clear();
            listY.Items.Clear();

            if (double.IsNaN(res[0]) || double.IsNaN(res[1]))
            {
                MessageBox.Show("Корни не найдены.");
                return;
            }

            listRoots.Items.Add("x" + (listRoots.Items.Count + 1) + " = "
                                + res[0].ToString("F16"));
            listY.Items.Add("y" + (listY.Items.Count + 1) + " = "
                            + res[1].ToString("F16"));
            #endregion
        }