2012-05-14 7 views
13

Estoy tratando de crear un infinito complejo igual a Inf + Inf * j donde j es la variable compleja. Cuando hago esto:Creando infinito complejo con std :: complex <T> en C++

#include <complex> 
#include <limits> 
using std; 

... 

complex<double> attempt1 = 
    complex<double>(numeric_limits<double>::infinity(), 
        numeric_limits<double>::infinity()); 

devuelve el número complejo (NaN + Inf * j).

Pero

complex<double> attempt2 = 
    complex<double>(numeric_limits<double>::infinity()); 

devuelve el número complejo (Inf + 0 * j).

También:

complex<double> attempt_at_imag_inf = 
    complex<double>(any_value_here, numeric_limits<double>::infinity()); 

devuelve el número complejo (NaN + Inf * j).

¿Alguien sabe lo que está pasando aquí? Cada vez que intento tener infinito para la parte imaginaria, entonces NaN está escrito en la parte real.

Lo anterior solo se aplica a los tipos que admiten NaN e Infinity, por supuesto. Estoy usando g ++ v4.6.1. Miré el encabezado numeric_limits y no hay indicación de que lo anterior deba suceder.

Para poner lo anterior en contexto, en realidad estoy haciendo lo anterior en una especialización parcial de numeric_limits for complex. Muchas gracias por considerar este problema.

REVISIÓN Post original

que estoy proporcionando un programa completo, pero corta para ilustrar el problema. También incluí información más calificada sobre cómo se debe compilar el programa para generar los resultados.

#include <iostream> 
#include <complex> 
#include <limits> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 

    complex<double> my_complex_inf = 
     complex<double>(numeric_limits<double>::infinity(), 
         numeric_limits<double>::infinity()); 

    cout << "my_complex_inf = " << my_complex_inf << endl; 

    complex<double> attempt2 = 
     complex<double>(numeric_limits<double>::infinity()); 

    cout << "attempt2 = " << attempt2 << endl; 

    double any_value_here = 0; 

    complex<double> attempt_at_imag_inf = 
     complex<double>(0, numeric_limits<double>::infinity()); 

    cout << "attempt_at_imag_inf = " << attempt_at_imag_inf << endl; 

    return 0; 

} 

Compilación de lo anterior en g ++ versión 4.6.1 en Ubuntu con el -std = C++ 0x da los siguientes resultados:

my_complex_inf = (nan,inf) 
attempt2 = (inf,0) 
attempt_at_imag_inf = (nan,inf) 

Sin la -std = C++ 0x la opción los resultados son los siguientes:

my_complex_inf = (inf,inf) 
attempt2 = (inf,0) 
attempt_at_imag_inf = (0,inf) 

Así que la pregunta realmente es ¿POR QUÉ GNU g ++ V4.6.1 dar las respuestas que lo hace cuando se especifica C++ 0x?

REVISIÓN 2 A Post original

he intentado lo siguiente en Octave (paquete de datos numéricos similar a Matlab):

a = inf + j * inf

Y la respuesta es:

a = NaN + Infi

Esto es exactamente lo que veo en mi código C++ 11 (C++ 0x). No sé con qué se compila Octave (creo que es una combinación de C++ y FORTRAN), pero si ese paquete arroja el resultado que obtengo, supongo que es un comportamiento bien conocido.

Sin embargo, he observado el borrador del estándar C++ 11 y no puedo encontrar ninguna mención de este comportamiento.

REVISIÓN 3 A Post original

añadiendo la siguiente línea

my_complex_inf.real(my_complex_inf.imag()); 

hasta justo después de la construcción de my_complex_inf devolver la respuesta "correcta" (inf, inf) cuando se compila para C++ 11. Desafortunadamente, este es ahora un proceso de 2 pasos y no puedo crear este tipo de infinito complejo en una función constexpr.

+4

Funciona correctamente [en g ++ 4.3.4] (http://ideone.com/xfXDo), [g ++ 4.5.1] (http://ideone.com/FpmZK), 4.6.3 y 4.7.0. Proporcione un programa de muestra breve y completo. Ver http://sscce.org/. –

+1

¿Estás seguro de que quieres 4 posibles infinitos para el plano complejo? Pensaría que querrías solo una (como en una esfera de Riemann). –

+1

Bueno, puedes probar '1/std :: complex (0)', ya que lo único importante que querrías es '1/infty == 0', si estás tratando de representar la esfera de Riemann. –

Respuesta

4

Un inf escalar convertido a complejo es inf + 0 j. Este es correcto arriba. Un desplazamiento Inf infrecuente en el plano complejo implicav una rotación y no es calculable, por lo tanto Nan es correcta. ¿Cuál es el problema otra vez?

"There be dragons."

+0

let a = 1, es decir, 1 + 0 * j. Una rotación de pi/4 es 1 * exp (j * pi/4), es decir, sqrt (2) + j * sqrt (2). Si a es inf, entonces b = inf * exp (j * pi/4). Como esto solo involucra la multiplicación de inf de partes reales y complejas, el resultado también debería ser inf (para partes reales y complejas). Entonces, no creo que nan deba surgir del cálculo de una rotación, si esto es cómo se implementa. –

4

Te encuentras con la forma en que C++ 11 (y C11) especifican números complejos y se confunden.

Básicamente, en el modelo exigido por la especificación, solo hay un infinito (representado por (inf, 0)), e intenta poner un 'infinito' en la parte imaginaria de un resultado complejo en Nan, porque no tiene sentido en ese modelo.

0

En la línea principal (gcc-4.8) i obtener con -std = C++ 0x la (sin -std) respuesta esperada:

my_complex_inf = (inf,inf) 
attempt2 = (inf,0) 
attempt_at_imag_inf = (0,inf) 

gcc-4.6.3 con -std-C++ 11 da la respuesta inesperada:

my_complex_inf = (-nan,inf) 
attempt2 = (inf,0) 
attempt_at_imag_inf = (-nan,inf) 

Creo que los constructores deberían simplemente establecer los tipos reales e imaginarios de acuerdo con los argumentos correspondientes. No debe haber nan.

Cuestiones relacionadas