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

Revision 883, 5.1 kB (checked in by smidl, 15 years ago)

bdmtoolbox + arx

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