C++ & Matlab 混合编程 - KLU(Sparse LU)

1. 软件版本信息

  • Matlab 2017b
  • Visual Studio 2015 Professional
  • Operating System Windows 10
  • KLU


2 KLU 编译

KLU是针对线性方程组中系数矩阵的LU分解的一类快速求解方法。源文件为C文件,理论上是可以直接在Visual Studio中直接使用的,可参见KLU使用说明。不过,大部分编程的人,尤其是高校研究生更熟悉Matlab。因此,若想在Matlab中使用KLU,则需进行额外的处理,即采用mex指令进行编译,不过KLU的编译是比较麻烦的。尽管如此,但是开发此代码的作者Tim Davis已以脚本文件完成编译部分,更加便捷,具体安装可参见KLU编译链接

2.1 KLU来源

From: http://faculty.cse.tamu.edu/davis/suitesparse.html,网页界面如下所示:

C++ & Matlab 混合编程 - KLU(Sparse LU)_第1张图片


下载后,文件内容大致如下所示:

C++ & Matlab 混合编程 - KLU(Sparse LU)_第2张图片

值得注意两点:

    其一,因为使用到LU分解,而该算法的快速性很大程度上依赖于减少Fill-in,因此Factorize之前需要进行排序以在Factorize之前减少注入元,提升计算效率。而用于排序的排序算法中,KLU算法包中自带有AMD, ColAMD,默认为AMD;除此之外, KLU也支持第三方库中排序算法,如Metis,  如性能较优的CHOLMOD。此外,下载链接为SuiteSparse(功能很强大,QR、Cholesky分解),而我们仅需要其中的一部分KLU, 因此下载时不要误认为链接有所问题。又回到Metis的补加上,因为SuiteSparse4.4.4,没有Metis,因此需要额外进行下载,下载链接为Metis下载链接,下载选项如下所示。下载后,将Metis文件复制粘贴在SuiteSparse4.4.4文件安装目录下,具体可参见下图。

C++ & Matlab 混合编程 - KLU(Sparse LU)_第3张图片


C++ & Matlab 混合编程 - KLU(Sparse LU)_第4张图片

     其二,SuiteSparse5.0以上,里面已经集成Metis包(版本为5.1),这是其一大好处,不过编译总是无法正常安装KLU,还不清楚原因。鉴于无法正常安装,笔者也就仅以正常安装测试成功的SuiteSparse4.4.4为例。如果有朋友测试成功更高版本的SuiteSparse,如5.0以上,还请分享,谢谢!


2.2 Matlab环境编译

安装请记住两点:其一,进入SuiteSparse4.4.4安装目录;其二,Matlab命令窗口敲入此指令(SuiteSparse_install),然后一路回车安装即可。为便于大家,此处也附上安装过程图片。

C++ & Matlab 混合编程 - KLU(Sparse LU)_第5张图片


3. 代码部分

3.1 Matlab 部分

3.1.1 图片

C++ & Matlab 混合编程 - KLU(Sparse LU)_第6张图片


3.1.2 代码

function [rst] = CallKLUInCPlusPlus()
try
   load A.mat;
   load b.mat;
   S = sparse (A) ;
   fprintf('KLU Time (Sparse and Double)\n');
   tic, LU=klu(S);x0=klu(LU,'\',b); toc;% klu sparse
   fprintf('Matlab Double and Dense\n');
   tic, x1 = A\b ; toc   
   fprintf('Matlab Double and Sparse\n');
   tic, x2 = S\b ; toc
   sA=single(A);
   fprintf('Matlab Single and Dense\n');
   tic, x3 = sA\b; toc;
   x=[x0 x1 x2 x3];
   rst=0;% Normal State
   return;
catch ME
    switch ME.identifier
        case 'MATLAB:UndefinedFunction'
            warning('Function is undefined.  Assigning a value of NaN.');
            a = NaN;
        case 'MATLAB:scriptNotAFunction'
            warning(['Attempting to execute script as function. '...
                'Running script and assigning output a value of 0.']);
            notaFunction;
            a = 0;
        otherwise
            rethrow(ME)
    end
    rst=1;% Error Occurs
    return;
end
end


3.1.3 数据

3.1.2代码中的数据,即load A.mat和load b.mat, 可以当作一个线性方程组的左端系数矩阵和右端向量矩阵理解。因此,生成这样的矩阵是比较方便的。但是此处,数据源于研究相关,不便透露,仅以图片形式直观展示系数矩阵A。不过为便于大家,也简单写了一个生成数据的函数(简称getData()函数),调用形式为[A,b]=getData(100,'double')。

function [A,b] = getData(n,clz)
    fprintf('Creating a matrix of size %d-by-%d.\n', n, n);
    A = rand(n, n,clz) + 100*eye(n, n,clz);
    b = rand(n, 1);
end

C++ & Matlab 混合编程 - KLU(Sparse LU)_第7张图片


3.2 C++部分

3.2.1 图片

C++ & Matlab 混合编程 - KLU(Sparse LU)_第8张图片


3.2.2 代码

#include "stdafx.h"
#include "CallKLUInCPlusPlus.h"
#include 
#include 

int main()
{
	// Set up the application state for the MATLAB Runtime instance created in the application.  
	if (!mclInitializeApplication(NULL, 0)) {
		std::cerr << "could not initialize the application properly"
			<< std::endl;
		return -1;
	}

	// Load the required MATLAB code into the MATLAB Runtime.  
	if (!CallKLUInCPlusPlusInitialize()) {
		std::cerr << "could not initialize the library properly"
			<< std::endl;
		return -1;
	}

	// Declare one variable using mxArray format
	mwArray out(1, 1, mxDOUBLE_CLASS);
	double *rst = new double[1];

	// Invoke CallKLUInCPlusPlus() method
	CallKLUInCPlusPlus(1, out);
	out.GetData(rst, 1);

	// Free all related resources occupied by current program
	CallKLUInCPlusPlusTerminate();
	mclTerminateApplication();

	getchar();
	return 0;
}


4. C++配置

C++与Matlab混编,总是涉及较多库文件,包含目录、Matlab的extern包含文件设置,很琐碎但也非常关键。此部分,可详见笔者此前关于C++&Matlab混合编程-动态链接库形式的博客的链接。此处,也回顾性的以图片形式说明配置过程。

C++ & Matlab 混合编程 - KLU(Sparse LU)_第9张图片


C++ & Matlab 混合编程 - KLU(Sparse LU)_第10张图片


C++ & Matlab 混合编程 - KLU(Sparse LU)_第11张图片


5. 测试结果

5.1 Matlab Result:

5.1.1 正确性:

C++ & Matlab 混合编程 - KLU(Sparse LU)_第12张图片


5.1.2 运行时间

C++ & Matlab 混合编程 - KLU(Sparse LU)_第13张图片


5.2 C++

所需时间:

C++ & Matlab 混合编程 - KLU(Sparse LU)_第14张图片


6. 有用链接

  • http://faculty.cse.tamu.edu/davis/suitesparse.html
  • http://faculty.cse.tamu.edu/davis/SuiteSparse/(重要,SuiteSparse4.4.4)
  • https://github.com/jlblancoc/suitesparse-metis-for-windows
  • http://www.voidcn.com/article/p-cotxqxjk-uc.html
  • http://glaros.dtc.umn.edu/gkhome/fsroot/sw/metis/OLD(重要->Metis版本4.0,以配合SuiteSparse4.4.4)
  • https://users.encs.concordia.ca/~krzyzak/R%20Code-Communications%20in%20Statistics%20and%20Simulation%202014/Zubeh%F6r/SuiteSparse/KLU/Doc/KLU_UserGuide.pdf(重要,KLU使用说明)

你可能感兴趣的:(编程语言)