C#线性插值 [英] C# Linear Interpolation

查看:375
本文介绍了C#线性插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有插一个数据文件,我从.CSV转换成一个X数组和Y数组,其中X [0]对应点Y例如,[0]的问题。

I'm having issues interpolating a data file, which i have converted from .csv into an X array and Y array where X[0] corresponds to point Y[0] for example.

我需要的值之间进行插补给我在最后一个光滑的文件。
我使用的PicoScope输出,这意味着每行的功能在时间间隔相等,所以只能采用Y值,这就是为什么我试图做到这一点的时候,你看到我的代码一种奇怪的方式。

I need to interpolate between the values to give me a smooth file at the end. I am using a Picoscope to output the function which means each line is equally spaced in time, so only using Y values, which is why I'm trying to do this in a strange way when you see my code.

该类型的值它处理为:

X     Y
0     0
2.5   0
2.5   12000
7.5   12000
7.5   3000
10    3000
10    6000
11    6625.254
12    7095.154

那么,2 Y值彼此相邻是相同的之间的直线他们,但是当他们从X = 10病房变化就像它成为在这个例子中正弦波。

So where 2 Y values next to each other are the same its a straight line between them but when they vary like from X = 10 on wards it becomes a sine wave in this example.

我一直在寻找的公式进行插值等和其他职位上在这里,但我没有做过那种数学多年,遗憾的是我不能弄明白任何更多,因为有2个未知数,我怎么也想不到能编写成C#。

I have been looking at the equations for interpolation etc and other posts on here but i haven't done that sort of maths for years and sadly i can't figure it out any more, because there's 2 unknowns and i can't think how to program that into c#.

我是什么:

int a = 0, d = 0, q = 0;
bool up = false;
double times = 0, change = 0, points = 0, pointchange = 0; 
double[] newy = new double[8192];
while (a < sizeoffile-1 && d < 8192)
{
    Console.Write("...");
    if (Y[a] == Y[a+1])//if the 2 values are the same add correct number of lines in to make it last the correct time
    {
        times = (X[a] - X[a + 1]);//number of repetitions
        if ((X[a + 1] - X[a]) > times)//if that was a negative number try the other way around
            times = (X[a + 1] - X[a]);//number of repetitions 
        do
        {
            newy[d] = Y[a];//add the values to the newy array which replaces y later on in the program
            d++;//increment newy position
            q++;//reduce number of reps in this loop
        }
        while (q < times + 1 && d < 8192);
        q = 0;//reset reps
    }
    else if (Y[a] != Y[a + 1])//if the 2 values are not the same interpolate between them
    {
        change = (Y[a] - Y[a + 1]);//work out difference between the values
        up = true;//the waveform is increasing
        if ((Y[a + 1] - Y[a]) > change)//if that number was a negative try the other way around
        {
            change = (Y[a + 1] - Y[a]);//work out difference bwteen values
            up = false;//the waveform is decreasing
        }
        points = (X[a] - X[a + 1]);//work out amount of time between given points
        if ((X[a + 1] - X[a]) > points)//if that was a negative try other way around
            points = (X[a + 1] - X[a]);///work out amount of time between given points
        pointchange = (change / points);//calculate the amount per point in time the value changes by
        if (points > 1)//any lower and the values cause errors
        {
            newy[d] = Y[a];//load first point
            d++;
            do
            {
                if (up == true)//
                    newy[d] = ((newy[d - 1]) + pointchange);
                else if (up == false)
                    newy[d] = ((newy[d - 1]) - pointchange);
                d++;
                q++;
            }
            while (q < points + 1 && d < 8192);
            q = 0;
        }
        else if (points != 0 && points > 0)
        {
            newy[d] = Y[a];//load first point
            d++;
        }
    }
    a++;
}

和这将创建一个紧密的波形,但它仍然是非常steppy。

and this creates a close waveform but it is still very steppy.

因此,谁能明白为什么这不是很准确?
如何提高其精度? ?
或这样使用阵列的不同方式。

So can anyone see why this isn't very accurate? How to improve its accuracy? Or a different way of doing this using arrays?

感谢您寻找:)

推荐答案

试试我这个方法:

static public double linear(double x, double x0, double x1, double y0, double y1)
{
    if ((x1 - x0) == 0)
    {
        return (y0 + y1) / 2;
    }
    return y0 + (x - x0) * (y1 - y0) / (x1 - x0);
}



有效,你应该能够把你的数组和使用它像这样:

Effectively you should be able to take your arrays and use it like this:

var newY = linear(X[0], X[0], X[1], Y[0], Y[1]);



我把代码的here ,但验证了该算法相匹配的理论这里,所以我 认为这是正确的。不过,你可能应该考虑使用,如果这仍然是steppy多项式插值,请注意理论联系,这表明线性插值产生steppy波。

I pulled the code from here, but verified that the algorithm matched the theory here, and so I think it's right. However, you probably should consider using polynomial interpolation if this is still steppy, please note the theory link, it shows that linear interpolation produces steppy waves.

所以,第一个链接我给了,在这里我一把抓起这个代码,也有一个多项式算法:

So, the first link I gave, where I grabbed this code from, also has a polynomial algorithm:

static public double lagrange(double x, double[] xd, double[] yd)
{
    if (xd.Length != yd.Length)
    {
        throw new ArgumentException("Arrays must be of equal length."); //$NON-NLS-1$
    }
    double sum = 0;
    for (int i = 0, n = xd.Length; i < n; i++)
    {
        if (x - xd[i] == 0)
        {
            return yd[i];
        }
        double product = yd[i];
        for (int j = 0; j < n; j++)
        {
            if ((i == j) || (xd[i] - xd[j] == 0))
            {
                continue;
            }
            product *= (x - xd[i]) / (xd[i] - xd[j]);
        }
        sum += product;
    }
    return sum;
}

要使用这一个你将不得不决定要如何抓紧你的 X 值,所以我们说,我们希望通过查找当前迭代和下之间的中点来做到这一点:

To use this one you're going to have to decide how you want to step up your x values, so let's say we wanted to do it by finding the midpoint between the current iteration and the next:

for (int i = 0; i < X.Length; i++)
{
    var newY = lagrange(new double[] { X[i]d, X[i+1]d }.Average(), X, Y);
}

请注意,将会有更多的这种循环,就像确保有一个 I + 1 等,但我想看看,如果我可以给你一个开始。

Please note that there will be more to this loop, like ensuring there is an i+1 and such, but I wanted to see if I could give you a start.

这篇关于C#线性插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆