2011-11-28 8 views
17

Ho scritto il seguente programma in Python 2 per fare calcoli di metodo di Newton per il mio problema di matematica impostato, e mentre funziona perfettamente, per motivi a mia insaputa, quando inizialmente lo carico in ipython con %run -i NewtonsMethodMultivariate.py, la divisione Python 3 non viene importata. Lo so perché dopo aver caricato il mio programma Python, inserendo x**(3/4) da "1". Dopo aver importato manualmente la nuova divisione, quindi x**(3/4) rimane x**(3/4), come previsto. Perchè è questo?Uso "da __future__ import division" nel mio programma, ma non è caricato con il mio programma

# 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) 

userei Python 3 per evitare questo problema, ma solo la mia distribuzione Linux navi SymPy per Python 2. Grazie all'aiuto chiunque può fornire.

Inoltre, nel caso qualcuno si stia chiedendo, non ho ancora generalizzato questo script per nxn Jacobians, e ho dovuto gestire solo 2x2 nel mio set di problemi. Inoltre, sto tagliando la matrice 2x2 zero invece di usare il comando zeros(2,1) perché SymPy 0.7.1, installato sulla mia macchina, si lamenta che "zeros() richiede esattamente un argomento", sebbene il wiki suggerisca diversamente. Forse questo comando è solo per la versione git. (Grazie eryksun per correggere la mia notazione, che ha fissato il problema con la funzione di zeri.)

+0

È 'zeros ((2,1))'; l'argomento è uno scalare o una tupla. Hai testato la divisione subito dopo l'importazione con 'print 1/2'? – eryksun

+0

Per curiosità, cosa succede se aggiungi 'print division' alla fine del tuo programma? Stampa qualcosa del tipo: '_Feature ((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)'? E se sì, che cosa ti dà la stessa istruzione di stampa dalla riga di comando ipython? Tieni presente che ci sono diverse decine di migliaia di risultati di Google per "ipython dalla futura divisione di importazione". Sembra che tu non sia il primo a notare questo. :-) –

+0

@eryksun Grazie per avermi corretto sull'utilizzo del comando zeri; Ho aggiornato il mio programma. Quindi se apro ipython, eseguo 'da __future__ import division', e quindi' print 1/2', il risultato è 0.5, come previsto. Ma se invece, aprendo ipython ed eseguendo '% run -i NewtonsMethodMultivariate.py', e poi' print 1/2', ottengo 0. La riga per importare la divisione Python 3 è chiaramente nel mio programma, quindi non so cosa succede –

risposta

12

Sia comando ipython -i e run -i in ipython interprete ignorano from __future__ import division in print05.py script.

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

In ipython console:

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 e import producono lo stesso risultato:

>>> 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 non dovrebbe avere effetto sul codice sorgente da diversi moduli, altrimenti si romperebbe codice in altri moduli che non si aspettano la sua presenza.

Qui, from __future__ import division ha effetto:

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

Il nome del modulo in questo caso è __main__ sia all'interno print05.py e nella richiesta.

Qui, il primo print 1/2 esegue nel modulo print05, il secondo nel modulo __main__ in modo che funziona anche come previsto:

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

Ed ecco qualcosa che non va:

$ 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 documentazione per __future__ di:

Se un interprete è avviato con l'opzione -i, viene passato uno script con il nome da eseguire e lo script include un'istruzione futura, sarà attivo nella sessione interattiva avviata dopo lo script è eseguito.

quindi potrebbe essere un bug nel ipython se l'opzione -i cerca di emulare la stessa opzione di pitone.

+0

Grazie mille per la spiegazione. È sfortunato, perché ho inserito la mia funzione "h" sulla riga di comando ipython, e ha termini con esponenti frazionari, ma suppongo di dover inserire hardcode "h" nel programma se non voglio importare manualmente la divisione futura. –

+0

@Sara Fauzia: se hai definito la funzione 'h()' * prima di * '..import divisione', allora userà * la divisione intero *. Puoi usare 'edit you_module.py' per aggiungere funzioni dalla console' ipython'. – jfs

+0

@ J.F. Sebastian Quindi, usando Python interattivamente, come hai sottolineato, infatti funziona correttamente, come ho appena testato. È un bug, cosa succede con ipython? –

0

SymPy fornisce anche uno script - isympy - che è un wrapper per IPython che esegue alcuni comandi comuni, inclusa un'importazione di divisione dal futuro. È abbastanza utile, e nelle versioni più recenti di IPython (0.11+) consente anche costruzioni automatiche di Simboli (che è bello come mi sembra sempre di dimenticare); eseguirlo con il parametro -a.

Per quanto riguarda Python 3, è supportato nella versione di sviluppo e la prossima versione lo avrà; quando le distribuzioni stanno per impacchettarlo, non lo so.

Problemi correlati