High-speed mathematics parser

By: Yura Pisarev

Abstract: The component is intended for mathematics calculations

TMathParser


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.

(Note: Download TMathParser from http://www.myart.bz/pisarev/)

As usual it is easy to use �

1) Place TMathParser component and some interface controls on the form:

Hide image

2) Use it:

Hide image
Click to see full-sized image

3) Expression is mathematic 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

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:

Hide image
Click to see full-sized image

Hide image

Hide image

Hide image

Hide image

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.


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;

Hide image
Click to see full-sized image

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.

The next example shows how to use non-standard function with parameters:

Hide image
Click to see full-sized image

Hide image

Hide image

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.


Parser lets you use types. The sample below shows how to work with them:

Hide image
Click to see full-sized image

Hide image

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.


And finally the colorful sample which allows building the graphs:

Hide image


Server Response from: ETNASC03