The mathexpr.c
file is responsible for evaluating symbolic mathematical expressions within the SWMM5 (Storm Water Management Model). The module parses and computes expressions that consist of numbers, variable names, mathematical functions, and arithmetic operators. The expressions are evaluated using a binary tree structure, and the results are computed through a stack-based evaluation mechanism.
Key Features:
Operand Codes:
- Operands: The file uses specific operand codes for operations like addition, subtraction, multiplication, division, and exponentiation. It also includes predefined functions such as
cos
,sin
,tan
,sqrt
, etc. - Example Operand Codes:
1
=(
2
=)
3
=+
7
= Number8
= User-defined variable10
to27
= Math functions likecos
,sin
,sqrt
,log10
,step
, etc.31
= Exponentiation (^
)
Core Data Structures:
-
ExprTree
: Represents a node in a binary tree structure for the mathematical expression. Each node holds an operator code (opcode
), the variable index (ivar
), or a numerical value (fvalue
). The tree has left and right pointers for its subtrees. -
MathExpr
: A linked list structure that represents the final postfix expression for evaluation.
Main Components and Functions:
-
mathexpr_create()
:- This is the main function that takes a mathematical expression in string form (
formula
) and a function to retrieve variable values (getVar
). - It uses a recursive function (
getTree()
) to parse the expression into a tree structure and then converts the tree into a postfix linked list (MathExpr
) throughtraverseTree()
.
- This is the main function that takes a mathematical expression in string form (
-
getTree()
:- This function recursively builds an expression tree from the string input. It processes operands, operators, functions, and variables.
- It handles parenthesis and operator precedence by creating a tree structure where the operators become the internal nodes, and the operands (variables and numbers) become the leaves.
-
mathexpr_eval()
:- This function evaluates the mathematical expression represented by the linked list (
MathExpr
). - It uses a stack (
ExprStack
) to evaluate the expression. For each operation (e.g., addition, multiplication), it pops values from the stack, performs the operation, and pushes the result back onto the stack.
- This function evaluates the mathematical expression represented by the linked list (
-
getToken()
:- Extracts a token (a variable or number) from the input expression string.
-
getMathFunc()
:- Identifies mathematical functions like
cos
,sin
,sqrt
, etc., from the current token.
- Identifies mathematical functions like
-
getOperand()
:- Identifies basic operands such as operators (
+
,-
,*
,/
, etc.), parentheses ((
,)
), and numbers.
- Identifies basic operands such as operators (
-
Mathematical Functions:
- The module supports a wide range of mathematical functions like
cos
,sin
,log
,sqrt
,exp
, and many others. These functions are handled using specific operand codes (e.g.,cos
is handled byopcode 10
).
- The module supports a wide range of mathematical functions like
-
getVariable()
:- Looks up a variable by name and returns its value index (if defined).
-
newNode()
:- Allocates memory for a new tree node used to build the expression tree.
-
deleteTree()
:- Frees the memory used by the expression tree after evaluation is complete.
Evaluation Logic:
- The evaluation logic follows the "postfix" or Reverse Polish Notation (RPN) approach. This allows for the evaluation of expressions without needing parentheses to dictate precedence.
- The expression is first parsed into a binary tree, then traversed into a linked list in postfix order. Finally, the linked list is evaluated using a stack-based approach where operands are pushed to the stack and operators pop operands from the stack to perform the operations.
Example Workflow:
-
Expression Input:
- A mathematical expression like
3 + sin(x) * 2
.
- A mathematical expression like
-
Parsing the Expression:
- The
getTree()
function builds an expression tree with operands (3
,x
,2
) and operators (+
,*
,sin
).
- The
-
Postfix Conversion:
- The expression tree is then converted into a linked list in postfix notation, e.g.,
3 2 x sin * +
.
- The expression tree is then converted into a linked list in postfix notation, e.g.,
-
Evaluation:
- The
mathexpr_eval()
function evaluates the postfix expression using a stack.
- The
-
Result:
- The result is computed by performing the operations in the correct order, yielding the final result.
Mathematical Functions Supported:
- Trigonometric:
cos
,sin
,tan
,cot
,asin
,acos
,atan
,acot
,sinh
,cosh
,tanh
,coth
- Other:
abs
,sgn
,sqrt
,log
,exp
,log10
,step
(for conditional expression), and^
(exponentiation).
Error Handling:
- The code includes error checking for invalid operators, mismatched parentheses, and undefined variables. If an error occurs, the system will set the
Err
flag, preventing further processing and indicating the error.
Summary:
This module provides a powerful way to evaluate complex mathematical expressions in SWMM5. It supports a wide range of mathematical functions and operations, including trigonometric, logarithmic, and arithmetic functions. The expression parsing and evaluation are handled efficiently using a binary tree for parsing and a stack for evaluation, making it suitable for the dynamic nature of SWMM5’s simulation environment.
No comments:
Post a Comment