public static Tuple<Function, string> FunctionVariation(Function I, double level = 1, double from = 0, double to = 1, string by = "x")
        {
            StringBuilder sb = new StringBuilder(
            @"<!DOCTYPE html>
            <?xml-stylesheet type='text/xsl' href='mathml.xsl'?>
            <html
             xmlns='http://www.w3.org/1999/xhtml'
             xmlns:math='http://www.w3.org/1998/Math/MathML'
             >
            <head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head>
            <body>
                <b>Вариация функции:</b></br>"
            );

            sb.AppendFormat("<math><mrow><mi>I</mi><mo>=</mo><mrow><msubsup><mo>&int;</mo><mn>{1}</mn><mn>{2}</mn></mrow><mrow><mfenced>{0}</mfenced></mrow><mo>d</mo><mi>{3}</mi></mrow></math></br>", I.ToMathML(), from, to, by);
            string[] vars = I.Variables;
            Dictionary<string, IMatrixElement> varsValues = new Dictionary<string, IMatrixElement>();

            Variable Alpha = new Variable("&alpha;");
            for (int i = 0; i < vars.Length; i++)
            {
                if (vars[i] != by)
                {
                    varsValues[vars[i]] = new FunctionMatrixElement(new Function(new Variable(vars[i]) + Alpha * new Variable("d" + vars[i])));
                }
            }

            Function I2 = new Function(I.SetVariablesValues(varsValues));
            sb.AppendFormat(@"
                <math><mrow>
                    <mi>I</mi><mfenced><mrow><mi>y</mi><mo>+</mo><mi>{4}</mi><mo>d</mo><mi>y</mi></mrow></mfenced><mo>=</mo>
                    <mrow>
                        <mrow><msubsup><mo>&int;</mo><mn>{1}</mn><mn>{2}</mn></msubsup></mrow>
                        <mrow>{0}</mrow><mrow><mo>d</mo><mi>{3}</mi></mrow></mrow>
                    </mrow>
                </mrow></math></br>", I2.ToMathML(), from, to, by, Alpha.Name);

            var curI = I2;
            for (int i = 0; i < level; i++)
            {
                sb.AppendFormat("</br></br>{0} вариация:</br>", i + 1);
                var dI2 = new Function(curI.Derivative(Alpha.Name));

                sb.AppendFormat("<math><mrow><msup><mo>d</mo><mn>{4}</mn></msup></mrow><mi>I</mi><mo>=</mo><msubsup><mo>&int;</mo><mn>{1}</mn><mn>{2}</mn></msubsup><mfenced><mrow>{0}</mrow></mfenced><mo>d</mo><mi>{3}</mi><math></br></br>", dI2.ToMathML(), from, to, by, i + 1);
                sb.AppendFormat("<math><mrow><msup><mo>d</mo><mn>{4}</mn></msup></mrow><mi>I</mi><mo>&InvisibleTimes;</mo><mrow><mfenced><mrow>{5}</mrow><mo>=</mo><mi>0</mi></mfenced></mrow><mo>=</mo><msubsup><mo>&int;</mo><mn>{1}</mn><mn>{2}</mn></msubsup><mfenced><mrow>{0}<mrow></mfenced><mo>d</mo><mi>{3}</mi><math>", dI2.SetVariableValue(Alpha.Name, 0).ToMathML(), from, to, by, i + 1, Alpha.Name);
                curI = dI2;
            }
            sb.Append("</body></html>");

            return new Tuple<Function, string>(new Function(curI.SetVariableValue(Alpha.Name, 0)), sb.ToString());
        }
        public static Tuple<Matrix, string> BarrierMethod(Function f, Equation[] q, Matrix x0, double e, double r0, double C)
        {
            List<Function> qm = new List<Function>(), qp = new List<Function>();
            StringBuilder sb = new StringBuilder("<h1>Метод барьерных функций</h1></br>");

            foreach (var qi in q)
            {
                if (qi.Sign == "<=")
                {
                    qp.Add(qi.AllToLeft());
                }
                if (qi.Sign == "=")
                {
                    qm.Add(qi.AllToLeft());
                }
            }

            sb.AppendFormat("<b>Функция</b> f = {0}</br><b>Ограничения:</b></br>", f.ToMathML());
            int i = 0;
            qm.ForEach(qi => sb.AppendFormat("&nbsp&nbsp&nbsp&nbspq({0}) = {1} = 0</br>", i++, qi.ToMathML()));
            i = 0;
            qp.ForEach(qi => sb.AppendFormat("&nbsp&nbsp&nbsp&nbspq({0}) = {1} <= 0</br>", i++, qi.ToMathML()));

            int k = 0;

            string[] vars = f.Variables;
            Matrix varsNames = new Matrix(vars.Length);

            for (i = 0; i < vars.Length; i++)
            {
                varsNames[i] = new FunctionMatrixElement(1, vars[i]);
            }

            sb.AppendFormat("Шаг 1. Задаём: <math><mrow><msub><mi>x</mi><mn>0</mn></msub></mrow><mo>=</mo><mrow>{0}</mrow><mo></math>,штраф <math><msub><mi>r</mi><mn>0</mn></msub><mo>=</mo></math>{1}, C = {2}, e = {3}, k = {4}</br>", x0.ToMathML(), r0, C, e, k);

            List<Matrix> x = new List<Matrix>();
            List<double> r = new List<double>();
            Function Sq = new Function();
            foreach(var qi in q) {
                Sq += qi.AllToLeft().Pow(-1);
            }

            Function P = new Variable("rk") * Sq;

            x.Add(x0);
            r.Add(r0);
            Matrix answer = x0;
            while (true)
            {
                sb.AppendFormat("---------------------------<b>{0} иттерация</b>-------------------</br>", k);

                Function F = f - P.SetVariableValue("rk", r[k]);

                sb.AppendFormat("Шаг 2. Вспомогательная функция = {0}</br>", F.ToMathML());
                //Function der = F.Derivative();

                //Matrix minX = SecondOrderMethods.NuthonMethod(F, x[k], e, e, 5).Item1;
                Matrix minX = MinimisationMethods.PenaltyMethod(F, q.ToArray(), x[k], e, r0, C).Item1;

                sb.AppendFormat("Шаг 3. Минимум функции F:</br>&nbsp&nbsp&nbsp&nbsp&nbsp<math><msub><mi>x</mi><mn>0</mn></msub><mo>=</mo><msub><mi>x</mi><mn>{0}</mn></msub><mo>=</mo></math>{1}</br>&nbsp&nbsp&nbsp&nbspX* = {2}</br>",
                                        k,
                                        x[k].ToMathML(),
                                        minX.ToMathML()
                );

                sb.AppendFormat("Шаг 4. Условие окончания: <math><mi>P</mi><mfenced><msup><mi>x</mi><mn>*</mn></msup><mfenced><msub><mi>r</mi><mn>{0}</mn></msub></mfenced><mo>,</mo><msub><mi>r</mi><mn>{0}</mn></msub></mfenced><mo><=?</mo><mi>e</mi><mo>=</mo><mi>{1}</mi></math></br>", k, e);
                double p = Math.Abs(new Function(P.SetVariableValue("rk", r[k])).SetVariablesValuesWithFixedOrder(minX, varsNames).ToDouble());

                sb.AppendFormat("&nbsp&nbsp&nbsp&nbsp{0} {1} {2}</br>", p, p <= e ? "<=" : ">", e);
                if (p <= e)
                {
                    answer = minX;
                    sb.AppendFormat("Следовательно x* = {0}", answer.ToMathML());
                    break;
                }
                else
                {
                    r.Add(r[k] / C);
                    x.Add(minX);
                    k++;
                }
            }

            return new Tuple<Matrix, string>(answer, sb.ToString());
        }
        public static Tuple<Matrix, string> PenaltyMethod(Function f, Equation[] q, Matrix x0, double e, double r0, double C)
        {
            string matrixStartLine = "[", matrixElementsSeparator = ", ", matrixEndLine = "]";

            List<Function> qm = new List<Function>(), qp = new List<Function>();
            StringBuilder sb = new StringBuilder("<h1>Метод штрафных функций</h1></br>");

            foreach (var qi in q)
            {
                if (qi.Sign == "<=")
                {
                    qp.Add(qi.AllToLeft());
                }
                if (qi.Sign == "=")
                {
                    qm.Add(qi.AllToLeft());
                }
            }

            sb.AppendFormat("<b>Функция</b> f = {0}</br><b>Ограничения:</b></br>", f.ToMathML());
            int i = 0;
            qm.ForEach(qi => sb.AppendFormat("&nbsp&nbsp&nbsp&nbspq({0}) = {1} = 0</br>", i++, qi.ToMathML()));
            i = 0;
            qp.ForEach(qi => sb.AppendFormat("&nbsp&nbsp&nbsp&nbspq({0}) = {1} <= 0</br>", i++, qi.ToMathML()));

            int k = 0;

            string[] vars = f.Variables;
            Matrix varsNames = new Matrix(vars.Length);

            for (i = 0; i < vars.Length; i++)
            {
                varsNames[i] = new FunctionMatrixElement(1, vars[i]);
            }

            sb.AppendFormat("Шаг 1. Задаём: <math><mrow><msub><mi>x</mi><mn>0</mn></msub></mrow><mo>=</mo><mrow>{0}</mrow><mo></math>,штраф <math><msub><mi>r</mi><mn>0</mn></msub><mo>=</mo></math>{1}, C = {2}, e = {3}, k = {4}</br>", x0.ToMathML(), r0, C, e, k);

            List<Matrix> x = new List<Matrix>();
            List<double> r = new List<double>();
            Function Sm = new Function();
            Function Sp = new Function();
            qm.ForEach(qi => Sm += qi.Pow(2));
            #warning Врятли без этого оно будет работать
            //qp.ForEach(qi => Sp += qi.AddFunction(new SliceFunction()).Pow(2));
            Function P = new Variable("rk") / 2.0 * (Sm + Sp);

            x.Add(x0);
            r.Add(r0);
            Matrix answer = x0;
            while (true)
            {
                sb.AppendFormat("---------------------------{0} иттерация-------------------\n", k);
                sb.AppendFormat("{0}\n", P);
                Function F = f + P.SetVariableValue("rk", r[k]);

                sb.AppendFormat("Шаг 2. Вспомогательная функция = {0}\n", F);

                Matrix minX = SecondOrderMethods.NuthonMethod(F, x[k], e, e, 5).Item1;

                sb.AppendFormat("Шаг 3. Минимум функции F:\n\tx[0] = x[{0}] = {1}\n\tX* = {2}\n",
                                        k,
                                        x[k].Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine),
                                        minX.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)
                );

                sb.AppendFormat("Шаг 4. Условие окончания: P(x*(r[{0}],r[{0}]) <=? e = {1}\n", k, e);
                double p = new Function(P.SetVariableValue("rk", r[k])).SetVariablesValuesWithFixedOrder(minX, varsNames).ToDouble();

                sb.AppendFormat("       {0} {1} {2}\n", p, p <= e ? "<=" : ">", e);
                if (p <= e)
                {
                    answer = minX;
                    sb.AppendFormat("Следовательно x* = {0}", answer.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine));
                    break;
                }
                else
                {
                    r.Add(C * r[k]);
                    x.Add(minX);
                    k++;
                }
            }

            return new Tuple<Matrix, string>(answer, sb.ToString());
        }
Esempio n. 4
0
        private static Function _fromStringWithoutBracers(string func, List<Function> fs)
        {
            string f = func.Trim();

            string _fMask = String.Format("^{0}$", Regex.Escape(String.Format(Function._funcMask, "```")).Replace("```", "(?<index>\\d+)"));
            string mask = _fMask;//@"^\[_f(?<index>\d+)\]$";
            var m = Regex.Match(f, mask);

            if (m.Success)
            {
                var index = Int32.Parse(m.Groups["index"].Value);
                if (index >= fs.Count)
                {
                    throw new InvalidFunctionStringException(func);
                }
                return fs[index];
            }

            // check math functions
            foreach (var mf in Function._allFunctions)
            {
                string[] _paramsIndexes = new string[mf.ParamsCount];
                for (int i = 0; i < mf.ParamsCount; i++)
                {
                    _paramsIndexes[i] = String.Format(@"\s*(?<p{0}>.+)\s*", i);
                }

                mask = String.Format(String.Format("^{0}$", mf.ToStringFormat), _paramsIndexes);

                m = Regex.Match(f, mask);

                if (m.Success)
                {
                    try
                    {
                        FunctionElement[] _params = new FunctionElement[mf.ParamsCount];
                        for (int i = 0; i < mf.ParamsCount; i++)
                        {
                            _params[i] = Function._fromStringWithoutBracers(m.Groups[String.Format("p{0}", i)].Value, fs);
                        }

                        try
                        {
                            return new Function(mf.Calculate(_params));
                        } // Skip this, because it can be other function with same signature.. Блять, прям перегрузка функций
                        catch (InvalidMathFunctionParameters)
                        { }
                    }
                    catch (InvalidFunctionStringException)
                    { }
                }
            }

            // Digit
            mask = @"^\s*(?<value>(?<minus>-?)\s*(?<digit>\d+([\.\,]\d+)?))\s*$";

            m = Regex.Match(f, mask);

            if (m.Success)
            {
                return new Function(Double.Parse(m.Groups["minus"].Value + m.Groups["digit"].Value));
            }

            // Variable
            try
            {
                var v = new Variable("");
                v.ParseFromString(f);
                return new Function(v);
            }
            catch { }

            try
            {
                var s = new StringVariable("");
                s.ParseFromString(f);
                return new Function(s);
            }
            catch { }

            try
            {
                if (f.Contains('{'))
                {
                    for (int i = 0; i < fs.Count; i++)
                    {
                        if (f.IndexOf(String.Format(Function._funcMask, i)) != -1)
                        {
                            f = f.Replace(String.Format(Function._funcMask, i), String.Format("({0})", fs[i].ToString()));
                        }
                    }
                    var v = new RecordVariable(f);
                    return new Function(v);
                }
            }
            catch { }

            try
            {
                if (f.Contains(ListVariable.OpenBracer))
                {
                    for (int i = 0; i < fs.Count; i++)
                    {
                        if (f.IndexOf(String.Format(Function._funcMask, i)) != -1)
                        {
                            f = f.Replace(String.Format(Function._funcMask, i), String.Format("({0})", fs[i].ToString()));
                        }
                    }
                    var v = new ListVariable(f);
                    return new Function(v);
                }
            }
            catch { }

            throw new InvalidFunctionStringException(func);
        }
Esempio n. 5
0
 public override object Clone()
 {
     Variable v = new Variable(this.name);
     v.CopyFunctions(this);
     return v;
 }