Muchas de las bibliotecas de C ++ más conocidas en ciencia computacional como Eigen , Trilinos y deal.II usan el objeto de biblioteca de encabezado de plantilla C ++ estándar std::complex<>
, para representar números complejos de punto flotante.
En la respuesta de Jack Poulson a una pregunta sobre constructores predeterminados, señala que tiene su propia implementación std::complex
en Elemental "por varias razones". ¿Cuáles son esas razones? ¿Cuáles son las ventajas y desventajas de este enfoque?
fuente
z
es una expresión de tipo lvalue cvstd::complex<T>
a continuación,reinterpret_cast<cv T(&)[2]>(z)
yreinterpret_cast<cv T(&)[2]>(z)[0]
designará la parte real dez
, yreinterpret_cast<cv T(&)[2]>(z)[1]
designará la parte imaginaria dez
. También se abordan las matrices de números complejos.Lo uso
std::complex<>
en mis programas y tengo que luchar con los indicadores del compilador y la solución para cada nuevo compilador o actualización del compilador. Intentaré contar estas peleas en orden cronológico:std::norm
(-ffast-math
.std::arg
a un no-opt bajo ciertas configuraciones (compatibilidad de enlace con una versión gcc específica). El problema resurgió con demasiada frecuencia, por lo questd::arg
tuvo que ser reemplazado poratan2(imag(),real())
. Pero fue demasiado fácil olvidar esto al escribir código nuevo.std::complex
utiliza diferentes convenciones de llamada (= ABI) que el tipo complejo C99 integrado y el tipo complejo Fortran incorporado para las nuevas versiones de gcc.-ffast-math
indicador de compilación interactúa con el manejo de excepciones de punto flotante de maneras inesperadas. Lo que sucede es que el compilador extrae las divisiones de los bucles, lo que provocadivision by zero
excepciones en tiempo de ejecución. Estas excepciones nunca habrían ocurrido dentro del ciclo, porque la división correspondiente no tuvo lugar debido a la lógica circundante. Esa fue realmente mala, porque era una biblioteca que se compiló por separado del programa que usaba la entrega de excepciones de punto flotante (usando diferentes indicadores de compilación) y se topaba con estos problemas (los equipos correspondientes estaban sentados en partes opuestas del mundo, así que Este problema realmente causó problemas graves). Esto se resolvió haciendo la optimización utilizada por el compilador a mano con más cuidado.-ffast-math
indicador de compilación. Después de una actualización a una versión más nueva de gcc, el rendimiento se redujo en un factor enorme. Todavía no he investigado este problema en detalle, pero me temo que está relacionado con el Anexo G del C99 . Tengo que admitir que estoy completamente confundido por esta extraña definición de multiplicación para números complejos, e incluso parece que existen diferentes versiones de esto con afirmaciones de que las otras versiones están equivocadas. Espero que el-fcx-limited-range
indicador de compilación resuelva el problema, porque parece haber otro problema relacionado con-ffast-math
esta nueva versión de gcc.-ffast-math
indicador de compilación hace que el comportamiento seaNaN
completamente impredecible para las versiones más nuevas de gcc (inclusoisnan
se ve afectado). La única solución parece ser evitar cualquier apariciónNaN
en el programa, lo que anula el propósito de la existencia deNaN
.Ahora puede preguntar si planeo abandonar los tipos complejos integrados y
std::complex
por estas razones. Me quedaré con los tipos integrados, siempre y cuando me quede con C ++. En caso de que C ++ logre volverse completamente inutilizable para la informática científica, preferiría considerar cambiar a un lenguaje que se ocupe más de los problemas relevantes para la informática científica.fuente