Quick start

The API is very simple to use. Let's begin from importing ILCalc's namespace:

Imports ILCalc

Context creation

Now we can create new expression context. Note that at this step you should specify the expression type by providing an generic type parameter for the CalcContext class constructor. More info about supported types can be founded here. For this examples the System.Double type was chosen:

Dim calc = new CalcContext(Of Double)("x")
We may specify the expression arguments to the constructor, or do it later, by the context's Arguments property.
For example, you may add another argument named "y":

calc.Arguments.Add("y")
Context is empty after creation, so let's import some built-it and user constants:

' built-in Pi, E, Inf and NaN constants:
calc.Constants.ImportBuiltIn( )

' user constants:
calc.Constants.Add("lambda0", 1.234)
calc.Constants.Add("epsilon", Double.Epsilon)
Now let's import some suitable methods. There are different ways to specify importing methods:

' standard System.Math methods:
calc.Functions.ImportBuiltIn( )

' user methods as delegates:
calc.Functions.Add("Simple", AdressOf Program.SimpleMethod)

' lambda expressions:
Dim val As Double = 1.23
calc.Functions.Add("Magic", Function val) ' even with closure!
calc.Functions.Add("Triple", Function(x) 3 * x)

' all suitable methods from whole class:
calc.Functions.Import(Type.GetType("MyFunctionsClass"))

' public method reflections:
calc.Functions.AddStatic("Some1",
    Type.GetType("SomeClass").GetMethod("SomeStaticMethod"))

' even instance methods with targets:
Dim c = new SomeClass()
calc.Functions.AddInstance("Some2",
    Type.GetType("SomeClass").GetMethod("SomeInstanceMethod"), c)
We can find a lot of Add( ) and Import( ) method overloads in FunctionCollection(Of T) / ConstantDictionary(Of T) classes.
Look for documentation for more detailed information about this methods.

Now it's time to set expression parse culture.
It's affects on parsing the decimal separator and arguments list separator symbols and number literals parsing.
Culture property can be set to null if you don't want to use any culture-sensitive features (defaults is '.' for decimal separator and ',' for arguments list separator).

calc.Culture = CultureInfo.InvariantCulture
Expression context contains some properties for other options.
We can disable the ignore-case mode for the identifiers names, that is used by default:

calc.IgnoreCase = False
Or can ask for performing overflow checks:

calc.OverflowCheck = True
For the next article examples we will use the default values for this two properties.

Evaluation

Let's define simple arithmetical expression and evaluates it in different ways:

Dim expression As String = "4x + 2sin(pi/6) - lambda0"
As we may see, expression may contains a couple of number literals (remember that all of them are threated as literals of Double type that we specify at the context creation step), arithmetical operators (including implicit multiplication), an argument name "x", imported Math.Sin() method with name "sin" and constant "lambda0".

Quick interpreter

This is the best way to use ILCalc when you need to evaluate the specified expression only once:

Dim result As Double = calc.Evaluate(expression, 1.0)  ' = 1.0
Every Evaluate() call executes expression parsing, so this way is not efficient if you need to evaluate the same expression more than once with different argument value.

We should specify expression string and another one parameter, that would be threated as argument "х" value.
Specified parameters count (except expression) should be exactly the same, as the context's Arguments.Count, otherwise we will get an exception here.
Value of arguments should be provided to method in the same order as their names presented in ArgumentCollection class. For example:

calc.Arguments.AddRange("X", "Z", "Lambda")
Dim result As Double = calc.Evaluate(expression, 1, 2, 3)

' expression will receive: X = 1,  Z = 2,  Lambda = 3

Interpret object

This is the best way when you need to evaluate expression more than once with giving some different argument values:

' create object:
Dim interpret = calc.CreateInterpret(expression)

' and separately invokes the evaluation:
Dim result As Double = interpret.Evaluate(4.0)  ' = 13.0
For this and following evaluation ways, we can use expression optimizer.
Optimizer options may be specified by context's Optimization property:

calc.Optimization = _
    OptimizeModes.ConstantFolding Or _
    OptimizeModes.PowOptimize

Evaluator object

This is the best way when you need for best performance during much many times expression evaluation.
Creation and usage looks exactly the same way, as Interpret(Of T) object, but backstage processes are different:

Dim evaluator = calc.CreateEvaluator(expression)

Dim result As Double = eval.Evaluate(3.0)  ' = 9.0
Creation of Evaluator is much slower than creation of Interpret object cause it uses runtime MSIL code generation, but evaluation performance may be more than 10x better. So we should use this way when the best evaluation performance is needed and the startup time is not important.

Tabulator object

This is the best way when you need for extra performance in during expression evaluation with argument(s) in the specified range(s).
Argument range may be represented with ValueRange(Of T) class. Tabulator creation is the same, as Evaluator:

Dim tab = calc.CreateTabulator(expression)

' use it by specify begin, end, step values:
Dim table As Double() = tab.Tabulate(1.0, 5.0, 0.25)  ' = { 1.0, 2.0, 3.0 ... }

' or via TabRange class:
Dim range = new TabRange(Of Double)(1.0, 5.0, 1.0)
range.Count = 100  ' set points count (recalculate step)

table = tab.Tabulate(range)  ' = { 1.0, 1.16, 1.32, 1.48 ... }
Note, that you should specify at least one argument for Tabulator usage. As we can see, usage of Tabulator is nearly the same as the usage of Evaluator, except that argument ranges should be provided instead of argument values.

Validator

If needed to check the expression validity in this context, we can use the context's Validate() method like this:

Try

  calc.Validate("2 / xyz")

Catch err As SyntaxException

  ' TODO: Show error message

  ' we can get some error information here:
  '  err.Position   = 4
  '  err.Length     = 3
  '  err.Substring  = "xyz"
  '  err.Expression = "2 / xyz"

End Try
Expression validation doesn't causes any compilation or evaluation, preforming only validity check.

Note

In the demos above used VB9 type inferring feature (Option Infer), that allows you to estimate many of type annotations.

Last edited Sep 9, 2009 at 11:48 AM by Pelmen64, version 3

Comments

No comments yet.