Matlab与.Net混合编程-多维数组赋值出错的问题
问题描述:
Matlab可编译供.net调用的dll。两种不同环境对数据类型的定义相差较大,因此在C#中调用Matlab编译的函数时,首先要将C#中的变量类型转换成与Matlab对应的中转类型。Matlab中的变量一般以矩阵形式表示,编译成.net dll后,通过MathWorks.MATLAB.NET.Arrays命名空间中的一系列类型来中转C#数据类型(如MWArray)。
C#中的简单数值、一维数组和二维数组可以隐式转换成MWNumericArray类型,因此在C#中可以很方便的定义用于调用Matlab函数的参数,如:
MWNumericArray a = 1.0; // 简单数值
MWNumericArray b = new Double[] {1.0, 2.0, 3.0 }; // 一维数组
MWNumericArray c = new Double[,] { {1.0, 2.0 }, {3.0, 4.0} }; // 二维数组,表示2*2的矩阵
根据简单调研,一般帖子上都会说一维、二维甚至多维矩阵的赋值原理类似,可参照低纬数组进行操作。我们在开发中很想当然的认为,三维数组应该也可以像二维矩阵一样定义和赋值,于是先定义了一个480*640*3的三维数组(用以传递图像数据):
double[,,] d = new double[480,640,3];
(...赋值过程省略...)
MWNumericArray e = d;
运行后出错了,经过调试,返现上一步中,想当然的480*640*3三维矩阵,赋值给MWNumericArray对象e后,变成了640*3*480矩阵,维度顺序完全跟预想的不一致。
原因分析:
后来在Matlab官方手册中发现”Rules for Data Conversion Between .NET and MATLAB“,其中对.net和Matlab多维数组有这么一段描述:“MATLAB and .NET implement different indexing strategies for multidimensional arrays. When you create a variable of type MWNumericArray, MATLAB automatically creates an equivalent array, using its own internal indexing. ”,说明Matlab和.Net在矩阵存储和索引的方式是有差异的。
以下是“Conversion Results: .NET Types to MATLAB Types”中的对照信息:
其中M、N代表行数、列数,P1...Pn表示Page1到Page n。在.Net中,多维数组Page在前(顺序从n到1),行列数在后,而Page在后(顺序从1到n),因此我们给480*640*3的Matlab矩阵类型赋值,需要定义一个3*480*640的三维数组,如:double[,,] d = new double[3,480,640]。 这也解释了之前为何二维矩阵(只有M、N,没有P)的赋值过程不会出错,而三维矩阵却不对。
参考内容:
1、Rules for Data Conversion Between .NET and MATLAB
http://cn.mathworks.com/help/compiler_sdk/dotnet/rules-for-data-conversion-between-net-and-matlab.html?searchHighlight=MWNumericArray%20.NET&s_tid=doc_srchtitle
2、Data Conversion Between .NET and MATLAB
http://cn.mathworks.com/help/compiler_sdk/dotnet/data-conversion-between-net-and-matlab.html?searchHighlight=MWNumericArray%20.NET&s_tid=doc_srchtitle