private Expression.Expression ConvertSubtraction(SubtractionNode node) { return(new Subtraction { Left = ConvertToExpression(node.Left), Right = ConvertToExpression(node.Right) }); }
public override ASTNode VisitBinaryOperatorExpression(EquationGrammarParser.BinaryOperatorExpressionContext context) { InfixExpressionNode node; int type = context.op.Type; switch (type) { case EquationGrammarLexer.CARET: node = new PowerNode(); break; case EquationGrammarLexer.PLUS: node = new AdditionNode(); break; case EquationGrammarLexer.MINUS: node = new SubtractionNode(); break; case EquationGrammarLexer.ASTERISK: node = new MultiplicationNode(); break; case EquationGrammarLexer.DIVISION: node = new DivisionNode(); break; default: throw new NotSupportedException(); } node.Left = (ExpressionNode)Visit(context.left); node.Right = (ExpressionNode)Visit(context.right); node.Line = context.start.Line; node.Position = context.start.Column; return(node); }
private NonlinearEquationDescription CompileEquations(RootNode root) { List <RPNExpression> rpnEquations = new List <RPNExpression>(); List <Expression.Expression> equations = new List <Expression.Expression>(); foreach (var constant in root.constants) { Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(constant.Right)); //ExpressionNode right = simplify(constant.Right); if (right is Float) { constants.Add(constant.Identifier, ((Float)right).Value); } else { constants.Add(constant.Identifier, float.NaN); compilerErrors.Add(new ErrorMessage("Определение константы " + constant.Identifier + " не является константным выражением")); } } foreach (var equation in root.equations) { SubtractionNode subtraction = new SubtractionNode { Left = equation.Left, Right = equation.Right, Line = equation.Line, Position = equation.Position }; Expression.Expression expression = ExpressionSimplifier.Simplify(ConvertToExpression(subtraction)); equations.Add(expression); } //initialValues aren't important foreach (var initialValue in root.initialValues) { if (variables.ContainsKey(initialValue.Identifier)) { Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(initialValue.Right)); //Expression expression = ConvertToExpression(right) if (right is Float) { initialValues[variables[initialValue.Identifier]] = ((Float)right).Value; } else { //add error message compilerErrors.Add(new ErrorMessage("Определение начального приближения переменной" + initialValue.Identifier + " не является константным выражением")); } } else { //add error message compilerErrors.Add(new ErrorMessage("Определение начального приближения несуществующей переменной")); } } //check that number of variables = number of equations if (variableNames.Count != equations.Count) { compilerErrors.Add(new ErrorMessage($"Количество переменных не совпадает с количеством уравнений: {variableNames.Count} переменных, {equations.Count} уравнений")); } if (equations.Count == 0) { compilerErrors.Add(new ErrorMessage("Пустая система уравнений")); } if (compilerErrors.Count > 0) { throw new CompilerException(compilerErrors); //fall back; } Expression.Compiler expCompiler = new Expression.Compiler(variables); for (int i = 0; i < equations.Count; i++) { rpnEquations.Add(expCompiler.Compile(equations[i])); } RPNExpression [,] jacobiMatrix = new RPNExpression[equations.Count, equations.Count]; Expression.DifferentiationVisitor difVisitor = new Expression.DifferentiationVisitor(); int j = 0; foreach (var equation in equations) { int i = 0; foreach (var variable in variableNames) { //find derivative for variable Expression.Expression derivative = ExpressionSimplifier.Simplify(difVisitor.Differentiate(equation, variable)); //simplify derivative expression RPNExpression exp = expCompiler.Compile(derivative); jacobiMatrix[i, j] = exp; i++; } j++; } NonlinearEquationDescription ned = new NonlinearEquationDescription(initialValues.ToArray(), variableNames.ToArray(), rpnEquations, jacobiMatrix); return(ned); }