unit ASNumUtils;
{$WARN SYMBOL_PLATFORM OFF}
{$WARN DUPLICATE_CTOR_DTOR OFF}
interface
uses SysUtils, Types, Math, ASNum, ASColors, ASPixmap;
type
TNumColorFunc<T> = reference to function(const Value: T): TASPixel;
TMatrixNormalizationKind = (mnkNone, mnkMinMax, mnkModulus);
TNonOptionalMatrixNormalizationKind = mnkMinMax..mnkModulus;
function MatrixPlot(const AMatrix: TRealMatrix;
AColorFunc: TNumColorFunc<TASR>; AWidth, AHeight: Integer;
ANormalizationKind: TMatrixNormalizationKind = mnkNone): TASPixmap; overload;
function MatrixPlot(const AMatrix: TRealMatrix;
const AColor: TASPixel; AWidth, AHeight: Integer;
ANormalizationKind: TNonOptionalMatrixNormalizationKind): TASPixmap; overload;
function MatrixPlot(const AMatrix: TRealMatrix;
const AColor1, AColor2: TASPixel; AWidth, AHeight: Integer;
ANormalizationKind: TNonOptionalMatrixNormalizationKind): TASPixmap; overload;
function MatrixPlot(const AMatrix: TRealMatrix;
const AColor1, AColor2, AColor3: TASPixel; AWidth, AHeight: Integer;
ANormalizationKind: TNonOptionalMatrixNormalizationKind): TASPixmap; overload;
implementation
function MatrixPlot(const AMatrix: TRealMatrix;
AColorFunc: TNumColorFunc<TASR>; AWidth, AHeight: Integer;
ANormalizationKind: TMatrixNormalizationKind): TASPixmap; overload;
var
CellWidth, CellHeight: Double;
y: Integer;
x: Integer;
minval, maxval, span: TASR;
begin
AWidth := Max(AWidth, AMatrix.Size.Cols);
AHeight := Max(AHeight, AMatrix.Size.Rows);
Result := TASPixmap.CreateUninitialized(AWidth, AHeight);
CellWidth := AWidth / AMatrix.Size.Cols;
CellHeight := AHeight / AMatrix.Size.Rows;
case ANormalizationKind of
mnkNone:
for y := 0 to AMatrix.Size.Rows - 1 do
for x := 0 to AMatrix.Size.Cols - 1 do
Result.FillRect(
Rect(Round(x * CellWidth),
Round(y * CellHeight),
Round((x + 1) * CellWidth),
Round((y + 1) * CellHeight)),
AColorFunc(AMatrix[y, x]));
mnkMinMax:
begin
minval := Min(AMatrix);
maxval := Max(AMatrix);
span := maxval - minval;
if span = 0 then
raise EMathException.Create('MatrixPlot: The smallest and the greatest value in the matrix coincide.');
for y := 0 to AMatrix.Size.Rows - 1 do
for x := 0 to AMatrix.Size.Cols - 1 do
Result.FillRect(
Rect(Round(x * CellWidth),
Round(y * CellHeight),
Round((x + 1) * CellWidth),
Round((y + 1) * CellHeight)),
AColorFunc((AMatrix[y, x] - minval) / span));
end;
mnkModulus:
begin
maxval := Max(AMatrix.Abs());
minval := -maxval;
span := maxval - minval;
if maxval = 0 then
raise EMathException.Create('MatrixPlot: The smallest and the greatest value in the matrix coincide.');
for y := 0 to AMatrix.Size.Rows - 1 do
for x := 0 to AMatrix.Size.Cols - 1 do
Result.FillRect(
Rect(Round(x * CellWidth),
Round(y * CellHeight),
Round((x + 1) * CellWidth),
Round((y + 1) * CellHeight)),
AColorFunc((AMatrix[y, x] - minval) / span));
end;
end;
end;
function MatrixPlot(const AMatrix: TRealMatrix;
const AColor: TASPixel; AWidth, AHeight: integer;
ANormalizationKind: TNonOptionalMatrixNormalizationKind): TASPixmap;
var
f: TNumColorFunc<TASR>;
begin
f := function(const Value: TASR): TASPixel
begin
Result := Value * AColor;
end;
Result := MatrixPlot(AMatrix, f, AWidth, AHeight, ANormalizationKind);
end;
function MatrixPlot(const AMatrix: TRealMatrix;
const AColor1, AColor2: TASPixel; AWidth, AHeight: integer;
ANormalizationKind: TNonOptionalMatrixNormalizationKind): TASPixmap;
var
f: TNumColorFunc<TASR>;
begin
f := function(const Value: TASR): TASPixel
begin
Result := (1 - Value) * AColor1 + Value * AColor2;
end;
Result := MatrixPlot(AMatrix, f, AWidth, AHeight, ANormalizationKind);
end;
function MatrixPlot(const AMatrix: TRealMatrix;
const AColor1, AColor2, AColor3: TASPixel; AWidth, AHeight: integer;
ANormalizationKind: TNonOptionalMatrixNormalizationKind): TASPixmap;
var
f: TNumColorFunc<TASR>;
begin
f := function(const Value: TASR): TASPixel
begin
if Value < 0.5 then
Result := (1 - 2*Value) * AColor1 + 2*Value * AColor2
else
Result := (1 - 2*(Value - 0.5)) * AColor2 + 2*(Value - 0.5) * AColor3
end;
Result := MatrixPlot(AMatrix, f, AWidth, AHeight, ANormalizationKind);
end;
end.