private Expression.Expression ConvertSubtraction(SubtractionNode node) { return(new Subtraction { Left = ConvertToExpression(node.Left), Right = ConvertToExpression(node.Right) }); }
public override ASTNode VisitBinaryOperatorExpression([NotNull] DAEImplicitGrammarParser.BinaryOperatorExpressionContext context) { InfixExpressionNode node; int type = context.op.Type; switch (type) { case DAEImplicitGrammarLexer.CARET: node = new PowerNode(); break; case DAEImplicitGrammarLexer.PLUS: node = new AdditionNode(); break; case DAEImplicitGrammarLexer.MINUS: node = new SubtractionNode(); break; case DAEImplicitGrammarLexer.ASTERISK: node = new MultiplicationNode(); break; case DAEImplicitGrammarLexer.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 Implicit.DAEIDescription CompileDAEImplicit(RootNode root) { List <Expression.Expression> equations = new List <Expression.Expression>(); constants["time"] = 1.0; constants["t0"] = 0.0; foreach (var constant in root.constants) { //Convert to expression Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(constant.Right)); if (right is Float) { constants[constant.Identifier] = ((Float)right).Value; } else { constants.Add(constant.Identifier, float.NaN); compilerErrors.Add(new ErrorMessage("Определение константы " + constant.Identifier + " не является константным выражением")); } } foreach (var parameter in root.parameters) { //Convert to expression Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(parameter.Right)); if (right is Float) { //parameters.Add(parameter.Identifier, ((Float)right).Value); parameters[parameter.Identifier] = ((Float)right).Value; } else { parameters.Add(parameter.Identifier, float.NaN); compilerErrors.Add(new ErrorMessage("Определение параметра " + parameter.Identifier + " не является константным выражением")); } } foreach (var equation in root.equations) { //Convert to expression SubtractionNode exp = new SubtractionNode { Left = equation.Left, Right = equation.Right, Line = equation.Line, Position = equation.Position }; Expression.Expression expression = ExpressionSimplifier.Simplify(ConvertToExpression(exp)); equations.Add(expression); } foreach (var initialValue in root.initialValues) { if (variables.ContainsKey(initialValue.Identifier)) { //Convert to expression Expression.Expression right = ExpressionSimplifier.Simplify(ConvertToExpression(initialValue.Right)); if (right is Float) { Variable var = variables[initialValue.Identifier]; var.InitialValue = ((Float)right).Value; var.Initialized = true; } 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 (variables.Count != equations.Count) { compilerErrors.Add(new ErrorMessage("Количество переменных не совпадает с количеством уравнений")); } if (equations.Count == 0) { compilerErrors.Add(new ErrorMessage("Пустая система уравнений")); } foreach (var variable in variables) { if (variable.Value.Initialized == false) { variable.Value.InitialValue = 0.0; //compilerErrors.Add(new ErrorMessage("Не объявлены начальные условия для переменной " + variable.Key)); } } if (compilerErrors.Count > 0) { throw new CompilerException(compilerErrors); //fall back; } List <RPNExpression> equationsRPN = new List <RPNExpression>(); List <string> variableNames = new List <string>(); List <string> symbolNames = new List <string>(); List <double> initialValues = new List <double>(); Dictionary <string, int> symbolIndicies = new Dictionary <string, int>(); List <Variable> variableList = new List <Variable>(); foreach (var variable in variables) { variableList.Add(variable.Value); } variableList.Sort(delegate(Variable x, Variable y) { return(x.Name.CompareTo(y.Name)); }); //time variable symbolIndicies.Add("t", 0); symbolNames.Add("t"); //variables foreach (var variable in variableList) { variableNames.Add(variable.Name); symbolNames.Add(variable.Name); initialValues.Add(variable.InitialValue); symbolIndicies.Add(variable.Name, symbolIndicies.Count); } //derivatives foreach (var variable in variableList) { symbolNames.Add(variable.Name + "'"); symbolIndicies.Add(variable.Name + "'", symbolIndicies.Count); } string[] parameterNames = new string[parameters.Count]; double[] parameterValues = new double[parameters.Count]; { int i = 0; foreach (var parameter in parameters) { parameterNames[i] = parameter.Key; parameterValues[i] = parameter.Value; i++; } } foreach (var parameter in parameterNames) { symbolNames.Add(parameter); symbolIndicies.Add(parameter, symbolIndicies.Count); } Expression.Compiler expCompiler = new Expression.Compiler(symbolIndicies); for (int i = 0; i < equations.Count; i++) { equationsRPN.Add(expCompiler.Compile(equations[i])); } MathUtils.SparseMatrix <RPNExpression> dfdx = MathUtils.SparseMatrix <RPNExpression> .Build(equations.Count, equations.Count); MathUtils.SparseMatrix <RPNExpression> dfddx = MathUtils.SparseMatrix <RPNExpression> .Build(equations.Count, equations.Count); Expression.DifferentiationVisitor difVisitor = new Expression.DifferentiationVisitor(); for (int j = 0; j < equations.Count; j++) { for (int i = 0; i < equations.Count; i++) { Expression.Expression derivative = ExpressionSimplifier.Simplify(difVisitor.Differentiate(equations[i], variableNames[j])); if (derivative.Type == ExpressionType.Float) { if ((derivative as Expression.Float).IsZero()) { continue; } } RPNExpression exp = expCompiler.Compile(derivative); //dfdx[i, j] = exp; dfdx.Add(i, j, exp); } } for (int j = 0; j < equations.Count; j++) { for (int i = 0; i < equations.Count; i++) { Expression.Expression derivative = ExpressionSimplifier.Simplify(difVisitor.Differentiate(equations[i], variableNames[j] + "'")); if (derivative.Type == ExpressionType.Float) { if ((derivative as Expression.Float).IsZero()) { continue; } } RPNExpression exp = expCompiler.Compile(derivative); //dfddx[i, j] = exp; dfddx.Add(i, j, exp); } } Implicit.DAEIDescription definition = new Implicit.DAEIDescription(variableNames.ToArray(), parameterNames, parameterValues, initialValues.ToArray(), equationsRPN, dfdx, dfddx, constants["t0"], constants["time"]); return(definition); }
private DAEDefinition compileDAE(RootNode root) { List <Expression.Expression> equations = new List <Expression.Expression>(); parameters["time"] = 1.0; parameters["t0"] = 0.0; foreach (var parameter in root.parameters) { //Convert to expression Expression.Expression right = ExpressionSimplifier.simplify(ConvertToExpression(parameter.Right)); if (right is Float) { //parameters.Add(parameter.Identifier, ((Float)right).Value); parameters[parameter.Identifier] = ((Float)right).Value; } else { parameters.Add(parameter.Identifier, float.NaN); compilerErrors.Add(new ErrorMessage("Определение параметра " + parameter.Identifier + " не является константным выражением")); } } foreach (var equation in root.equations) { //Convert to expression SubtractionNode exp = new SubtractionNode { Left = equation.Left, Right = equation.Right, Line = equation.Line, Position = equation.Position }; equations.Add(ConvertToExpression(exp)); } foreach (var initialValue in root.initialValues) { if (variables.ContainsKey(initialValue.Identifier)) { Expression.Expression right = ExpressionSimplifier.simplify(ConvertToExpression(initialValue.Right)); if (right is Float) { Variable var = variables[initialValue.Identifier]; var.InitialValue = ((Float)right).Value; var.Initialized = true; } 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 (variables.Count - 1 != equations.Count) { compilerErrors.Add(new ErrorMessage("Количество переменных не совпадает с количеством уравнений")); } if (equations.Count == 0) { compilerErrors.Add(new ErrorMessage("Пустая система уравнений")); } foreach (var variable in variables) { if (variable.Value.Initialized == false) { compilerErrors.Add(new ErrorMessage("Не объявлены начальные условия для переменной " + variable.Key)); } } if (compilerErrors.Count > 0) { throw new Exception("Equation definition errors"); //fall back; } List <Expression.Expression> explicitDifferentialEquations = new List <Expression.Expression>(); List <Expression.Expression> implicitDifferentialEquations = new List <Expression.Expression>(); List <Expression.Expression> algebraicEquations = new List <Expression.Expression>(); bool semiExplicitForm = true; for (int i = 0; i < equations.Count; i++) { var equation = equations[i]; var astEquation = root.equations[i]; Subtraction exp = (Subtraction)equation; if (astEquation.Left.Type == ASTNodeType.Derivative) { exp.Right = ExpressionSimplifier.simplify(exp.Right); if (hasDerivative(exp.Right) || variables[(astEquation.Left as DerivativeNode).Identifier].DerCount != 1) { semiExplicitForm = false; implicitDifferentialEquations.Add(ExpressionSimplifier.simplify(exp)); } else { exp.Right = ExpressionSimplifier.simplify(exp.Right); explicitDifferentialEquations.Add(exp); } } else { Expression.Expression t_exp = ExpressionSimplifier.simplify(exp); if (hasDerivative(t_exp)) { semiExplicitForm = false; implicitDifferentialEquations.Add(t_exp); } else { algebraicEquations.Add(t_exp); } } } /* * if all differential equations are explicit then * create semiExplicit definition */ if (semiExplicitForm) { List <string> variableNamesX = new List <string>(); List <double> initialValuesX = new List <double>(); List <string> variableNamesZ = new List <string>(); List <double> initialValuesZ = new List <double>(); List <RPNExpression> differentialEquationsRPN = new List <RPNExpression>(); List <RPNExpression> algebraicEquationRPN = new List <RPNExpression>(); Dictionary <string, int> variableIndicies = new Dictionary <string, int>(); List <Variable> variableListX = new List <Variable>(); List <Variable> variableListZ = new List <Variable>(); foreach (var variable in variables) { if (variable.Value.VarType == Variable.Type.Algebraic) { variableListZ.Add(variable.Value); } else { variableListX.Add(variable.Value); } } variableListX.Sort(delegate(Variable x, Variable y) { return(x.Name.CompareTo(y.Name)); }); variableListZ.Sort(delegate(Variable x, Variable y) { return(x.Name.CompareTo(y.Name)); }); variableIndicies.Add("t", 0); foreach (var variable in variableListX) { variableNamesX.Add(variable.Name); initialValuesX.Add(variable.InitialValue); variableIndicies.Add(variable.Name, variableIndicies.Count); } foreach (var variable in variableListZ) { variableNamesZ.Add(variable.Name); initialValuesZ.Add(variable.InitialValue); variableIndicies.Add(variable.Name, variableIndicies.Count); } /* * for (int i = 0; i < explicitDifferentialEquations.Count; i++) * { * Subtraction equation = (Subtraction)explicitDifferentialEquations[i]; * Expression.Variable left = (Expression.Variable)equation.Left; * string variableName = left.Name.TrimEnd(new char['\'']); * variableIndicies.Add(variableName, variableIndicies.Count); * variableNamesX.Add(variableName); * initialValuesX.Add(variables[variableName].InitialValue); * } * foreach (var variable in variableList) * { * if (variable.Value.VarType == Variable.Type.Algebraic) * { * variableNamesZ.Add(variable.Key); * initialValuesZ.Add(variable.Value.InitialValue); * variableIndicies.Add(variable.Key, variableIndicies.Count); * } * }*/ ExpressionCompiler expCompiler = new ExpressionCompiler(variableIndicies); for (int i = 0; i < explicitDifferentialEquations.Count; i++) { Subtraction equation = (Subtraction)explicitDifferentialEquations[i]; differentialEquationsRPN.Add(expCompiler.compile(equation.Right)); } for (int i = 0; i < algebraicEquations.Count; i++) { algebraicEquationRPN.Add(expCompiler.compile(algebraicEquations[i])); } DAESemiExplicitDefinition definition = new DAESemiExplicitDefinition( variableNamesX.ToArray(), variableNamesZ.ToArray(), initialValuesX.ToArray(), initialValuesZ.ToArray(), differentialEquationsRPN, algebraicEquationRPN ); return(definition); } else { List <RPNExpression> equationsRPN = new List <RPNExpression>(); List <string> variableNames = new List <string>(); List <double> initialValues = new List <double>(); Dictionary <string, int> variableIndicies = new Dictionary <string, int>(); List <Variable> variableList = new List <Variable>(); foreach (var variable in variables) { variableList.Add(variable.Value); } variableList.Sort(delegate(Variable x, Variable y) { return(x.Name.CompareTo(y.Name)); }); //time variable variableIndicies.Add("t", 0); //variables foreach (var variable in variableList) { variableNames.Add(variable.Name); initialValues.Add(variable.InitialValue); variableIndicies.Add(variable.Name, variableIndicies.Count); } //derivatives foreach (var variable in variableList) { variableIndicies.Add(variable.Name + "'", variableIndicies.Count); } ExpressionCompiler expCompiler = new ExpressionCompiler(variableIndicies); for (int i = 0; i < implicitDifferentialEquations.Count; i++) { equationsRPN.Add(expCompiler.compile(implicitDifferentialEquations[i])); } for (int i = 0; i < explicitDifferentialEquations.Count; i++) { Subtraction equation = (Subtraction)explicitDifferentialEquations[i]; equationsRPN.Add(expCompiler.compile(equation)); } for (int i = 0; i < algebraicEquations.Count; i++) { equationsRPN.Add(expCompiler.compile(algebraicEquations[i])); } DAEImplicitDefinition definition = new DAEImplicitDefinition(variableNames.ToArray(), initialValues.ToArray(), equationsRPN); return(definition); } }