Dynamically generate a function expression (C #)
I mentioned in an article "draw a C # program of function graphics and a pathological function:
The C # program of this function graph has a serious drawback, that is, the function expression is directly written in the source program and cannot be input interactively like SciLab and Matlab. I don't know if the System. Reflection. Emit. ILGenerator class can dynamically generate the function expression entered by the user? "Space/IV" points out in the comment below:
To dynamically generate the function expression entered by the user, it may be helpful to see the following post:
Http://community.csdn.net/Expert/topic/4169/4169185.xml After research, I wrote a class Expression that dynamically generates the function Expression you entered. The Expression uses the C # syntax and can contain an independent variable (x ), the Independent Variables and values are of the "double" type. The following is the running result of the test program:
C> ExpressionTest
Usage: ExpressionTest expression [parameters...]
C> ExpressionTest Math. PI * Math. E 0
F (x): Math. PI * Math. E
F (0) = 8.53973422267357
C> ExpressionTest Math. Pow (2, x) 0 10 49 50 1024-1-1024
F (x): Math. Pow (2, x)
F (0) = 1
F (10) = 1024
F (49) = 562949953421312
F (50) = 1.12589990682132e + 15
F (1024) = positive infinity
F (-1) = 0.5
F (-1024) = 5.562684646268E-309
C> ExpressionTest double u = Math. PI-x; double pi2 = Math. PI * Math. PI; return 3 * x + Math. log (u * u)/pi2/pi2 + 1; 3.13 3.14 3.15 3.16
F (x): double u = Math. PI-x; double pi2 = Math. PI * Math. PI; return 3 * x + Math. log (u * u)/pi2/pi2 + 1;
F (3.13) = 30.2991811562164
F (3.14) = 30.44652582187
F (3.15) = 30.6693849404716
F (3.16) = 30.8747746902426
F (3.1416) = 30.3662371931734
The last example is the calculation result of the following functions:
In fact, this pathological function is mentioned in Chapter 3 "inner method and external Method" in C numerical algorithm (version 2:
---------------------------------------------------------------------------
It is easy to construct some pathological functions to make the internal Insertion Method fail. For example, consider the Function
F (x) = 3 * x2 + π-4 * ln [(π-x) 2] + 1
It is defined in addition to x = π, but not in x = π. In other cases, values are positive and negative. This function will certainly get an incorrect solution at x = 3.13 In any interpolation method based on values x = 3.14, 3.15, 3.16, and 3.1416, although the curves drawn from these five points are indeed quite smooth! (Use a calculator .)
---------------------------------------------------------------------------
It can be seen that, in any interpolation method based on values x = 3.13, 3.14, 3.15, and 3.16, the solution obtained at x = 3.1416 must be between 30.44652582187 and 30.6693849404716, however, the actual solution should be 30.3662371931734, so the author asserted that there would certainly be a wrong solution.
The following is the source program:
// ExpressionTest. cs-a test program that dynamically generates a mathematical expression and calculates its value
// Compilation method: csc ExpressionTest. cs Expression. cs
Using System;
Using Skyiv. Util;
Namespace Skyiv. Test
{
Class ExpressionTest
{
Static void Main (string [] args)
{
Try
{
If (args. Length> 0)
{
Console. WriteLine (f (x): {0}, args [0]);
Expression expression = new Expression (args [0]);
For (int I = 1; I <args. Length; I ++)
{
Double x = double. Parse (args [I]);
Console. WriteLine (f ({0}) = {1}, x, expression. Compute (x ));
}
}
Else Console. WriteLine (Usage: ExpressionTest expression [parameters]);
}
Catch (Exception ex)
{
Console. WriteLine (error: + ex. Message );
}
}
}
}
// Expression. cs-dynamically generate a mathematical Expression and calculate its value
// The expression uses the C # syntax and can contain an independent variable (x ).
// The Independent Variables and values of the expression are of the (double) type.
// Example:
// Expression expression = new Expression (Math. Sin (x ));
// Console. WriteLine (expression. Compute (Math. PI/2 ));
// Expression = new Expression (double u = Math. PI-x; +
// Double pi2 = Math. PI * Math. PI; +
// Return 3 * x + Math. Log (u * u)/pi2/pi2 + 1 ;);
// Console. WriteLine (expression. Compute (0 ));
Using System;
Using System. CodeDom. Compiler;
Using Microsoft. CSharp;
Using System. Reflection;
Using System. Text;
Namespace Skyiv. Util
{
Sealed class Expression
{
Object instance;
MethodInfo method;
Public Expression (string expression)
{
If (expression. IndexOf (return) <0) expression = return + expression + ;;
String className = Expression;
String methodName = Compute;
CompilerParameters p = new CompilerParameters ();
P. GenerateInMemory = true;
CompilerResults cr = new CSharpCodeProvider (). CompileAssemblyFromSource (p, string.
Format (using System; sealed class {0 }{{ public double {1} (double x) {{{ 2 }}}}},
ClassName, methodName, expression ));
If (cr. Errors. Count> 0)
{
String msg = Expression (+ expression + ):;
Foreach (CompilerError err in cr. Errors) msg + = err. ToString () +;
Throw new Exception (msg );
}
Instance = cr. CompiledAssembly. CreateInstance (className );
Method = instance. GetType (). GetMethod (methodName );
}
Public double Compute (double x)
{
Return (double) method. Invoke (instance, new object [] {x });
}
}
}
To the CSDN Forum,
LoveCherry! ^_^)"Thanks, my program developed on the basis of his program.