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:

 

 

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.