Documentation for MOpt.jl

This is a Julia library to run moment optimization in parallel.

Contents:

Getting Started

Let’s see how to get started very quickly. You start by ....

Setting the problem

This package implements several MCMC algorithms to optimize a non-differentiable objective function. The main application are likelihood-free estimators, which requires evaluating the objective at many regions. In general, this implements Simulated Method of Moments. The library is targeted to run MCMC on an SGE cluster, where each node is a chain.

For an R implementation which is the basis of this package, see [https://github.com/tlamadon/mopt](https://github.com/tlamadon/mopt)

Example Useage

using Mopt

# get a parameter vector
p = ["a" => 3.1 , "b" => 4.9]
# define params to use with bounds
pb= [ "a" => [0,1] , "b" => [0,1] ]

# get some moments
# first entry is moment estimate, second is standard deviation
moms = [
  "alpha" => [ 0.8 , 0.02 ],
  "beta"  => [ 0.8 , 0.02 ],
  "gamma" => [ 0.8 , 0.02 ]
]

# a subset of moments to match
submoms = ["alpha", "beta"]

# call objective
x = Mopt.Testobj(p,moms,submoms)

# Define an Moment Optimization Problem
mprob = Mopt.MProb(p,pb,Mopt.Testobj,moms;moments_subset=submoms)

# show
mprob

# step 2: choose an algorithm
# ----------------------
algo = Mopt.MAlgoRandom(mprob,opts=["mode"=>"serial","maxiter"=>100])

# step 3: run estimation
# ----------------------
runMopt(algo)

Setting up a moment problems

This section describes how to create the MProb object that will store the description of the problem. In general this is composed of the set of parameters we will iterate over together with their bounds, as well as the set of moments to match, with their value and their precision.

We start by creating an empty MProb object and we progressively add content to it.

using Mopt
mprob = MProb()

We then describe the step required to scuccessfuly set up the object.

Step 1: add parameters

There are two types of parameters, some are sampled by the algorythm and some are not. Here are ways to add arguments to the description:

addParam!(mprob, "c", 0.1)
addParam!(mprob, "d", 0.2)
addSampledParam!(mprob, "a", 0.1, 0, 1)
addSampledParam!(mprob, "b", 0.1, 0, 1)

But parameters can also be added all at once using for instance a dictionary

ps  = { "c" => 0.1 , "d" => 0.2}
addParam!(mprob,ps)
pss = { "a" => [0.1, 0, 1] , "b" => [0.1, 0, 1]}
addSampledParam!(mprob,pss)

Step 2: add moments

The second step is to add moments to the description. These are moments that the objective function will use as matching criteria. This is more for analysis purposes, as ex-post it can be very informative to look at what parameter is affected by what particular moments, or to check the shape of the moment conditions at maximum.

In a spirit similar to the parameters, moments can be added as follows:

addMoment!(mprob, "m1", 0.1, 0.001)
addMoment!(mprob, "m2", 0.1, 0.001)

But as well using a DataFrame which is usually how moments are loaded, from a csv file or other source. In this case the used needs to provide the names of the columns that must be used.

dd = DataFrame(name= ["m1", "m2"], value=[0.1,0.1], sd=[0.01,0.01])
addMoment!(mprob, dd, [:name,:value,:sd])

Done, next is selecting an algorithm

This is it, your problem is now created, you can move to the second step which is to select an algorithm.

Putting all at once using Lazy.jl

mprob = @> begin
  Mprob()
  addParam!("c", 0.1)
  addParam!("d", 0.2)
  addSampledParam!("a", 0.1, 0, 1)
  addSampledParam!("b", 0.1, 0, 1)
  addMoment!("m1", 0.1, 0.001)
  addMoment!("m2", 0.1, 0.001)
end

Writing an objective function

We show here how to write your own objective function. The signature is:

obj(x::Dict,mom::DataFrame,whichmom::Array{ASCIIString,1},vargs...)

where the first agrument is a dictionary of values for the parameters. The second is a dataFrame that contains information about the different moments to match. This will include the value of the moments together with their standard error.

The objective function should return another Dictionary that includes:

  • value: the value of the objective function
  • params: the list of parameters with their value, this should just be a deep copy of x
  • time: the amount of time spent in the objective function
  • moments: a DataFrame with the evaluated moments

here is a full example:

function Testobj(x::Dict,mom::DataFrame,whichmom::Array{ASCIIString,1},vargs...)

  t0 = time()

  if length(vargs) > 0
      if get(vargs[1],"printlevel",0) > 0
          info("in Test objective function")
      end
  end

  mm = deepcopy(mom)
  nm0 = names(mm)
  DataFrames.insert_single_column!(mm,zeros(nrow(mm)),ncol(mm)+1)
  names!(mm,[nm0,:model_value])

  for ir in eachrow(mm)
      ir[:model_value] = ir[:data_value] + 2.2
  end

  # output all moments
  mout = transpose(mm[[:moment,:model_value]],1)

  # subset mm to required moments to compute function value
  mm = mm[findin(mm[:moment],whichmom),:]

  # compute distance
  v = sum((mm[:data_value] - mm[:model_value]).^2)

  # status
  status = 1

  # time out
  t0 = time() - t0

  # return a dict
  ret = ["value" => v, "params" => deepcopy(x), "time" => t0, "status" => status, "moments" => mout]
  return ret

end

Indices and tables