加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用表达式树构建Func多项式

发布时间:2020-12-15 19:26:39 所属栏目:百科 来源:网络整理
导读:TL; DR 如何使用系数数组构建表达式并将其转换为Func int,double?有比表达树更好的方法吗? 我有一个不可变的序列类型,使用Func int,double构造用于为序列A生成术语An的公式.我开始构建一个辅助类,用一些简单的参数构造常见的数学公式: public static Sequ
TL; DR

如何使用系数数组构建表达式并将其转换为Func< int,double>?有比表达树更好的方法吗?

我有一个不可变的序列类型,使用Func< int,double>构造用于为序列A生成术语An的公式.我开始构建一个辅助类,用一些简单的参数构造常见的数学公式:

public static Sequence CreateLinearSequence (double m,double b)
{ return new Sequence (n => m * n + b); }

我为常量序列,对数和简单多项式(线性,二次,三次和四次)构建了标准方法,但我想使用params关键字扩展它以支持任意数量的项.

这是我的方法:

public static Sequence CreatePolynomialSequence (params double[] coeff)
 {
     Expression<Func<int,double>> e = x => 0;
     double pow = 0;

     for (int i = coeff.Length - 1; i >= 0; i--)
     {
         double c = coeff[i];
         var p = Expression.Parameter (typeof (int),"x");
         e = Expression.Lambda<Func<int,double>> (
             Expression.Add (
                 e,(Expression<Func<int,double>>)(x => c * Math.Pow (x,pow))
             ),p);
         pow++; 
     }
     return new Sequence (e.Compile ());
 }

对你们这些人来说,我做错了可能是显而易见的;我搞砸了一下,直到我得到了一些我觉得应该工作的东西,但事实并非如此.

目标是使序列像这样工作一个数组double [] coeff = {a,b,c,d,e,f,g,h}

x => h gx fx ^ 2 ex ^ 3 dx ^ 4 cx ^ 5 bx ^ 6 ax ^ 7使用适当的Math.Pow(x,exponent)调用.

运行

var s2 = SequenceHelper.CreatePolynomialSequence (new[] { 1d,2 });
Console.WriteLine ("s2: " + s2);

结果是

Unhandled Exception: System.InvalidOperationException: The binary
operator Add is not defined for the types
‘System.Func2[System.Int32,System.Double]' and
'System.Func
2[System.Int32,System.Double]’. at
System.Linq.Expressions.Expression.GetUserDefinedBinaryOperatorOrThrow
(ExpressionType binaryType,System.String name,
System.Linq.Expressions.Expression left,
System.Linq.Expressions.Expression right,Boolean liftToNull)
[0x0004a] in
/private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Ast/BinaryExpression.cs:658
at System.Linq.Expressions.Expression.Add
(System.Linq.Expressions.Expression left,System.Reflection.MethodInfo
method) [0x00057] in
/private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Ast/BinaryExpression.cs:1409
at System.Linq.Expressions.Expression.Add
(System.Linq.Expressions.Expression left,
System.Linq.Expressions.Expression right) [0x00000] in
/private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Ast/BinaryExpression.cs:1390
at Sequence.SequenceHelper.CreatePolynomialSequence (System.Double[]
coeff) [0x00110] in
/Users/Knoble/MonoProjects/Sequences/Sequence/SequenceHelper.cs:88
at Sequence.Test.Main () [0x0001f] in
/Users/Knoble/MonoProjects/Sequences/Sequence/Test.cs:53 [ERROR]
FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: The
binary operator Add is not defined for the types
‘System.Func2[System.Int32,
System.Linq.Expressions.Expression right) [0x00000] in
/private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Ast/BinaryExpression.cs:1390
at Sequence.SequenceHelper.CreatePolynomialSequence (System.Double[]
coeff) [0x00110] in
/Users/Knoble/MonoProjects/Sequences/Sequence/SequenceHelper.cs:88
at Sequence.Test.Main () [0x0001f] in
/Users/Knoble/MonoProjects/Sequences/Sequence/Test.cs:53 The
application was terminated by a signal: SIGHUP

解决方法

我对问题和所有三个答案感到困惑;如果您打算将它们编译成委托,那么为什么要搞乱表达式树呢?直接返回代表!

public static Func<double,double> CreatePolynomialFunction (params double[] coeff)
{
    if (coeff == null) throw new ArgumentNullException("coeff");
    return x => 
    {
        double sum = 0.0;
        double xPower = 1;
        for (int power = 0; power < coeff.Length; power += 1)
        {
            sum += xPower * coeff[power];
            xPower *= x;
        }
        return sum;
    };
}

完成.不要乱用表达树.

(我注意到我假设数组中的第n个项目是第n个系数;显然你在数组中向后列出你的系数.这似乎容易出错,但是如果这就是你想要的那么那么修改这个答案并不困难将循环从Length-1运行到零.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读