답변:
이 토론은 PETSc 목록에 여러 번 등장했다고 생각합니다. 나의 주요 이유는 다음과 같습니다.
C ++ 표준에 따르면 std :: complex는 float, double 및 long double 데이터 유형에 대해서만 정의됩니다. 따라서 쿼드 정밀도와 같은 다른 데이터 유형에는 사용할 수 없습니다.
표준은 복소수 산술의 안정성을 보장하지 않습니다.
표준은 std :: complex의 데이터가 실제 구성 요소로 저장되고 그 뒤에 가상 구성 요소가 저장된다는 것을 보증하지 않습니다. 이것은 BLAS 및 LAPACK과 같은 외부 라이브러리와의 인터페이스에 중요합니다. 모든 주요 구현에 해당되지만 보장 할 수 있기를 바랍니다.
나는 실제와 가상의 구성 요소를 직접 조작 할 수있는 것을 선호합니다. std :: complex는이를 불필요하게 어렵게 만듭니다.
결국 데이터 유형이 필드를 요구하는 대신 링이어야하는보다 일반적인 버전을 원합니다. 여기에는 가우스 정수가 포함됩니다.
나는 std::complex<>
내 프로그램에서 사용 하며 각각의 새로운 컴파일러 또는 컴파일러 업그레이드에 대한 컴파일러 플래그 및 해결 방법과 싸워야합니다. 나는이 싸움들을 시간 순서대로 설명하려고 노력할 것이다.
std::norm
-ffast-math
std::arg
특정 구성 (비교적 gcc- 버전과의 링크 호환성)에서 비 선택으로 컴파일 되었습니다. 문제가 너무 자주 재 포장되었으므로 std::arg
로 대체해야했습니다 atan2(imag(),real())
. 그러나 새로운 코드를 작성할 때 이것을 잊어 버리는 것은 너무 쉽다.std::complex
은 내장 C99 복합 유형과 다른 통화 규칙 (= ABI) 및 최신 gcc 버전에 대한 내장 포트란 복합 유형을 사용합니다.-ffast-math
예상치 못한 방법으로 소수점 예외 부동의 처리와 컴파일 플래그 상호 작용. 컴파일러가 디비전을 루프 밖으로 끌어내어 division by zero
런타임에 예외 가 발생합니다. 이러한 예외는 주변 논리로 인해 해당 분할이 발생하지 않았기 때문에 루프 내에서 발생하지 않았을 것입니다. 부동 소수점 예외 처리 (다른 컴파일 플래그 사용)를 사용하고 이러한 문제가 발생하는 프로그램과 별도로 컴파일 된 라이브러리이기 때문에 실제로는 나빴습니다. 이 문제는 실제로 나쁜 문제를 일으켰습니다). 이것은 컴파일러가 직접 사용하는 최적화를보다주의 깊게 수행함으로써 해결되었습니다.-ffast-math
컴파일 플래그를 사용하지 않았습니다 . 최신 gcc 버전으로 업그레이드 한 후 성능이 크게 떨어졌습니다. 이 문제를 아직 자세히 조사하지는 않았지만 C99 Annex G 와 관련이 있다고 생각합니다 . 나는 복잡한 숫자에 대한이 곱셈의 이상한 정의에 완전히 혼란스러워하고 다른 버전이 잘못 인도되었다는 주장과 함께 다른 버전이 존재하는 것으로 보입니다. 이 새로운 gcc 버전 -fcx-limited-range
과 관련된 다른 문제가있는 것처럼 보이기 때문에 컴파일 플래그가 문제를 해결할 수 있기를 바랍니다 -ffast-math
.-ffast-math
컴파일 플래그의 동작한다 NaN
GCC의 새 버전을 완전히 예측할 수없는 (심지어 isnan
영향을). 유일한 해결 방법은 NaN
프로그램의 존재 를 피하는 것 입니다 NaN
.이제 내장 복잡한 유형을 포기할 것인지 여부와 std::complex
이러한 이유로 물어볼 수 있습니다 . C ++을 사용하는 한 내장 유형을 유지합니다. C ++이 과학 컴퓨팅에 완전히 사용할 수 없게되어야하는 경우 과학 컴퓨팅과 관련된 문제를보다 잘 처리하는 언어로 전환하려고합니다.
z
형의 좌변 표현 CVstd::complex<T>
후는reinterpret_cast<cv T(&)[2]>(z)
및reinterpret_cast<cv T(&)[2]>(z)[0]
의 실수 부를 지정한다z
과reinterpret_cast<cv T(&)[2]>(z)[1]
허수 부분을 지정한다z
. 복소수 배열도 다룹니다.