2011-11-28 15 views
17

Escribí el siguiente programa en Python 2 para hacer cálculos de métodos de Newton para mi conjunto de problemas matemáticos, y aunque funciona perfectamente, por razones sin que yo sepa, cuando inicialmente lo cargo en ipython con %run -i NewtonsMethodMultivariate.py, la división de Python 3 no se importa. Lo sé porque después de cargar mi programa Python, ingresar x**(3/4) da "1". Después de importar manualmente la nueva división, x**(3/4) sigue siendo x**(3/4), como se esperaba. ¿Por qué es esto?Usando "desde __future__ división de importación" en mi programa, pero no está cargado con mi programa

# coding: utf-8 
from __future__ import division 
from sympy import symbols, Matrix, zeros 

x, y = symbols('x y') 
X = Matrix([[x],[y]]) 
tol = 1e-3 

def roots(h,a): 
    def F(s): 
    return h.subs({x: s[0,0], y: s[1,0]}) 
    def D(s): 
    return h.jacobian(X).subs({x: s[0,0], y: s[1,0]}) 
    if F(a) == zeros((2,1)): 
    return a 
    else: 
    while (F(a)).norm() > tol: 
     a = a - ((D(a))**(-1))*F(a) 
     print a.evalf(10) 

me gustaría utilizar Python 3 para evitar este problema, sino sólo mi distribución Linux barcos sympy para Python 2. Gracias a la ayuda cualquier persona puede proporcionar.

Además, en caso de que alguien se esté preguntando, aún no he generalizado este script para nxn Jacobianos, y solo tuve que lidiar con 2x2 en mi conjunto de problemas. Además, estoy cortando la matriz cero de 2x2 en lugar de usar el comando zeros(2,1) porque SymPy 0.7.1, instalado en mi máquina, se queja de que "ceros() toma exactamente un argumento", aunque wiki sugiere lo contrario. Quizás este comando sea solo para la versión de git. (Gracias eryksun para corregir mi notación, que ha solucionado el problema con la función de ceros.)

+0

Es 'ceros ((2,1))'; el argumento es un escalar o una tupla. ¿Evaluó la división inmediatamente después de la importación con 'print 1/2'? – eryksun

+0

Por curiosidad, ¿qué sucede si agrega 'print division' al final de su programa? ¿Imprime algo así como: '_Feature ((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)'? Y si es así, ¿qué le da esa misma declaración de impresión desde la línea de comando de ipython? Tenga en cuenta que hay varias decenas de miles de resultados de Google para "ipython de la futura división de importación". Parece que no eres el primero en notar esto. :-) –

+0

@eryksun Gracias por corregirme sobre mi uso del comando de ceros; He actualizado mi programa. Entonces, si abro ipython, ejecuto 'from __future__ import division', y luego' print 1/2', el resultado es 0.5, como se esperaba. Pero si en cambio, al abrir ipython y ejecutar '% run -i NewtonsMethodMultivariate.py', y luego' print 1/2', obtengo 0. La línea para importar la división de Python 3 está claramente en mi programa, así que No sé qué pasa. –

Respuesta

12

Ambos comandos ipython -i y run -i en ipython intérprete ignoran from __future__ import division en print05.py guión.

$ cat print05.py 
from __future__ import division 
print(1/2) 

En ipython consola:

In [1]: print 1/2 
0 
In [2]: run -i print05.py 
0.5 
In [3]: division 
Out[3]: _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) 
In [4]: print 1/2 
0 
In [5]: from __future__ import division 
In [6]: print 1/2 
0.5 

execfile y import producen el mismo resultado:

>>> print 1/2 
0 
>>> execfile('print05.py') 
0.5 
>>> print 1/2 
0 
>>> from __future__ import division 
>>> print 1/2 
0.5 

from __future__ import division no debería tener efecto sobre el código fuente de los diferentes módulos, de lo contrario se rompería código en otros módulos que no esperan su presencia.

Aquí, from __future__ import division tiene efecto:

$ python -i print05.py 
0.5 
>>> print 1/2 
0.5 
>>> division 
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) 

El nombre del módulo en este caso es __main__ tanto dentro print05.py y en el símbolo.

Aquí, la primera print 1/2 ejecuta en print05 módulo, la segunda en __main__ módulo de manera que también funciona como se esperaba:

$ python -im print05 
0.5 
>>> print 1/2 
0 

Y aquí hay algo mal:

$ ipython -i print05.py 
0.5 
In [1]: division 
Out[1]: _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192) 
In [2]: print 1/2 
0 

la documentación para __future__ Diga:

Si es un intérprete comenzó con la opción -i, se pasa un nombre de secuencia de comandos para ejecutarse, y la secuencia de comandos incluye una instrucción futura, estará en vigor en la sesión interactiva iniciada después de que se ejecutó el script .

lo que podría ser un error en ipython si su opción -i trata de emular la misma opción pitón.

+0

Muchas gracias por la explicación. Es desafortunado, porque investigué mi función "h" en la línea de comando de ipython, y tiene términos con exponentes fraccionarios, pero supongo que tengo que codificar "h" en el programa si no quiero importar la división futura manualmente. –

+0

@Sara Fauzia: si definió 'h()' function * antes de '' ..import division', entonces usará la división * integer *. Puede usar 'edit you_module.py' para agregar funciones de la consola' ipython'. – jfs

+0

@ J.F. Sebastian So usa python interactivamente, como usted señaló, indeeds funciona correctamente, como acabo de probar. ¿Es esto un error? ¿Qué sucede con ipython? –

0

SymPy también proporciona un script - isympy - que es un contenedor para IPython que ejecuta algunos comandos comunes, incluida una importación de división de futuros. Es bastante útil, y en las versiones más nuevas de IPython (0.11+) también permite construcciones automáticas de Símbolos (lo cual es bueno, como siempre me olvido); ejecutarlo con el parámetro -a.

En cuanto a Python 3, hay soporte para esto en la versión de desarrollo y la próxima versión lo tendrá; cuando las distribuciones van a empacar no lo sé.

Cuestiones relacionadas