I want to build in my application the possibility of drawing mathematical functions. In the plotting library that I'm using (OxyPlot) there is a great support for that. See this example:
y = ax³ + bx² + cx + d = 0
is being plotted this way:
new FunctionSeries( x => a*x*x*x + b*x*x + c*x + d, /* other stuff, spacing, number of points, etc */ )
Trigonometrical functions are done the same way:
y = sin(3x) + 5cos(x)
is
new FunctionSeries(x => Math.Sin(3*x) + 5*Math.Cos(x) , ....);
I would be very happy if someone could guide me in the conversion between a string (written in a textbox for example) and a call of a method that has inside the syntax shown.
EDIT: the first parameter in the FunctionSeries(a, ....) a is Func<double, double>
EDIT2: Is there a way to say to the compiler, hey, believe me "x => 5*x*x" is a Func, take it literally
something like :
Func<double, double> f = (Func<double, double>)myString;
Here I have a partial solution:
var expresionData = new List<DataPoint>();
Regex pattern = new Regex("[x]");
for (int i = 0; i < 100; i++)
{
string a = pattern.Replace(ExpresionString, i.ToString());
NCalc.Expression exp = new NCalc.Expression(a);
expresionData.Add(new DataPoint(i,Double.Parse(exp.Evaluate().ToString())));
}
I'm doing a little trick here: I transform each 'x' in the typed string to i, then I evaluate the expression and add the point. It's pretty slow. I'm still very interested in the original question:
How to transform a string to Func<double, double> (or just make the compiler take it literally).
Related
I'm trying to find a fit function that has the form:
f(x) = P / (1 + e^((x + m) / s)
Where P is a known constant. I'm fitting this function to a list of measured doubles (between 20-100 elements) and all these values has a corresponding x-value. I'm relatively new to C# and not very in to the maths either so I find it kind of hard to read the documentation available.
I have tried using AlgLib, but don't know where to start or what function to use.
Edit: So to precise what I#m looking for: I'd like to find a C# method where i can pass the functions form, aswell as some coordinates (x- and y-values) and have the method returning the two unknown variables (s and m above).
I use AlgLib daily for exactly this purpose. If you go to the link http://www.alglib.net/docs.php and scroll all the way down, you'll find the documentation with code examples in a number of languages (including C#) that I think will help you immensely: http://www.alglib.net/translator/man/manual.csharp.html
For your problem, you should consider all the constraints you need, but a simple example of obtaining a nonlinear least-squares fit given your input function and data would look something like this:
public SomeReturnObject Optimize(SortedDictionary<double, double> dataToFitTo, double p, double initialGuessM, double initialGuessS)
{
var x = new double[dataToFitTo.Count,1];
for(int i=0; i < dataToFitTo.Count; i++)
{
x[i, 0] = dataToFitTo.Keys.ElementAt(i);
}
var y = dataToFitTo.Values.ToArray();
var c = new[] {initialGuessM, initialGuessS};
int info;
alglib.lsfitstate state;
alglib.lsfitreport rep;
alglib.lsfitcreatef(x, y, c, 0.0001, out state);
alglib.lsfitsetcond(state, epsf, 0, 0);
alglib.lsfitfit(state, MyFunc, null, p);
alglib.lsfitresults(state, out info, out c, out rep);
/* When you get here, the c[] array should have the optimized values
for m and s, so you'll want to handle accordingly depending on your
needs. I'm not sure if you want out parameters for m and s or an
object that has m and s as properties. */
}
private void MyFunc(double[] c, double[] x, ref double func, object obj)
{
var xPt = x[0];
var m = c[0];
var s = c[1];
var P = (double)obj;
func = P / (1 + Math.Exp((xPt + m) / s));
}
Mind you, this is just a quick and dirty example. There is a lot of built-in functionality in Alglib so you'll need to adjust the problem code here to suit your needs with boundary constraints, weighting, step size, variable scaling....etc. It should be clear how to do all that from the examples and documentation in the second link.
Also note that Alglib is very particular about the method signature of MyFunc, so I would avoid moving around those inputs or adding any more.
Alternatively, you can write your own Levenberg-Marquardt algorithm if Alglib doesn't satisfy all your needs.
In C#, I am looking for a way to solve simple equations like this. Z = A + B
I am trying to build a class that would give me the 3rd parameter if I give any of the 2 others.
Example, given Z=A+B
If you know A=3 and B=6 then you know Z=9
If you know A=4 and Z=8 then you know B=4
How would I best perform these kinds of tasks in software?
The other idea is to use math expressions evaluates, like ncalc. They can interpret math expressions, for example convert 3*(8+2) into 30, but not solve equations like 3*(8+x)=30 --> x=2.
Are you sure NCalc wouldn't do what you need? Take a look at an example from http://ncalc.codeplex.com/.
Define parameters, even dynamic or expressions
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());
Please note this is untested - but it looks like you could do something like this with NCalc:
var e = new Expression("[A] + [B]");
e.Parameters = /* your input */
var result = e.Evaluate();
Try out C# Expression Evaluator , See if it matches your requirements.
I am trying to generate a formula which could be anything like this, this is just a sample,
A + B + C > D - A
Now, A, B, C, D, etc are Column Names of a sheet (like excel sheet) i will be accessing in memory.
I need to generate a Rule, like the above A + B + C > D - A which will decide what kind of values user can add in a Cell.
Currently this is how i have begun:
string toValidate = "A + B + C > D + E - A";
string lhs = "", rhs = "";
string[] comparisonOperators = new string[] { "=", ">", "<", "<>", "!=" };
char[] arithmeticOperators = { '+', '-', '/', '*' };
toValidate = toValidate.Replace(#" ", "");
for (int i = 0; i < comparisonOperators.Length; i++)
{
if (toValidate.Contains(comparisonOperators[i]))
{
operatorIndex = toValidate.IndexOf(comparisonOperators[i]);
break;
}
}
lhs = toValidate.Substring(0, operatorIndex);
rhs = toValidate.Substring(operatorIndex + 1);
string[] columnLhsList = lhs.Split(arithmeticOperators);
string[] columnRhsList = rhs.Split(arithmeticOperators);
However even though i have the strings as lhs and rhs and even my operator which > in the above code, i am not able to understand how can i apply the formula on the sheet itself. I just need to know which Column has which operator associated.
Since i have the individual column names, but not the operator before them, for e.g,
+ before A - before A in another case.
How do i parse the above please help.
It is, however, a very fun question if you want to make simple formula parsers like this yourself.
I advice you to check out this article, since it is very clearly written and understandable because of it.
Shunting-yard Algorithm
Personally, I would never try/dare to create my own formula expression parser. Instead, I would (and did) use one of the may available ones, e.g. NCalc over at CodePlex.com.
Using these tools, it is as easy as writing
Expression e = new Expression("2 + 3 * 5");
Debug.Assert(17 == e.Evaluate());
to get your formula evaluated.
Usually such libraries are very solid, well tested and have a rich function set. It would take ages (if ever) to do such a high quality library on my own.
To further cite the NCalc website, you can even use variables like e.g.:
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());
Looking at the string class metadata, I only see the operators == and != overloaded. So how is it able to perform concatenation for the '+' operator?
Edit:
Some interesting notes from Eric Lippert on string concatenation:
Part 1
Part 2
There is also a super article from Joel referred in part 2 (http://www.joelonsoftware.com/articles/fog0000000319.html)
It doesn't - the C# compiler does :)
So this code:
string x = "hello";
string y = "there";
string z = "chaps";
string all = x + y + z;
actually gets compiled as:
string x = "hello";
string y = "there";
string z = "chaps";
string all = string.Concat(x, y, z);
(Gah - intervening edit removed other bits accidentally.)
The benefit of the C# compiler noticing that there are multiple string concatenations here is that you don't end up creating an intermediate string of x + y which then needs to be copied again as part of the concatenation of (x + y) and z. Instead, we get it all done in one go.
EDIT: Note that the compiler can't do anything if you concatenate in a loop. For example, this code:
string x = "";
foreach (string y in strings)
{
x += y;
}
just ends up as equivalent to:
string x = "";
foreach (string y in strings)
{
x = string.Concat(x, y);
}
... so this does generate a lot of garbage, and it's why you should use a StringBuilder for such cases. I have an article going into more details about the two which will hopefully answer further questions.
I was playing around with a code golf question yesterday for building a christmas tree which came around last year and I threw together a quick recursive algorithm to do the job:
static string f(int n, int r)
{
return "\n".PadLeft(2 * r, '*').PadLeft(n + r)
+ (r < n ? f(n, ++r) : "*".PadLeft(n));
}
I got to wondering if I could do the same thing with a Func:
Func<int,int,string> f = (n, r) => {
return "\n".PadLeft(2 * r, '*').PadLeft(n + r)
+ (r < n ? f(n, ++r) : "*".PadLeft(n));
};
This would do the job except that the recursive part doesn't recognize that the call to f is actually a call to itself. This would lead me to conclude that a Func can't call itself recursively - but I wonder if I'm drawing false conclusions or if it can be done but requires a different approach.
Any ideas?
Func<int, int, string> f = null;
f = (x, y) => f(x, y);
Obviously this will cause a StackOverflowException, but you get the idea.
See this for a very geeky coverage of recursive lambdas, fixed points, Y-combinators, etc. Very interesting read.