Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C语言实现deboor样条算法#_C#_.net_Math_Interpolation_Polynomial Math - Fatal编程技术网

C# 用C语言实现deboor样条算法#

C# 用C语言实现deboor样条算法#,c#,.net,math,interpolation,polynomial-math,C#,.net,Math,Interpolation,Polynomial Math,我知道这是一个有点“请做我的家庭作业”的问题,但我正在尝试实现De Boor算法,如下所述: 我有一个泛型类,它接受任何类型的数组和两个函数,每个点产生一个x和y 当我向GetPoint(x)提供一个非常接近_d中最低x值的x时,我得到了非常不准确的插值 有人能看出我做错了什么吗?非常感谢 我使用的数据是: x y 0.002739726 0.999988548 0.019178082 0.999917365 0.038356164 0.999835128 0.0575342

我知道这是一个有点“请做我的家庭作业”的问题,但我正在尝试实现De Boor算法,如下所述:

我有一个泛型类,它接受任何类型的数组和两个函数,每个点产生一个x和y

当我向GetPoint(x)提供一个非常接近_d中最低x值的x时,我得到了非常不准确的插值

有人能看出我做错了什么吗?非常感谢

我使用的数据是:

x           y
0.002739726 0.999988548
0.019178082 0.999917365
0.038356164 0.999835128
0.057534247 0.999753381
0.082191781 0.999648832
0.167123288 0.999286638
0.249315068 0.998939303
0.334246575 0.998583164
0.419178082 0.998222171
0.495890411 0.997899634
0.747945205 0.99680615
1           0.99559971
1.249315068 0.994187653
1.495890411 0.9926708
1.747945205 0.99066351
2           0.988439344
2.249315068 0.985377424
2.498630137 0.981972695
2.750684932 0.978188863
3.002739726 0.974069647
4.002739726 0.952415995
5.002739726 0.926226504
6.002739726 0.897271422
7.005479452 0.866241091
8.005479452 0.834348616
9.005479452 0.802369725
代码

public class Spline<T>
{
    /// <summary>
    /// Coordinate
    /// </summary>
    private struct TwoDPoint
    {
        public double x;
        public double y;
    };

    /// <summary>
    /// Unused apart from debugging.
    /// </summary>
    private T [] _originalDataPoints;

    /// <summary>
    /// Stores the points we will perform the algorithm on.
    /// </summary>      
    private TwoDPoint [] _d;        
    private int _n; // Value for the "order" used in the De Boor algorithm

    public Spline(T [] dataPoints, Func<T, double> xFunc, Func<T, double> yFunc, int n)
    {           
        SortAndAssignPoints(dataPoints, xFunc, yFunc);
        _n = n;         
    }

    /// <summary>
    /// Populates points in d sorted ascending by their x value
    /// </summary>
    private void SortAndAssignPoints(T [] dataPoints, Func<T, double> xFunc, Func<T, double> yFunc)
    {
        _originalDataPoints = dataPoints;

        _d = dataPoints
            .Select(point => new TwoDPoint()
                        {
                            x = xFunc(point),
                            y = yFunc(point)
                        })
            .OrderBy(point => point.x).ToArray();
    }   

    /// <summary>
    /// Function which gets an interpolated value
    /// </summary>
    public double GetPoint(double x)
    {
        double sum = 0;

        for (int i = 0; i < _d.Length; i++)
        {
            sum += _d[i].y * N_General(_n, i, x);
        }

        return sum;         
    }

    /// <summary>
    /// General N function as given in the algorithm
    /// </summary>
    private double N_General(int n, int i, double x)
    {
        if (n == 0)
        {
            return N_Base(i, x);
        }

        double firstCoefficient;

        if ((i + n) > (_d.Length - 1))
        {
            firstCoefficient = 0D;
        }
        else
        {
            firstCoefficient =
                (x - _d[i].x) / (_d[i + n].x - _d[i].x);                
        }

        double secondCoefficient;

        if ((i + n + 1) > (_d.Length - 1))
        {
            secondCoefficient = 0D;
        }
        else
        {
            secondCoefficient = 
                (_d[i + n + 1].x - x) / (_d[i + n + 1].x - _d[i + 1].x);                
        }


        return firstCoefficient * N_General(n - 1, i, x) +
            secondCoefficient * N_General(n - 1, i + 1, x);
    }       

    /// <summary>
    /// N_i^0 as given in the algorithm
    /// </summary>
    private double N_Base(int i, double x)
    {
        //Bound check
        if (
            (i >= (_d.Length - 1)) ||
            (i < 0)
        )
        {
            return 0;
        }           

        if ((x >= _d[i].x) &&
            (x < _d[i+1].x))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}
公共类样条曲线
{
/// 
///协调
/// 
私有结构双点
{
公共双x;
公共双y;
};
/// 
///除调试外,未使用。
/// 
私人T[]_原始数据点;
/// 
///存储我们将对其执行算法的点。
///       
私人双点[]\u d;
private int _n;//德布尔算法中使用的“顺序”的值
公共样条曲线(T[]数据点,Func xFunc,Func yFunc,int n)
{           
SortAndAssignPoints(数据点、xFunc、yFunc);
_n=n;
}
/// 
///填充按x值升序排列的d中的点
/// 
私有void排序和赋值点(T[]数据点,Func xFunc,Func yFunc)
{
_原始数据点=数据点;
_d=数据点
.Select(点=>newtwodpoint()
{
x=xFunc(点),
y=yFunc(点)
})
.OrderBy(point=>point.x).ToArray();
}   
/// 
///获取插值的函数
/// 
公共双GetPoint(双x)
{
双和=0;
对于(int i=0;i<\u d.Length;i++)
{
求和+=\u d[i].y*N\u一般(\u N,i,x);
}
回报金额;
}
/// 
///算法中给出的一般N函数
/// 
专用双N_常规(整数N,整数i,双x)
{
如果(n==0)
{
返回N_基(i,x);
}
双第一系数;
如果((i+n)>(_d.长度-1))
{
第一系数=0D;
}
其他的
{
第一系数=
(x-d[i].x)/(d[i+n].x-d[i].x);
}
二次系数;
如果((i+n+1)>(d.Length-1))
{
二次系数=0D;
}
其他的
{
第二系数=
(_-d[i+n+1].x-x)/(_-d[i+n+1].x-_-d[i+1].x);
}
返回第一个系数*N_一般(N-1,i,x)+
二次系数*N_一般(N-1,i+1,x);
}       
/// 
///N_i^0,如算法中所示
/// 
专用双N_基(整数i,双x)
{
//装订支票
如果(
(i>=(d.Length-1))||
(i<0)
)
{
返回0;
}           
如果((x>=\u d[i].x)&&
(x<\u d[i+1].x))
{
返回1;
}
其他的
{
返回0;
}
}
}

根据您的代码,看起来您使用了来自_d的y值作为控制点,来自_d的x值作为节点值。请注意,对于B样条曲线,控制点通常不位于曲线本身上。因此,您不应该期望将x值从数据数组传递到GetPoint(x)函数将返回数据数组中相应的y值

此外,对于B样条曲线,应始终遵循“节点数=控制点数+顺序”的规则。您确实不能将_d[i].x用作结,而将_d[i].y用作控制点,因为您将拥有相同数量的结和控制点


最后,我建议您使用Wikipedia链接,而不要使用Wikipedia链接,因为它可以更好地描述De Boor-Cox算法。

我知道,但我正在努力将这个示例映射到我自己的示例中。谢谢你,谢谢你!很抱歉回复太晚-但是谢谢你的链接!