Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia, run function multiple times, save results in array

I am building a microsimulation model in Julia. I have built the structure of my function and it runs great for for 1 "person". I'd like to write the script to run 100000+ people through the model and save the results in one location.

Eventually I'd like to execute this in parallel.

Below I have included a simple working version of the code with dummy probabilities.

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)
like image 835
MJH Avatar asked Jul 21 '16 22:07

MJH


1 Answers

You are looking for the functions map and pmap (for parallelization). I've simplified your function to give a more minimal working example. (in the future, please see this link for guidance on creating such minimal examples in your questions).

map takes a function (that you specify) and applies it to all of the elements in an array. If your function takes multiple arguments (as yours does), then you simply feed map multiple successive arrays. map then returns a new array with the results of all your functions.

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)

If you want to parallelize things, there are just three simple adjustments. 1. use the addprocs() function to add however many additional processes you want. 2. use the @everywhere macro when declaring your function so that your worker processes also have access to it. 3. use the function pmap instead of map:

addprocs(2)

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

Results = pmap(MicroSim, Start_Ages, Stages)
like image 193
Michael Ohlrogge Avatar answered Nov 18 '22 17:11

Michael Ohlrogge