Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 从静态阵列迁移到动态阵列_Delphi_Matrix - Fatal编程技术网

Delphi 从静态阵列迁移到动态阵列

Delphi 从静态阵列迁移到动态阵列,delphi,matrix,Delphi,Matrix,之前,我为矩阵数据集设计了静态数组 TMatrix = record row, column: word; {m columns ,n strings } Data: array[1..160, 1..160] of real var Mymatrix : TMatrix; begin Mymatrix.row := 160; - maximum size for row us is 160 for 2 x 2 static design. Mymatrix.c

之前,我为矩阵数据集设计了静态数组

TMatrix = record
    row, column: word; {m columns ,n strings }
    Data: array[1..160, 1..160] of real

 var
 Mymatrix  : TMatrix;

 begin

 Mymatrix.row := 160; - maximum size for row us is 160 for 2 x 2 static design.
 Mymatrix.columns := 160; -  maximum size for column us is 160  for 2 x 2 static design.
以目前的设计,我只能有160 x 160的二维矩阵设计。如果输入更多数组大小[1..161,1..161],编译器将警告E2100数据类型太大:超过2 GB错误。因此,如果我将代码转换为动态数组,我需要重新构造所有当前代码,以读取从0开始的矩阵。先前,对于静态数组,数组将从1开始。一些外部函数从1开始读取矩阵

所以,现在我一直在使用我当前的代码,我需要创建超过1000个N x N的矩阵大小。在我目前的静态阵列设计中,如果低于160 x 160,一切正常。因此,我需要在不改变当前静态阵列设计的情况下获得任何解决方案


谢谢。

继续使用基于1的索引会更容易。你可以用几种不同的方法。例如:

type
  TMatrix = record
  private
    Data: array of array of Real;
    function GetRowCount: Integer;
    function GetColCount: Integer;
    function GetItem(Row, Col: Integer): Real;
    procedure SetItem(Row, Col: Integer; Value: Real);
  public      
    procedure SetSize(RowCount, ColCount: Integer);
    property RowCount: Integer read GetRowCount;
    property ColCount: Integer read GetColCount;
    property Items[Row, Col: Integer]: Real read GetItem write SetItem; default;
  end;

function TMatrix.GetRowCount: Integer;
begin
  Result := Length(Data)-1;
end;

function TMatrix.GetColCount: Integer;
begin
  if Assigned(Data) then
    Result := Length(Data[0])-1
  else
    Result := 0;
end;

procedure TMatrix.SetSize(RowCount, ColCount: Integer);
begin
  SetLength(Data, RowCount+1, ColCount+1);
end;

function TMatrix.GetItem(Row, Col: Integer): Real;
begin
  Assert(InRange(Row, 1, RowCount));
  Assert(InRange(Col, 1, ColCount));
  Result := Data[Row, Col];
end;

procedure TMatrix.SetItem(Row, Col: Integer; Value: Real);
begin
  Assert(InRange(Row, 1, RowCount));
  Assert(InRange(Col, 1, ColCount));
  Data[Row, Col] := Value;
end;

这里的技巧是,即使动态数组使用基于0的索引,您也只需忽略存储在0索引中的值。如果您从使用基于1的索引的Fortran移植代码,这种方法通常是最有效的。

继续使用基于1的索引会更容易。你可以用几种不同的方法。例如:

type
  TMatrix = record
  private
    Data: array of array of Real;
    function GetRowCount: Integer;
    function GetColCount: Integer;
    function GetItem(Row, Col: Integer): Real;
    procedure SetItem(Row, Col: Integer; Value: Real);
  public      
    procedure SetSize(RowCount, ColCount: Integer);
    property RowCount: Integer read GetRowCount;
    property ColCount: Integer read GetColCount;
    property Items[Row, Col: Integer]: Real read GetItem write SetItem; default;
  end;

function TMatrix.GetRowCount: Integer;
begin
  Result := Length(Data)-1;
end;

function TMatrix.GetColCount: Integer;
begin
  if Assigned(Data) then
    Result := Length(Data[0])-1
  else
    Result := 0;
end;

procedure TMatrix.SetSize(RowCount, ColCount: Integer);
begin
  SetLength(Data, RowCount+1, ColCount+1);
end;

function TMatrix.GetItem(Row, Col: Integer): Real;
begin
  Assert(InRange(Row, 1, RowCount));
  Assert(InRange(Col, 1, ColCount));
  Result := Data[Row, Col];
end;

procedure TMatrix.SetItem(Row, Col: Integer; Value: Real);
begin
  Assert(InRange(Row, 1, RowCount));
  Assert(InRange(Col, 1, ColCount));
  Data[Row, Col] := Value;
end;


这里的技巧是,即使动态数组使用基于0的索引,您也只需忽略存储在0索引中的值。如果您从Fortran移植代码,而Fortran使用基于1的索引,这种方法通常是最有效的。

这里有一个更大的问题!如果161x161大于2GB,则切换到动态阵列将无济于事,因为Win32进程的最大分配大小为2GB。除非你转到64位,否则你几乎被卡住了
161*161*SizeOf(Real)
当然不大于2GB的TMatrix,161x161为207376字节。您应该能够编译
数据:Real的数组[1..16383,1..16383]
@David,Sertac:除非
real
被重新定义为其他东西(这不太可能,但可能)。你这里有一个更大的问题!如果161x161大于2GB,则切换到动态阵列将无济于事,因为Win32进程的最大分配大小为2GB。除非你转到64位,否则你几乎被卡住了
161*161*SizeOf(Real)
当然不大于2GB的TMatrix,161x161为207376字节。您应该能够编译
数据:Real的数组[1..16383,1..16383]
@David,Sertac:除非
real
被重新定义为其他东西(这不太可能,但可能)。+1但是为什么要有额外的行和列呢?我认为使用记录及其getter和setter就足以进行索引转换了?我能想到的唯一原因是外部索引与内部索引的调试时间匹配?@marjannema您当然可以在getter和setter中执行基于0到1的索引移位。这是完全可行的。但是,索引代码中有大量的+1和-1会导致性能下降。通常这并不重要,但有时的确如此。在我的例子中,在我的代码库中,像这样的矩阵是我代码算法的核心,甚至性能下降两个百分点都很重要。啊,牺牲一点数据空间来获得性能。。。我喜欢:)@marjannema我确实想知道Fortran实现如何处理这个问题。考虑到效率对于典型Fortran代码的高度重要性,如果基于1的Fortran数组和矩阵必须支付+1索引惩罚,那将是令人惊讶的。看起来我现在找到了解决方案。谢谢大家的帮助。代码工作起来就像一个符咒,只需要很少的修改。+1但是为什么要有一个额外的行和列呢?我认为使用记录及其getter和setter就足以进行索引转换了?我能想到的唯一原因是外部索引与内部索引的调试时间匹配?@marjannema您当然可以在getter和setter中执行基于0到1的索引移位。这是完全可行的。但是,索引代码中有大量的+1和-1会导致性能下降。通常这并不重要,但有时的确如此。在我的例子中,在我的代码库中,像这样的矩阵是我代码算法的核心,甚至性能下降两个百分点都很重要。啊,牺牲一点数据空间来获得性能。。。我喜欢:)@marjannema我确实想知道Fortran实现如何处理这个问题。考虑到效率对于典型Fortran代码的高度重要性,如果基于1的Fortran数组和矩阵必须支付+1索引惩罚,那将是令人惊讶的。看起来我现在找到了解决方案。谢谢大家的帮助。代码工作起来就像一个魅力,只需很少的修改。