如何将多维动态数组移动或复制到 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语言完成的。但是我认为上面应该有你需要的想法。