Example #1
0
        /// <summary>Метод определения значения</summary>
        /// <returns>Численное значение элемента выражения</returns>
        public override double GetValue(MathExpression ParametersExpression, MathExpression Function)
        {
            var x      = ParametersExpression.Variable[0];
            var x_node = ParametersExpression.Tree
                         .OfType <VariableValueNode>()
                         .First(n => ReferenceEquals(x, n.Variable));
            var interval = (IntervalNode)x_node.Parent.Right ?? throw new InvalidOperationException("Правый узел дерева не определён - невозможно рассчитать интервал значений интегрирования");
            var min_node = (ComputedNode)interval.Left ?? throw new InvalidOperationException("В левом поддереве интервала значений отсутствует элемент - невозможно определить минимальное значение интервала");
            var max_node = (ComputedNode)interval.Right ?? throw new InvalidOperationException("В правом поддереве интервала значений отсутствует элемент - невозможно определить максимальное значение интервала");;

            var min = min_node.Compute();
            var max = max_node.Compute();

            Func <double, double> f = xx =>
            {
                x.Value = xx;
                return(Function.Compute());
            };

            if (_IsAdaptive)
            {
                return(f.GetIntegralValue_Adaptive(min, max));
            }

            var dx      = ParametersExpression.Variable[$"d{x_node.Variable.Name}"];
            var dx_node = ParametersExpression.Tree
                          .OfType <VariableValueNode>()
                          .First(n => ReferenceEquals(dx, n.Variable));
            var dx_value_node = (ConstValueNode)dx_node.Parent.Right ?? throw new InvalidOperationException("Отсутствует правое поддерево у родительского элемента dx - невозможно рассчитать шаг интегрирования");

            dx.Value = dx_value_node.Value;
            return(f.GetIntegralValue(min, max, dx.GetValue()));
        }
Example #2
0
        /// <summary>Метод определения значения</summary>
        /// <returns>Численное значение элемента выражения</returns>
        public override double GetValue(MathExpression ParametersExpression, MathExpression Function)
        {
            var parameters_root = ParametersExpression.Tree.Root;
            var iterator        = ((VariableValueNode)parameters_root.Left)?.Variable ?? throw new InvalidOperationException("Не определён узел дерева с итератором суммы");

            var interval = (IntervalNode)parameters_root.Right ?? throw new InvalidOperationException("Не определён узел дерева с интервалом значений суммы");
            var min_node = (ComputedNode)interval.Min ?? throw new InvalidOperationException("Не определён узел дерева с минимальным значением интервала суммы");
            var max_node = (ComputedNode)interval.Max ?? throw new InvalidOperationException("Не определён узел дерева с максимальным значением интервала суммы");;

            var min = min_node.Compute();
            var max = max_node.Compute();

            var sum = 0.0;

            if (min < max)
            {
                for (int i = (int)min, Max = (int)max; i < Max; i++)
                {
                    iterator.Value = i;
                    sum           += Function.Compute();
                }
            }
            else
            {
                for (int i = (int)min, Min = (int)max - 1; i >= Min; i--)
                {
                    iterator.Value = i;
                    sum           += Function.Compute();
                }
            }
            return(sum);
        }
Example #3
0
        /// <summary>Инициализация оператора</summary>
        /// <param name="Parameters">Блок параметров</param>
        /// <param name="Function">Блок ядра функции</param>
        /// <param name="Parser">Парсер</param>
        /// <param name="Expression">Внешнее выражение</param>
        public override void Initialize
        (
            MathExpression Parameters,
            MathExpression Function,
            ExpressionParser Parser,
            MathExpression Expression
        )
        {
            base.Initialize(Parameters, Function, Parser, Expression);

            var iterator_var = Parameters.Tree
                               .OfType <VariableValueNode>()
                               .Where(n => n.Parent is EqualityOperatorNode)
                               .Select(n => n.Variable)
                               .FirstOrDefault();

            if (iterator_var is null)
            {
                throw new FormatException();
            }
            var iterator_var_name = iterator_var.Name;
            var iterator_node     = Parameters.Tree
                                    .OfType <VariableValueNode>()
                                    .FirstOrDefault(n => n.Parent is EqualityOperatorNode && n.Variable.Name == $"d{iterator_var_name}");
            var iterator_diff_var = iterator_node?.Variable;

            _IsAdaptive = iterator_diff_var is null;

            Function.Variable.ClearCollection();
            Function.Variable.Add(iterator_var);
            Function.Tree
            .OfType <VariableValueNode>()
            .Where(n => !ReferenceEquals(n.Variable, iterator_var))
            .Foreach(Function, Expression, (n, func, expr) => func.Variable.Add(n.Variable = expr.Variable[n.Variable.Name]));

            Parameters.Variable.ClearCollection();
            Parameters.Variable.Add(iterator_var);
            if (!_IsAdaptive)
            {
                Debug.Assert(iterator_diff_var != null, "iterator_diff_var != null");
                Parameters.Variable.Add(iterator_diff_var);
                if (iterator_node.Parent.Parent.IsLeftSubtree)
                {
                    iterator_node.Parent.Parent.Parent.Left = null;
                }
                else
                {
                    iterator_node.Parent.Parent.Parent.Right = null;
                }
                iterator_node.Parent.Parent = null;
                Parameters.Tree.Root        = new FunctionArgumentNode("Domain", Parameters.Tree.Root)
                {
                    Right = new FunctionArgumentNode("step", iterator_node.Parent)
                };
            }
            Parameters.Tree
            .OfType <VariableValueNode>()
            .Where(n => !ReferenceEquals(n.Variable, iterator_var) && !ReferenceEquals(n.Variable, iterator_diff_var))
            .Foreach(Parameters, Expression, (n, pp, expr) => pp.Variable.Add(n.Variable = expr.Variable[n.Variable.Name]));
        }
Example #4
0
        /// <summary>Скомпилировать в выражение</summary>
        /// <param name="Function">Ядро функции</param>
        /// <param name="Parameters">Массив параметров</param>
        /// <param name="ParametersExpression">Выражение параметров</param>
        /// <returns>Скомпилированное выражение System.Linq.Expressions</returns>
        public override Expression Compile(MathExpression ParametersExpression, MathExpression Function, ParameterExpression[] Parameters)
        {
            var parameters_root = ParametersExpression.Tree.Root;
            var iterator        = ((VariableValueNode)parameters_root.Left)?.Variable ?? throw new InvalidOperationException("Не определён узел дерева с итератором суммы");

            var interval_node = parameters_root.Right ?? throw new InvalidOperationException("Не определён узел дерева с интервалом суммы");
            var min_node      = (ComputedNode)interval_node.Left ?? throw new InvalidOperationException("Не определён узел дерева с минимумом интервала суммы");
            var max_node      = (ComputedNode)interval_node.Right ?? throw new InvalidOperationException("Не определён узел дерева с минимумом интервала суммы");

            var min = min_node.Compile();
            var max = max_node.Compile();

            var iterator_parameter = Expression.Parameter(typeof(double), iterator.Name);
            var parameters         = Parameters.AppendFirst(iterator_parameter).ToArray();
            var body = ((ComputedNode)Function.Tree.Root).Compile(parameters);
            var expr = Expression.Lambda(body, parameters).Compile();

            var expr_p = new[]
            {
                Expression.Constant(expr), min, max,
                Expression.NewArrayInit(typeof(double), Parameters.Cast <Expression>().ToArray())
            };

            return(Expression.Call(new SumDelegate(GetSum).Method, expr_p));
        }
Example #5
0
 /// <summary>Инициализация оператора</summary>
 /// <param name="Parameters">Блок параметров</param>
 /// <param name="Function">Блок ядра функции</param>
 /// <param name="Parser">Парсер мат.выражения</param>
 /// <param name="Expression">Внешнее мат.выражение</param>
 public virtual void Initialize
 (
     [NotNull] MathExpression Parameters,
     [NotNull] MathExpression Function,
     [NotNull] ExpressionParser Parser,
     [NotNull] MathExpression Expression
 )
 {
 }
Example #6
0
        /// <summary>Инициализация оператора</summary>
        /// <param name="Parameters">Блок параметров</param>
        /// <param name="Function">Блок ядра функции</param>
        /// <param name="Parser">Парсер мат.выражения</param>
        /// <param name="Expression">Внешнее мат.выражение</param>
        public override void Initialize
        (
            MathExpression Parameters,
            MathExpression Function,
            ExpressionParser Parser,
            MathExpression Expression
        )
        {
            base.Initialize(Parameters, Function, Parser, Expression);

            var iterator_var = Parameters.Tree
                               .Where(n => n is VariableValueNode && n.Parent is EqualityOperatorNode)
                               .Select(n => ((VariableValueNode)n).Variable)
                               .FirstOrDefault();

            Function.Variable.ClearCollection();
            if (iterator_var != null)
            {
                Function.Variable.Add(iterator_var);
            }

            var iterator_variables = Function.Tree
                                     .OfType <VariableValueNode>()
                                     .Where(n => !ReferenceEquals(n.Variable, iterator_var));

            foreach (var n in iterator_variables)
            {
                Function.Variable.Add(n.Variable = Expression.Variable[n.Variable.Name]);
            }

            //Function.Tree
            //    .Where(n => n is VariableValueNode)
            //    .Cast<VariableValueNode>()
            //    .Where(n => !ReferenceEquals(n.Variable, iterator_var))
            //    .Foreach(Expression, Function, (n, i, expr, f) => f.Variable.Add(n.Variable = expr.Variable[n.Variable.Name]));

            Parameters.Variable.ClearCollection();

            var variable_nodes = Parameters.Tree
                                 .OfType <VariableValueNode>()
                                 .Where(n => !ReferenceEquals(n.Variable, iterator_var));

            foreach (var variable_node in variable_nodes)
            {
                var variable = Expression.Variable[variable_node.Variable.Name];
                variable_node.Variable = variable;
                Parameters.Variable.Add(variable);
            }

            //Parameters.Tree
            //    .Where(n => n is VariableValueNode)
            //    .Cast<VariableValueNode>()
            //    .Where(n => !ReferenceEquals(n.Variable, iterator_var))
            //    .Foreach(Expression, Function, (n, i, expr, f) => f.Variable.Add(n.Variable = expr.Variable[n.Variable.Name]));
        }
Example #7
0
        /// <summary>Скомпилировать в выражение</summary>
        /// <param name="Function">Ядро функции</param>
        /// <param name="Parameters">Массив параметров</param>
        /// <param name="ParametersExpression">Выражение параметров</param>
        /// <returns>Скомпилированное выражение <see cref="System.Linq.Expressions"/></returns>
        public override Expression Compile
        (
            MathExpression ParametersExpression,
            MathExpression Function,
            ParameterExpression[] Parameters
        )
        {
            var iterator = ParametersExpression.Variable[0];
            var x_node   = ParametersExpression.Tree
                           .Where(n => n is VariableValueNode)
                           .Cast <VariableValueNode>()
                           .First(n => ReferenceEquals(iterator, n.Variable));

            var interval       = (IntervalNode)x_node.Parent.Right ?? throw new InvalidOperationException("Отсутствует правое поддерево у родительского узла");
            var interval_left  = (ComputedNode)interval.Left ?? throw new InvalidOperationException("Отсутствует левое поддерево");
            var interval_right = (ComputedNode)interval.Right ?? throw new InvalidOperationException("Отсутствует правое поддерево");
            var min            = interval_left.Compile();
            var max            = interval_right.Compile();

            var iterator_parameter = Expression.Parameter(typeof(double), iterator.Name);
            var parameters         = new[] { iterator_parameter };
            var body     = ((ComputedNode)Function.Tree.Root).Compile(parameters);
            var function = Expression.Lambda(body, parameters).Compile();

            if (_IsAdaptive)
            {
                return(Expression.Call(new AdaptiveIntegralDelegate(GetAdaptiveIntegral).Method, new[]
                {
                    function.ToExpression(), min, max,
                    Expression.NewArrayInit(typeof(double))
                }));
            }

            var dx_var  = ParametersExpression.Variable[1];
            var dx_node = ParametersExpression.Tree
                          .Where(n => n is VariableValueNode)
                          .Cast <VariableValueNode>()
                          .First(n => ReferenceEquals(dx_var, n.Variable));
            var dx = dx_node.Compile();

            return(Expression.Call(new IntegralDelegate(GetIntegral).Method, new[]
            {
                function.ToExpression(), min, max,
                Expression.NewArrayInit(typeof(double), Parameters.Cast <Expression>().ToArray()),
                dx
            }));
        }
Example #8
0
        /// <summary>Получить корень поддерева выражений</summary>
        /// <param name="Parser">Парсер выражения</param>
        /// <param name="Expression">Математическое выражение</param>
        /// <returns>Корень поддерева</returns>
        public override ExpressionTreeNode GetSubTree(ExpressionParser Parser, MathExpression Expression)
        {
            var separator = Parser.ExpressionSeparator; // фиксируем символ-разделитель выражений
            // Разбиваем последовательность элементов выражения на группы, разделённые символом-разделителем
            // Извлекаем из каждой группы корень дерева выражений и складываем их в массив
            var roots = Terms
                        .Split(t => t is CharTerm term && term.Value == separator)
                        .Select(g => Parser.GetRoot(g, Expression)).ToArray();


            if (roots.Length == 1)
            {
                return(roots[0]);                  // Если найден только один корень, то возвращаем его
            }
            // Иначе корней найдено много
            ExpressionTreeNode argument = null; // объявляем ссылку на аргумент

            // проходим по всем найденным корням
            foreach (var root in roots)
            {
                var arg = root switch
                {
                    FunctionArgumentNode => root,
                    FunctionArgumentNameNode name_node => new FunctionArgumentNode(name_node),
                    VariantOperatorNode when root.Left is VariableValueNode value_node => new FunctionArgumentNode(value_node.Name, root.Right),
                    _ => new FunctionArgumentNode(string.Empty, root)
                };

                argument = argument is null
                    ? arg                   // Если аргумент не был указан, то сохраняем полученный узел, как аргумент
                    : argument.Right = arg; //  сохраняем полученный узел в правое поддерево аргумента
            }
            // Если аргумент не был выделен, то что-то пошло не так - ошибка формата
            if (argument is null)
            {
                throw new FormatException("Не определён аргумент функции");
            }
            return(argument.Root); // Вернуть корень аргумента
        }
    }
Example #9
0
 /// <summary>Получить поддерево</summary>
 /// <param name="Parser">Парсер мат.выражения</param>
 /// <param name="Expression">Математическое выражение</param>
 /// <returns>Результат вызова метода Parser.GetOperatorNode(Value)</returns>
 public override ExpressionTreeNode GetSubTree(ExpressionParser Parser, MathExpression Expression) =>
 Parser.GetOperatorNode(Value);
Example #10
0
 public abstract Expression Compile
 (
     [NotNull] MathExpression ParametersExpression,
     [NotNull] MathExpression Function,
     [NotNull] ParameterExpression[] Parameters
 );
Example #11
0
 /// <summary>Метод определения значения</summary>
 /// <param name="ParametersExpression">Выражение параметров</param>
 /// <param name="Function">Ядро функционала</param>
 /// <returns>Численное значение вычисленного выражения</returns>
 public abstract double GetValue([NotNull] MathExpression ParametersExpression, [NotNull] MathExpression Function);
Example #12
0
 /// <summary>Поддерево элемента, состоящее из узла-переменной</summary>
 /// <param name="Parser">Парсер</param>
 /// <param name="Expression">Математическое выражение</param>
 /// <returns>Узел дерева с переменной, полученной из Expression.Variable[Name]</returns>
 public override ExpressionTreeNode GetSubTree(ExpressionParser Parser, MathExpression Expression)
 => new VariableValueNode(Expression.Variable[Name]);
Example #13
0
 /// <inheritdoc />
 public override Expression Compile(MathExpression ParametersExpression, MathExpression Function, ParameterExpression[] Parameters) => throw new NotImplementedException();
Example #14
0
 /// <inheritdoc />
 public override double GetValue(MathExpression ParametersExpression, MathExpression Function) => throw new NotImplementedException();