我正在尝试在c#中实现B-Splines的递归定义,但我无法做到正确。这就是我所做的:
public static Double RecursiveBSpline(int i, Double[] t, int order, Double x)
{
Double result = 0;
if (order == 0)
{
if (t[i] <= x && x < t[i + 1])
{
result = 1;
}
else
{
result = 0;
}
}
else
{
Double denom1, denom2, num1, num2;
denom1 = t[i + order + 1] - t[i + 1];
denom2 = t[i + order] - t[i];
if (denom1 == 0)
{
num1 = 0;
}
else
{
num1 = t[i + order + 1] - x / denom1;
}
if (denom2 == 0)
{
num2 = 0;
}
else
{
num2 = x - t[i] / denom2;
}
result = num1 * RecursiveBSpline(i + 1, t, order - 1, x)
+ num2 * RecursiveBSpline(i, t, order - 1, x);
}
return result;
}
以下是我如何调用该函数:
Double[] vect = new Double[] { 0, 1, 2, 3 };
MessageBox.Show(BSpline.RecursiveBSpline(0,vect,2,0.5).ToString());
我应该在屏幕上看到0,125,而不是0,25。两个分母变量用于检查它们是否等于0,如果是,则根据定义将该数字设置为0。有人能指出我弄错了吗?
答案 0 :(得分:1)
请记住,数学和逻辑operators in C# have a precedence order。如果你把正确的术语放在括号中,你的第二个解决方案可以正常工作(下面的解释)。这一行:
num2 = x - t[i] / denom2;
应更改为:
num2 = (x - t[i]) / denom2;
等等。然后根据需要得到结果:0.125
除法运算符具有比加法运算符更高的顺序优先级。要影响执行顺序,请使用大括号(首先评估大括号中的所有内容):
var r1 = 2 + 2 / 2; // Step1: 2 / 2 = 1 Step2: 2 + 1 Output: 3
var r2 = (2 + 2) / 2; // Step1: (2 + 2) = 4 Step2: 4 / 2 = 2 Output: 2