Domanda

Sto scrivendo alcune trasformazioni di coordinate (più precisamente il Joukoswky Transform, Wikipedia Joukowsky Transform ), e mi sono interessato in termini di prestazioni, ma ovviamente di precisione. Sto cercando di fare la trasformazioni di coordinate in due modi:

1) Calcolare le parti reali e complessi separati, utilizzando doppia precisione, come di seguito:

double r2 = chi.x*chi.x + chi.y*chi.y;

//double sq = pow(r2,-0.5*n) + pow(r2,0.5*n); //slow!!!
double sq = sqrt(r2); //way faster!
double co = cos(atan2(chi.y,chi.x));
double si = sin(atan2(chi.y,chi.x));

Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*si*sq;

dove chi e Z sono strutture semplici con doppio xey come membri.

2) Uso di complesso:

Z = 0.5 * (chi + (1.0 / chi));

Dove Z e chi sono complesse. Ci parte interessante è che davvero il caso 1) è più veloce (circa 20%), ma la precisione è male, dando errore nel terzo numero decimale dopo la virgola dopo la trasformata inversa, mentre il complesso dà indietro il numero esatto. Quindi, il problema è sulle cos (atan2), sin (atan2)? Ma se lo è, come le maniglie complessi che?

EDIT: appena capito che questo non era esattamente la domanda che avevo in mente. Devo fare la trasformazione generale, come

Z = 1/2 * (chi ^ n + (1 / CHI) ^ n), e finora il codice di cui sopra è stato il modo in cui ho pensato di farlo. Più precisamente,

    double sq = pow(sqrt(r2),n); //way faster!
double co = cos(n*atan2(chi.y,chi.x));
double si = sin(n*atan2(chi.y,chi.x));

Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*(si*sq - sq/si);

Anche la correzione bug su Z.y.

È stato utile?

Soluzione

Credo che in 1) dovrebbe essere

Z.y = 0.5*(si*sq - si/sq);

Se si vuole veramente buone prestazioni si consiglia di tornare a principi primi e osservare che

1/(a+ib) = (a-ib)/(a*a+b*b)

No sqrt(), atan2() o cos() o sin().

Altri suggerimenti

r = sqrt(x*x+y*y) Data:

cos(atan2(y,x)) == x/r
sin(atan2(y,x)) == y/r

Il calcolo in questo modo dovrebbe essere più accurato e veloce.

Quando si collega questi valori nelle formule per Z.x e Z.y, la radice quadrata annullerà fuori pure, così ti verrà lasciato con le operazioni aritmetiche di base solo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top