如何将多维动态数组移动或复制到 matlab 的数组
How to MOVE or COPY multidimensional dynamic arrays to matlab`s arrays
如果我使用非动态数组,一切正常
pmxArray = mxArray^;
perA_ptr: pmxArray;
perA: array[1..3,1..4] of double;
perA_ptr := mxCreateDoubleMatrix(4,3,mxREAL);
Move(perA, mxGetPr(perA_ptr)^, 4*3*sizeof(double));
......
_mlflinprog1(1,perX_ptr,perF_ptr,perA_ptr,perB_ptr,perLB_ptr);
这是可行的。
但我需要使用动态数组。我有一个问题
perA: array of array of Double;
SetLength(perA,4,3);
perA_ptr := mxCreateDoubleMatrix(4,3,mxREAL);
Move(perA, mxGetPr(perA_ptr)^, 12*sizeof(double));
不起作用,数组中只有垃圾;
Move(perA[0,0], mxGetPr(perA_ptr)^, 4*sizeof(double));
- 第一行有效,但我需要复制所有数组的数据,IDK 如何在 delphi.
中做到这一点
这是 matlab c 共享库所需的数组。
您的静态数组存储在一个连续的块中。二维动态数组参差不齐。在 C 术语中,您有 double**
。尽管 Delphi 数组有额外的簿记功能,但这就是您需要考虑的方式。
所以当你这样做时
SetLength(perA, 4, 3);
你有一个长度为 4 的数组 perA
,每个元素都是另一个数组。每个内部数组的长度为 3。每个内部数组的 3 个元素连续存储,但这些数组不连续。因此,您需要一次复制一行。
具体如何实现取决于您的 Delphi 矩阵是以行优先还是列优先存储的。如果是前者,那么填充矩阵然后转置它是最简单的。两种变体的代码可能如下所示:
type
TDoubleMatrix = array of array of Double;
function CreateDoubleMatrixColMajor(nRow, nCol: Integer): TDoubleMatrix;
begin
SetLength(Result, nCol, nRow);
end;
function CreatemxArrayFromColMajor(const M: TDoubleMatrix): PmxArray;
var
col: Integer;
nRow, nCol: Integer;
values: PDouble;
begin
nCol := Length(M);
Assert(nCol > 0);
nRow := Length(M[0]);
Assert(nRow > 0);
result := mxCreateDoubleMatrix(nRow, nCol, mxREAL);
values := mxGetData(result);
for col := 0 to nCol - 1 do
begin
Assert(Length(M[col]) = nRow);
Move(M[col], values^, nRow * SizeOf(Double));
inc(values, nRow);
end;
end;
function CreateDoubleMatrixRowMajor(nRow, nCol: Integer): TDoubleMatrix;
begin
SetLength(Result, nRow, nCol);
end;
function CreatemxArrayFromRowMajor(const M: TDoubleMatrix): PmxArray;
var
row: Integer;
nRow, nCol: Integer;
tmp: PmxArray;
values: PDouble;
begin
nRow := Length(M);
Assert(nRow > 0);
nCol := Length(M[0]);
Assert(nCol > 0);
tmp := mxCreateDoubleMatrix(nCol, nRow, mxREAL);
values := mxGetData(tmp);
for row := 0 to nRow - 1 do
begin
Assert(Length(M[row]) = nCol);
Move(M[row], values^, nCol * SizeOf(Double));
inc(values, nCol);
end;
mexCallMATLAB(1, @result, 1, @tmp, 'transpose');
mxDestroyArray(tmp);
end;
我什至没有编译任何代码。我所有的Matlab编程都是用C语言完成的。但是我认为上面应该有你需要的想法。
如果我使用非动态数组,一切正常
pmxArray = mxArray^;
perA_ptr: pmxArray;
perA: array[1..3,1..4] of double;
perA_ptr := mxCreateDoubleMatrix(4,3,mxREAL);
Move(perA, mxGetPr(perA_ptr)^, 4*3*sizeof(double));
......
_mlflinprog1(1,perX_ptr,perF_ptr,perA_ptr,perB_ptr,perLB_ptr);
这是可行的。
但我需要使用动态数组。我有一个问题
perA: array of array of Double;
SetLength(perA,4,3);
perA_ptr := mxCreateDoubleMatrix(4,3,mxREAL);
Move(perA, mxGetPr(perA_ptr)^, 12*sizeof(double));
不起作用,数组中只有垃圾;
Move(perA[0,0], mxGetPr(perA_ptr)^, 4*sizeof(double));
- 第一行有效,但我需要复制所有数组的数据,IDK 如何在 delphi.
这是 matlab c 共享库所需的数组。
您的静态数组存储在一个连续的块中。二维动态数组参差不齐。在 C 术语中,您有 double**
。尽管 Delphi 数组有额外的簿记功能,但这就是您需要考虑的方式。
所以当你这样做时
SetLength(perA, 4, 3);
你有一个长度为 4 的数组 perA
,每个元素都是另一个数组。每个内部数组的长度为 3。每个内部数组的 3 个元素连续存储,但这些数组不连续。因此,您需要一次复制一行。
具体如何实现取决于您的 Delphi 矩阵是以行优先还是列优先存储的。如果是前者,那么填充矩阵然后转置它是最简单的。两种变体的代码可能如下所示:
type
TDoubleMatrix = array of array of Double;
function CreateDoubleMatrixColMajor(nRow, nCol: Integer): TDoubleMatrix;
begin
SetLength(Result, nCol, nRow);
end;
function CreatemxArrayFromColMajor(const M: TDoubleMatrix): PmxArray;
var
col: Integer;
nRow, nCol: Integer;
values: PDouble;
begin
nCol := Length(M);
Assert(nCol > 0);
nRow := Length(M[0]);
Assert(nRow > 0);
result := mxCreateDoubleMatrix(nRow, nCol, mxREAL);
values := mxGetData(result);
for col := 0 to nCol - 1 do
begin
Assert(Length(M[col]) = nRow);
Move(M[col], values^, nRow * SizeOf(Double));
inc(values, nRow);
end;
end;
function CreateDoubleMatrixRowMajor(nRow, nCol: Integer): TDoubleMatrix;
begin
SetLength(Result, nRow, nCol);
end;
function CreatemxArrayFromRowMajor(const M: TDoubleMatrix): PmxArray;
var
row: Integer;
nRow, nCol: Integer;
tmp: PmxArray;
values: PDouble;
begin
nRow := Length(M);
Assert(nRow > 0);
nCol := Length(M[0]);
Assert(nCol > 0);
tmp := mxCreateDoubleMatrix(nCol, nRow, mxREAL);
values := mxGetData(tmp);
for row := 0 to nRow - 1 do
begin
Assert(Length(M[row]) = nCol);
Move(M[row], values^, nCol * SizeOf(Double));
inc(values, nCol);
end;
mexCallMATLAB(1, @result, 1, @tmp, 'transpose');
mxDestroyArray(tmp);
end;
我什至没有编译任何代码。我所有的Matlab编程都是用C语言完成的。但是我认为上面应该有你需要的想法。