5

Ich baue ein Mikrosimulationsmodell in Julia. Ich habe die Struktur meiner Funktion aufgebaut und läuft super für 1 "Person". Ich möchte das Skript schreiben, um 100000+ Personen durch das Modell zu führen und die Ergebnisse an einem Ort zu speichern.Julia, Funktion mehrmals ausführen, Ergebnisse im Array speichern

Schließlich möchte ich das parallel ausführen.

Im Folgenden habe ich eine einfache funktionierende Version des Codes mit Dummy-Wahrscheinlichkeiten enthalten.

using Distributions 

# Microsim function 
function MicroSim(start_age, stages) 
    stage = 0 
    age = start_age 

    # Set all trackers to 0 
    Death_tracker = 0 
    Disease_tracker = 0 

    # While loop 
    while stage <= stages 
    age = age 

    ########################################################### 
    # Probability of Death 
    pD = 0.02 

    if age == 100 
     pD = 1.0 
    else 
     pD = pD 
    end 

    # Coin flip 
    dist_pD = Bernoulli(pD) 
    Died = rand(dist_pD, 1) 

    if Died == [1] 
     Death_tracker = 1 
     # death tracker loop break 
     if Death_tracker == 1 
     # println("I died") 
     break 
     end 
    else 
     Death_tracker = Death_tracker 
    end 
    ########################################################### 

    # Update age and stage 
    age = age + 1 
    stage = stage + 1 

    end 

return age, Death_tracker 

end 


MicroSim(18,100) 
+1

können Sie nicht Schleife, die oft Funktion? 'für i in 1: 100 println (MicroSim (18,100)) ende ' – amrods

Antwort

6

Sie suchen die Funktionen map und pmap (Parallelisierung). Ich habe Ihre Funktion vereinfacht, um ein minimaleres Arbeitsbeispiel zu geben. (In der Zukunft finden Sie in this link für die Anleitung zum Erstellen solcher minimale Beispiele in Ihren Fragen).

map übernimmt eine Funktion (die Sie angeben) und wendet sie auf alle Elemente in einem Array an. Wenn Ihre Funktion mehrere Argumente benötigt (wie bei Ihnen), geben Sie einfach map mehrere aufeinanderfolgende Arrays ein. map gibt dann ein neues Array mit den Ergebnissen all Ihrer Funktionen zurück.

function MicroSim(start_age, stages) 
    return rand(start_age), rand(stages) 
end 

Start_Ages = [10, 20, 15] 
Stages = [1, 4, 5] 

Results = map(MicroSim, Start_Ages, Stages) 

Wenn Sie Dinge parallelisieren möchten, gibt es nur drei einfache Anpassungen. 1. Verwenden Sie die addprocs()-Funktion, um so viele zusätzliche Prozesse hinzuzufügen, wie Sie möchten. 2. Verwenden Sie das Makro @everywhere, wenn Sie Ihre Funktion deklarieren, damit auch Ihre Worker-Prozesse darauf zugreifen können. 3. Verwenden Sie die Funktion pmap statt map:

addprocs(2) 

@everywhere begin 
    function MicroSim(start_age, stages) 
     return rand(start_age), rand(stages) 
    end 
end 

Results = pmap(MicroSim, Start_Ages, Stages) 
+0

Ich frage mich, ob Sie hier auch @ vectorize_2arg verwenden können? –

+0

Vielen Dank für diese Antwort. Die Map-Funktion wendet die richtigen Elemente an und erzeugt Ergebnisse, aber alles wird in einem Vektor gespeichert, in dem jedes Element ein Tupel ist. Gibt es eine einfache Möglichkeit, dies in ein Array zu konvertieren? – MJH

+0

@MJH Momentan gibt Ihre Funktion ein Tupel aus. Wenn Sie den Rückgabewert in Klammern setzen, wird ein Array ausgegeben. Dann können Sie 'BigArray = vcat (results ...)' verwenden, um es in ein einzelnes Array zu verwandeln, eine Zeile für jeden Lauf Ihrer Simulation. –