Chapter 6

To run MIMOSE models, you will need a copy of this tool, available from Koblenz.

To use the code, save all code segments which belong to the same model description to a file with the extension .desc.

The opinion formation model (pages 108-116)

This model is a simple two-level model. The two following objects must be saved to the same model description file or loaded from pop.desc.

pop := 
{
 x       :  real := 2 * haselements (persons.att,1)  / length (persons)  - 1;
 persons :  list of person;
 outx    :  list of real := append (outx_1,x)
};

person :=
{ 
 att :  int := case att_1 of
        1 :0 if 
             uniform(1,0.0,1.0) <
             nu * exp(-(pi + kappa * elem(p.x_1,1)))
           else 1;
        default:1 if 
             uniform(1,0.0,1.0) <
             nu * exp(  pi + kappa * elem(p.x_1,1)) 
           else 0;
        end;
 p   :  list of pop
};

After checking the model description, MIMOSE will open an initialisation window (see page 110) which can then be filled with initialisation data (or use pop.init). MIMOSE will also open a simulation run initialisation window (see page 112) where the desired initialisation can be inserted (or use pop.sim).

To run the model for more than one population at the same time, include the following code into your description file (or load multipop.desc):

experiment :=
{
 pops : list of pop;
 mean : real := pluslist(pops.x)/length(pops.x);
 outmean : list of real := append(outmean_1, mean);
}

Check the model description again and fill in the initialisation window. Don't forget to initialise a number of populations, and to initialise pop.persons with makegroupref instead of makeref. The complete initialisation file for the multi-population experiment is

%experiment := 1;
experiment.outmean_1 := <<[]>>;
experiment.pops := makeref(experiment, pop);
%pop := 20;
pop.x_1 := makeinst(20, 0.0);
pop.outx_1 := makeinst(20, []);
pop.persons := makegroupref(pop,makelist(20,1),person,makelist(20,100));
%person := 2000;
person.att_1 := makeinst(2000,uniform(1,0,1));
person.p := makegroupref(person,makelist(20,100),pop,makelist(20,1));
nu := 0.02;
pi := 0.0;
kappa := 1.5;

You can load this file into the initialisation window or use multipop.init; to describe the simulation parameters you can use multipop.sim.

The gender segregation model (pages 117-123)

The description file can be found at teachers.desc (which does not contain the variable nu described on page 122, see below).
system :=
{
  schooltypes   : list of schooltype;
};
schooltype :=
{
  schools : list of school;
};
school :=
{
  lteacher     : list of teacher
               := updateref(lteacher_1, friend(teacher.position)); 
  sexRatio     : real    /* sex=0: male, sex=1: female! */
               := haselements(lteacher.sex,1) / length(lteacher);
  sexRatioList : list of real 
               := append(sexRatioList_1, sexRatio);
  prob1        : real 
               := nu * exp(kappa * sexRatio_1);    
};
teacher :=
{
  position :  list of school;
  sex      :  int;
  age      :  int 
           := age_1 + 1;
  duration :  int 
           := (normal(1,15,5) if sex else normal(1,30,5))
              if count = 1 else
              duration_1 - 1;
  cond     :  int 
           := 1 if (duration_1 = 1) || (age_1 >= 64) else 0;
  death    :  list of teacher
           := delete(self(teacher),
                     self(teacher) if cond_2 else []);
  new      :  list of teacher
           := copy(self(teacher), 
                   cond_1, 
                   [age_1      :: uniform(1,25,30),
                    cond_1     :: 0,
                    cond_2     :: 0,
                    sex        :: 1 if 
                                  prob(1,position.prob1_1)
                                  else 0,
                    duration_1 :: normal(2,15,5) 
                                  if sex else 
                                  normal(2,30,5)      
                   ]);
};

Since the initialisation is intricate in this model, and you might have difficulties in finding all typing errors you might make, here is the complete initialisation file:

%system := 1;
system.schooltypes := makeref(system,schooltype);
%schooltype := 3;
schooltype.schools := 
makegroupref(schooltype,[1,1,1],school,[45,45,60]);
%school := 150;
school.lteacher_1 := makegroupref(school,makelist(150,1),
                                  teacher,makelist(150,30));
school.sexRatioList_1 := makeinst(150,[]);
school.sexRatio_1 := makeinst(150,uniform(3,0.0,1.0));
school.prob1_1 := makeinst(150,uniform(3,0.0,1.0));
%teacher := 4500;
teacher.sex := makegroupinst(makeinst(1350,1 if prob(6,0.88) else 0),
                             makeinst(1350,1 if prob(7,0.22) else 0),
                             makeinst(1800,1 if prob(8,0.08) else 0));
teacher.age_1 := makeinst(4500,uniform(2,25,65));
teacher.duration_1 := makeinst(4500,0);
teacher.cond_1 := makeinst(4500,0);
teacher.cond_2 := makeinst(4500,0);
teacher.position := makegroupref(teacher,makelist(150,30),
                                 school,makelist(150,1));
nu := 0.1;
kappa := 0.5;

The add-ins mentioned on page 113 have been inserted at the right places in the following two files (nykoed.desc and nykoed.init):

system :=
{
  schooltypes   : list of schooltype;
  schools       : list of school;
  SR : real := pluslist(schools.toReplace);
  SRp : real := pluslist(schools.wToRepl);
  ny : real := SR/(2.0*SRp);
  nylist : list of real := append(nylist_1, ny);
};
schooltype :=
{
  schools : list of school;
};
school :=
{
  sys      : list of system;
  lteacher : list of teacher
           := updateref(lteacher_1,friend(teacher.position)); 
  sexratio : real    /* sex=0: male, sex=1: female! */
           := haselements(lteacher.sex,1) / length(lteacher);
  toReplace : integer 
            := haselements(lteacher.cond,1);
  wToRepl  : real := toReplace*prob1/sys.ny_1;
  sexlist  : list of real := append(sexlist_1, sexratio);
  prob1    : real 
           := sys.ny_1 * exp(kappa * sexratio_1);    
};
teacher :=
{
  position :  list of school;
  sex      :  int;
  age      :  int 
           := age_1 + 1;
  duration :  int 
           := (normal(1,15,5) if sex else normal(1,30,5))
              if count = 1 else
              duration_1 - 1;
  cond     :  int 
           := 1 if (duration_1 = 1) || (age_1 >= 64) else 0;
  death    :  list of teacher
           := delete(self(teacher),  self(teacher) if cond_2 else []);
  new      :  list of teacher
           := copy(self(teacher), 
                   cond_1, 
                   [age_1      :: uniform(1,25,30),
                    cond_1     :: 0,
                    cond_2     :: 0,
                    sex        :: 1 if prob(1,position.prob1_1) 
                                   else 0,
                    duration_1 :: normal(2,15,5) 
                                  if sex else 
                                  normal(2,30,5)      
                   ]);
};

And here is the initialisation file:

%system := 1;
system.nylist_1 := <<[]>>;
system.schooltypes := makeref(system,schooltype);
system.schools := makeref(system,school);
system.ny_1 := <<0.1>>;
%school := 150;
school.lteacher_1 := makegroupref(school,makelist(150,1),teacher,makelist(150,30));
school.sexlist_1 := makeinst(150,[]);
school.sexratio_1 := makeinst(150,uniform(3,0.0,1.0));
school.sys := makeref(school,system);
school.prob1_1 := makeinst(150,uniform(3,0.0,1.0));
%schooltype := 3;
schooltype.schools := makegroupref(schooltype,[1,1,1],school,[45,45,60]);
%teacher := 4500;
teacher.sex := makegroupinst(makeinst(1350,1 if prob(6,0.88) else 0),
                             makeinst(1350,1 if prob(7,0.22) else 0),
                             makeinst(1800,1 if prob(8,0.08) else 0));
teacher.cond_1 := makeinst(4500,0);
teacher.cond_2 := makeinst(4500,0);
teacher.age_1 := makeinst(4500,uniform(2,25,65));
teacher.duration_1 := makeinst(4500,0);
teacher.position := makegroupref(teacher,makelist(150,30),school,makelist(150,1));
kappa := 0.5;
Both models can be initialised with same file.

The hawk-dove-law-abider model revisited (page 123-127)

MIMOSE as a tool for macro models (page 123)

Here is the code for the MIMOSE macro model which is equivalent to the DYNAMO model and the STELLA model. Store it to or load it from hobbes.desc.

hobbes :=          
{
	hawk : real := hawk_1 + DT * (yieldh_1 - hawk_1 * yields_1);           
	dove : real := dove_1 + DT * (yieldd_1 - dove_1 * yields_1);           
	lawa : real := lawa_1 + DT * (yieldl_1 - lawa_1 * yields_1);
	yieldd : real := (dove * rdd + hawk * rdh + lawa * rdl) * dove;           
	yieldh : real := (dove * rhd + hawk * rhh + lawa * rhl) * hawk;           
	yieldl : real := (dove * rld + hawk * rlh + lawa * rll) * lawa;           
	yields : real := yieldd + yieldh + yieldl;
	lHawk: list of real := append(lHawk_1,hawk);
	lDove: list of real := append(lDove_1,dove);
	lLawA: list of real := append(lLawA_1,lawa);          
};

And here is the corresponding initialisation file. Save it to or load it from hobbes.init and set the simulation parameters as in hobbes.sim:

%hobbes := 1;hobbes.dove_1 := <<0.05>>;
hobbes.yieldd_1 := <<0.0>>;
hobbes.yields_1 := <<0.0>>;
hobbes.hawk_1 := <<0.9>>;
hobbes.yieldh_1 := <<0.0>>;
hobbes.lawa_1 := <<0.05>>;
hobbes.yieldl_1 := <<0.0>>;
hobbes.lDove_1 := <<[]>>;
hobbes.lHawk_1 := <<[]>>;
hobbes.lLawA_1 := <<[]>>;
rdd := 10/2 - 3;
rdh := 0;
rdl := rdd/2;
rhd := 10;
rhh := (10 - 20)/2;
rhl := (rhh + 10)/2;
rld := (rdd + 10)/2;
rlh := rhh/2;
rll := 10/2;

The multi-level alternative (pages 123-127)

Here is the code for the two-level model of hawks, doves and law-abiders. Save it to something like multihdla.desc or load it from here:

individual := 
{
	r : real := uniform(1, 0.0, 1.0);
	strategy : int := case strategy_1 of
	0 : 1 if r < p.pHawkToDove_1 else
	2 if r < p.pHawkToDove_1 + p.pHawkToLawA_1 
	else strategy_1;
	1 : 0 if r < p.pDoveToHawk_1 else
	2 if r < p.pDoveToHawk_1 + p.pDoveToLawA_1 
	else strategy_1;
	default : 0 if r < p.pLawAToHawk_1 else
	1 if r < p.pLawAToHawk_1 + p.pLawAToDove_1 
	else strategy_1;
	end;
	p : list of pop;
}

pop :=
{
	indiv : list of individual;
	hawk : int := haselements(indiv.strategy, 0);
	dove : int := haselements(indiv.strategy, 1);
	lawa : int := haselements(indiv.strategy, 2);
	yieldh : real := kappa*(dove*rhd + hawk*rhh + lawa*rhl)*hawk;
	yieldd : real := kappa*(dove*rdd + hawk*rdh + lawa*rdl)*dove;
	yieldl : real := kappa*(dove*rld + hawk*rlh + lawa*rll)*lawa;
	pHawkToDove : real := nu * exp(yieldd - yieldh);
	pHawkToLawA : real := nu * exp(yieldl - yieldh);
	pDoveToHawk : real := nu * exp(yieldh - yieldd);
	pDoveToLawA : real := nu * exp(yieldl - yieldd);
	pLawAToHawk : real := nu * exp(yieldh - yieldl);
	pLawAToDove : real := nu * exp(yieldd - yieldl);
	lHawk : list of int := append(lHawk_1, hawk);
	lDove : list of int := append(lDove_1, dove);
	lLawA : list of int := append(lLawA_1, lawa);
}

To make initialisation easier, here is also the initialisation file. Save it to something like multihdla.init or load it from here (the simulation run be initialised from this file):

%individual := 100;
individual.att_1 := makegroupinst(makeinst(90,0),makeinst(5,1),makeinst(5,2));
individual.p := makeref(individual,pop);
%pop := 1;
pop.pHawkToDove_1 := <<0.0>>;
pop.pHawkToLawA_1 := <<0.0>>;
pop.pDoveToHawk_1 := <<0.0>>;
pop.pDoveToLawA_1 := <<0.0>>;
pop.pLawAToHawk_1 := <<0.0>>;
pop.pLawAToDove_1 := <<0.0>>;
pop.lHawk_1 := <<[]>>;
pop.lDove_1 := <<[]>>;
pop.lLawA_1 := <<[]>>;
pop.indiv := makeref(pop,individual);
ny := 0.001;
kappa := 0.0001;
rdd := 10/2 - 3;
rdh := 0;
rdl := rdd/2;
rhd := 10;
rhh := (10 - 20)/2;
rhl := (rhh + 10)/2;
rld := (rdd + 10)/2;
rlh := rhh/2;
rll := 10/2;

This code is © Nigel Gilbert and Klaus G. Troitzsch 2005

It may be freely reproduced and incorporated into other software provided that reasonable acknowledgement of its source is given.

Send email to the authors Program code Sample chapter