root/applications/bdmtoolbox/mex/arena.cpp @ 779

Revision 779, 5.1 kB (checked in by smidl, 14 years ago)

correct handling of messages in arena

Line 
1
2/*!
3\file
4\brief Application Arena - Interaction of Mulptiple Participants
5
6Arena is a space in which participants (agents) live, there is one data source, arbitrary number of agents which communicate between each other.
7
8\section ex Matlab usage
9Execute command:
10\code
11>> arena(DS, {A1,A2,...},experiment,logger);
12\endcode
13where DS is a valid datasource and A1,... are agents and logger (optional) specified by their corresponding structures.
14 */
15
16#include <base/datasources.h>
17#include <base/loggers.h>
18#include <mpdm/arx_agent.h>
19
20//#include "mex_datasource.h"
21
22using namespace bdm;
23
24#ifdef MEX
25#include <itpp/itmex.h>
26#include <mex/mex_BM.h>
27#include <mex/mex_logger.h>
28#include <mex/mex_datasource.h>
29
30void mexFunction ( int n_output, mxArray *output[], int n_input, const mxArray *input[] ) {
31        // Check the number of inputs and output arguments
32        if ( n_input<2 ) mexErrMsgTxt ( "Usage:\n"
33                                                "result=arena(system, agents, experiment, logger)\n"
34                                                "  system     = struct('class','datasource',...);  % Estimated system\n"
35                                                "  agents     = {struct('class','agent',...),  % Estimators\n"
36                                                "                struct('class','agent',...),...} \n"
37                                                "  === optional ==="
38                                                "  experiment = struct('ndat',10);                 % number of data in experiment, full length of finite datasources, 10 otherwise \n"
39                                                "  logger     = struct('class','mexlogger');       % How to store results, default=mexlog, i.e. matlab structure\n\n"
40                                                "see documentation of classes datasource, BM, and mexlogger and their offsprings in BDM." );
41
42        RV::clear_all();
43        //CONFIG
44        UImxArray Cfg;
45        try {
46                Cfg.addGroup ( input[0],"system" );
47                Cfg.addList ( input[1],"agents" );
48                if ( n_input>2 ) {
49                        Cfg.addGroup ( input[2],"experiment" );
50                }
51                if ( n_input>3 ) {
52                        Cfg.addGroup ( input[3],"logger" );
53                }
54        } catch ( SettingException e ) {
55                it_error ( "error: "+string ( e.getPath() ) );
56        }
57
58        //DBG
59        Cfg.writeFile ( "arena.cfg" );
60
61#else
62int main ( int argc, char* argv[] ) {
63        const char *fname;
64        if ( argc>1 ) {
65                fname = argv[1];
66        } else {
67                fname="arena.cfg";
68        }
69        UIFile Cfg ( fname );
70#endif
71
72        RNG_randomize();
73       
74        shared_ptr<DS> Ds = UI::build<DS> ( Cfg, "system" );
75        Array<shared_ptr<Participant> > Ags;
76        UI::get ( Ags,Cfg, "agents" );
77        int Ndat=100;
78        int burnin=0;
79       
80        shared_ptr<epdf> burn_pdf; 
81       
82        if ( Cfg.exists ( "experiment" ) ) {
83                Setting &exper=Cfg.getRoot()["experiment"];
84                if (UI::get(Ndat, exper, "Ndat", UI::optional ) ) {
85                        bdm_assert ( Ndat<=Ds->max_length(), "Data source has less data then required" );
86                };
87                if (UI::get(burnin, exper, "burnin",UI::optional )){
88                        burn_pdf = UI::build<epdf>(exper,"burn_pdf", UI::compulsory);
89                        if (burn_pdf){
90                                bdm_assert(burn_pdf->dimension()==Ds->_urv()._dsize(),"Given burn_pdf does not match the DataSource");
91                        } else {
92                                bdm_error("burn_pdf not specified!");
93                        }
94                       
95                }
96        } else {
97                if ( Ds->max_length() < std::numeric_limits< int >::max() ) {
98                        Ndat=Ds->max_length();
99                }
100                ;// else Ndat=10;
101        }
102        shared_ptr<logger> L = UI::build<logger> ( Cfg, "logger",UI::optional );
103        if ( !L ) {
104#ifdef MEX
105                //mex logger has only from_setting constructor - we  have to fill it...
106                L=new mexlog ( Ndat );
107#else
108                L=new stdlog();
109#endif
110        }
111
112        Config MsgStore;
113        MsgStore.setAutoConvert(true);
114        Setting& Queue = MsgStore.getRoot().add("queue", Setting::TypeList);
115       
116        Ds->log_register ( *L, "DS" );
117        for ( int i=0; i<Ags.length(); i++ ) {
118                Ags ( i )->log_register ( *L,Ags(i)->_name() ); // estimate
119                Ags (i )->ds_register(*Ds);
120        }
121        L->init();
122
123        vec glob_dt(Ds->_drv()._dsize() );
124        vec glob_ut(Ds->_urv()._dsize() );
125        for ( int tK=0;tK<Ndat;tK++ ) {
126                Ds->log_write ( );
127                Ds->getdata(glob_dt);
128               
129                for ( int i=0; i<Ags.length(); i++ ) {
130                        Ags(i) -> adapt(glob_dt);
131                }
132                for ( int i=0; i<Ags.length(); i++ ) {
133                        Ags(i) -> broadcast(Queue);
134                }
135                // parse message queue
136                for ( int m=Queue.getLength()-1; m>=0; m-- ) { // go backwards - last mesages are discarded
137                        for ( int i=0; i<Ags.length(); i++ ) {
138                                Setting& msg=Queue[m];
139                                string m_to=msg["to"];
140                                if (m_to==Ags(i)->_name()) {
141                                        Ags(i)->receive(msg);
142                                        Queue.remove(m);
143                                        break;
144                                        // message delivered;
145                                }
146                        }
147                }
148                if (Queue.getLength()>0){bdm_error("undelivered messages - probably unknown neighbours");}
149               
150                if (tK <burnin){
151                        glob_ut=burn_pdf->sample();
152                } else {
153                        for ( int i=0; i<Ags.length(); i++ ) {
154                                Ags(i) -> act(glob_ut);
155                        }
156                }
157               
158                L->step();
159                Ds->write(glob_ut);
160                Ds->step();                                                     // simulator step
161               
162                for ( int i=0; i<Ags.length(); i++ ) {
163                        Ags(i) -> step();
164                }
165               
166        }
167
168        L->finalize();
169        // ------------------ End of routine -----------------------------
170
171#ifdef MEX
172        mexlog* mL=dynamic_cast<mexlog*> ( L.get() );
173
174        if ( mL ) { // user wants output!!
175                if ( n_output<1 ) mexErrMsgTxt ( "Wrong number of output variables!" );
176                output[0] = mL->toCell();
177                if (n_output>1) {
178                        mL->_setting_conf().setAutoConvert(true);
179                        output[1]= UImxArray::create_mxArray(mL->_setting_conf().getRoot());
180                }
181        }
182#endif
183}
Note: See TracBrowser for help on using the browser.