Remove trailing whitespace from Lepton per suggestion from @akohlmey
This commit is contained in:
@ -56,9 +56,9 @@ class ParsedExpression;
|
|||||||
* A CompiledExpression is a highly optimized representation of an expression for cases when you want to evaluate
|
* A CompiledExpression is a highly optimized representation of an expression for cases when you want to evaluate
|
||||||
* it many times as quickly as possible. You should treat it as an opaque object; none of the internal representation
|
* it many times as quickly as possible. You should treat it as an opaque object; none of the internal representation
|
||||||
* is visible.
|
* is visible.
|
||||||
*
|
*
|
||||||
* A CompiledExpression is created by calling createCompiledExpression() on a ParsedExpression.
|
* A CompiledExpression is created by calling createCompiledExpression() on a ParsedExpression.
|
||||||
*
|
*
|
||||||
* WARNING: CompiledExpression is NOT thread safe. You should never access a CompiledExpression from two threads at
|
* WARNING: CompiledExpression is NOT thread safe. You should never access a CompiledExpression from two threads at
|
||||||
* the same time.
|
* the same time.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -59,12 +59,12 @@ class ParsedExpression;
|
|||||||
* vector unit (AVX on x86, NEON on ARM) to evaluate the expression for multiple sets of arguments at once. It also differs
|
* vector unit (AVX on x86, NEON on ARM) to evaluate the expression for multiple sets of arguments at once. It also differs
|
||||||
* from CompiledExpression and ParsedExpression in using single precision rather than double precision to evaluate the expression.
|
* from CompiledExpression and ParsedExpression in using single precision rather than double precision to evaluate the expression.
|
||||||
* You should treat it as an opaque object; none of the internal representation is visible.
|
* You should treat it as an opaque object; none of the internal representation is visible.
|
||||||
*
|
*
|
||||||
* A CompiledVectorExpression is created by calling createCompiledVectorExpression() on a ParsedExpression. When you create
|
* A CompiledVectorExpression is created by calling createCompiledVectorExpression() on a ParsedExpression. When you create
|
||||||
* it, you must specify the width of the vectors on which to compute the expression. The allowed widths depend on the type of
|
* it, you must specify the width of the vectors on which to compute the expression. The allowed widths depend on the type of
|
||||||
* CPU it is running on. 4 is always allowed, and 8 is allowed on x86 processors with AVX. Call getAllowedWidths() to query
|
* CPU it is running on. 4 is always allowed, and 8 is allowed on x86 processors with AVX. Call getAllowedWidths() to query
|
||||||
* the allowed values.
|
* the allowed values.
|
||||||
*
|
*
|
||||||
* WARNING: CompiledVectorExpression is NOT thread safe. You should never access a CompiledVectorExpression from two threads at
|
* WARNING: CompiledVectorExpression is NOT thread safe. You should never access a CompiledVectorExpression from two threads at
|
||||||
* the same time.
|
* the same time.
|
||||||
*/
|
*/
|
||||||
@ -86,7 +86,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Get a pointer to the memory location where the value of a particular variable is stored. This can be used
|
* Get a pointer to the memory location where the value of a particular variable is stored. This can be used
|
||||||
* to set the value of the variable before calling evaluate().
|
* to set the value of the variable before calling evaluate().
|
||||||
*
|
*
|
||||||
* @param name the name of the variable to query
|
* @param name the name of the variable to query
|
||||||
* @return a pointer to N floating point values, where N is the vector width
|
* @return a pointer to N floating point values, where N is the vector width
|
||||||
*/
|
*/
|
||||||
@ -100,7 +100,7 @@ public:
|
|||||||
void setVariableLocations(std::map<std::string, float*>& variableLocations);
|
void setVariableLocations(std::map<std::string, float*>& variableLocations);
|
||||||
/**
|
/**
|
||||||
* Evaluate the expression. The values of all variables should have been set before calling this.
|
* Evaluate the expression. The values of all variables should have been set before calling this.
|
||||||
*
|
*
|
||||||
* @return a pointer to N floating point values, where N is the vector width
|
* @return a pointer to N floating point values, where N is the vector width
|
||||||
*/
|
*/
|
||||||
const float* evaluate() const;
|
const float* evaluate() const;
|
||||||
|
|||||||
@ -83,7 +83,7 @@ class LEPTON_EXPORT PlaceholderFunction : public CustomFunction {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create a Placeholder function.
|
* Create a Placeholder function.
|
||||||
*
|
*
|
||||||
* @param numArgs the number of arguments the function expects
|
* @param numArgs the number of arguments the function expects
|
||||||
*/
|
*/
|
||||||
PlaceholderFunction(int numArgs) : numArgs(numArgs) {
|
PlaceholderFunction(int numArgs) : numArgs(numArgs) {
|
||||||
|
|||||||
@ -67,7 +67,7 @@ public:
|
|||||||
const Operation& getOperation(int index) const;
|
const Operation& getOperation(int index) const;
|
||||||
/**
|
/**
|
||||||
* Change an Operation in this program.
|
* Change an Operation in this program.
|
||||||
*
|
*
|
||||||
* The Operation must have been allocated on the heap with the "new" operator.
|
* The Operation must have been allocated on the heap with the "new" operator.
|
||||||
* The ExpressionProgram assumes ownership of it and will delete it when it
|
* The ExpressionProgram assumes ownership of it and will delete it when it
|
||||||
* is no longer needed.
|
* is no longer needed.
|
||||||
|
|||||||
@ -1017,7 +1017,7 @@ public:
|
|||||||
double evaluate(double* args, const std::map<std::string, double>& variables) const {
|
double evaluate(double* args, const std::map<std::string, double>& variables) const {
|
||||||
if (isIntPower) {
|
if (isIntPower) {
|
||||||
// Integer powers can be computed much more quickly by repeated multiplication.
|
// Integer powers can be computed much more quickly by repeated multiplication.
|
||||||
|
|
||||||
int exponent = intValue;
|
int exponent = intValue;
|
||||||
double base = args[0];
|
double base = args[0];
|
||||||
if (exponent < 0) {
|
if (exponent < 0) {
|
||||||
|
|||||||
@ -106,7 +106,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Create a CompiledVectorExpression that allows the expression to be evaluated efficiently
|
* Create a CompiledVectorExpression that allows the expression to be evaluated efficiently
|
||||||
* using the CPU's vector unit.
|
* using the CPU's vector unit.
|
||||||
*
|
*
|
||||||
* @param width the width of the vectors to evaluate it on. The allowed values
|
* @param width the width of the vectors to evaluate it on. The allowed values
|
||||||
* depend on the CPU. 4 is always allowed, and 8 is allowed on
|
* depend on the CPU. 4 is always allowed, and 8 is allowed on
|
||||||
* x86 processors with AVX. Call CompiledVectorExpression::getAllowedWidths()
|
* x86 processors with AVX. Call CompiledVectorExpression::getAllowedWidths()
|
||||||
|
|||||||
@ -84,17 +84,17 @@ CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expr
|
|||||||
void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
|
void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
|
||||||
if (findTempIndex(node, temps) != -1)
|
if (findTempIndex(node, temps) != -1)
|
||||||
return; // We have already processed a node identical to this one.
|
return; // We have already processed a node identical to this one.
|
||||||
|
|
||||||
// Process the child nodes.
|
// Process the child nodes.
|
||||||
|
|
||||||
vector<int> args;
|
vector<int> args;
|
||||||
for (int i = 0; i < node.getChildren().size(); i++) {
|
for (int i = 0; i < node.getChildren().size(); i++) {
|
||||||
compileExpression(node.getChildren()[i], temps);
|
compileExpression(node.getChildren()[i], temps);
|
||||||
args.push_back(findTempIndex(node.getChildren()[i], temps));
|
args.push_back(findTempIndex(node.getChildren()[i], temps));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process this node.
|
// Process this node.
|
||||||
|
|
||||||
if (node.getOperation().getId() == Operation::VARIABLE) {
|
if (node.getOperation().getId() == Operation::VARIABLE) {
|
||||||
variableIndices[node.getOperation().getName()] = (int) workspace.size();
|
variableIndices[node.getOperation().getName()] = (int) workspace.size();
|
||||||
variableNames.insert(node.getOperation().getName());
|
variableNames.insert(node.getOperation().getName());
|
||||||
@ -108,7 +108,7 @@ void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vecto
|
|||||||
arguments[stepIndex].push_back(0); // The value won't actually be used. We just need something there.
|
arguments[stepIndex].push_back(0); // The value won't actually be used. We just need something there.
|
||||||
else {
|
else {
|
||||||
// If the arguments are sequential, we can just pass a pointer to the first one.
|
// If the arguments are sequential, we can just pass a pointer to the first one.
|
||||||
|
|
||||||
bool sequential = true;
|
bool sequential = true;
|
||||||
for (int i = 1; i < args.size(); i++)
|
for (int i = 1; i < args.size(); i++)
|
||||||
if (args[i] != args[i-1]+1)
|
if (args[i] != args[i-1]+1)
|
||||||
@ -148,12 +148,12 @@ void CompiledExpression::setVariableLocations(map<string, double*>& variableLoca
|
|||||||
variablePointers = variableLocations;
|
variablePointers = variableLocations;
|
||||||
#ifdef LEPTON_USE_JIT
|
#ifdef LEPTON_USE_JIT
|
||||||
// Rebuild the JIT code.
|
// Rebuild the JIT code.
|
||||||
|
|
||||||
if (workspace.size() > 0)
|
if (workspace.size() > 0)
|
||||||
generateJitCode();
|
generateJitCode();
|
||||||
#endif
|
#endif
|
||||||
// Make a list of all variables we will need to copy before evaluating the expression.
|
// Make a list of all variables we will need to copy before evaluating the expression.
|
||||||
|
|
||||||
variablesToCopy.clear();
|
variablesToCopy.clear();
|
||||||
for (map<string, int>::const_iterator iter = variableIndices.begin(); iter != variableIndices.end(); ++iter) {
|
for (map<string, int>::const_iterator iter = variableIndices.begin(); iter != variableIndices.end(); ++iter) {
|
||||||
map<string, double*>::iterator pointer = variablePointers.find(iter->first);
|
map<string, double*>::iterator pointer = variablePointers.find(iter->first);
|
||||||
@ -169,7 +169,7 @@ double CompiledExpression::evaluate() const {
|
|||||||
*variablesToCopy[i].first = *variablesToCopy[i].second;
|
*variablesToCopy[i].first = *variablesToCopy[i].second;
|
||||||
|
|
||||||
// Loop over the operations and evaluate each one.
|
// Loop over the operations and evaluate each one.
|
||||||
|
|
||||||
for (int step = 0; step < operation.size(); step++) {
|
for (int step = 0; step < operation.size(); step++) {
|
||||||
const vector<int>& args = arguments[step];
|
const vector<int>& args = arguments[step];
|
||||||
if (args.size() == 1)
|
if (args.size() == 1)
|
||||||
@ -245,9 +245,9 @@ void CompiledExpression::generateJitCode() {
|
|||||||
vector<vector<int> > groups, groupPowers;
|
vector<vector<int> > groups, groupPowers;
|
||||||
vector<int> stepGroup;
|
vector<int> stepGroup;
|
||||||
findPowerGroups(groups, groupPowers, stepGroup);
|
findPowerGroups(groups, groupPowers, stepGroup);
|
||||||
|
|
||||||
// Load the arguments into variables.
|
// Load the arguments into variables.
|
||||||
|
|
||||||
for (set<string>::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) {
|
for (set<string>::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) {
|
||||||
map<string, int>::iterator index = variableIndices.find(*iter);
|
map<string, int>::iterator index = variableIndices.find(*iter);
|
||||||
arm::Gp variablePointer = c.newIntPtr();
|
arm::Gp variablePointer = c.newIntPtr();
|
||||||
@ -256,11 +256,11 @@ void CompiledExpression::generateJitCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make a list of all constants that will be needed for evaluation.
|
// Make a list of all constants that will be needed for evaluation.
|
||||||
|
|
||||||
vector<int> operationConstantIndex(operation.size(), -1);
|
vector<int> operationConstantIndex(operation.size(), -1);
|
||||||
for (int step = 0; step < (int) operation.size(); step++) {
|
for (int step = 0; step < (int) operation.size(); step++) {
|
||||||
// Find the constant value (if any) used by this operation.
|
// Find the constant value (if any) used by this operation.
|
||||||
|
|
||||||
Operation& op = *operation[step];
|
Operation& op = *operation[step];
|
||||||
double value;
|
double value;
|
||||||
if (op.getId() == Operation::CONSTANT)
|
if (op.getId() == Operation::CONSTANT)
|
||||||
@ -283,9 +283,9 @@ void CompiledExpression::generateJitCode() {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// See if we already have a variable for this constant.
|
// See if we already have a variable for this constant.
|
||||||
|
|
||||||
for (int i = 0; i < (int) constants.size(); i++)
|
for (int i = 0; i < (int) constants.size(); i++)
|
||||||
if (value == constants[i]) {
|
if (value == constants[i]) {
|
||||||
operationConstantIndex[step] = i;
|
operationConstantIndex[step] = i;
|
||||||
@ -296,9 +296,9 @@ void CompiledExpression::generateJitCode() {
|
|||||||
constants.push_back(value);
|
constants.push_back(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load constants into variables.
|
// Load constants into variables.
|
||||||
|
|
||||||
vector<arm::Vec> constantVar(constants.size());
|
vector<arm::Vec> constantVar(constants.size());
|
||||||
if (constants.size() > 0) {
|
if (constants.size() > 0) {
|
||||||
arm::Gp constantsPointer = c.newIntPtr();
|
arm::Gp constantsPointer = c.newIntPtr();
|
||||||
@ -360,13 +360,13 @@ void CompiledExpression::generateJitCode() {
|
|||||||
vector<int> args = arguments[step];
|
vector<int> args = arguments[step];
|
||||||
if (args.size() == 1) {
|
if (args.size() == 1) {
|
||||||
// One or more sequential arguments. Fill out the list.
|
// One or more sequential arguments. Fill out the list.
|
||||||
|
|
||||||
for (int i = 1; i < op.getNumArguments(); i++)
|
for (int i = 1; i < op.getNumArguments(); i++)
|
||||||
args.push_back(args[0]+i);
|
args.push_back(args[0]+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate instructions to execute this operation.
|
// Generate instructions to execute this operation.
|
||||||
|
|
||||||
switch (op.getId()) {
|
switch (op.getId()) {
|
||||||
case Operation::CONSTANT:
|
case Operation::CONSTANT:
|
||||||
c.fmov(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
|
c.fmov(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
|
||||||
@ -476,7 +476,7 @@ void CompiledExpression::generateJitCode() {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Just invoke evaluateOperation().
|
// Just invoke evaluateOperation().
|
||||||
|
|
||||||
for (int i = 0; i < (int) args.size(); i++)
|
for (int i = 0; i < (int) args.size(); i++)
|
||||||
c.str(workspaceVar[args[i]], arm::ptr(argsPointer, 8*i));
|
c.str(workspaceVar[args[i]], arm::ptr(argsPointer, 8*i));
|
||||||
arm::Gp fn = c.newIntPtr();
|
arm::Gp fn = c.newIntPtr();
|
||||||
@ -532,7 +532,7 @@ void CompiledExpression::generateJitCode() {
|
|||||||
findPowerGroups(groups, groupPowers, stepGroup);
|
findPowerGroups(groups, groupPowers, stepGroup);
|
||||||
|
|
||||||
// Load the arguments into variables.
|
// Load the arguments into variables.
|
||||||
|
|
||||||
x86::Gp variablePointer = c.newIntPtr();
|
x86::Gp variablePointer = c.newIntPtr();
|
||||||
for (set<string>::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) {
|
for (set<string>::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) {
|
||||||
map<string, int>::iterator index = variableIndices.find(*iter);
|
map<string, int>::iterator index = variableIndices.find(*iter);
|
||||||
@ -541,11 +541,11 @@ void CompiledExpression::generateJitCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make a list of all constants that will be needed for evaluation.
|
// Make a list of all constants that will be needed for evaluation.
|
||||||
|
|
||||||
vector<int> operationConstantIndex(operation.size(), -1);
|
vector<int> operationConstantIndex(operation.size(), -1);
|
||||||
for (int step = 0; step < (int) operation.size(); step++) {
|
for (int step = 0; step < (int) operation.size(); step++) {
|
||||||
// Find the constant value (if any) used by this operation.
|
// Find the constant value (if any) used by this operation.
|
||||||
|
|
||||||
Operation& op = *operation[step];
|
Operation& op = *operation[step];
|
||||||
double value;
|
double value;
|
||||||
if (op.getId() == Operation::CONSTANT)
|
if (op.getId() == Operation::CONSTANT)
|
||||||
@ -572,9 +572,9 @@ void CompiledExpression::generateJitCode() {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// See if we already have a variable for this constant.
|
// See if we already have a variable for this constant.
|
||||||
|
|
||||||
for (int i = 0; i < (int) constants.size(); i++)
|
for (int i = 0; i < (int) constants.size(); i++)
|
||||||
if (value == constants[i]) {
|
if (value == constants[i]) {
|
||||||
operationConstantIndex[step] = i;
|
operationConstantIndex[step] = i;
|
||||||
@ -585,9 +585,9 @@ void CompiledExpression::generateJitCode() {
|
|||||||
constants.push_back(value);
|
constants.push_back(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load constants into variables.
|
// Load constants into variables.
|
||||||
|
|
||||||
vector<x86::Xmm> constantVar(constants.size());
|
vector<x86::Xmm> constantVar(constants.size());
|
||||||
if (constants.size() > 0) {
|
if (constants.size() > 0) {
|
||||||
x86::Gp constantsPointer = c.newIntPtr();
|
x86::Gp constantsPointer = c.newIntPtr();
|
||||||
@ -597,9 +597,9 @@ void CompiledExpression::generateJitCode() {
|
|||||||
c.vmovsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0));
|
c.vmovsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the operations.
|
// Evaluate the operations.
|
||||||
|
|
||||||
vector<bool> hasComputedPower(operation.size(), false);
|
vector<bool> hasComputedPower(operation.size(), false);
|
||||||
for (int step = 0; step < (int) operation.size(); step++) {
|
for (int step = 0; step < (int) operation.size(); step++) {
|
||||||
if (hasComputedPower[step])
|
if (hasComputedPower[step])
|
||||||
@ -649,13 +649,13 @@ void CompiledExpression::generateJitCode() {
|
|||||||
vector<int> args = arguments[step];
|
vector<int> args = arguments[step];
|
||||||
if (args.size() == 1) {
|
if (args.size() == 1) {
|
||||||
// One or more sequential arguments. Fill out the list.
|
// One or more sequential arguments. Fill out the list.
|
||||||
|
|
||||||
for (int i = 1; i < op.getNumArguments(); i++)
|
for (int i = 1; i < op.getNumArguments(); i++)
|
||||||
args.push_back(args[0]+i);
|
args.push_back(args[0]+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate instructions to execute this operation.
|
// Generate instructions to execute this operation.
|
||||||
|
|
||||||
switch (op.getId()) {
|
switch (op.getId()) {
|
||||||
case Operation::CONSTANT:
|
case Operation::CONSTANT:
|
||||||
c.vmovsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]], constantVar[operationConstantIndex[step]]);
|
c.vmovsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]], constantVar[operationConstantIndex[step]]);
|
||||||
@ -772,7 +772,7 @@ void CompiledExpression::generateJitCode() {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Just invoke evaluateOperation().
|
// Just invoke evaluateOperation().
|
||||||
|
|
||||||
for (int i = 0; i < (int) args.size(); i++)
|
for (int i = 0; i < (int) args.size(); i++)
|
||||||
c.vmovsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]);
|
c.vmovsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]);
|
||||||
x86::Gp fn = c.newIntPtr();
|
x86::Gp fn = c.newIntPtr();
|
||||||
|
|||||||
@ -132,7 +132,7 @@ void ExpressionTreeNode::assignTags(vector<const ExpressionTreeNode*>& examples)
|
|||||||
child.assignTags(examples);
|
child.assignTags(examples);
|
||||||
if (numTags == examples.size()) {
|
if (numTags == examples.size()) {
|
||||||
// All the children matched existing tags, so possibly this node does too.
|
// All the children matched existing tags, so possibly this node does too.
|
||||||
|
|
||||||
for (int i = 0; i < examples.size(); i++) {
|
for (int i = 0; i < examples.size(); i++) {
|
||||||
const ExpressionTreeNode& example = *examples[i];
|
const ExpressionTreeNode& example = *examples[i];
|
||||||
bool matches = (getChildren().size() == example.getChildren().size() && getOperation() == example.getOperation());
|
bool matches = (getChildren().size() == example.getChildren().size() && getOperation() == example.getOperation());
|
||||||
@ -145,9 +145,9 @@ void ExpressionTreeNode::assignTags(vector<const ExpressionTreeNode*>& examples)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This node does not match any previous node, so assign a new tag.
|
// This node does not match any previous node, so assign a new tag.
|
||||||
|
|
||||||
tag = examples.size();
|
tag = examples.size();
|
||||||
examples.push_back(this);
|
examples.push_back(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Up to version 11 (VC++ 2012), Microsoft does not support the
|
* Up to version 11 (VC++ 2012), Microsoft does not support the
|
||||||
* standard C99 erf() and erfc() functions so we have to fake them here.
|
* standard C99 erf() and erfc() functions so we have to fake them here.
|
||||||
* These were added in version 12 (VC++ 2013), which sets _MSC_VER=1800
|
* These were added in version 12 (VC++ 2013), which sets _MSC_VER=1800
|
||||||
* (VC11 has _MSC_VER=1700).
|
* (VC11 has _MSC_VER=1700).
|
||||||
*/
|
*/
|
||||||
@ -15,7 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#if _MSC_VER <= 1700 // 1700 is VC11, 1800 is VC12
|
#if _MSC_VER <= 1700 // 1700 is VC11, 1800 is VC12
|
||||||
/***************************
|
/***************************
|
||||||
* erf.cpp
|
* erf.cpp
|
||||||
* author: Steve Strand
|
* author: Steve Strand
|
||||||
|
|||||||
@ -152,10 +152,10 @@ ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const Expressio
|
|||||||
else
|
else
|
||||||
children[i] = cached->second;
|
children[i] = cached->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect some info on constant expressions in children
|
// Collect some info on constant expressions in children
|
||||||
bool first_const = children.size() > 0 && isConstant(children[0]); // is first child constant?
|
bool first_const = children.size() > 0 && isConstant(children[0]); // is first child constant?
|
||||||
bool second_const = children.size() > 1 && isConstant(children[1]); ; // is second child constant?
|
bool second_const = children.size() > 1 && isConstant(children[1]); ; // is second child constant?
|
||||||
double first, second; // if yes, value of first and second child
|
double first, second; // if yes, value of first and second child
|
||||||
if (first_const)
|
if (first_const)
|
||||||
first = getConstantValue(children[0]);
|
first = getConstantValue(children[0]);
|
||||||
@ -205,7 +205,7 @@ ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const Expressio
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Operation::MULTIPLY:
|
case Operation::MULTIPLY:
|
||||||
{
|
{
|
||||||
if ((first_const && first == 0.0) || (second_const && second == 0.0)) // Multiply by 0
|
if ((first_const && first == 0.0) || (second_const && second == 0.0)) // Multiply by 0
|
||||||
return ExpressionTreeNode(new Operation::Constant(0.0));
|
return ExpressionTreeNode(new Operation::Constant(0.0));
|
||||||
if (first_const && first == 1.0) // Multiply by 1
|
if (first_const && first == 1.0) // Multiply by 1
|
||||||
|
|||||||
@ -66,7 +66,7 @@ private:
|
|||||||
|
|
||||||
string Parser::trim(const string& expression) {
|
string Parser::trim(const string& expression) {
|
||||||
// Remove leading and trailing spaces.
|
// Remove leading and trailing spaces.
|
||||||
|
|
||||||
int start, end;
|
int start, end;
|
||||||
for (start = 0; start < (int) expression.size() && isspace(expression[start]); start++)
|
for (start = 0; start < (int) expression.size() && isspace(expression[start]); start++)
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user