2016-07-21 31 views
5

Buduję model mikrosimulacji w Julia. Zbudowałem strukturę mojej funkcji i działa świetnie dla 1 osoby. Chciałbym napisać skrypt, aby uruchomić 100000 osób poprzez model i zapisać wyniki w jednym miejscu.Julia, uruchom funkcję wiele razy, zapisz wyniki w tablicy

Ostatecznie chciałbym wykonać to równolegle.

Poniżej zamieściłem prostą roboczą wersję kodu z prawdopodobieństwem atrapa.

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

nie możesz pętli funkcję wiele razy? 'for i in 1: 100 println (MicroSim (18,100)) end' – amrods

Odpowiedz

6

Szukasz funkcji map i pmap (dla parallelization). Uprościliśmy twoją funkcję, aby dać bardziej minimalny przykład pracy. (w przyszłości zobacz pod adresem this link, aby uzyskać wskazówki dotyczące tworzenia takich minimalnych przykładów w pytaniach).

map przyjmuje funkcję (określoną przez użytkownika) i stosuje ją do wszystkich elementów w tablicy. Jeśli twoja funkcja przyjmuje wiele argumentów (tak jak twoja), po prostu karmisz map wiele kolejnych tablic. map następnie zwraca nową tablicę z wynikami wszystkich twoich funkcji.

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) 

Jeśli chcesz zrównoleglić rzeczy, istnieją tylko trzy proste poprawki. 1. użyj funkcji addprocs(), aby dodać dowolną liczbę dodatkowych procesów, które chcesz. 2. podczas deklarowania funkcji używaj makra @everywhere, aby procesy robocze również miały do ​​niego dostęp. 3. użyć funkcji pmap zamiast 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

Zastanawiam się, czy możesz również użyć @ vectorize_2arg tutaj? –

+0

Dziękuję za tę odpowiedź. Funkcja mapy stosuje poprawne elementy i generuje wyniki, ale wszystko jest przechowywane w wektorze, gdzie każdy element jest krotką. Czy istnieje jakiś prosty sposób przekonwertowania tego do tablicy? – MJH

+0

@MJH Teraz twoja funkcja wyprowadza krotkę. Jeśli umieścisz nawiasy wokół wartości zwracanej, wyświetli się tablica. Następnie możesz użyć 'BigArray = vcat (results ...)', aby przekształcić go w pojedynczą tablicę, jeden wiersz dla każdego przebiegu twojej symulacji. –