Frequently Asked Questions on Lsd
What is Lsd?
Lsd (Laboratory for Simulation Development) is a language to write
simulation models, which appear as stand-alone programs complete of
graphical
based interfaces for any possible use of the model (from running the
simulation
to prepare scientific publications). Two characteristics make Lsd
particularly
useful in order to use simulation models in social sciences:
1) a Lsd model is an extremely simple to use, stand-alone program that even non-expert computer users can use to run and test the results from simulation models.
2) Model writers need to write all and only the code directly linked to the content of the model, having automatically available all interfaces that allow to access any aspect of the model, simplifying the process of building the model and allowing an easy distribution of the model.
Lsd tries to break the trade-off between simplicity of use of a simulation model and complexity to build it. This is obtain by allowing programmers to write pieces of code independently for each equation (i.e. Variable) of the model. In this way the process of code writing is greatly simplified because a complex model is decomposed in its individual equations. When the equations are (supposed to be) ready, the system automatically generates an executable complete with interfaces. The system automatically exploits the Variables' code as required during a simulation run, storing the results, signalling errors, and allowing the model inspections, without any need for the modeller to write specific code for these operations.
Although very simple to use, Lsd is also extremely powerful, since it is based on C++, and therefore the resulting simulations are fast and virtually unlimited in their dimensions.
The general philosophy of Lsd models is based on the difference equations model: modellers write each Variables' equation in order to compute its generic value at time t using Parameters and other models Variables at time t, t-1, t-2 etc. Any legal C++ statement can be included in a Variable's equation, allowing the use of a large set of libraries available for this language.
Lsd is particularly useful for agent based models, since it entails models based on a hierarchy of entities, with fast and automatic search through the "tree" of entities for the correct elements.
Lsd is distributed as source code (completely free to use, under the GNU general public license) that must be integrated with the code of the model to compile a stand-alone Lsd instance, a model. Lsd makes use of Tcl/Tk libraries and of the GNU C++ compiler, all of which is freely available under the same GNU general public licence).
What is LMM?
LMM (Lsd Model Manager) is an integrated environment created to to
develop and manage a set of Lsd models. LMM is composed by a text
editor,
specially suited for C++ coding in general and Lsd coding in
particular,
and by a set of commands. The editor is automatically used to write the
Lsd equations. The commands available make automatic the procedures of
compiling, debugging and running Lsd programs in a transparent way, so
that even non-expert programmers can use C++ compiled code for their
simulation
models. See the LMM Manual for further
information.
Return to the top
Where do I start using a Lsd model?
The distribution of Lsd includes several example models, some of which
are for purely teaching purposes, while others are complex models with
scientific purposes.
Although Lsd model programs are stand-alone programs, the best and
simplest way is to use LMM to compile and run them.
To run a Lsd model program follow these steps:
The equations are implemented as pieces of code, defined independently for each equation, which are implemented in a Lsd model program. This program can either create, load or modify a model structure, which contains the definitions for all the items in the model, initializations etc.
Lsd is founded on the opinion that generating values is still not sufficient to exploit simulation models. It is necessary to fully understand the results. For this, Lsd model programs produce automatically a complete documentation of the model, called model report, which provide a complete description of the model in a very clear and intuitive way.
Technically, when a user asks to run a Lsd simulation exercise with the following steps:
The necessity to write C++ code for the equations is the major difficulty for writing Lsd models. This is necessary because, after all, a simulation is a program and model writers must be aware of the content of their model, and Lsd does not pose any limitation on the family of models that can be implemented with it. On the other hand, Lsd facilitates enormously the code writing in respect of writing a pure C++ program. In fact, it takes the burden of two major difficulties in writing simulation programs. The first, it is to ensure that Variables' values updating is consistent, that is, that the equations be computed at the right time so that lagged and updated values are used appropriately. The second difficulty is to be sure that Variables contained in different instances of the same Objects use the correct values (a big source of troubles for agent-based, micro-founded models where the same entity is replicated many times in the models).
The problem of the scheduling of the operations during a simulation time step is solved in Lsd by writing equations as difference equations. That is, model writers use a lag notation that implicitly provides the correct scheduling. A powerful debugger helps to solve the problem of scheduling errors even under the most extreme conditions.
The problem of multiple Variables with the same name is solved by using a hierarchical structure. That is, if model writers do not specify which instance they need to use in their equations, the system automatically provides the value of the "closest" instance of the requested element. Overruling systems allow anyway modellers to access any value of the model they may necessitate.
All in all, writing the equations' code for a Lsd model has the same
difficulty of writing the C++ equivalent of the set of difference
equations
expressing the model, and therefore the complexity depends on the model
only. Moreover, an equation can contain any legal C++ code besides
computing
numerical values. For example, an equation can overwrite other
Variables'
or Parameters' values of the model, create or remove Objects, quit the
simulation, trigger messages under particular circumstances, etc.
Return to the top
Object Obj
{ Variables: X, Y, Z, ...;
Parameters: H, K, ...;
Objects: Obj1, Obj2, Obj3, ...;
Function: F1, F2, ...;
}
Labels for Objects, Parameters and Variables must be unique strings
of standard characters (e.g. no spaces).
Since an Object can be composed by other Objects, a model is made of
a collection of Objects in the form of a hierarchical structure. Any
model
"begins" with the uppermost Object called Root that, in general,
shouldn't
contain other elements as Variables and Parameters. Objects in Lsd are
defined by model writers and (apart the Root) can be replicated by
users
in many instances in a model setting.
The hierarchical structure is used during a simulation to "induce" where the data required in an equation must be retrieved. In fact, in general there are many instances of each Object type, and therefore there many instances of Variables and Parameters with the same label. In general, consider the case of the equation for Variable A using the values of Parameter B. If B is defined as a member of the same Object as A, then the equation for A will use the instance of B in the same Object. If B is not contained in the same Object type (and there are many instances of the Object containing B) the structure of the model is crucial. Lsd has a default system that provides always the required values searching through the whole model. The model writer, when designing the model, must ensure that the correct instance is used. Most of the times, the default systems provides the correct solution. But modellers can always overrule the default system and implement model specific data retrieving systems.
Generally speaking, an Object must be represented as a descendant
from
a parent Object in case during all its existence in the model (Object
can
be created or removed during simulation runs) it uses the values of the
same identical instance of the parent Object. If instead, the
(purported)
descendant Object can refer to different instances of the parent
Object,
then it should be placed in a parallel "branch" of the other Object.
Return to the top
Technically, a Variable is made of an equation, attached to a list of numerical values (Lsd implements only real valued Variables) each tagged with a time index. Different instances of the same Variable have the same equation to compute their value, although these value in general may differ because they use the values from different instances of the same type of Object.
The numerical values are computed using the equation and the past
values
are shifted so that at each generic time step during a simulation the
system
(or the user of the model) can access the desired Variable's value
knowing
which value was computed at each time step. Variables that are never
used
with lagged (past) values in the model (i.e. in the equations) do not
require
to be initialized before the simulation run, since their value is
computed
at the very first time step using their equation. Instead, Variables
with
lags requires initial values to be used at the very beginning of the
simulation
runs.
Return to the top
In detail, a Lsd configuration is a standard text file, but should never be edited manually. For interested users, Lsd Model files have the following structure:
The structure of a model is a hierarchy in that represents "what contains what" in the reality represented by the simulation model. The entities, or Objects, in the model can be hierarchically linked or "parallel". In the first case, the parent Objects (higher in the hierarchy) can access many instances of the same Objects descending from them, so that they can compute aggregate values produced by the whole set of descendants. Descending Objects, instead, have access to only one instance of the parent Object, and it is the same instance for all the same descendants, so that they can access the same values contained in the parent. This system allows model writers to easily write equations code relying on the hierarchical links to individuate the correct instance to use in the equations. Independent, or parallel, can access each others' values as long as they are unique instances.
The general rule is that Variables in descending Objects must make use in their equation of elements in parent Objects when they must refer to the same instance for all their existence in the simulation. If, instead, a descending Object needs to access different instances then the Objects must not be hierarchically linked (and the modeller must explicitly provide the code for which instance to access).
For example, consider a model where many instance of Object Firm have the Variable Quantity. The equation for Quantity makes use of the lagged value of Variable Price. Suppose Objects Firm are defined as descendants from Object Supply, that is, many Firm are part of a Supply side, which, in turn, is defined as having a parallel Object Demand. We can imagine three situations: Variable Price is placed in the same Object Firm, or in the Object Supply, or in Object Demand. Wherever it is placed, in the equation for Quantity is always possible to refer to values for Price without specifying where this Variable is contained. The difference is about how the model considers the Price to be formed.
In case Price is contained in each Firm, there will be as many Prices as many Firms, with Demand represented as Price-taker.
For a Lsd model does not make any difference whether the Variable
Price
is placed as part of Object Firm or as part of Object Market containing
Object Firms. The only difference is that, in the first case, each Firm
will use the value of a different instance of Variable Price (one in
each
Firm), while, in the second case, all Firms will use the same instance,
since they will find the same Variable Price contained in the Object
Market
containing them. The same applies also if there are many Objects
Markets,
each with its group of Firms. In this case (and with a centralized
Price)
each Firm will use the instance of Price in "its own" market, with no
danger
that a different instance of Price can be used.
Return to the top
The simplicity of use Lsd permits to distribute models to non-expert users that can easily understand and replicate the results. Lsd can run under any Windows and Unix system (and it is possible to run a model created in one environment in another). The complete Lsd installation is very small (~5-15 Mb, depending the OS used). It does not require any additional software for Windows users, while under Unix is required a GNU C++ compiler, and the Tcl/Tk libraries, already installed in practically any Unix system.
Lsd models are, by all means, pure C++ compiled code using dynamically allocated memory, therefore exploiting at the best the power of your system.
Last, but not least, Lsd stresses specificully the problem of documentation, which causes the large majority of potential users to abandon simulations since it is not clear what a model does. Any Lsd model is accompanied by an automatically created HTML document, the Model Report, showing the code used for the equations and their connections with other elements of the model. Moreover, Lsd creates automatically another document, the Model Help, listing all elements of the model, so that the modeller can easily include comments and indications on the element's meaning. Both the Model Help and the Model Repor contain cross-references linking each other at the correct sections for each element of the model, and can be accessed by users under the menu item "Help".
During a simulation run only the data specifically indicated to be
saved
are kept in memory. Lsd is endowed with an Analysis
of Result module that permits to print graphs and produce some
statistics
from these series. The same module allows to export data in a variety
of
text formats for more sophisticated statistical or graphical
elaborations.
In case the configuration asks for many simulation runs to be done
in a sequence (typically, for robustness analysis), the system saves on
files the data at the end of each simulation. Each of these files
(extension
.res) can be used in the Analysis of Result module in Lsd. Moreover,
only
in case of multiple simulation runs, the system saves also the values
of
each series at the very last time step for each simulation run in a
single
file (called .tot file). This file (to be used with the Analysis of
Result
module) can be used to compare the final statuses of the model in each
simulaiton.
Concerning the documentation for Lsd in general, being a matter of software, the best way to learn Lsd is to use it. A hyper-manual is available, with all the aspects of Lsd reproduced as html files that can be browsed as hypertext with a normal Internet browser (e.g. Netscape Navigator, recommended, or Microsoft Explorer). This documentation is particularly useful because shows users the same interfaces of the Lsd models providing explanation on the functioning of the system.
Concerning the specific documentation of each Lsd model it depends
on
the model writer. Lsd offers the possibility to create automatically a
html file (Model Report) describing the content of the model as a
hypertext
that can be read at different levels of detail (overall model
structure,
individual elements, the whole code of the model's equations, each
numerical
value used). Modellers have also available the possibility to fill in
the
automatically created Model Help file, commenting any element of the
model.
Both the Model Report and the Model Help are shown automatically when
requested
from the menu Help of the Lsd model program.
Return to the top
Since my graduate dissertation (" tesi di Laurea", supervised by Prof. G.Dosi) I used simulation models, both for my own studies or under contract for other researchers. The basic motivation of Lsd (I mean, my own motivations) is laziness. I simply did not want to write twice the same code for different models. Since it is pretty common that a computer program uses 90% of the code for non-core operations, I found myself writing programs 90% of which were similar to previously written code every time I started a model. The basic idea of Lsd is to separate the model content from the "service" simulation code. In this way, writing the few lines of code corresponding to the equations of a model you obtain a fully serviced program, with interfaces, file management, debug control etc.
The history of evolution of Lsd is made of too many small steps to be reported in detail. However, it is made of two different, although related, purposes. I want Lsd to: