Pergunta

O manual da FFTW diz É isso aí fftw_complex tipo é compatível com bit para std::complex<double> classe em stl. Mas isso não funciona para mim:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx;
   fx = reinterpret_cast<fftw_complex>(x);
}

Isso me dá um erro:

error: invalid cast from type ‘std::complex<double>’ to type ‘double [2]’

O que estou fazendo errado?

Foi útil?

Solução

Reescreva seu código da seguinte forma:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx;
   memcpy( &fx, &x, sizeof( fftw_complex ) );
}

Todo compilador que usei otimizará o memcpy porque está copiando um fixo, ou seja, no momento da compilação, quantidade de dados.

Isso evita Problemas de alias do ponteiro.

Editar: Você também pode evitar problemas rígidos de alias usando um sindicato da seguinte maneira:

#include <complex>
#include <fftw3.h>
int main()
{
   union stdfftw
   {
       std::complex< double > stdc;
       fftw_complex           fftw;
   };
   std::complex<double> x(1,0);
   stdfftw u;
   u.stdc = x;
   fftw_complex fx = u.fftw;
}

Embora estritamente essas regras C99 (não tenho certeza sobre o C ++) estejam quebradas à medida que a leitura de um membro diferente de um sindicato para aquele escrito também é indefinido. Funciona na maioria dos compiladores. Pessoalmente, prefiro meu método original.

Outras dicas

A idéia por trás da compatibilidade de bits dos tipos complexos FFTW_Complex e C99 e C ++ não é que eles possam ser facilmente criados um do outro, mas que todas as funções no FFTW que levam ponteiros para FFTW_Complex também podem levar os ponteiros para o complexo C ++ Std ::. Portanto, a melhor abordagem é provavelmente usar o STD :: complexo <> ao longo do seu programa e apenas converter ponteiros para esses valores ao chamar funções do FFTW:

std::vector<std::complex<double> > a1, a2;
....
....
fftw_plan_dft(N, reinterpret_cast<fftw_complex*>(&a1[0]),
                 reinterpret_cast<fftw_complex*>(&a2[0]),
                 FFTW_FORWARD, FFTW_ESTIMATE);
....

reinterpret_cast Funciona apenas para ponteiros e referências. Então você teria que fazer isso:

#include <complex>
#include <fftw3.h>
int main()
{
   std::complex<double> x(1,0);
   fftw_complex fx(*reinterpret_cast<fftw_complex*>(&x));
}

Isso assume isso fftw_complex tem um construtor de cópia. Para evitar problemas com alias rígidos, Solução de Goz deve ser preferido.

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