AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Einfache Version von Numpy in Delphi nachbauen

Ein Thema von bernhard_LA · begonnen am 3. Jan 2024 · letzter Beitrag vom 3. Jan 2024
 
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.124 Beiträge
 
Delphi 11 Alexandria
 
#1

Einfache Version von Numpy in Delphi nachbauen

  Alt 3. Jan 2024, 07:53
Ich will Python-Code unter Delphi nachbauen und dann in einem weiteren Schritt mit meinen eigenen Ideen , Bibliotheken auf meine eigentliche Aufgabenstellung anpassen.
Ich brauche im ersten Schritt um im Programm-Ablauf identisch zum Original-Code zu bleiben, eine "Mini"-Numpy Emulierung. Weiter unten habe ich meine "Spielversion" - eingefügt.

Meine Frage : was wäre die beste Lösung um alle ArrayTypen (Integer, Float, Bool) zu unterstützen ? Wie würde man am elegantesten 2D und 3D Array Typen untertützen , dh. eine Interpretation meines 1D-Arrays in 2D oder 3D
.


Delphi-Quellcode:
var
  A: TNDArray;
  i, j: Integer;
  NumPy : TNumPy;
begin

  A := TNumPy.ToArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

  // Save the 2D array as a CSV file
  TNumPy.Shape(4, 4); // Set the shape of the array

  TNumPy.Savetxt('c:\temp\output.csv', A ); // Save the array as a CSV file
end ;



Andere Ideen zu diesem Projekt, bin für alle Anmerkungen offen









Delphi-Quellcode:
unit Unit_NumPy;

interface

uses
  System.Classes, System.SysUtils, System.Generics.Collections, System.Math;

type
  T2DDoubleArray = array of array of Double;
  TNDArray = TArray<Double>;
  TNDArray2 = TArray<TNDArray> ;
  TByteArray = TArray<Byte>;
  TBoolArray = Tarray<Boolean>;
  TCardinalArray = TArray<Cardinal>;
  TIntegerArray = TArray<Integer>;


  TNumPy = class
  class var
    FWidth: Integer;
    FHeight: Integer;

  private


  public
    class function arange(const start, stop, step: Double): TNDArray; static;
    class function ToArray(const Values: array of Double): TNDArray; overload; static;
    class function ToArray(const Values: T2DDoubleArray): TArray<TNDArray>; overload; static;
    class function diff(const a: TNDArray): TNDArray; static;
    class function mean(const a: TNDArray): Double; static;
    class function sum(const a: TNDArray): Double; static;
    class function prod(const a: TNDArray): Double; static;
    class function ConvertByteArrayToNDArray(const a: TByteArray)
      : TNDArray; static;
    class function max(const a: TNDArray): Double; static;
    class function min(const a: TNDArray): Double; static;
    class function unique(const a: TNDArray): TNDArray; static;
    class function isnan(const a: TNDArray): TBoolArray; static;
    class function all(const a: TNDArray): Boolean;
    class procedure Shape(X, y: Integer);
    class procedure Savetxt(const fname: string; const X: TNDArray;
      const fmt: string = '%.18e'; const delimiter: string = ';';
      const newline: string = #10; const header: string = '';
      const footer: string = ''; const comments: string = '# ';
      const encoding: TEncoding = nil);

  end;

implementation

{ TNumPy }


class function TNumPy.min(const a: TNDArray): Double;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);

  if n = 0 then
    Exit(0);

  Result := a[0];

  for i := 1 to n - 1 do
    if a[i] < Result then
      Result := a[i];
end;



class function TNumPy.max(const a: TNDArray): Double;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);

  if n = 0 then
    Exit(0);

  Result := a[0];

  for i := 1 to n - 1 do
    if a[i] > Result then
      Result := a[i];
end;



class function TNumPy.ToArray(const Values: array of Double): TNDArray;
var
  i: Integer;
begin
  SetLength(Result, Length(Values));
  for i := 0 to High(Values) do
    Result[i] := Values[i];
end;


class function TNumPy.isnan(const a: TNDArray): TBoolArray;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);
  SetLength(Result, n);

  for i := 0 to n - 1 do
    Result[i] := System.Math.IsNan(a[i]);
end;

class function TNumPy.ToArray(const Values: T2DDoubleArray): TArray<TNDArray>;
var
  i, j: Integer;
begin
  SetLength(Result, Length(Values));
  for i := 0 to High(Values) do
  begin
    SetLength(Result[i], Length(Values[i]));
    for j := 0 to High(Values[i]) do
      Result[i][j] := Values[i][j];
  end;
end;

class function TNumPy.arange(const start, stop, step: Double): TNDArray;
var
  i: Integer;
  n: Integer;
begin
  n := Round((stop - start) / step);
  SetLength(Result, n);

  for i := 0 to n - 1 do
    Result[i] := start + i * step;
end;

class function TNumPy.ConvertByteArrayToNDArray(const a: TByteArray): TNDArray;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);
  SetLength(Result, n);

  for i := 0 to n - 1 do
    Result[i] := a[i];
end;

class function TNumPy.diff(const a: TNDArray): TNDArray;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a) - 1;
  SetLength(Result, n);

  for i := 0 to n - 1 do
    Result[i] := a[i + 1] - a[i];
end;

class function TNumPy.mean(const a: TNDArray): Double;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);

  if n = 0 then
    Exit(0);

  Result := 0;

  for i := 0 to n - 1 do
    Result := Result + a[i];

  Result := Result / n;
end;

class function TNumPy.prod(const a: TNDArray): Double;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);
  Result := 1;

  for i := 0 to n - 1 do
    Result := Result * a[i];
end;

class procedure TNumPy.Shape(X, y: Integer);
begin
  FWidth := X;
  FHeight := y;
end;

class function TNumPy.unique(const a: TNDArray): TNDArray;
var
  i, j: Integer;
  temp: Double;
  uniqueArr: TList<Double>;
begin
  uniqueArr := TList<Double>.Create;

  try
    for i := 0 to Length(a) - 1 do
    begin
      temp := a[i];
      if not uniqueArr.Contains(temp) then
        uniqueArr.Add(temp);
    end;

    SetLength(Result, uniqueArr.Count);

    for j := 0 to uniqueArr.Count - 1 do
      Result[j] := uniqueArr[j];

  finally
    uniqueArr.Free;
  end;
end;

class function TNumPy.sum(const a: TNDArray): Double;
var
  i: Integer;
  n: Integer;
begin
  n := Length(a);
  Result := 0;

  for i := 0 to n - 1 do
    Result := Result + a[i];
end;

class procedure TNumPy.Savetxt(const fname: string; const X: TNDArray;
  const fmt: string = '%.18e'; const delimiter: string = ';';
  const newline: string = #10; const header: string = '';
  const footer: string = ''; const comments: string = '# ';
  const encoding: TEncoding = nil);
var
  sl: TStringList;
  i, j: Integer;
  row: string;
  width, height: Integer;
begin
  width := FWidth;
  Height := FHeight;

  if (width = 0) or (height = 0) then
    raise Exception.Create('Invalid array shape');

  sl := TStringList.Create;

  try
    if header <> 'then
      sl.Add(comments + header);

    for i := 0 to height - 1 do
    begin
      row := Format(fmt, [X[i * width]]);
      for j := 1 to width - 1 do
        row := row + delimiter + Format(fmt, [X[i * width + j]]);
      sl.Add(row);
    end;

    if footer <> 'then
      sl.Add(comments + footer);

    sl.SaveToFile(fname, encoding);

  finally
    sl.Free;
  end;
end;


class function TNumPy.all(const a: TNDArray): Boolean;
var
  i: Integer;
begin
  for i := 0 to Length(a) - 1 do
  begin
    if not (a[i] <> 0) then
    begin
      Result := False;
      Exit;
    end;
  end;
  Result := True;
end;

end.

Geändert von bernhard_LA ( 3. Jan 2024 um 07:55 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz