使用armodillo库实现matlab源码转c++

直接切入正题,最近需要将matlab转成c++集成到项目做成调用dll来做,查了常用的matlab转成c++的方法。说的最多的就是使用matlab coder,这是matlab自带的转换工具,但是研究过matlab coder之后,果断放弃了这种思路,原因是matlab coder很多的matlab自带函数都无法支持,完全不能满足我项目的要求。

有人说,为啥不使用联编的方式,联编需要调用matlab引擎。仍然不能脱离matlab。matlab付费,而且相比直接使用c++实现相同功能时,调用c++可以在调用速度上实现质的提高。

首先,介绍一个c++库—armodillo(C++ library for linear algebra & scientific computing),这样就能在c++中使用类似matlab中的向量矩阵等类型,并且提供了矩阵的操作函数和matlab中的一些函数(具体功能和使用,官网上都有,不过是英文)。

话不多说,我第一次尝试转换的是matlab中的kstest2函数(ks检验),贴的代码中没有做判断逻辑,但是主逻辑都实现了,说下思路,首先,要先找到matlab函数的源码(type 函数名),然后看懂matlab源码中想表达的意思,使用armodillo中对应的类型和方法对应编程就行,很简单。下面贴一个我最初的ks函数(并不完整,但能运行,结果和matlab一样),当然,现在我转换的功底已经有点了(嘿嘿,有些原因,成熟的算法不能发布,但是思想最重要哦)


#include <iostream>
#include <armadillo>
#include <vector>
#include<fstream>
#include <string>
#pragma warning(disable:4996)
using namespace std;
using namespace arma;
void kstest2(vec A, vec B, double alpha, int tail)
{
	//double alpha = 0.05;
	//int tail = 0;

	//colvec A;
	//A << 1 << endr << 3 << endr << 2 << endr;
	//colvec B;
	//B << 2 << endr;

	vec I1;
	I1 << -INFINITY << endr;
	vec I2;
	I2 << INFINITY << endr;

	vec binEdges;
	binEdges = join_cols(join_cols(I1, sort(join_cols(A, B))), I2);
	uvec binCounts1 = histc(A, binEdges);
	uvec binCounts2 = histc(B, binEdges);
	vec sumCounts1(binCounts1.size());
	uvec sum1 = cumsum(binCounts1);
	double  sum2 = sum(binCounts1);
	for (int i = 0; i < binCounts1.size(); i++)
	{
		sumCounts1(i) = sum1(i, 0) / sum2;
	}


	vec sumCounts2(binCounts2.size());
	uvec sum3 = cumsum(binCounts2);
	double  sum4 = sum(binCounts2);
	for (int i = 0; i < binCounts2.size(); i++)
	{
		sumCounts2(i) = sum3(i, 0) / sum4;
	}
	sumCounts1.resize(sumCounts1.size() - 1);
	sumCounts2.resize(sumCounts2.size() - 1);
	vec sampleCDF1 = sumCounts1;
	vec sampleCDF2 = sumCounts2;

	vec deltaCDF = abs(sampleCDF1 - sampleCDF2);


	double KSstatistic = (double)max(deltaCDF);
	cout<<"KSstatistic=" << KSstatistic<<endl;

	double n1 = A.size();
	double n2 = B.size();
	double n = n1 * n2 / (n1 + n2);

	double lambda = (sqrt(n) + 0.12 + 0.11 / sqrt(n)) * KSstatistic;


	vec j = linspace<vec>(1, 101, 101);
	j = j - 1;
	for (int i = 0; i < j.size(); i++)
	{
		j(i) = (double)pow(-1, j(i));
	}
	vec j1 = exp(pow(linspace<vec>(1, 101, 101), 2)*(-2 * lambda*lambda));

	for (int i = 0; i < j.size(); i++)
	{
		j1(i) = j(i)*j1(i);
	}

	double pValue = 2 * sum(j1);
	pValue = min(max(pValue, 0.0), 1.0);
    cout<<"pValue="<<pValue<<endl;
	int H = (alpha >= pValue);
	cout<<"H="<<H;
}

int main()
{
	
	vector<double> vec1;
	vec1.push_back(1);
	vec1.push_back(100);
	vec1.push_back(2);

	vector<double> vec2;
	vec2.push_back(1);
	vec2.push_back(3);
	
	vector<double> vec1;
	vector<double> vec2;

	vec A(vec1);
	vec B(vec2);
	kstest2(A, B, 0.05, 0);
	
	return 1;	
}

输入的方式多种多样,我大概研究了四种,,在代码中写了两种,文档中都有,根据需要来做吧。
当然,运行之前需要配置armodillo的环境,夜已深,还有其他重要事要做,嘿嘿,安装的部分我之后再写吧。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值