C语言实现matlab的interp2()函数
项目要用到matlab中的Vq = interp2(X,Y,V,Xq,Yq)函数,即把一个已知经纬度和对应值的矩阵,插值变换到一个给定经纬度网格中,也就是对给定网格填值,需要用到插值,这里使用双线性内插法。
*(这只是一个初步完成代码,仅供参考)
以下是对应C代码和测试程序:
//************************************
// 函数名称: inter_linear()
// 函数说明:计算两点之间某一给定点的值,(x0,y0)->(x1,y1),已知x(x0<x<x1),求y
// 返 回 值: double
// 参 数: double x0,y0,x1,y1/*in*/ 两个点的坐标(x0,y0)(x1,y1) // 作 者:WSS
// 作成日期:2019/09/05 //************************************
double inter_linear(double x0, double y0, double x1, double y1, double x)
{
double a0, a1, y;
a0 = (x - x1) / (x0 - x1);
a1 = (x - x0) / (x1 - x0);
y = a0*y0 + a1*y1;
return y;
}
//************************************
// 函数名称: interp2d()
// 函数说明:二维插值,同matlab的interp2()功能
// 返 回 值: double
// 参 数: x,y分别为长度为m和n的向量(一维数组),z为矩阵(对应的二维数组(m,n))
// a,b分别为长度为asize和bsize的向量(一维数组),out_result为矩阵(对应的二维数组(asize,bsize)) // 作 者:WSS
// 作成日期:2019/09/05 //************************************
int interp2d(double *x, double *y, double *z, int m, int n, double *a, double *b, int asize,int bsize,double *out_result)
{
//a,b是待插值的矩阵行和列,遍历a,取出行,遍历b取出列,将插值计算后的值存储在out_result中
double pointa = ;
double pointb = ;
double w1, w2,w;
const int nu_val = -;
int tempi = ;
int tempj =;
for (int i = ; i < asize; ++i)
{
for (int j = ; j < bsize; ++j)
{
// 找到网格点位置
pointa = a[i];
pointb = b[j];
//确定pointa pointb所在的位置
for (int p = ; p < m-; ++p)
{
if (pointa < x[]||pointa>x[m-])//范围外的值不进行插值处理
{
tempi = nu_val;
break;
}
else if (pointa == x[m - ])
{
tempi = m - ;
break;
}
else if(pointa >= x[p] && pointa < x[p+])//x升序
{
tempi = p;
break;
}
}
for (int q = ; q < n - ; ++q)
{
if (pointb< y[] || pointb>y[n- ])//范围外的值不进行插值处理
{
tempj = nu_val;
break;
}
else if (pointb == y[n - ])
{
tempj = n - ;
break;
}
else if (pointb >= y[q] && pointb < y[q + ])//y升序
{
tempj = q;
break;
}
}
if (tempj == nu_val || tempi == nu_val)
{
out_result[i*bsize + j] = nu_val;
}
else
{
//如果四个点,有一个点为-9999,就不进行插值了
if(z[tempi*n + tempj]<-||z[tempi*n + tempj + ]<-||z[(tempi + )*n + tempj]<-||z[(tempi + )*n + tempj + ]<-)
{
out_result[i*bsize + j] = nu_val;
}
else
{
//cout << tempi << " " << tempj << endl;
/**************x方向进行插值*************/
if (x[tempi] == pointa)
{
//取网格节点值
w1 = z[tempi*n + tempj];
w2 = z[tempi*n + tempj + ];
//y方向进行插值
if (y[tempj] == pointb)
{
w = w1;
}
else
{
w = inter_linear(y[tempj], w1, y[tempj + ], w2, pointb);
}
}
else
{
//x方向进行插值
w1 = inter_linear(x[tempi], z[tempi*n + tempj], x[tempi + ], z[(tempi + )*n + tempj], pointa);
w2 = inter_linear(x[tempi], z[tempi*n + tempj + ], x[tempi + ], z[(tempi + )*n + tempj + ], pointa);
/*******y方向进行插值********/ if (y[tempj] == pointb) { //取网格节点值 w = w1; }
else
{
//进行插值(y) w = inter_linear(y[tempj], w1, y[tempj + ], w2, pointb);
}
}
out_result[i*bsize + j] = w;
} } }
}
return ;
}
测试函数:
int main()
{
//插值函数测试
int ret = ;
double a1[] = { , , , , };
double a2[] = {,,,,,};
double z[] ;
for (int i = ; i < ; ++i)
{
for (int j = ; j < ; ++j)
{
z[i*+j] = a1[i]+a2[j];
}
} double b1[] = { , , , , , , , , , };
double b2[] = { , , , , , , , , , , , , , , , , , };
double zout[];
ret = interp2d(a1, a2, z, , , b1, b2, , , zout);
for (int i = ; i < ; ++i)
{
for (int j = ; j < ; j++)
{
cout << z[i * + j] << " ";
}
cout << endl;
}
cout << endl;
for (int i = ; i < ; ++i)
{
for (int j = ; j <; j++)
{
cout << zout[i * + j] << " ";
}
cout << endl;
}
return 0;
}
C语言实现matlab的interp2()函数的更多相关文章
- 【matlab】设定函数默认参数
C++/java/python系列的语言,函数可以有默认值,通常类似如下的形式: funtion_name (param1, param2=default_value, ...) 到了matlab下发 ...
- C语言与MATLAB接口 编程与实例 李传军编着
罗列一下以前自己学习C语言与MATLAB混编的笔记,顺便复习一遍. <C语言与MATLAB接口 编程与实例 李传军编着>(未看完,目前看到P106) 目录P4-8 ************ ...
- MATLAB模糊逻辑工具箱函数
说明:本文档中所列出的函数适用于Matlab5.3以上版本,为了简明起见,只列出了函数名,若需要进一步的说明,请参阅MATLAB的帮助文档. 1. GUI工具 Anfisedit 打开ANF ...
- Atitit java c# php c++ js跨语言调用matlab实现边缘检测等功能attilax总结
Atitit java c# php c++ js跨语言调用matlab实现边缘检测等功能attilax总结 1.1. 边缘检测的基本方法Canny最常用了1 1.2. 编写matlab边缘检测代码, ...
- matlab中patch函数的用法
http://blog.sina.com.cn/s/blog_707b64550100z1nz.html matlab中patch函数的用法——emily (2011-11-18 17:20:33) ...
- Matlab基本函数-conj函数
Matlab基本函数-conj函数 1.conj函数:用于计算复数的共轭值 2.用法说明:y=conj(x)函数计算复数x的共轭值.输出结果y的维数跟输入x的维数一致,返回值为:real(y)-i*i ...
- 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...
- 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...
- matlab画图形函数 semilogx
matlab画图形函数 semilogx loglog 主要是学习semilogx函数,其中常用的是semilogy函数,即后标为x的是在x轴取对数,为y的是y轴坐标取对数.loglog是x y轴都取 ...
随机推荐
- Spring Boot 集成 Seata 解决分布式事务问题
seata 简介 Seata 是 阿里巴巴2019年开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务.在 Seata 开源之前,Seata 对应的内部版本在阿里内部一 ...
- 【转】【e周美文】优秀博客上榜推荐
Everybody,本周的博客推荐开始啦,记住,有好的博客可要给小活推荐一下哦. 7.19日 博客推荐 Android权限列表作者:@大漠落日 链接:http://my.eoe.cn/1103623/ ...
- 基于redis有序集合,实现简单的延时任务
基于redis有序集合,实现简单的延时任务 延时任务的场景很多,开发过程中我们经常会遇到,比如说: 1.订单未付款,5分钟后自动取消,这是电商网站非常普遍的需求: 2.用户创建订单不付款,3分钟后自动 ...
- vue状态管理vuex从浅入深详细讲解
1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...
- es5和es6中查找数组中的元素
let array = [1,2,3,4,5] //es5 let find = array.filter(function (item){ return item %2 === 0//返回满足条件的 ...
- acmPush模块示例demo
感谢论坛版主 马浩川 的分享. 模块介绍: 阿里移动推送(Alibaba Cloud Mobile Push)是基于大数据的移动智能推送服务,帮助App快速集成移动推送的功能,在实现高效.精确.实时 ...
- struct结构体 重载运算符
struct node{ int x,y,z; }; bool operator<(node a,node b) { if(a.x!=b.x) return a.x<b.x; if(a.y ...
- mysql安装忘记初始密码怎么办
title: MySQL安装过程忘记初始密码最简单最简单解决办法 MySQL安装过程忘记初始密码最简单解决办法 在安装MySQL的时候会给定一个初始的密码,而这个初始的密码特别恶心人一堆大小写特殊 ...
- java: integer number is too large
今天想定义一个类常量,结果如下面那样定义,确报错了.error is: Integer number too large public static final Long STARTTIME = 14 ...
- Java.前端模板.Thymleaf
1. Input 日期格式化 <input id="renewalDate" name="renewalDate" th:value="${#d ...