Pergunta

Estou escrevendo algumas transformações de coordenadas (mais especificamente a transformação Joukoswky, Wikipedia Joukowsky Transform), e estou interessado em desempenho, mas é claro que precisão. Estou tentando fazer as transformações de coordenadas de duas maneiras:

1) Calcular as peças reais e complexas em separado, usando dupla precisão, como abaixo:

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;

onde chi e z são estruturas simples com x e y como membros.

2) Usando o complexo:

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

Onde z e chi são complexos. A parte interessante é que, de fato, o caso 1) é mais rápido (cerca de 20%), mas a precisão é ruim, dando erro no terceiro número decimal após a vírgula após a transformação inversa, enquanto o complexo retribui o número exato. Então, o problema está no COS (ATAN2), SIN (ATAN2)? Mas se for, como o complexo lida com isso?

EDIT: Acabei de descobrir que essa não era exatamente a pergunta que eu tinha em mente. Eu tenho que fazer a transformação geral, como

Z = 1/2*(chi^n + (1/chi)^n) e, até agora, o código acima foi a maneira como eu imaginei fazê -lo. Mais 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);

Também corrigindo o bug em zy

Foi útil?

Solução

Eu acho que em 1) deve ser

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

Se você quer um desempenho realmente bom, pode voltar aos primeiros princípios e observar isso

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

Não sqrt(), atan2() ou cos() ou sin().

Outras dicas

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

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

Calcular dessa maneira deve ser mais preciso e mais rápido.

Quando você conecta esses valores às fórmulas para ZX e ZY, a raiz quadrada também será cancelada, para que você fique apenas com operações aritméticas básicas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top