Lui*_*cía 8 c matlab linear-interpolation
你知道Matlab interp1函数的任何C实现(只是'线性'函数)吗?我认识一个Java.
Nik*_*yan 12
我已将Luis的代码移植到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;
}
Run Code Online (Sandbox Code Playgroud)
我自己实现了这种线性插值(其中一些是用西班牙语写的,对不起).名为encuentraValorMasProximo的函数只是在数组(xD)中找到最近的值(elementoMasProximo)和索引(indiceEnVector)到另一个值(xx [i]).
void interp1(int *x, int x_tam, double *y, int *xx, int xx_tam, double *yy)
{
double *dx, *dy, *slope, *intercept, *elementoMasProximo, *xD;
int i, *indiceEnVector;
dx=(double *)calloc(x_tam-1,sizeof(double));
dy=(double *)calloc(x_tam-1,sizeof(double));
slope=(double *)calloc(x_tam-1,sizeof(double));
intercept=(double *)calloc(x_tam-1,sizeof(double));
indiceEnVector=(int *) malloc(sizeof(int));
elementoMasProximo=(double *) malloc(sizeof(double));
xD=(double *)calloc(x_tam,sizeof(double));
for(i=0;i<x_tam;i++){
xD[i]=x[i];
}
for(i = 0; i < x_tam; i++){
if(i<x_tam-1){
dx[i] = x[i + 1] - x[i];
dy[i] = y[i + 1] - y[i];
slope[i] = dy[i] / dx[i];
intercept[i] = y[i] - x[i] * slope[i];
}else{
dx[i]=dx[i-1];
dy[i]=dy[i-1];
slope[i]=slope[i-1];
intercept[i]=intercept[i-1];
}
}
for (i = 0; i < xx_tam; i++) {
encuentraValorMasProximo(xx[i], xD, x_tam, x_tam, elementoMasProximo, indiceEnVector);
yy[i]=slope[*indiceEnVector] * xx[i] + intercept[*indiceEnVector];
}
}
Run Code Online (Sandbox Code Playgroud)
该测试功能可以是:
void main(){
int x_tam, xx_tam, i;
double *yy;
int x[]={3,6,9};
double y[]={6,12,18};
int xx[]={1,2,3,4,5,6,7,8,9,10};
x_tam=3;
xx_tam=10;
yy=(double *) calloc(xx_tam,sizeof(double));
interp1(x, x_tam, y, xx, xx_tam, yy);
for(i=0;i<xx_tam;i++){
printf("%d\t%f\n",xx[i],yy[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
而其结果:
1 2.000000
2 4.000000
3 6.000000
4 8.000000
5 10.000000
6 12.000000
7 14.000000
8 16.000000
9 18.000000
10 20.000000
常用函数的优秀实现可以在C语言中的Numerical Recipes一书中找到,该书可以在线免费查看.第3.1.2章有一个线性插值配方,本章的其余部分涵盖了更高级的配方.
我强烈推荐这本书,它编写得很好,涵盖了大量的算法,这些算法也以非常有效且仍然可以理解的方式实现.
Luis提交的C-Code存在问题.首先,encuentraValorMasProximo丢失了.其次,阵列预留是一个数字短.我也清理了这个功能.下面是带有encuentraValorMasProximo函数的功能性C代码(重命名为findNearestNeighbourIndex).
#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);
}
Run Code Online (Sandbox Code Playgroud)