[Python-es] Implementación de cmath.sqrt

Chema Cortes pych3m4 en gmail.com
Jue Mar 14 22:56:58 CET 2013


Sencillamente, está preservando el signo de la parte imaginaria tal y
como se define para las raices cuadradas con complejos.

>>> cmath.sqrt(0j)
0j
>>> cmath.sqrt(-0j)
-0j


La pregunta hay que reformularla a ¿para qué queremos "ceros con
signos"? Sin entrar en mucho detalle, se necesitan para que algunas
transformaciones, válidas en el espacio de los números reales, queden
bien definidas en el plano complejo, sin discontinuidades al
aproximarse a las asíntotas, lo que simplifica bastante los cálculos.


<http://port70.net/~nsz/articles/float/kahan_branch_cuts_complex_elementary_functions_1987.pdf>


El día 14 de marzo de 2013 15:39, Ricardo Cárdenes
<ricardo.cardenes en gmail.com> escribió:
> De hecho, fíjate la implementación antigua:
>
> 245        Py_complex r;
> 246        double s,d;
> 247        if (x.real == 0. && x.imag == 0.)
> 248                r = x;
>
> El cambio a lo que tienes ahí es relativamente reciente (r62380, en 2008).
> El parche es una colaboración con Mark Dickinson. Quizá puedas averiguar
> googleando un poco por qué lo implementaron así.
>
>
> 2013/3/14 Ricardo Cárdenes <ricardo.cardenes en gmail.com>
>>
>> La representación interna de un complejo son dos números reales: la
>> magnitud de su parte real y la magnitud de su parte imaginaria. En principio
>> "r.real = 0.; r.imag = z.imag;" es lo mismo que "r.real = 0.; r.imag = 0.;",
>> así que no tengo nada claro lo que está pasando ahí. cmath.sqrt devuelve un
>> complejo siempre (es la idea)
>>
>>
>> 2013/3/14 Daπid <davidmenhur en gmail.com>
>>>
>>> Hola:
>>>
>>> Estaba echándole un vistazo superficial a la biblioteca cmath de
>>> Python [1] cuando encontré esto:
>>>
>>> static Py_complex
>>> 667     c_sqrt(Py_complex z)
>>> 668     {
>>> [...]
>>> 696     Py_complex r;
>>> [...]
>>> 702     if (z.real == 0. && z.imag == 0.) {
>>> 703     r.real = 0.;
>>> 704     r.imag = z.imag;
>>> 705     return r;
>>> 706     }
>>> ...
>>>
>>> El códig en primer lugar comprueba si el número es 0, y si no continúa
>>> calculando la raíz cuadrada para números generales. Por supuesto, la
>>> raíz cuadrada de 0+0j es 0+0j, pero lo calcula de forma curiosa: la
>>> parte real la pone como 0 y la imaginaria como la imaginaria del
>>> número original (que es 0). ¿Por qué es esto?
>>>
>>> Se me ocurrió que podría ser para preservar tipos, pero
>>>
>>> >>> cmath.sqrt(0)
>>> 0j
>>>
>>> devuelve un complejo, no un real.
>>>
>>>
>>>
>>> [1]
>>> http://svn.python.org/view/python/trunk/Modules/cmathmodule.c?revision=76978&view=markup
>>> _______________________________________________
>>> Python-es mailing list
>>> Python-es en python.org
>>> http://mail.python.org/mailman/listinfo/python-es
>>> FAQ: http://python-es-faq.wikidot.com/
>>
>>
>
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/
>



--
Hyperreals *R: http://ch3m4.org/blog
Quarks, bits y otras criaturas infinitesimales


Más información sobre la lista de distribución Python-es