Mega Code Archive

 
Categories / Delphi / Algorithm Math
 

TMathParser

Title: TMathParser Question: 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. Answer: There is a new version of parser for Delphi 7 here, this is also available for Delphi 5 here; and it is possible to download it for Delphi 6 here. It implements additional features, including support of function with unlimited parameters. As usual it is easy to use it 1) Place TMathParser component and some interface controls on the form: 2) Use it: 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 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 cant 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 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 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 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 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 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