Sam said:
Say I have an equation x = x^2+5, it is an expression dynamically
input by the user in the form of a string, i want to get the value of
x as a result.
Are there any package accepting input of equations in strings and
output the result in double?
You can use runtime compilation to get the function evaluation
and regular Newtons method to find root.
See code below for a simple example to get you started.
Arne
=================================
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace E
{
public interface IFuncEval
{
double Eval(double x);
}
public class FuncEvalFactory
{
private static int n = 0;
private static Dictionary<string,IFuncEval> m = new
Dictionary<string,IFuncEval>();
public static IFuncEval Create(string expr)
{
IFuncEval o = null;
if(m.ContainsKey(expr))
{
o = m[expr];
}
else
{
n++;
string cn = "FuncEval_" + n;
string src = "using System;" +
"using E;" +
"" +
"public class " + cn + " : IFuncEval" +
"{" +
" public double Eval(double x)" +
" {" +
" return " + expr + ";" +
" }" +
"}";
//Console.WriteLine(src);
CodeDomProvider comp = new CSharpCodeProvider();
CompilerParameters param = new CompilerParameters();
param.GenerateInMemory = true;
param.ReferencedAssemblies.Add("System.dll");
param.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
CompilerResults res =
comp.CompileAssemblyFromSource(param, src);
//foreach(CompilerError ce in res.Errors)
//{
// Console.WriteLine(ce.ToString());
//}
Assembly asm = res.CompiledAssembly;
o = (IFuncEval)asm.CreateInstance(cn);
m.Add(expr, o);
}
return o;
}
}
public class Solver
{
private const double SMALL = 0.0000000001;
private static double Deriv(IFuncEval f, double x)
{
return (f.Eval(x + SMALL/2) - f.Eval(x - SMALL/2)) / SMALL;
}
public static double FindRoot(string expr)
{
IFuncEval f = FuncEvalFactory.Create(expr);
double res = 1;
double oldres;
do
{
oldres = res;
res = res - f.Eval(res)/Deriv(f, res);
}
while(Math.Abs(res - oldres) > SMALL);
return res;
}
}
public class MainClass
{
public static void Main(string[] args)
{
Console.WriteLine(Solver.FindRoot("Math.Pow(x, 2) + x - 3"));
Console.WriteLine(Solver.FindRoot("Math.Pow(x, 5) - x + 5"));
}
}
}