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索引惩罚,那将是令人惊讶的。看起来我现在找到了解决方案。谢谢大家的帮助。代码工作起来就像一个魅力,只需很少的修改。