TMathParser
Contents
Review
There is a new
version of parser available (download).
The component is
intended for mathematics calculations. It contains standard set of mathematics
functions, such as sin or sqrt. It also contains standard set of types, such as
byte or word which are used for specifying the functions. It is possible to
create your own functions and types. The parser works with the high speed -
about ten million operations per second for simple mathematics formulas. It
creates binary representation of formula (script) and makes all the following
calculations by the script. There are no limitations for the formula; it could
have any length and any amount of embedded formulas. Embedded formula is
expression that is located between brackets and has increased calculation
priority. The parser implements many features, including methods for
simplifying the formula and support of function with unlimited parameters.
It implements
additional features, including support of function with unlimited parameters.
As usual it is
easy to use –
1) Place TMathParser
component and some interface controls on the form:

2) Use it:

3) Expression is
mathematics formula which can be constructed using the elements:
- +: operand, executes adding operation
- -: operand, executes subtraction operation
- *: function, executes multiplying operation
- /: function, executes division operation
- Sqrt: functions, root of a number. Root can have any degree
- Div: functions, executes integer division
operation
- Mod: functions, executes remainder operation
- Int: function, returns the integer part of
a number
- Frac: function, returns the fractional part
of a number
- Random: function, returns random number
within the range 0 <= value < 1
- Trunc: function, truncates a number to an
integer
- Round: function, returns the value rounded
to the nearest whole number
- Sin: function, returns the sine of the
angle in radians
- ArcSin: function, returns the inverse sine of
a number
- Sinh: function, returns the hyperbolic sine
of an angle
- ArcSinh: function, returns the inverse
hyperbolic sine of a number
- Cos: function, returns the cosine of the
angle in radians
- ArcCos: function, returns the inverse cosine
of a number
- Cosh: function, returns the hyperbolic
cosine of an angle
- ArcCosh: function, returns the inverse
hyperbolic cosine of a number
- Tan: function, returns the tangent of the
angle
- ArcTan: function, returns the arctangent of a
number
- Tanh: function, returns the hyperbolic
tangent of an angle
- ArcTanh: function, the inverse hyperbolic
tangent of a number
- CoTan: function, returns the cotangent of
the angle
- ArcCoTan: function, returns the inverse
cotangent of a number
- CoTanh: function, returns the hyperbolic
cotangent of an angle
- ArcCoTanh: function, the inverse hyperbolic
cotangent of a number
- Sec: function, returns the secant of an
angle
- ArcSec: function, returns the inverse secant
of a number
- Sech: function, returns the hyperbolic
secant of an angle
- ArcSech: function, returns the inverse
hyperbolic secant of a number
- Csc: function, returns the cosecant of an
angle
- ArcCsc: function, returns the inverse
cosecant of a number
- Csch: function, returns the hyperbolic
cosecant of an angle
- ArcCsch: function, returns the inverse
hyperbolic secant of a number
- Abs: function, returns an absolute value
- Ln: function, returns the natural log of
an expression
- Lg: function, returns log base 10
- Log: function, returns the log of
expression for a specified base
- Pi: function, returns 3.1415926535897932385
- Exp: function, returns the exponential of
an expression
- !: function, returns factorial of an
expression
- ^: function, raises expression to any
power
- ArcTan2
[Y, X: Double] function,
calculates ArcTan(Y/X), and returns an angle in the correct
quadrant. The values of X and Y must be between –2^64 and 2^64.
Inaddition, the value of X can’t be 0. The return value will fall in
the range from -Pi to Pi radians.
- Hypot
[X, Y: Double] function,
returns the length of the hypotenuse of a right triangle. Specify the
lengths of the sides adjacent to the right angle in X and Y. Hypot usesthe
formula Sqrt(X**2 + Y**2)
- RadToDeg
function, converts radians
to degrees
- RadToGrad
function, converts radians
to grads
- RadToCycle
function, converts radians
to cycles
- DegToRad
function, returns the
value of a degree measurement expressed in radians
- DegToGrad function, returns the value of a
degree measurement expressed in grads
- DegToCycle function, returns the value of a
degree measurement expressed in cycles
- GradToRad function, converts grad measurements
to radians
- GradToDeg function, converts grad measurements
to degrees
- GradToCycle function, converts grad measurements
to cycles
- CycleToRad function, converts an angle
measurement from cycles to radians
- CycleToDeg function, converts an angle
measurement from cycles to degrees
- CycleToGrad function, converts an angle
measurement from cycles to grads.
- LnXP1 function, returns the natural log of
(X+1)
- Log10 function, calculates log base 10
- Log2 function, calculates log base 2
- IntPower [Base:
Double; Exponent: Integer] function, calculates the integral power
of a base value
- Power [Base:
Double; Exponent: Double] function, Raises Base to any power
- Ldexp
[X: Double; P: Double]
function, calculates X times (2 to the power of P)
- Ceil function, rounds variables up toward
positive infinity
- Floor function, rounds variables toward
negative infinity
- Poly
[X: Double; Coefficients(1)..Coefficients(N): Double] function, evaluates a uniform
polynomial of one variable at the value X
- Mean
[Data(1)..Data(N): Double]
function, returns the average of all values in an array
- Sum
[Data(1)..Data(N): Double]
function, returns the sum of the elements in an array
- SumInt
[Data(1)..Data(N): Integer]
function, returns the sum of the elements in an integer array
- SumOfSquares [Data(1)..Data(N):
Double] function, returns the sum of the squared values from a data
array
- MinValue [Data(1)..Data(N):
Double] function, returns smallest signed value in an array
- MinIntValue [Data(1)..Data(N):
Integer] function, returns the smallest signed value in an integer
array
- Min
[A,B: Double] function,
returns the lesser of two numeric values
- MaxValue [Data(1)..Data(N):
Double] function, returns the largest signed value in an array
- MaxIntValue [Data(1)..Data(N):
Integer] function, returns the largest signed value in an integer
array
- Max
[A,B: Double] function,
returns the greater of two numeric values
- StdDev [Data(1)..Data(N):
Double] function, returns the sample standard deviation for
elements in an array
- PopnStdDev [Data(1)..Data(N):
Double] function, calculates the population standard deviation
- Variance [Data(1)..Data(N):
Double] function, calculates statistical sample variance from an
array of data
- PopnVariance [Data(1)..Data(N):
Double] function, calculates the population variance
- TotalVariance [Data(1)..Data(N):
Double] function, returns the statistical variance from an array of
values
- Norm [Data(1)..Data(N):
Double] function, returns the Euclidean 'L-2' norm
- RandG [Mean,
StdDev: Double] function, generates random numbers with Gaussian
distribution
- RandomRange [AFrom, ATo:
Integer] function, returns a random integer from a specified range
- RandomFrom [Value(1)..Value(N):
Double] function, returns a randomly selected element from an array
- EnsureRange
[AValue, AMin, AMax: Double]
function, returns the closest value to a specified value within a
specified range
Download
sample
Optimization
Some mathematic
expressions can be optimized. Optimization is simplifying of mathematic
expression (if possible) at binary level; the result is an increase in
evaluation speed. You need to call just one function to optimize the
expression:

The optimal script
represents a simple number. If OptimizeScript function called and OptimalScript
function returns false, this does not mean the script is not changed. Probably
many parts of the script become optimal in contrast to the whole script. As it
is shown above, function random makes full optimization impossible.
Download
sample
Creating the function
It is easy to
create your own function. To do this you need first to declare procedure of
TFunctionEvent type in your application.
TFunctionEvent = procedure(FunctionIndex:
Integer; TypeIndex: Integer;
out Value:
Double; LValue, RValue: Double; Parameters: TParameters;
var
Done: Boolean) of object;
Procedure of this
type calls each time it is necessary to execute any function.
Then you register
your function by method:
procedure RegisterFunction(var Index:
Integer; const AName: string;
ARequireValue1, ARequireValue2, AOptimizable: Boolean;
AParameterCount: Integer); virtual;

procedure RegisterFunction(var Index:
Integer; const AName: string;
ARequireValue1, ARequireValue2, AOptimizable: Boolean;
AParameterCount: Integer); virtual;
If
RegisterFunction succeeded then FunctionIndex is the index of the function;
otherwise FunctionIndex is set to -1. AName is a new function name.
ARequireValue1, ARequireValue2 parameters specify whether or not the new
function needs expressions before or after itself. For example, the standard
function * (multiplying) needs both parameters (2 * 3, where 2 and 3 are in a
role of expression); and function Sqrt needs the parameter only after itself.
Function Pi does not need any parameters, it returns 3.1415926535897932385.
AOptimizable parameter specifies whether it is possible to optimize the
function. For example, it is possible to optimize standard function Cos; but
you cannot optimize function Random because it returns different values each
time it is called.
If AParameterCount
parameter is more than zero, then the function needs AParameterCount parameters
after itself, which are enclosed in square braces. This also means that the
function is of new type and cannot require parameters before or after itself,
unlike standard function does. Any of the parameters in square braces can be either
a string variable or mathematic expression; in case if it is a mathematic
expression, it participates in optimization process too.
procedure CustomFunction(FunctionIndex: Integer;
TypeIndex: Integer;
out Value:
Double; LValue, RValue: Double; Parameters: TParameters;
var
Done: Boolean);
This procedure is
called each time it is necessary to execute any function. Using it allows you to
overwrite the standard functions behavior as well. FunctionIndex is the index
of the function, TypeIndex is the index of the type (we will see later how to
use types). The result of execution must be placed in Value parameter. As it
was mentioned before, the function may require the expression either after or
before itself. Results of these expressions are stored in LValue (expression
before current function) and RValue (expression after current function)
parameters. Parameters are an array of TParameter values:
TParameter = record
TypeIndex:
Integer;
case
Byte of
0: (Value: Double);
1: (S: ShortString);
end;
TParameters = array
of TParameter;
This record
contains the value of the parameter and its type.
As a default Done
parameter is False. If procedure handles the current function, it must set Done
parameter to true.
Download sample
Non-standard function with
parameters
The next example
shows how to use non-standard function with parameters:

This sample
implements two Delphi functions: StrToInt which
converts a string that represents an integer and Power
(please note that Power function is already
included in standard functions set and its behavior is changed in the sample;
in such a manner it is possible to overwrite the behavior of any function)
which raises a number to any power. You can see their description in Delphi help. Both functions need parameters. First function needs one string parameter and
the second one needs two numeric parameters.
Download sample
Types
Parser lets you
use types. The sample below shows how to work with them:

As it is shown
above you can specify a type within a number of parameters of non-standard
function. You can also specify type for every standard function.
Download sample
Building the graphs
And finally the
old colorful sample which allows building the graphs:
1)

2)

3)

4)

5)

6)

7)

8)

9)

10)

11)

12)
Download sample
Downloads
These downloads below are for Delphi 7. There is a
package with components and samples for Delphi 5 here; the same package for Delphi 6 is here.