在 C# 中组合委托(和积算法)
Combining delegates in C# (Sum-Product Algorithm)
我目前正在为离散变量实施信念传播。
消息是函数。我需要能够使用乘积和求和来组合它们以生成新函数。
我目前有一个使用委托的基本实现,但我想知道是否有更好的方法来处理这个问题。我还担心这将如何使用代表进行扩展。
这是我的实现示例:
public Func<double, double> ProductFunc(List<Func<double, double>> messages)
{
// Construct the product of the message functions
Func<double, double> productFunc = delegate(double x)
{
double productValue = 1.0;
foreach(Func<double, double> message in messages)
{
productValue *= message(x);
}
return productValue;
};
return productFunc;
}
有没有更有效的方法来实现?
您拥有的代码实际上做您想要的吗?
我问,因为规范不是很清楚。您拥有的代码捕获对 List<Func<double, double>>
对象的引用,以及 returns 一个 Func<double, double>
委托,它将在调用委托时按原样 枚举列表(与调用方法时使用的列表相反)。
也许这就是您想要的。它与整个过程中使用的延迟执行一致。 LINQ。但这确实意味着调用者要么打算更改列表将更改返回委托的评估,要么必须非常小心不要更改列表。
如果您想要实现的是捕获调用时存在的数学关系,您可能更希望该方法看起来像这样:
public Func<double, double> ProductFunc(List<Func<double, double>> messages)
{
Func<double, double> productFunc = x => 1.0;
foreach (Func<double, double> message in messages)
{
Func<double, double> currentFunc = productFunc;
productFunc = x => currentFunc(x) * message(x);
}
return productFunc;
}
在我看来,哪种方式都可以。这仅取决于您实际希望代码具有的行为。你的问题中没有足够的上下文让我知道。
I'm also concerned about how this will scale using delegates
它应该可以正常缩放。无论如何,您已经在使用委托。以任何一种方式组合它们都不太可能导致不当的性能问题,并且在任何情况下代码都按原样正确表达。如果您 运行 遇到 特定的 性能问题,导致代码无法满足某些 objective 可衡量的性能目标,那么您可以考虑将代码调整为解决这个问题(并可能在此过程中至少失去一些表现力)。
我目前正在为离散变量实施信念传播。
消息是函数。我需要能够使用乘积和求和来组合它们以生成新函数。
我目前有一个使用委托的基本实现,但我想知道是否有更好的方法来处理这个问题。我还担心这将如何使用代表进行扩展。
这是我的实现示例:
public Func<double, double> ProductFunc(List<Func<double, double>> messages)
{
// Construct the product of the message functions
Func<double, double> productFunc = delegate(double x)
{
double productValue = 1.0;
foreach(Func<double, double> message in messages)
{
productValue *= message(x);
}
return productValue;
};
return productFunc;
}
有没有更有效的方法来实现?
您拥有的代码实际上做您想要的吗?
我问,因为规范不是很清楚。您拥有的代码捕获对 List<Func<double, double>>
对象的引用,以及 returns 一个 Func<double, double>
委托,它将在调用委托时按原样 枚举列表(与调用方法时使用的列表相反)。
也许这就是您想要的。它与整个过程中使用的延迟执行一致。 LINQ。但这确实意味着调用者要么打算更改列表将更改返回委托的评估,要么必须非常小心不要更改列表。
如果您想要实现的是捕获调用时存在的数学关系,您可能更希望该方法看起来像这样:
public Func<double, double> ProductFunc(List<Func<double, double>> messages)
{
Func<double, double> productFunc = x => 1.0;
foreach (Func<double, double> message in messages)
{
Func<double, double> currentFunc = productFunc;
productFunc = x => currentFunc(x) * message(x);
}
return productFunc;
}
在我看来,哪种方式都可以。这仅取决于您实际希望代码具有的行为。你的问题中没有足够的上下文让我知道。
I'm also concerned about how this will scale using delegates
它应该可以正常缩放。无论如何,您已经在使用委托。以任何一种方式组合它们都不太可能导致不当的性能问题,并且在任何情况下代码都按原样正确表达。如果您 运行 遇到 特定的 性能问题,导致代码无法满足某些 objective 可衡量的性能目标,那么您可以考虑将代码调整为解决这个问题(并可能在此过程中至少失去一些表现力)。