Bonjour,

Je ne sais pas si je suis au bon endroit, mais j'essaye de traduire une fonction récursive python en delphi pascal et je n'y arrive pas .
La fonction python est un calcul de fft :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def fft(u):
    # u : numpy.ndarray
    N = len(u)
    if N==1:
        return u
    pair = u[0::2]
    impair = u[1::2]
    tfd_pair = fft(pair)
    tfd_impair = fft(impair)
    tfd = numpy.zeros(N,dtype=numpy.complex64)
    W = numpy.exp(-1j*2*numpy.pi/N)
    N2 = N//2
    for n in range(N2):
        tfd[n] = tfd_pair[n]+tfd_impair[n]*W**n
    for n in range(N2,N):
        tfd[n] = tfd_pair[n-N2]+tfd_impair[n-N2]*W**n
    return tfd
j'ai essayé de faire la traduction en delphi mais ça ne semble pas marcher.
Il a fallu que j'implémente un type Tcomplex qui n'existe pas en delphi, avec quelques fonctions associées
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
type 
   TComplex=packed record
      re: double;
      im: double;
 
      class function Pui(const x: TComplex; n: Integer): TComplex; static;
      class operator Multiply(const x, y: TComplex): TComplex;
      class operator Add(const x, y: TComplex): TComplex;
   end;
 
 
type
   taocx=array of TComplex;
   ptaocx=^taocx;
 
function PuiCx(const x: TComplex; n: Integer): TComplex; overload;
 
implementation
 
{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}
{$R *.iPhone4in.fmx IOS}
 
// opérations sur nombres complexes
class function TComplex.Pui(const x: TComplex; n: Integer): TComplex;
var
  r, theta: Double;
begin
// Convertir x en coordonnées polaires
r := Hypot(x.Re, x.Im);
theta := ArcTan2(x.Im, x.Re);
 
// Appliquer la formule de Moivre
r := Power(r, n);
theta := theta * n;
 
// Convertir le résultat en coordonnées rectangulaires
Result.Re := r * Cos(theta);
Result.Im := r * Sin(theta);
end;
 
function PuiCx(const x: TComplex; n: Integer): TComplex;
begin
result:=TComplex.Pui(x, n);
end;
 
class operator TComplex.Add(const x, y: TComplex): TComplex;
begin
Result.Re := x.Re + y.Re;
Result.Im := x.Im + y.Im;
end;
 
class operator TComplex.Multiply(const x, y: TComplex): TComplex;
begin
Result.Re := x.Re * y.Re - x.Im * y.Im;
Result.Im := x.Re * y.Im + x.Im * y.Re;
end;
 
// en paramètres d entrée : tableau des complexes issus de la conversion des entiers   
// en résultat le tableau de la FFT
function FFT(cxs: taocx): taocx;
   var
      Nb, N2, n: Integer;
      pair, impair, tfd_pair, tfd_impair, tfd: taocx;
      W: TComplex;
   begin
 
   Nb := Length(cxs);
   if Nb = 1 then
      Exit(cxs);
   SetLength(pair, Nb div 2);
   SetLength(impair, Nb div 2);
   for n := 0 to Nb div 2 - 1 do
      begin
      pair[n] := cxs[2*n];
      impair[n] :=cxs[(2*n)+1];
      end;
   tfd_pair := FFT(pair);
   tfd_impair := FFT(impair);
   SetLength(tfd, Nb);
   W.re:=0;
   W.im:=-(2*Pi/Nb);
   N2 := Nb div 2;
   for n := 0 to N2 - 1 do
      begin
      tfd[n] := tfd_pair[n] + (tfd_impair[n] * PuiCx(W, n));
      tfd[n+N2] := tfd_pair[n] + (tfd_impair[n] * PuiCx(W, n + N2));
      end;
   Result := tfd;
   end;
Mais là où le bât blesse c'est que du fait de la récursivité, lorsque les instructions de fft sur les rangs pairs

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
SetLength(pair, Length(pcxs^) div 2);
   for n := 0 to Length(pcxs^) div 2 - 1 do
      begin
      pair[n] := pcxs^[2*n];
      end;
   tfd_pair := FFT(@pair, 'pair'); // le string pair est ajouté pour faciliter le traçage dans mon fichier de débogage car sur android je n'arrive pas à faire du pas à pas.
sont exécutées, elles s'appellent récursivement jusqu'à ce que la taille du tableau pair soit de 1.
Et ensuite quand l'instruction de dimensionnement du tableau impair arrive :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
   SetLength(impair, Length(pcxs^) div 2);
   for n := 0 to Length(pcxs^) div 2 - 1 do
      begin
      impair[n] :=pcxs^[(2*n)+1];
      end;
   tfd_impair := FFT(@impair, 'impair');
la taille du tableau cxs d'origine est déjà réduite à 1 donc je débute impair avec un tableau de taille 1 !

donc je cherche à résoudre ce problème, mais je n'y arrive pas ... et je connais quasiment pas python.
Donc j'ai peut-être mal compris l'écriture python et donc mal traduit.
Mais si quelqu'un avait la connaissance des deux langages ?

Merci d'avance de votre aide.