+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 5 su 5

Discussione: Array numpy creato da una tupla

  1. #1
    lucagalbu non è in linea Scolaretto
    Luogo
    Italy
    Post
    244

    Array numpy creato da una tupla

    Ciao!
    Ho creato una tupla di coordinate

    codice:
    def position(riga, L, diametro):
        passo=L/float(riga)
    
        #calcolo le posizioni
        posizioni=[]
        for i in xrange(riga):
            for j in xrange(riga):
                x=i*passo; y=j*passo;
                posizioni.append([x, y])
                posizioni.append([x+passo/2., y+passo/2.])
                 
        return posizioni  #e' una tupla, non numpy array
    questa tupla la trasformo in un numpy array

    codice:
    posizioni=np.array(position(riga, L, diametro))
    Ció che non capisco è perché quando passo "posizioni" ad una funzione, viene passato per valore e non per referenza
    Colui che pone una domanda è uno sciocco per cinque minuti; colui che non pone una domanda rimane uno sciocco per sempre

  2. #2
    Post
    4,740
    Blogs
    12
    Quote Originariamente inviato da lucagalbu Visualizza il messaggio
    Ció che non capisco è perché quando passo "posizioni" ad una funzione, viene passato per valore e non per referenza
    Premetto che "posizioni" è una lista e non una tupla.

    In verità in Python tutti gli oggetti vengono passati per riferimento. Il problema è distinguere tra tipi di oggetto mutabili e immutabili. A tal proposito ti consiglio di leggere la documentazione ufficiale sul Data Model. Ad esempio, numeri, stringhe e tuple sono tipi di oggetto immutabili. Quindi, passando ad una funzione questi tipi di oggetto, è possibile "modificarli" creando una copia degli stessi (modificata) e restituendo quest'ultima. D'altra parte, oggetti di tipo mutabili, come liste e dizionari, possono essere modificati dalle funzioni.

    Nel tuo codice, non vedo nessuna tupla: l'oggetto "posizioni" è una lista. Giusto per riassumere, le definizioni sono le seguenti:

    codice:
    ()
    È una tupla, quindi immutabile.

    codice:
    []
    È una lista, quindi mutabile.

    codice:
    {}
    È un dizionario, quindi mutabile.

    Spero di essere stato chiaro, riodina un po' il codice e aggiornaci sull'argomento.

    Nel caso di numpy, l'oggetto array è mutabile
    Ultima modifica di Master85; 28-10-2012 03:34 

  3. #3
    lucagalbu non è in linea Scolaretto
    Luogo
    Italy
    Post
    244
    Sì, sì, è una lista!
    Comunque, se in numpy l'array è mutabile, quando lo passo ad una funzione questa dovrebbe essere in grado di modificarlo, mentre invece non lo fa.

    Nel mio programma creo due numpy array, posizioni che è creato come ho scritto nel primo post e velocita che viene creato così
    codice:
    #posizioni iniziali
    posizioni=np.array(position(riga, L, diametro))  #position() ritorna una lista
    #velocita iniziali
    nprnd.seed()
    velocita=nprnd.rand(N, 2)
    velocita=2.*velocita-1   #intervallo [-1,1]
    velocita_totale=velocita.sum(0)
    for i in range(0,2):     #annullo la quantita di moto totale
        velocita[:,i]=velocita[:,i]-velocita_totale[i]/N
    Gli array posizioni e velocita vengono passati alla funzione exec_collisioni():
    Ti posto la funzione che dovrebbe modificare l'array
    codice:
    def exec_collisioni(num_collisioni,
                        tempo_corrente, tempo_min, diametro, L, N,
                        particella1, particella2,
                        posizioni, velocita, matrice_collisioni):       #posizioni e velocita sono matrici del tipo numpy array
        somma_variazioni=0
        for counter in xrange(num_collisioni):
            #sys.stderr.write("Counter: " +str(counter)+"\n")
            #aggiorno la matrice di collisione (C++ wrap)
            term(tempo_corrente, diametro, L, N,
                 particella1, particella2,
                 posizioni, velocita, matrice_collisioni)
            
            #aggiorno le posizioni
            #indice del minimo della matrice
            collisione_min=matrice_collisioni.argmin()  
            particella1=int(np.floor(collisione_min/N))
            particella2=collisione_min%N
            tempo_old=tempo_min
            tempo_min=matrice_collisioni[particella1, particella2]
            posizioni=(posizioni+velocita*(tempo_min-tempo_old))%L    #qui modifico posizioni, ma l'array originale non viene modificato
            tempo_corrente=tempo_min
        
            #aggiorno le velocita delle particelle che hanno colliso
            velocita[particella1], velocita[particella2], variazione_velocita = new_velocity(
                posizioni[particella1], posizioni[particella2],
                velocita[particella1], velocita[particella2],
                L, diametro)                                              #qui modifico velocita e questa modifica si riflette nell'array originario
            somma_variazioni=fabs(variazione_velocita)
    
        return posizioni, tempo_corrente, tempo_min, particella1, particella2, somma_variazioni
    Dopo aver chiamato questa funzione, velocita viene modificato, mentre posizioni no.
    Colui che pone una domanda è uno sciocco per cinque minuti; colui che non pone una domanda rimane uno sciocco per sempre

  4. #4
    Post
    4,740
    Blogs
    12
    Quote Originariamente inviato da lucagalbu Visualizza il messaggio
    codice:
    posizioni=(posizioni+velocita*(tempo_min-tempo_old))%L    #qui modifico posizioni, ma l'array originale non viene modificato
    In questo caso, stai associando al nome "posizioni" un nuovo array. Ma non stai cambiando (modificando) il valore dell'array precedentemente puntato da "posizioni". Per capire cosa sta succedendo, ti consiglio di usare la funzione id() (ritorna un intero univoco per ciascun oggetto utilizzato). Potrai vedere che chiamando la funzione id() subito dopo la riga incriminata, otterrai un identificativo diverso.

    Se vuoi modificare lo stesso array "posizioni" senza crearne uno nuovo, è consigliabile iterare su ogni singolo elemento e modificarne il valore associato:

    codice:
    ...
    for i in xrange(posizioni.size):
        posizioni[i] = new_val
    ...
    In questo modo modifichi lo stesso oggetto puntato da "posizioni"
    Ultima modifica di Master85; 30-10-2012 13:30 

  5. #5
    lucagalbu non è in linea Scolaretto
    Luogo
    Italy
    Post
    244
    Capito!
    Grazie mille
    Colui che pone una domanda è uno sciocco per cinque minuti; colui che non pone una domanda rimane uno sciocco per sempre

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi