2012-10-21 47 views
1

以前我有用於矩陣數據集設計從靜態數組遷移到動態數組

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×160在2維矩陣的設計。如果我輸入更多陣列大小[1..161,1..161],編譯器將提醒爲E2100數據類型過大:超過2GB錯誤。所以如果我將代碼轉換爲動態數組,我需要重新構造我當前的所有代碼以讀取從0開始的矩陣。對於靜態數組,陣列將從1開始。一些外部函數開始從1讀取矩陣。

所以,現在我堅持使用當前代碼,我需要創建超過一千個N x N矩陣大小。用我目前的靜態數組設計,如果低於160 x 160,一切都會好起來。所以,我需要獲得任何解決方案而不需要太多來改變我當前的靜態數組設計。

謝謝。

+0

這裏有更大的問題!如果161x161大於2GB,切換到動態數組將無濟於事,因爲Win32進程的最大分配大小爲2GB。除非你去64位,否則你會很困難! – LaKraven

+1

'161 * 161 * SizeOf(Real)'當然不大於2GB –

+1

帶有161x161的TMatrix的大小爲207376字節。 –

回答

6

繼續使用基於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移植使用基於1的索引的代碼,則此方法通常最有效。

+0

+1,但爲什麼要有額外的行和列?我會認爲使用記錄及其獲取者和設置者足以進行索引轉換?我唯一能想到的是外部索引調試時間匹配到內部索引嗎? –

+0

@MarjanVenema你當然可以在getter和setter中做0到1的索引移位。這是完全可行的。但是,它在索引代碼中會產生大量的+1和-1性能損失。通常這並不重要,但有時候確實如此。就我而言,在我的代碼庫中,像這樣的矩陣是我的代碼算法的核心,甚至幾%的性能下降也很重要。 –

+0

啊,在犧牲一點數據空間的同時犧牲性能......我喜歡:) –