All experiments are demonstarted on scenario simulator which can be either standalone application or mex file (simulator.mex**).
Specific treatment was developed for objects. Since BDM is designed as object oriented library, the configuration was designed to honor the rule of inheritance. That is, offspring of a class can be used in place of its predecessor. Hence, objects (instances of classes) are configured by a structure with compulsory field class
. This is a string variable corresponding to the name of the class to be used.
The configuration has two possible options:
DS.class='MemDS';
DS.Data =[1 2 3 4 5 6];
The code above is the minimum necessary information to run scenario simulator
in matlab. To actually do so, make sure that matlab can find the simulator.mex file, e.g. by running:
>> addpath _path_to_/bmtoolbox/mex/
The expected result for Matlab is:
>> M=simulator(DS)
M =
ch0: [6x1 double]
If you see this result, you have configured BDM correctly and you have sucessfully run you first experiment. In other cases, please check your installation, BDM Use - Installation. All that the simulator did was actually copying DS.Data
to M.ch0
. Explanation of the experiment and the logic used there follows.
u
typically denotes input and y
denotes output of the system. A causal dependence between input and output is typically presumed.We are predominantly concerned with discrete-time systems, hence, we will add indeces to both input and output, and . We presume that the causal dependence is comes before .
One of the definition of a system is that system is a "set of variables observed on a part of the world". Under this definition system is understood as generator of data. This definition may be a considered too simplistic, but it serves well as a description of what software object DataSource
is.
DataSource is an object that is essentially:
No fruther specification, e.g. if the data are pre-recorded or computed on-the-fly, are given. Specific behaviour of various DataSources is implemented as specialization of the root class bdm::DS.
Operation of such object is trivial, the data are stored as a matrix and the general operations defined above are specialized as follows:
This is the default bahavior. It can be customized using the UI mechanism. When the object of class MemDS is created it calls method bdm::MemDS::from_setting() and the input structure is parsed for settings. All available settings are documented in the method, see bdm::MemDS::from_setting(). The options are:
DS.class = 'MemDS'; DS.Data = (...); // Data matrix or data vector --- optional --- DS.drv = RV({"ch0",...} ); // Identification how rows of the matrix Data will be known to others DS.time = 0; // Index of the first column to user_info, DS.rowid = [1,2,3...]; // ids of rows to be used
Fields time
and rowid
are self-explanatory. Field drv
is a the one that specifies identification of the data elements, (point 3. of the general requirements of a DataSource).
All optionals fields will be filled by default values, it this case:
DS.drv = RV({'ch0'},1,0);
DS.time = 0;
DS.rowid = [1];
random
variable
which is a description of random variable or its realization. This object playes role of identifier of elements of vectors of data (in datasources), expected inputs to functions (in pdfs), or required results (operations conditioning).
Mathematical interpretation of RV is straightforward. Consider pdf , then is the part represented by RV. Explicit naming of random variables may seem unnecessary for many operations with pdf, e.g. for generation of a uniform sample from <0,1> it is not necessary to specify any random variable. For this reason, RV are often optional information to specify. However, the considered scenanrio simulator
is build in a way that requires RV to be given.
In software, RV
has three compulsory properties:
names={'a', 'b'}; sizes=[ 2 , 3]; times=[-1, 1];
For convenience in Matlab, the following operations are defined:
See examples in bdmtoolbox/tutorial/userguide
simulator
scenario connects the DataSource to second basic class of BDM, bdm:logger. The logger is a class that take care of storing results -- in this case, results of simulation. The connection between these blocks is done automatically. The logger stores results of simulations under the names specified in drv. Readers familiar with Simulink environment may look at the RV as being unique identifiers of inputs and outputs of simulation blocks. The inputs are connected automatically with the outputs with matching RV. This view is however, very incomplete, RV have more roles than this.These abstarct operations can be specialized in many ways. For example, storing all results in memory and writing them to disc when finished (bdm::memlog), storing data in a matlab structure (bdm::mexlog), writing them out in ascii (bdm::stdlog) or more sophisticated buffered output to harddrive (bdm::dirfilelog).
Since all experiments are performed in matlab, the default mexlog class will be used. However, the way how the results are to be stored can be configured using configuration structure filled by fields from from_setting
of the chosen logger, and passing it as third argument to simulator
.
simulator
is written to accept any datasource (i.e. any offspring of bdm::DS). For full list of offsprings, click see Classes > Class Hierarchy.At the time of writing this tutorial, available datasources are bdm::DS
The MemDS has already been introduced in the example in memds. However, any of the classes listed above can be used to replace it in the example. This will be demonstrated on the EpdfDS
class.
Brief decription of the class states that EpdfDS "Simulate data from a static pdf (epdf)". The static pdf means unconditional pdf in the sense that the random variable is conditioned by numerical values only. In mathematical notation it could be both and . The latter case is true only when all denotes observed values.
For example, we wish to simulate realizations of a Uniform pdf on interval <-1,1>. This is achieved by plugging an object representing uniform pdf into general simulator of independent random samples, EpdfDS. Uniform density is implemented as class bdm::euni. An instance of euni
can be again created method from_setting
, in this case bdm::euni.from_setting(). Using documentation we define it with the following code:
U.class='euni'; U.rv = RV({'a'}); U.high = 1.0; U.low = -1.0;
The datasource itself, i.e. the instanc of EpdfDS
can be then configured via:
DS.class = 'EpdfDS';
DS.epdf = U;
U
is the structure defined above.
Contrary to the previous example, we need to tell to algorithm simulator
how many samples from the data source we need. This is configured by variable experiment.ndat
. The configuration has to be finalized by:
experiment.ndat = 10; M=simulator(DS,experiment);
The result is as expected in field M.a
the name of which corresponds to name of U.rv
.
If the task was only to generate random realizations, this would indeed be a very clumsy way of doing it. However, the power of the proposed approach will be revelead in more demanding examples, one of which follows next.
where are known constants, and is known variance.
Direct application of EpdfDS
is not possible, since the pdf above is conditioned on values of and . We need to handle two issues:
The first issue can be handled in two ways. First, can be considered as input and as such it could be externally given to the datasource. This solution is used in scenario closedloop
. However, for the simulator
scenario we will apply the second option, that is we complement by extra pdf:
where is another known constant. Thus, the joint density is now:
and we have no need for input since the datasource have all necessary information inside. All that is required is to store them and copy their values to appropriate places.
That is done in automatic way using dedicated class bdm::datalink_buffered. The only issue a user may need to take care about is the missing initial conditions for simulation. By default these are set to zeros. Using the default values, the full configuration of this system is:
y = RV({'y'}); u = RV({'u'}); fy.class = 'mlnorm<ldmat>'; fy.rv = y; fy.rvc = RV({'y','u'}, [1 1], [-3, -1]); fy.A = [0.5, -0.9]; fy.const = 0; fy.R = 0.1; fu.class = 'enorm<ldmat>'; fu.rv = u; fu.mu = 0; fu.R = 0.2; DS.class = 'MpdfDS'; DS.mpdf.class = 'mprod'; DS.mpdf.mpdfs = {fy, epdf2mpdf(fu)};
Explanation of this example will require few remarks:
fy
object is 'mlnorm<ldmat>' which is Normal pdf with mean value given by linear function, and covariance matrix stored in LD decomposition, see bdm::mlnorm for details.mpdfs
of its configuration structure is a list of conditional densities. Conditional density is represented by class mpdf
and its offsprings. Class RV
is used to describe both variables before conditioning (field rv
) and after conditioning sign (field rvc
).mpdfs
. Hence, the pdf must be converted to conditional density with empty conditioning, . This is achieved by calling function epdf2mpdf which is only a trivial wrapper creating class bdm::mepdf.
The code above can be immediatelly run, usin the same execution sequence of estimator
as above.
DS.init_rv = RV({'y','y','y'}, [1,1,1], [-1,-2,-3]); DS.init_values = [0.1, 0.2, 0.3];
The values of init_values
will be copied to places in history identified by corresponding values of init_rv
. Initial data is not checked for completeness, i.e. values of random variables missing from init_rv
(in this case all occurences of ) are still initialized to 0.
simulator
is compatible with some datasource class.
For example, the output of MemDS
can be stored as an .it file (filename is specified in configuration structure) which can be later read by bdm::ITppFileDS.
In matlab, the output of mexlog is a structure of vectors or matrices. The results can be saved in a matlab file using:
Data=[M.y; M.u]; drv = RVjoin({y,u}); save mpdfds_results Data drv
mxDS.class = 'MemDS'; mxDS.Data = 'Data'; mxDS.drv = drv;