You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7097 8e941d3f-bd1b-0410-a28a-d453659cc2b4
270 lines
6.1 KiB
ObjectPascal
270 lines
6.1 KiB
ObjectPascal
{-----------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: JvTFSparseMatrix.PAS, released on 2003-08-01.
|
|
|
|
The Initial Developer of the Original Code is Unlimited Intelligence Limited.
|
|
Portions created by Unlimited Intelligence Limited are Copyright (C) 1999-2002 Unlimited Intelligence Limited.
|
|
All Rights Reserved.
|
|
|
|
Contributor(s):
|
|
Mike Kolter (original code)
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.delphi-jedi.org
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
// $Id$
|
|
|
|
unit JvTFSparseMatrix;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils;
|
|
|
|
type
|
|
// NativeInt = Integer;
|
|
|
|
EJvTFSparseMatrixError = class(Exception);
|
|
PSMQuantum = ^TSMQuantum;
|
|
TSMQuantum = record
|
|
Index: Integer;
|
|
Data: NativeInt;
|
|
Link: PSMQuantum;
|
|
end;
|
|
|
|
TJvTFSparseMatrix = class(TObject)
|
|
private
|
|
FMatrix: TSMQuantum;
|
|
FNullValue: NativeInt;
|
|
procedure SetNullValue(Value: NativeInt);
|
|
function GetData(Row, Col: Integer): NativeInt;
|
|
procedure SetData(Row, Col: Integer; Value: NativeInt);
|
|
procedure Put(Row, Col: Integer; Data: NativeInt);
|
|
function Get(Row, Col: Integer): NativeInt;
|
|
function FindQuantum(Row, Col: Integer;
|
|
var Prev, Curr: PSMQuantum; var RowExists: Boolean): Boolean;
|
|
public
|
|
destructor Destroy; override;
|
|
procedure Clear;
|
|
procedure Pack;
|
|
procedure CopyTo(DestMatrix: TJvTFSparseMatrix);
|
|
property Data[Row, Col: Integer]: NativeInt read GetData write SetData; default;
|
|
property NullValue: NativeInt read FNullValue write SetNullValue default 0;
|
|
procedure Dump(const DumpList: TStrings);
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
JvResources;
|
|
|
|
destructor TJvTFSparseMatrix.Destroy;
|
|
begin
|
|
Clear;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.Clear;
|
|
var
|
|
P, CurrRow, CurrCol: PSMQuantum;
|
|
begin
|
|
CurrRow := PSMQuantum(FMatrix.Data);
|
|
|
|
while CurrRow <> nil do
|
|
begin
|
|
CurrCol := CurrRow^.Link;
|
|
while CurrCol <> nil do
|
|
begin
|
|
P := CurrCol;
|
|
CurrCol := CurrCol^.Link;
|
|
Dispose(P);
|
|
end;
|
|
|
|
P := CurrRow;
|
|
CurrRow := PSMQuantum(CurrRow^.Data);
|
|
Dispose(P);
|
|
end;
|
|
|
|
FMatrix.Data := 0;
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.CopyTo(DestMatrix: TJvTFSparseMatrix);
|
|
var
|
|
CurrRow, CurrCol: PSMQuantum;
|
|
begin
|
|
DestMatrix.Clear;
|
|
DestMatrix.NullValue := NullValue;
|
|
|
|
CurrRow := PSMQuantum(FMatrix.Data);
|
|
|
|
while CurrRow <> nil do
|
|
begin
|
|
CurrCol := CurrRow^.Link;
|
|
while CurrCol <> nil do
|
|
begin
|
|
DestMatrix[CurrRow^.Index, CurrCol^.Index] := CurrCol^.Data;
|
|
CurrCol := CurrCol^.Link;
|
|
end;
|
|
|
|
CurrRow := PSMQuantum(CurrRow^.Data);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.Dump(const DumpList: TStrings);
|
|
var
|
|
CurrRow, CurrCol: PSMQuantum;
|
|
begin
|
|
DumpList.Clear;
|
|
CurrRow := PSMQuantum(FMatrix.Data);
|
|
DumpList.BeginUpdate;
|
|
try
|
|
while CurrRow <> nil do
|
|
begin
|
|
CurrCol := CurrRow^.Link;
|
|
while CurrCol <> nil do
|
|
begin
|
|
DumpList.Add('(' + IntToStr(CurrRow^.Index) + ', ' +
|
|
IntToStr(CurrCol^.Index) + ') ' +
|
|
IntToStr(CurrCol^.Data));
|
|
CurrCol := CurrCol^.Link;
|
|
end;
|
|
CurrRow := PSMQuantum(CurrRow^.Data);
|
|
end;
|
|
finally
|
|
DumpList.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TJvTFSparseMatrix.FindQuantum(Row, Col: Integer;
|
|
var Prev, Curr: PSMQuantum; var RowExists: Boolean): Boolean;
|
|
begin
|
|
Prev := @FMatrix;
|
|
Curr := PSMQuantum(FMatrix.Data);
|
|
Result := False;
|
|
RowExists := False;
|
|
|
|
// Find Row Header
|
|
while (Curr <> nil) and (Curr^.Index < Row) do
|
|
begin
|
|
Prev := Curr;
|
|
Curr := PSMQuantum(Curr^.Data);
|
|
end;
|
|
|
|
// If Row Header found, then find col
|
|
if (Curr <> nil) and (Curr^.Index = Row) then
|
|
begin
|
|
RowExists := True;
|
|
Prev := Curr;
|
|
Curr := Curr^.Link;
|
|
while (Curr <> nil) and (Curr^.Index < Col) do
|
|
begin
|
|
Prev := Curr;
|
|
Curr := Curr^.Link;
|
|
end;
|
|
|
|
Result := (Curr <> nil) and (Curr^.Index = Col);
|
|
end;
|
|
end;
|
|
|
|
function TJvTFSparseMatrix.Get(Row, Col: Integer): NativeInt;
|
|
var
|
|
Prev, Curr: PSMQuantum;
|
|
RowExists: Boolean;
|
|
begin
|
|
if FindQuantum(Row, Col, Prev, Curr, RowExists) then
|
|
Result := Curr^.Data
|
|
else
|
|
Result := NullValue;
|
|
end;
|
|
|
|
function TJvTFSparseMatrix.GetData(Row, Col: Integer): NativeInt;
|
|
begin
|
|
Result := Get(Row, Col);
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.Put(Row, Col: Integer; Data: NativeInt);
|
|
var
|
|
P, Prev, Curr: PSMQuantum;
|
|
RowExists: Boolean;
|
|
begin
|
|
if FindQuantum(Row, Col, Prev, Curr, RowExists) then
|
|
if Data <> NullValue then
|
|
Curr^.Data := Data
|
|
else
|
|
begin
|
|
Prev^.Link := Curr^.Link;
|
|
Dispose(Curr);
|
|
end
|
|
else
|
|
if Data <> NullValue then
|
|
begin
|
|
if not RowExists then
|
|
begin
|
|
New(P);
|
|
P^.Index := Row;
|
|
P^.Link := nil;
|
|
P^.Data := Prev^.Data;
|
|
PSMQuantum(Prev^.Data) := P;
|
|
Prev := P;
|
|
end;
|
|
|
|
New(P);
|
|
P^.Index := Col;
|
|
P^.Data := Data;
|
|
P^.Link := Prev^.Link;
|
|
Prev^.Link := P;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.SetData(Row, Col: Integer; Value: NativeInt);
|
|
begin
|
|
Put(Row, Col, Value);
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.SetNullValue(Value: NativeInt);
|
|
begin
|
|
if FMatrix.Data = 0 then
|
|
FNullValue := Value
|
|
else
|
|
raise EJvTFSparseMatrixError.CreateRes(@RsEMatrixMustBeEmpty);
|
|
end;
|
|
|
|
procedure TJvTFSparseMatrix.Pack;
|
|
var
|
|
P, Prev, CurrRow: PSMQuantum;
|
|
begin
|
|
CurrRow := PSMQuantum(FMatrix.Data);
|
|
Prev := @FMatrix;
|
|
|
|
while CurrRow <> nil do
|
|
begin
|
|
if CurrRow^.Link <> nil then
|
|
begin
|
|
Prev := CurrRow;
|
|
CurrRow := PSMQuantum(CurrRow^.Data);
|
|
end
|
|
else
|
|
begin
|
|
P := CurrRow;
|
|
Prev^.Data := CurrRow^.Data;
|
|
Dispose(P);
|
|
CurrRow := PSMQuantum(Prev^.Data);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|