Matlab interp1函数的C实现(线性插值)

Matlab interp1函数的C实现(线性插值),c,matlab,linear-interpolation,C,Matlab,Linear Interpolation,你知道MatlabInterp1函数的任何C实现吗(仅仅是“线性”函数)?我知道一个。你可以看看GSL(数字科学图书馆)。有许多类似Matlab的函数,其中包括一维插值函数 我现在正在打电话,抱歉,无法提供链接。您知道吗?它从Matlab代码自动生成c/c++代码。如果你的Matlab软件包中有这个函数,你可以通过它运行interp1函数,看看Matlab给出了什么。在这本书中可以找到常用函数的优秀实现,这本书可以在线免费查看。第3.1.2章有一个线性插值公式,本章其余部分将介绍更高级的公式 我

你知道MatlabInterp1函数的任何C实现吗(仅仅是“线性”函数)?我知道一个。你可以看看GSL(数字科学图书馆)。有许多类似Matlab的函数,其中包括一维插值函数


我现在正在打电话,抱歉,无法提供链接。

您知道吗?它从Matlab代码自动生成c/c++代码。如果你的Matlab软件包中有这个函数,你可以通过它运行interp1函数,看看Matlab给出了什么。

在这本书中可以找到常用函数的优秀实现,这本书可以在线免费查看。第3.1.2章有一个线性插值公式,本章其余部分将介绍更高级的公式


我可以强烈推荐这本书,它写得非常好,涵盖了大量的算法,这些算法也是以一种非常有效且仍然可以理解的方式实现的。

我自己实现了这个线性插值(抱歉,其中一些是用西班牙语编写的)。名为encuteRavalorMasProximo的函数仅查找数组(xD)中与另一个(xx[i])最近的值(elementomaproximo)和索引(indicenVector)

void interp1(int*x,int x_tam,double*y,int*xx,int xx_tam,double*yy)
{
双*dx,*dy,*slope,*intercept,*elementomaproximo,*xD;
int i,*指示向量;
dx=(双*)calloc(x_tam-1,sizeof(双));
dy=(双*)calloc(x_tam-1,sizeof(双));
斜率=(双*)calloc(x_tam-1,尺寸(双));
截距=(双*)calloc(x_tam-1,sizeof(双));
indicenVector=(int*)malloc(sizeof(int));
elementomaproximo=(双*)malloc(sizeof(双));
xD=(双*)calloc(x_tam,sizeof(双));

对于(i=0;i我已经将路易斯的代码移植到C++中。它看起来很有用,但是我没有太多检查过,所以请注意并重新检查你的结果。< /P>
#include <vector>
#include <cfloat>
#include <math.h>

vector< float > interp1( vector< float > &x, vector< float > &y, vector< float > &x_new )
{
    vector< float > y_new;
    y_new.reserve( x_new.size() );

    std::vector< float > dx, dy, slope, intercept;
    dx.reserve( x.size() );
    dy.reserve( x.size() );
    slope.reserve( x.size() );
    intercept.reserve( x.size() );
    for( int i = 0; i < x.size(); ++i ){
        if( i < x.size()-1 )
        {
            dx.push_back( x[i+1] - x[i] );
            dy.push_back( y[i+1] - y[i] );
            slope.push_back( dy[i] / dx[i] );
            intercept.push_back( y[i] - x[i] * slope[i] );
        }
        else
        {
            dx.push_back( dx[i-1] );
            dy.push_back( dy[i-1] );
            slope.push_back( slope[i-1] );
            intercept.push_back( intercept[i-1] );
        }
    }

    for ( int i = 0; i < x_new.size(); ++i ) 
    {
        int idx = findNearestNeighbourIndex( x_new[i], x );
        y_new.push_back( slope[idx] * x_new[i] + intercept[idx] );

    }

}

int findNearestNeighbourIndex( float value, vector< float > &x )
{
    float dist = FLT_MAX;
    int idx = -1;
    for ( int i = 0; i < x.size(); ++i ) {
        float newDist = value - x[i];
        if ( newDist > 0 && newDist < dist ) {
            dist = newDist;
            idx = i;
        }
    }

    return idx;
}
#包括
#包括
#包括
向量interp1(向量&x,向量&y,向量&x\u新)
{
向量y_新;
y_new.reserve(x_new.size());
标准:向量dx,dy,斜率,截距;
dx.保留(x.大小());
dy.保留(x.大小());
坡度.储量(x.尺寸());
截距保留(x.size());
对于(int i=0;i&x)
{
浮动距离=FLT_最大值;
intidx=-1;
对于(int i=0;i0&&newDist
请参阅fileexchange中的lininterp1f。

Luis提交的C代码有问题。首先,EncUserRavalorMasProximo丢失。其次,数组保留少了一个数字。我还清理了该函数。下面是带有EncUserRavalorMasProximo函数(重命名为FindNearestNeightUrIndex)的功能C代码

#包括
int FindNearestNeightUrIndex(双值,双*x,int len)
{
双区;
int-idx;
int i;
idx=-1;
dist=DBL_MAX;
对于(i=0;i0&&newDist如果(i@user1097111,您的代码存在一个bug,在函数findnearestneaturindex中,它应该是if(newDist>=0&&newDist0&&newDist如果这对将来的某个人有帮助,这是一个没有临时数组和0 bug的版本

#include <iostream>
#include <vector>
#include <limits>
#include <cmath>


template<typename Real>
int nearestNeighbourIndex(std::vector<Real> &x, Real &value)
{
    Real dist = std::numeric_limits<Real>::max();
    Real newDist = dist;
    size_t idx = 0;

    for (size_t i = 0; i < x.size(); ++i) {
        newDist = std::abs(value - x[i]);
        if (newDist <= dist) {
            dist = newDist;
            idx = i;
        }
    }

    return idx;
}

template<typename Real>
std::vector<Real> interp1(std::vector<Real> &x, std::vector<Real> &y, std::vector<Real> &x_new)
{
    std::vector<Real> y_new;
    Real dx, dy, m, b;
    size_t x_max_idx = x.size() - 1;
    size_t x_new_size = x_new.size();

    y_new.reserve(x_new_size);

    for (size_t i = 0; i < x_new_size; ++i)
    {
        size_t idx = nearestNeighbourIndex(x, x_new[i]);

        if (x[idx] > x_new[i])
        {
            dx = idx > 0 ? (x[idx] - x[idx - 1]) : (x[idx + 1] - x[idx]);
            dy = idx > 0 ? (y[idx] - y[idx - 1]) : (y[idx + 1] - y[idx]);
        }
        else
        {
            dx = idx < x_max_idx ? (x[idx + 1] - x[idx]) : (x[idx] - x[idx - 1]);
            dy = idx < x_max_idx ? (y[idx + 1] - y[idx]) : (y[idx] - y[idx - 1]);
        }

        m = dy / dx;
        b = y[idx] - x[idx] * m;

        y_new.push_back(x_new[i] * m + b);
    }

    return y_new;
}

int main() {
    vector<float> x{1, 2, 3, 4, 5};
    vector<float> y{5, 6, 7, 8, 9};
    vector<float> newx{0, 5, 6.123, 12.123, 2, 4};

    auto res = interp1(x, y, newx);
    for (auto i: res)
        cout << i << " ";
    cout << endl;
}
#包括
#包括
#包括
#包括
模板
int近邻索引(标准::向量和x,实值和值)
{
实距离=标准::数值限制::最大值();
实际新距离=距离;
大小\u t idx=0;
对于(大小i=0;i0?(x[idx]-x[idx-1]):(x[idx+1]-x[idx]);
dy=idx>0?(y[idx]-y[idx-1]):(y[idx+1]-y[idx]);
}
其他的
{
dx=idx我尝试过,但它是难以辨认的。1是因为。但是,它太重,不能只用于一个函数,但它可以作为替代。他特别要求C实现,所以这不是一个真正的合适的答案。这是好的,因为我正在寻找一个C++实现。谢谢!
#include <vector>
#include <cfloat>
#include <math.h>

vector< float > interp1( vector< float > &x, vector< float > &y, vector< float > &x_new )
{
    vector< float > y_new;
    y_new.reserve( x_new.size() );

    std::vector< float > dx, dy, slope, intercept;
    dx.reserve( x.size() );
    dy.reserve( x.size() );
    slope.reserve( x.size() );
    intercept.reserve( x.size() );
    for( int i = 0; i < x.size(); ++i ){
        if( i < x.size()-1 )
        {
            dx.push_back( x[i+1] - x[i] );
            dy.push_back( y[i+1] - y[i] );
            slope.push_back( dy[i] / dx[i] );
            intercept.push_back( y[i] - x[i] * slope[i] );
        }
        else
        {
            dx.push_back( dx[i-1] );
            dy.push_back( dy[i-1] );
            slope.push_back( slope[i-1] );
            intercept.push_back( intercept[i-1] );
        }
    }

    for ( int i = 0; i < x_new.size(); ++i ) 
    {
        int idx = findNearestNeighbourIndex( x_new[i], x );
        y_new.push_back( slope[idx] * x_new[i] + intercept[idx] );

    }

}

int findNearestNeighbourIndex( float value, vector< float > &x )
{
    float dist = FLT_MAX;
    int idx = -1;
    for ( int i = 0; i < x.size(); ++i ) {
        float newDist = value - x[i];
        if ( newDist > 0 && newDist < dist ) {
            dist = newDist;
            idx = i;
        }
    }

    return idx;
}
#include <float.h> 

int findNearestNeighbourIndex( double value, double *x, int len )
{
    double dist;
    int idx;
    int i;

    idx = -1;
    dist = DBL_MAX;
    for ( i = 0; i < len; i++ ) {
        double newDist = value - x[i];
        if ( newDist > 0 && newDist < dist ) {
            dist = newDist;
            idx = i;
        }
    }

    return idx;
}

void interp1(double *x, int x_tam, double *y, double *xx, int xx_tam, double *yy)
{
    double dx, dy, *slope, *intercept;
    int i, indiceEnVector;

    slope=(double *)calloc(x_tam,sizeof(double));
    intercept=(double *)calloc(x_tam,sizeof(double));

    for(i = 0; i < x_tam; i++){
        if(i<x_tam-1){
            dx = x[i + 1] - x[i];
            dy = y[i + 1] - y[i];
            slope[i] = dy / dx;
            intercept[i] = y[i] - x[i] * slope[i];
        }else{
            slope[i]=slope[i-1];
            intercept[i]=intercept[i-1];
        }
    }

    for (i = 0; i < xx_tam; i++) {
        indiceEnVector = findNearestNeighbourIndex( xx[i], x, x_tam);
        if (indiceEnVector != -1)
            yy[i]=slope[indiceEnVector] * xx[i] + intercept[indiceEnVector];
        else
            yy[i]=DBL_MAX;
    }
    free(slope);
    free(intercept);
}
#include <iostream>
#include <vector>
#include <limits>
#include <cmath>


template<typename Real>
int nearestNeighbourIndex(std::vector<Real> &x, Real &value)
{
    Real dist = std::numeric_limits<Real>::max();
    Real newDist = dist;
    size_t idx = 0;

    for (size_t i = 0; i < x.size(); ++i) {
        newDist = std::abs(value - x[i]);
        if (newDist <= dist) {
            dist = newDist;
            idx = i;
        }
    }

    return idx;
}

template<typename Real>
std::vector<Real> interp1(std::vector<Real> &x, std::vector<Real> &y, std::vector<Real> &x_new)
{
    std::vector<Real> y_new;
    Real dx, dy, m, b;
    size_t x_max_idx = x.size() - 1;
    size_t x_new_size = x_new.size();

    y_new.reserve(x_new_size);

    for (size_t i = 0; i < x_new_size; ++i)
    {
        size_t idx = nearestNeighbourIndex(x, x_new[i]);

        if (x[idx] > x_new[i])
        {
            dx = idx > 0 ? (x[idx] - x[idx - 1]) : (x[idx + 1] - x[idx]);
            dy = idx > 0 ? (y[idx] - y[idx - 1]) : (y[idx + 1] - y[idx]);
        }
        else
        {
            dx = idx < x_max_idx ? (x[idx + 1] - x[idx]) : (x[idx] - x[idx - 1]);
            dy = idx < x_max_idx ? (y[idx + 1] - y[idx]) : (y[idx] - y[idx - 1]);
        }

        m = dy / dx;
        b = y[idx] - x[idx] * m;

        y_new.push_back(x_new[i] * m + b);
    }

    return y_new;
}

int main() {
    vector<float> x{1, 2, 3, 4, 5};
    vector<float> y{5, 6, 7, 8, 9};
    vector<float> newx{0, 5, 6.123, 12.123, 2, 4};

    auto res = interp1(x, y, newx);
    for (auto i: res)
        cout << i << " ";
    cout << endl;
}