1 | #ifndef MXDS_H |
---|
2 | #define MXDS_H |
---|
3 | |
---|
4 | |
---|
5 | #include "../bdm/bdmerror.h" |
---|
6 | #include "../bdm/base/datasources.h" |
---|
7 | #include "mex_parser.h" |
---|
8 | |
---|
9 | namespace bdm { |
---|
10 | /*! |
---|
11 | * \brief Memory storage of off-line data column-wise |
---|
12 | |
---|
13 | The data are stored in an internal matrix \c Data . Each column of Data corresponds to one discrete time observation \f$t\f$. Access to this matrix is via indices \c rowid and \c delays. |
---|
14 | |
---|
15 | The data can be loaded from a file. |
---|
16 | */ |
---|
17 | class mxArrayDS : public MemDS { |
---|
18 | public: |
---|
19 | //!Default constructor |
---|
20 | mxArrayDS ():MemDS() {}; |
---|
21 | |
---|
22 | /*! \brief Create memory data source from mxArray |
---|
23 | |
---|
24 | \code |
---|
25 | system={ |
---|
26 | type="mexDS"; |
---|
27 | varname=""; // name of workspace variable |
---|
28 | row_rv = {class='RV',...} // definition of |
---|
29 | }; |
---|
30 | \endcode |
---|
31 | |
---|
32 | MemDS with the above fields will be created; |
---|
33 | |
---|
34 | */ |
---|
35 | void from_setting ( const Setting &set ) { |
---|
36 | Data = mxArray2mat ( mexGetVariable ( "base", set["varname"] ) ); |
---|
37 | /* UI::get ( rowid, set, "rids" , UI::compulsory ); |
---|
38 | bdm_assert_debug ( max ( rowid ) <= Data.rows(), "MemDS rowid is too high for given Dat." ); |
---|
39 | |
---|
40 | UI::get ( delays, set, "tds", UI::compulsory ); |
---|
41 | time = max ( delays ); |
---|
42 | bdm_assert_debug ( time < Data.cols(), "MemDS delays are too high." ); |
---|
43 | */ |
---|
44 | //set MemDS |
---|
45 | rowid = linspace(0,Data.rows()-1); |
---|
46 | dtsize=rowid.length(); |
---|
47 | ytsize=rowid.length(); |
---|
48 | utsize=0; |
---|
49 | |
---|
50 | shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional ); |
---|
51 | RV ru = RV(); |
---|
52 | if (r){ |
---|
53 | set_drv ( *r, ru ); |
---|
54 | } else { |
---|
55 | RV def((const char*)set["varname"],Data.rows()); |
---|
56 | set_drv(def, ru); |
---|
57 | } |
---|
58 | } |
---|
59 | |
---|
60 | |
---|
61 | // TODO dodelat void to_setting( Setting &set ) const; |
---|
62 | }; |
---|
63 | |
---|
64 | UIREGISTER ( mxArrayDS ); |
---|
65 | SHAREDPTR ( mxArrayDS ); |
---|
66 | |
---|
67 | /*! |
---|
68 | * \brief Matlab wrapper for DS mapping functions step() to a matlab function |
---|
69 | |
---|
70 | The identifier of matlab function is stored in attribute \c name. |
---|
71 | This identifier defines: |
---|
72 | \li function to call to do a step(): name_step.m |
---|
73 | \li workspace variable to write input to: name_input |
---|
74 | */ |
---|
75 | class mexDS : public DS { |
---|
76 | protected: |
---|
77 | //! identifier of matlab function |
---|
78 | string step_name; |
---|
79 | //! identifier of matlab input variabel |
---|
80 | string input_name; |
---|
81 | //! cache of results from name_step |
---|
82 | vec dt; |
---|
83 | //! cache of inputs |
---|
84 | vec ut; |
---|
85 | public: |
---|
86 | //!Default constructor |
---|
87 | mexDS ():DS() {}; |
---|
88 | |
---|
89 | /*! \brief Create memory data source from mxArray |
---|
90 | |
---|
91 | \code |
---|
92 | system={ |
---|
93 | class="mexDS"; |
---|
94 | step_name=""; // name of function to call |
---|
95 | input_name=""; // name of workspace variable where inputs are written |
---|
96 | yrv = {class='RV',...} // identification of outputs |
---|
97 | urv = {class='RV',...} // identification of inputs |
---|
98 | }; |
---|
99 | \endcode |
---|
100 | |
---|
101 | MemDS with the above fields will be created; |
---|
102 | |
---|
103 | */ |
---|
104 | void from_setting ( const Setting &set ) { |
---|
105 | UI::get(step_name, set, "step_name", UI::compulsory); |
---|
106 | UI::get(input_name, set, "input_name", UI::compulsory); |
---|
107 | |
---|
108 | shared_ptr<RV> ry = UI::build<RV> ( set, "yrv", UI::compulsory ); |
---|
109 | shared_ptr<RV> ru = UI::build<RV> ( set, "urv", UI::compulsory); |
---|
110 | |
---|
111 | ytsize=ry->_dsize(); |
---|
112 | utsize=ru->_dsize(); |
---|
113 | dtsize = ytsize+utsize; |
---|
114 | |
---|
115 | set_drv(*ry, *ru); |
---|
116 | validate(); |
---|
117 | } |
---|
118 | |
---|
119 | void step() { |
---|
120 | mxArray* tmp; |
---|
121 | mxArray* dummy=NULL; |
---|
122 | // write inputs to variable input_name |
---|
123 | mxArray* mxinp= mexGetVariable ( "global", input_name.c_str()) ; |
---|
124 | if (mxinp){ |
---|
125 | if((int)mxGetM(mxinp)!=utsize || (int)mxGetN(mxinp)!=utsize) { |
---|
126 | // mxinp is invalid - create new one |
---|
127 | mxDestroyArray(mxinp); |
---|
128 | mxinp=mxCreateDoubleMatrix(utsize,1,mxREAL); |
---|
129 | } |
---|
130 | |
---|
131 | } else { |
---|
132 | mxinp=mxCreateDoubleMatrix(utsize,1,mxREAL); |
---|
133 | } |
---|
134 | vec2mxArray(ut, mxinp); |
---|
135 | mexPutVariable("global",input_name.c_str(),mxinp); |
---|
136 | // call function step_name |
---|
137 | mexCallMATLAB(1, &tmp, 0, (mxArray **) &dummy, step_name.c_str()); |
---|
138 | // save its results |
---|
139 | bdm_assert_debug((int)mxGetM(tmp)==ytsize || (int)mxGetN(tmp)==ytsize,"mexDS.step() expected return vector of length " + num2str(dtsize) + |
---|
140 | "got vector " + num2str((int)mxGetM(tmp)) + "x" + num2str((int)mxGetN(tmp))); |
---|
141 | //write y |
---|
142 | dt.set_subvector(0,mxArray2vec(tmp)); |
---|
143 | //write u |
---|
144 | dt.set_subvector(ytsize,ut); |
---|
145 | } |
---|
146 | void write(const vec &ut0){ |
---|
147 | bdm_assert_debug(ut0.length()==ut.length(),"mexDS: Incompatible input vector"); |
---|
148 | ut=ut0; |
---|
149 | } |
---|
150 | void getdata(vec &dt_out) const { |
---|
151 | bdm_assert_debug(dt_out.length()==dt.length(),"mexDS: Incompatible output vector"); |
---|
152 | dt_out = dt; |
---|
153 | } |
---|
154 | |
---|
155 | void validate() { |
---|
156 | dt=zeros(dtsize); |
---|
157 | ut=zeros(utsize); |
---|
158 | } |
---|
159 | |
---|
160 | // TODO dodelat void to_setting( Setting &set ) const; |
---|
161 | }; |
---|
162 | |
---|
163 | UIREGISTER ( mexDS ); |
---|
164 | SHAREDPTR ( mexDS ); |
---|
165 | |
---|
166 | } |
---|
167 | #endif //MXDS_H |
---|