할 수 있는 std::벡터<std::complex<boost:multiprecision::float128>>(N).데이터를()안전 reinterpret_casted 을 fftwq_complex*?
-
22-12-2019 - |
문제
지 않았다 정말 예를 들어 다음과 같은 작업을,하지만 실제로 그것은(g++4.6.4 으로,--std=c++0x):
#include <boost/multiprecision/float128.hpp>
#include <blitz/array.h>
#include <fftw3.h>
int main(int /*argc*/, char** /*argv*/)
{
//these are the same
std::cout << sizeof(std::complex<boost::multiprecision::float128>) << " " << sizeof(fftwq_complex) << std::endl;
typedef std::vector< std::complex<boost::multiprecision::float128> > boost128cvec;
//typedef std::vector<std::complex<boost::multiprecision::float128> , fftw::allocator< std::complex<boost::multiprecision::float128> > > boost128cvec;
//declare a std::vector consisting of std::complex<boost::multiprecision::float128>
boost128cvec test_vector3(12);
//casting its data storatge to fftwq_complex*
fftwq_complex* test_ptr3 = reinterpret_cast<fftwq_complex*>(test_vector3.data());
//also create a view to the same data as a blitz::Array
blitz::Array<std::complex<boost::multiprecision::float128>, 1> test_array3(test_vector3.data(), blitz::TinyVector<int, 1>(12), blitz::neverDeleteData);
test_vector3[3] = std::complex<boost::multiprecision::float128>(1.23,4.56);
//this line would not work with std::vector
test_array3 = sin(test_array3);
//this line would not work with the built-in type __float128
test_vector3[4] = sin(test_vector3[3]);
//all of those print the same numbers
std::cout << "fftw::vector: " << test_vector3[3].real() << " + i " << test_vector3[3].imag() << std::endl;
std::cout << "fftw_complex: " << (long double)test_ptr3[3][0] << " + i " << (long double)test_ptr3[3][1] << std::endl;
std::cout << "blitz: " << test_array3(3).real() << " + i " << test_array3(3).imag() << std::endl << std::endl;
}
두 비고:
- 목표가 될 수 있을 모두 사용
fftw
고blitz::Array
작업에 같은 데이터가 필요없이 복사 그들에게 주면서 동시에 사용할 수있는 일반적인 funcionst 아sin()
또한 복잡한 변수를 가진 쿼드 정밀도 - 이
blitz
-부분이 잘 작동하는 것으로 예상된다.그러나 놀라운(나)는fftwq_complex*
부분도 잘 작동합니다. - 이
fftw::allocator
간단한 교체std::allocator
를 사용하는fftwq_malloc
을 보장하는 올바른 사용 가능한 컴파일러 정렬,그러나 그게 중요하지 않습니다 이 질문에 대해서는,그래서 내가 왼쪽 그것(적어도 내가 생각하는 것이 중요하지 않습니다 이에 대한 질문에)
나의 질문은:어떻게 얇은 얼음이 난 밟?
해결책
당신이 거의 저장:
std::vector
호환되는 array(당신은에 액세스할 수 있는 첫 번째 요소를 가리키는 포인터를 통해vector.data()
, 으로 응답에 이 질문std::complex<T>
설계에 호환되는 Array 형태의T[2]
, 과 호환되는,FFTW.이 설명서 FFTW 문서C++자신의 복잡한 템플릿 클래스에 정의된 표준 헤더 파일.보도에 따르면,C++표준 위원회가 최근에 동의하는 위임하는 저장소에 사용되는 형식이 유형이 될 이진환 C99 유형,즉배 T[2]와 연속적인 실시는[0]가상의[1]부분입니다.(보고서를 참조하세요 http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2002/n1388.pdf WG21/N1388.) 의 일부이지만 공인 표준으로 이 글을 쓰고,제안을 밝혔다:"이 솔루션 테스트되었습니다 모든 현재의 주요 구현하는 표준 라이브러리와 다음과 같습니다." 을 정도로 이것은 사실이 있는 경우 복잡한 변수*x,당신이 통과할 수 있게 직접 FFTW 을 통해 reinterpret_cast(x)
유일한 마음을 유지하는 data()
가 무효화되는 경우 당신은 값을 추가하 벡터입니다.
마지막 부분이 있는 사 겸용성
boost::multiprecision::float128
고 __float128
.부스트 문서를 제공에 대한 보장이 없다.무엇을 할 수 있는 그러나,일부를 추가 정 주장하는 코드에서 실패하는 경우 변환은 불가능합니다.이것은 다음과 같이 표시될 수 있습니다:
static_assert(std::is_standard_layout<float128>::value,"no standard type");
static_assert(sizeof(float128) == sizeof(__float128),"size mismatch");
가 sizeof
을 보장하는 동일한 크기의 향상을 입력하고__float128 고 is_standard_layout 검사:
포인터를 기준 레이아웃 등으로 변환될 수 있습니다(와 reinterpret_cast)포인터를 그 첫 번째 정적이 아닌 데이터 구성원과 그 반대입니다.
물론,이것만은 힌트를 작동하면서 결국,당신이 말할 수 없는 경우 형식이 정말로 __float128
, 지만,ab 향상국이 자신의 유형이 얇은 래퍼로 그 주위에,그것은 잘해야한다.는 경우는 변경에서 디자인이나 구조물의 float128
, 정적 주장은 실패합니다.