2016-06-10 2 views
1

Dies ist, was ich importiert haben:Anfügen hält auf den gleichen Artikel anhängt, nicht die richtigen anhängen, Python

import random 
import matplotlib.pyplot as plt 
from math import log, e, ceil, floor 
import numpy as np 
from numpy import arange,array 
import pdb 
from random import randint 

Hier habe ich die Funktionsmatrix (p, m)

def matrix(p,m):   # A matrix with zeros everywhere, except in every entry in the middle of the row 
    v = [0]*m 
    v[(m+1)/2 - 1] = 1 
    vv = array([v,]*p) 
    return vv 

ct = np.zeros(5)   # Here, I choose 5 cause I wanted to work with an example, but should be p in general 
definieren Hier definieren

MHops I, die im wesentlichen die Dimensionen der Matrix erfolgt, der Matrix und der Vektor ct und gibt mir eine neue Matrix mm und einen neuen Vektor ct

def MHops(p,m,mm,ct): 

k = 0 
while k < p :     # This 'spans' the rows 
    i = 0 
    while i < m :    # This 'spans' the columns 
     if mm[k][i] == 0 : 
      i+=1 
     else: 
      R = random.random() 
      t = -log(1-R,e)    # Calculate time of the hopping 
      ct[k] = ct[k] + t 
      r = random.random() 
      if 0 <= r < 0.5 :    # particle hops right 
       if 0 <= i < m-1: 
        mm[k][i] = 0 
        mm[k][i+1] = 1 
        break 
       else: 
        break   # Because it is at the boundary 
      else:       # particle hops left 
       if 0 < i <=m-1:  
        mm[k][i] = 0 
        mm[k][i-1] = 1 
        break 
       else:    # Because it is at the boundary 
        break 
      break 
    k+=1  
return (mm,ct)    # Gives me the new matrix showing the new position of the particles and a new vector of times, showing the times taken by each particle to hop 

Nun möchte ich diesen Prozess wiederholen, aber ich möchte jeden Schritt in einer Liste visualisieren können. Kurz gesagt, was ich tue, ist: 1. Erstellen einer Matrix, die ein Gitter darstellt, wobei 0 bedeutet, dass es kein Teilchen in diesem Schlitz gibt und 1 bedeutet, dass dort ein Teilchen ist. 2. Erstellen Sie eine Funktion MHops, die einen zufälligen Schritt von einem Schritt simuliert und mir die neue Matrix und einen Vektor ct gibt, der die Zeiten anzeigt, zu denen sich die Partikel bewegen.

Jetzt möchte ich einen Vektor oder ein Array haben, wo ich 2 * n Objekte habe, d. H. Die Matrix mm und der Vektor ct für n Iterationen. Ich möchte das in einem Array, einer Liste oder so etwas, weil ich sie später verwenden muss.

Hier beginnt mein Problem:

ich eine leere Liste zu erstellen, ich anhängen verwenden, um Elemente bei jeder Iteration der while-Schleife anzuhängen. Das Ergebnis, das ich erhalte, ist jedoch eine Liste d mit n gleichen Objekten aus der letzten Iteration!

Daher meine Funktion für die Iteration ist die folgende:

def rep_MHops(n,p,m,mm,ct): 
    mat = mm 
    cct = ct 
    d = [] 
    i = 0 
    while i < n : 
     y = MHops(p,m,mat,cct)  # Calculate the hop, so y is a tuple y = (mm,ct) 
     mat = y[0]     # I reset mat and cct so that for the next iteration, I go further 
     cct = y[1] 
     d.append(mat) 
     d.append(cct) 
     i+=1 
    return d 


z = rep_MHops(3,5,5,matrix(5,5),ct)  #If you check this, it doesn't work 
print z 

aber es nicht funktioniert, verstehe ich nicht, warum. Was ich mache ist MHops zu verwenden, dann möchte ich die neue Matrix und den neuen Vektor als solche in der Ausgabe von MHops setzen und dies wieder tun. Wenn Sie jedoch diesen Code ausführen, werden Sie sehen, dass v funktioniert, dh der Vektor der Zeiten erhöht sich und die Matrix des Gitters ändert sich, wenn ich dies an d anfüge, ist d im Grunde eine Liste von n gleichen Objekten, wo das Objekt sind die letzte Iteration.

Was ist mein Fehler? Außerdem, wenn Sie Codierungsratschläge für diesen Code haben, wären sie mehr als willkommen, ich bin mir nicht sicher, ob dies ein effizienter Weg ist.

Nur um Sie besser zu verstehen, würde ich gerne den letzten Vektor d in einer anderen Funktion verwenden, wo ich zuerst eine zufällige Zeit T auswähle, dann würde ich grundsätzlich jeden ungeraden Eintrag (jeden ct) überprüfen und somit jeden überprüfen Eingabe von jedem ct und sehen, ob diese Zahlen kleiner oder gleich T sind. Wenn dies passiert, dann ist die Bewegung des Teilchens passiert, sonst nicht. Von diesem dann werde ich versuchen, mit Matpotlibt das Ergebnis mit einem Histogramm oder etwas ähnliches zu visualisieren.

Gibt es jemanden, der diese Art von Simulation in Matlab ausführen kann? Glaubst du, es wäre einfacher?

+0

Ich bin unsicher über die Logik, weil ich nicht mit dem Problem vertraut bin, aber ich habe ein paar Tipps für Ihren Code. Listen können mit der '.append (object_to_append)' -Methode wie gezeigt angefügt werden. In manchen Fällen ist es sinnvoll, die Einträge in der Liste "list [index] = some_value" zu ersetzen. In Ihrem Fall gibt es jedoch keinen Grund, eine Liste mit n Indizes zu instanziieren. Erstellen Sie einfach eine leere Liste und verwenden Sie bei jeder Iteration die Append-Methode, anstatt einen zuvor erstellten Wert zu ersetzen! – TheLazyScripter

+0

Vielen Dank für Ihren Kommentar, allerdings hatte ich das schon ausprobiert. Ich hatte 'd = []' und nach 'cct = y [1]' hatte ich 'd.append (mat)' und 'd.append (cct)' aber es hat nicht funktioniert !! –

+0

Was ich hatte, war: 'def rep_MHops (n, p, m, mm, ct):' ' mat = mm' ' CCT = ct' 'd = []' ' i = 0 ' ' während i

Antwort

0

Sie vorbei und Speicherung von Referenzen nicht kopiert, so auf der nächsten Iteration der Schleife MHops ändert Ihre zuvor gespeicherte Version in d. Verwenden Sie import copy; d.append(copy.deepcopy(mat)), um stattdessen eine Kopie zu speichern, die später nicht mehr geändert wird.

Warum?

Python übergibt die Liste als Referenz, und jede Schleife, die Sie eine Referenz auf die gleichen Matrixobjekt in d speichern.

Ich habe durch Python-Dokumente, und die einzige Erwähnung, die ich finden kann, ist "how do i write a function with output parameters (call by reference)".

Hier ist ein einfacheres Beispiel des Codes:

def rep_MHops(mat_init): 
    mat = mat_init 
    d = [] 
    for i in range(5): 
     mat = MHops(mat) 
     d.append(mat) 
    return d 


def MHops(mat): 
    mat[0] += 1 
    return mat 

mat_init = [10] 
z = rep_MHops(mat_init) 
print(z) 

Wenn Lauf gibt:

[[15], [15], [15], [15], [15]] 

Python geht nur veränderbare Objekte (wie Listen) Bezug genommen wird. Eine ganze Zahl ist kein veränderliches Objekt, hier ist eine leicht modifizierte Version des obigen Beispiels, das auf einer einzigen Ganzzahl arbeitet:

def rep_MHops_simple(mat_init): 
    mat = mat_init 
    d = [] 
    for i in range(5): 
     mat = MHops_simple(mat) 
     d.append(mat) 
    return d 


def MHops_simple(mat): 
    mat += 1 
    return mat 

z = rep_MHops_simple(mat_init=10) 
print(z) 

Wenn Lauf gibt:

[11, 12, 13, 14, 15] 

welches das Verhalten, das Sie erwartet haben .

Diese SO-Antwort How do I pass a variable by reference? erklärt es sehr gut.

+0

Vielen Dank @RedCraig! Ich habe nie darüber nachgedacht –

Verwandte Themen