Line data Source code
1 : /* -------------------------------------------------------------------------- * 2 : * lepton * 3 : * -------------------------------------------------------------------------- * 4 : * This is part of the lepton expression parser. * 5 : * See https://openmm.org/development. * 6 : * * 7 : * Portions copyright (c) 2009-2018 Stanford University and the Authors. * 8 : * Authors: Peter Eastman * 9 : * Contributors: * 10 : * * 11 : * Permission is hereby granted, free of charge, to any person obtaining a * 12 : * copy of this software and associated documentation files (the "Software"), * 13 : * to deal in the Software without restriction, including without limitation * 14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 15 : * and/or sell copies of the Software, and to permit persons to whom the * 16 : * Software is furnished to do so, subject to the following conditions: * 17 : * * 18 : * The above copyright notice and this permission notice shall be included in * 19 : * all copies or substantial portions of the Software. * 20 : * * 21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 22 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 24 : * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 25 : * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 26 : * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 27 : * USE OR OTHER DEALINGS IN THE SOFTWARE. * 28 : * -------------------------------------------------------------------------- */ 29 : 30 : #include "ExpressionProgram.h" 31 : #include "Operation.h" 32 : #include "ParsedExpression.h" 33 : 34 : namespace PLMD { 35 : using namespace lepton; 36 : using namespace std; 37 : 38 0 : ExpressionProgram::ExpressionProgram() : maxArgs(0), stackSize(0) { 39 0 : } 40 : 41 0 : ExpressionProgram::ExpressionProgram(const ParsedExpression& expression) : maxArgs(0), stackSize(0) { 42 0 : buildProgram(expression.getRootNode()); 43 : int currentStackSize = 0; 44 0 : for (int i = 0; i < (int) operations.size(); i++) { 45 0 : int args = operations[i]->getNumArguments(); 46 0 : if (args > maxArgs) 47 0 : maxArgs = args; 48 0 : currentStackSize += 1-args; 49 0 : if (currentStackSize > stackSize) 50 0 : stackSize = currentStackSize; 51 : } 52 0 : } 53 : 54 0 : ExpressionProgram::~ExpressionProgram() { 55 0 : for (int i = 0; i < (int) operations.size(); i++) 56 0 : delete operations[i]; 57 0 : } 58 : 59 0 : ExpressionProgram::ExpressionProgram(const ExpressionProgram& program) { 60 0 : *this = program; 61 0 : } 62 : 63 0 : ExpressionProgram& ExpressionProgram::operator=(const ExpressionProgram& program) { 64 0 : maxArgs = program.maxArgs; 65 0 : stackSize = program.stackSize; 66 0 : operations.resize(program.operations.size()); 67 0 : for (int i = 0; i < (int) operations.size(); i++) 68 0 : operations[i] = program.operations[i]->clone(); 69 0 : return *this; 70 : } 71 : 72 0 : void ExpressionProgram::buildProgram(const ExpressionTreeNode& node) { 73 0 : for (int i = (int) node.getChildren().size()-1; i >= 0; i--) 74 0 : buildProgram(node.getChildren()[i]); 75 0 : operations.push_back(node.getOperation().clone()); 76 0 : } 77 : 78 0 : int ExpressionProgram::getNumOperations() const { 79 0 : return (int) operations.size(); 80 : } 81 : 82 0 : const Operation& ExpressionProgram::getOperation(int index) const { 83 0 : return *operations[index]; 84 : } 85 : 86 0 : void ExpressionProgram::setOperation(int index, Operation* operation) { 87 0 : delete operations[index]; 88 0 : operations[index] = operation; 89 0 : } 90 : 91 0 : int ExpressionProgram::getStackSize() const { 92 0 : return stackSize; 93 : } 94 : 95 0 : double ExpressionProgram::evaluate() const { 96 0 : return evaluate(map<string, double>()); 97 : } 98 : 99 0 : double ExpressionProgram::evaluate(const std::map<std::string, double>& variables) const { 100 0 : vector<double> stack(stackSize+1); 101 0 : int stackPointer = stackSize; 102 0 : for (int i = 0; i < (int) operations.size(); i++) { 103 0 : int numArgs = operations[i]->getNumArguments(); 104 0 : double result = operations[i]->evaluate(&stack[stackPointer], variables); 105 0 : stackPointer += numArgs-1; 106 0 : stack[stackPointer] = result; 107 : } 108 0 : return stack[stackSize-1]; 109 : } 110 : }