Commit 4cbb82d4 authored by Peter Eastman's avatar Peter Eastman
Browse files

Added some optimizations

parent ab09b522
...@@ -68,16 +68,24 @@ double ParsedExpression::evaluate(const ExpressionTreeNode& node, const map<stri ...@@ -68,16 +68,24 @@ double ParsedExpression::evaluate(const ExpressionTreeNode& node, const map<stri
ParsedExpression ParsedExpression::optimize() const { ParsedExpression ParsedExpression::optimize() const {
ExpressionTreeNode result = precalculateConstantSubexpressions(getRootNode()); ExpressionTreeNode result = precalculateConstantSubexpressions(getRootNode());
result = substituteSimplerExpression(result); while (true) {
result = substituteSimplerExpression(result); ExpressionTreeNode simplified = substituteSimplerExpression(result);
if (simplified == result)
break;
result = simplified;
}
return ParsedExpression(result); return ParsedExpression(result);
} }
ParsedExpression ParsedExpression::optimize(const map<string, double>& variables) const { ParsedExpression ParsedExpression::optimize(const map<string, double>& variables) const {
ExpressionTreeNode result = preevaluateVariables(getRootNode(), variables); ExpressionTreeNode result = preevaluateVariables(getRootNode(), variables);
result = precalculateConstantSubexpressions(result); result = precalculateConstantSubexpressions(result);
result = substituteSimplerExpression(result); while (true) {
result = substituteSimplerExpression(result); ExpressionTreeNode simplified = substituteSimplerExpression(result);
if (simplified == result)
break;
result = simplified;
}
return ParsedExpression(result); return ParsedExpression(result);
} }
...@@ -206,12 +214,16 @@ ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const Expressio ...@@ -206,12 +214,16 @@ ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const Expressio
{ {
if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine a multiply and a negate into a single multiply if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine a multiply and a negate into a single multiply
return ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]); return ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
if (children[0].getOperation().getId() == Operation::CONSTANT) // Negate a constant
return ExpressionTreeNode(new Operation::Constant(-getConstantValue(children[0])));
break; break;
} }
case Operation::MULTIPLY_CONSTANT: case Operation::MULTIPLY_CONSTANT:
{ {
if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one
return ExpressionTreeNode(new Operation::MultiplyConstant(dynamic_cast<const Operation::MultiplyConstant*>(&node.getOperation())->getValue()*dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]); return ExpressionTreeNode(new Operation::MultiplyConstant(dynamic_cast<const Operation::MultiplyConstant*>(&node.getOperation())->getValue()*dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
if (children[0].getOperation().getId() == Operation::CONSTANT) // Multiply two constants
return ExpressionTreeNode(new Operation::Constant(dynamic_cast<const Operation::MultiplyConstant*>(&node.getOperation())->getValue()*getConstantValue(children[0])));
} }
} }
return ExpressionTreeNode(node.getOperation().clone(), children); return ExpressionTreeNode(node.getOperation().clone(), children);
......
...@@ -219,7 +219,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int ...@@ -219,7 +219,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int
pos++; pos++;
result = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0); result = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0);
if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen) if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
throw Exception("Parse error: unbalanced parentheses"); throw Exception("Parse error: unbalanced parentheses");
pos++; pos++;
} }
else if (token.getType() == ParseToken::Function) { else if (token.getType() == ParseToken::Function) {
...@@ -233,7 +233,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int ...@@ -233,7 +233,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int
pos++; pos++;
} while (moreArgs); } while (moreArgs);
if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen) if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
throw Exception("Parse error: unbalanced parentheses"); throw Exception("Parse error: unbalanced parentheses");
pos++; pos++;
Operation* op = getFunctionOperation(token.getText(), customFunctions); Operation* op = getFunctionOperation(token.getText(), customFunctions);
try { try {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment