Is there any calculation engine for C# that can automatically recalculate dependent fields when a value changes?
Let me freestyle for a second, I'm imagining something like this..
Field<double> quantity = Field.Create<double>("Quantity");
Field<double> unitCost = Field.Create<double>("Unit Cost");
Field<double> total = Field.Create<double>("Total");
total.Calculation((q,uc) => q * uc, quantity, value);
// would have signature something like this:
// void Calculation<TR,T1,T1>(Func<TR,T1,T2>, Field<T1>, Field<T2>)
This would set up fields that auto-propagate dependent values.
quantity.Value = 5.0;
unitCost.Value = 1.5;
Assert.That(total.Value, Is.EqualTo(7.5));
Obviously this is a simple example, the end uses would be much more akin to the calculations of a complex spreadsheet.
Thinking further it would be amazing if the field/cells would support change notification.
Have you seen http://ncalc.codeplex.com ?
It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:
Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi");
e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());
It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.
It also supports logical operators, date/time's strings and if statements.
a solution
You could possibly do automatic recalculation by implementing INotifyPropertyChanged then doing something like
On notifypropertyupdated in the class
There are calculation engines for scalar parameters, and there are higher-level calculation engines for tables, typically used for applications like financial planning, fee and commission calculations, network and contract computations...
Let me explain this shortly. Consider following formulas for scalars:
1) z = f1(x,y)
2) p = f2(z,n)
3) q = f3(x,p)
...
and so on. Configuring such functions and dependency trees requires a calculation engine with scalar parameters. I would (also) recommend following link for such a calculation engine written in c# as a good starting point: http://www.codeproject.com/Articles/246374/A-Calculation-Engine-for-NET
As mentioned, there are also calculation engines with table functions that take tables as parameters. The main principle is but the same:
1) (T4, T5) = TableFunction1(T1, T2, T3)
2) (T7, T8) = TableFunction2(T2, T4)
...
and so on. Note that a table function can return multiple tables as outputs, as shown above.
There two key issues to be observed here:
a) The values of tables T7 and T8 depend on tables T2 and T4. Therefore, the tables T7 and T8 need to be updated by executing the function "TableFunction2" only if there is a change in one of the input parameters T2 or T4.
Similarly, T4 need to be updated only if T1, T2 or T3 is updated; dependency tree!
b) Separation of database from the calculation process: The calculation engine must work independent of any fixed data structure or database schema so that it can be integrated with any database and data structure.
You can find my related article where these principles are explained at:
Logical Architecture of a Rule-Based Calculation Framework http://finaquant.com/logical-architecture-of-a-rule-based-calculation-framework/1053
Now, a C#/.NET library for a calculation engine with tables as input and output parameters is being developed based on these principles.
Note to moderators: Please delete the link above if it is counted as self-promotion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With