2010-11-18 5 views
12

FFTW मैनुअल says कि अपनी fftw_complex प्रकार बिट एसटीएल में std::complex<double> वर्ग के लिए संगत है। लेकिन यह मेरे लिए काम नहीं करता:समस्या कास्टिंग एसटीएल जटिल <double> fftw_complex को

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

क्या मैं गलत कर रहा हूँ:

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

यह मैं एक त्रुटि देता है?

उत्तर

8

अपने कोड को फिर से लिखना:

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

हर संकलक मैं memcpy बाहर अनुकूलित करेंगे का उपयोग किया है, क्योंकि यह एक निश्चित अर्थात संकलन समय पर, डेटा की मात्रा को कॉपी कर रहा है।

यह pointer aliasing issues से बचाता है।

संपादित करें: तुम भी इस प्रकार एक संघ का उपयोग कर सख्त अलियासिंग मुद्दों से बचने कर सकते हैं:

#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; 
} 

हालांकि सख्ती से इस C99 नियम (सी के बारे में ++ सुनिश्चित नहीं हैं) एक संघ का एक अलग सदस्य से पढ़ने के रूप में टूट रहे हैं लिखे गए एक को भी अपरिभाषित है। यह हालांकि अधिकांश कंपाइलरों पर काम करता है। व्यक्तिगत रूप से मैं अपनी मूल विधि पसंद करता हूं।

+0

ठीक है, यह मेरे लिए काम करता है! 3 साल शुद्ध सी में कोडिंग नहीं कर रहा :) धन्यवाद बहुत कुछ। – galadog

+0

@galadog क्या memcpy आवश्यक है? आप ऐसा क्यों नहीं कर सकते: 'std :: complex x (1,0); fftw_complex * fx = & x' –

+0

@ एंड्रे बूस: क्योंकि यह सख्त एलियासिंग नियमों को तोड़ता है ... – Goz

4

reinterpret_cast केवल पॉइंटर्स और संदर्भों के लिए काम करता है। तो तुम यह करने के लिए होगा:

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

इसमें यह माना जाता fftw_complex एक प्रति निर्माता है। सख्त एलियासिंग के साथ समस्याओं से बचने के लिए, Goz's solution को प्राथमिकता दी जानी चाहिए। इस प्रकार

+1

क्या आप ऊपर कर सख्त अलियासिंग नियम टूट जाता है और बचा जाना चाहिए: इसलिए सबसे अच्छा तरीका अपने कार्यक्रम के दौरान std :: जटिल <> उपयोग करने के लिए और केवल इन मूल्यों की ओर इशारा परिवर्तित जब FFTW कार्यों बुला शायद है। जीसीसी आपको ऐसा करने के लिए चेतावनी देगा और यदि आपके पास सख्त एलियासिंग चालू है तो संभावित रूप से तोड़ दिया जाएगा। – Goz

+0

@Goz: आप सही हैं। मैंने एक चेतावनी जोड़ा और आपके उत्तर को संदर्भित किया। –

+2

संदर्भों के लिए भी काम करता है: 'fftw_complex fx (reinterpret_cast (x)); ' – MSalters

18

fftw_complex और सी 99 और सी ++ जटिल प्रकारों की बिट-संगतता के पीछे विचार यह नहीं है कि उन्हें आसानी से एक दूसरे से बनाया जा सकता है, लेकिन एफएफटीडब्ल्यू में सभी फ़ंक्शन जो fftw_complex पर पॉइंटर्स लेते हैं, वे भी C++ std :: जटिल।

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); 
.... 
+0

अब तक जाने का सबसे अच्छा तरीका है। – Mike

संबंधित मुद्दे