[706] | 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 { |
---|
[737] | 18 | public: |
---|
[706] | 19 | //!Default constructor |
---|
[737] | 20 | mxArrayDS () : MemDS() {}; |
---|
[706] | 21 | |
---|
| 22 | /*! \brief Create memory data source from mxArray |
---|
| 23 | |
---|
| 24 | \code |
---|
| 25 | system={ |
---|
| 26 | type="mexDS"; |
---|
| 27 | varname=""; // name of workspace variable |
---|
[737] | 28 | row_rv = {class='RV',...} // definition of |
---|
[706] | 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"] ) ); |
---|
[737] | 37 | /* UI::get ( rowid, set, "rids" , UI::compulsory ); |
---|
| 38 | bdm_assert_debug ( max ( rowid ) <= Data.rows(), "MemDS rowid is too high for given Dat." ); |
---|
[706] | 39 | |
---|
[737] | 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 | */ |
---|
[706] | 44 | //set MemDS |
---|
[904] | 45 | dtsize = Data.rows(); |
---|
[737] | 46 | utsize = 0; |
---|
| 47 | |
---|
[706] | 48 | shared_ptr<RV> r = UI::build<RV> ( set, "rv", UI::optional ); |
---|
| 49 | RV ru = RV(); |
---|
[737] | 50 | if ( r ) { |
---|
[706] | 51 | set_drv ( *r, ru ); |
---|
| 52 | } else { |
---|
[737] | 53 | RV def ( ( const char* ) set["varname"], Data.rows() ); |
---|
| 54 | set_drv ( def, ru ); |
---|
[706] | 55 | } |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | |
---|
| 59 | // TODO dodelat void to_setting( Setting &set ) const; |
---|
| 60 | }; |
---|
| 61 | |
---|
| 62 | UIREGISTER ( mxArrayDS ); |
---|
| 63 | SHAREDPTR ( mxArrayDS ); |
---|
| 64 | |
---|
| 65 | /*! |
---|
| 66 | * \brief Matlab wrapper for DS mapping functions step() to a matlab function |
---|
| 67 | |
---|
| 68 | The identifier of matlab function is stored in attribute \c name. |
---|
[737] | 69 | This identifier defines: |
---|
[706] | 70 | \li function to call to do a step(): name_step.m |
---|
| 71 | \li workspace variable to write input to: name_input |
---|
| 72 | */ |
---|
| 73 | class mexDS : public DS { |
---|
[737] | 74 | protected: |
---|
| 75 | //! identifier of matlab function |
---|
| 76 | string step_name; |
---|
| 77 | //! identifier of matlab input variabel |
---|
| 78 | string input_name; |
---|
| 79 | //! cache of results from name_step |
---|
| 80 | vec dt; |
---|
| 81 | //! cache of inputs |
---|
| 82 | vec ut; |
---|
| 83 | public: |
---|
[706] | 84 | //!Default constructor |
---|
[737] | 85 | mexDS () : DS() {}; |
---|
[706] | 86 | |
---|
[895] | 87 | /*! \brief Data source computed by matlab function |
---|
[706] | 88 | |
---|
| 89 | \code |
---|
| 90 | system={ |
---|
| 91 | class="mexDS"; |
---|
| 92 | step_name=""; // name of function to call |
---|
| 93 | input_name=""; // name of workspace variable where inputs are written |
---|
[895] | 94 | drv = {class='RV',...} // identification of outputs |
---|
[706] | 95 | urv = {class='RV',...} // identification of inputs |
---|
| 96 | }; |
---|
| 97 | \endcode |
---|
| 98 | |
---|
| 99 | MemDS with the above fields will be created; |
---|
| 100 | |
---|
| 101 | */ |
---|
| 102 | void from_setting ( const Setting &set ) { |
---|
[737] | 103 | UI::get ( step_name, set, "step_name", UI::compulsory ); |
---|
| 104 | UI::get ( input_name, set, "input_name", UI::compulsory ); |
---|
| 105 | |
---|
[895] | 106 | shared_ptr<RV> rd = UI::build<RV> ( set, "drv", UI::compulsory ); |
---|
[737] | 107 | shared_ptr<RV> ru = UI::build<RV> ( set, "urv", UI::compulsory ); |
---|
[706] | 108 | |
---|
[895] | 109 | dtsize = rd->_dsize(); |
---|
[737] | 110 | utsize = ru->_dsize(); |
---|
| 111 | |
---|
[895] | 112 | set_drv ( *rd, *ru ); |
---|
[706] | 113 | validate(); |
---|
| 114 | } |
---|
[737] | 115 | |
---|
[896] | 116 | virtual void getdata ( vec &dt, const ivec &indices ) NOT_IMPLEMENTED_VOID; |
---|
[766] | 117 | |
---|
[896] | 118 | virtual void write ( const vec &ut, const ivec &indices ) NOT_IMPLEMENTED_VOID; |
---|
[766] | 119 | |
---|
| 120 | |
---|
[706] | 121 | void step() { |
---|
| 122 | mxArray* tmp; |
---|
[737] | 123 | mxArray* dummy = NULL; |
---|
[706] | 124 | // write inputs to variable input_name |
---|
[737] | 125 | mxArray* mxinp = mexGetVariable ( "global", input_name.c_str() ) ; |
---|
| 126 | if ( mxinp ) { |
---|
| 127 | if ( ( int ) mxGetM ( mxinp ) != utsize || ( int ) mxGetN ( mxinp ) != utsize ) { |
---|
[706] | 128 | // mxinp is invalid - create new one |
---|
[737] | 129 | mxDestroyArray ( mxinp ); |
---|
| 130 | mxinp = mxCreateDoubleMatrix ( utsize, 1, mxREAL ); |
---|
[706] | 131 | } |
---|
[737] | 132 | |
---|
[706] | 133 | } else { |
---|
[737] | 134 | mxinp = mxCreateDoubleMatrix ( utsize, 1, mxREAL ); |
---|
[706] | 135 | } |
---|
[737] | 136 | vec2mxArray ( ut, mxinp ); |
---|
| 137 | mexPutVariable ( "global", input_name.c_str(), mxinp ); |
---|
[706] | 138 | // call function step_name |
---|
[737] | 139 | mexCallMATLAB ( 1, &tmp, 0, ( mxArray ** ) &dummy, step_name.c_str() ); |
---|
[706] | 140 | // save its results |
---|
[895] | 141 | bdm_assert_debug ( ( int ) mxGetM ( tmp ) == dtsize || ( int ) mxGetN ( tmp ) == dtsize, "mexDS.step() expected return vector of length " + num2str ( dtsize ) + |
---|
[737] | 142 | "got vector " + num2str ( ( int ) mxGetM ( tmp ) ) + "x" + num2str ( ( int ) mxGetN ( tmp ) ) ); |
---|
[706] | 143 | //write y |
---|
[737] | 144 | dt.set_subvector ( 0, mxArray2vec ( tmp ) ); |
---|
[706] | 145 | //write u |
---|
| 146 | } |
---|
[737] | 147 | void write ( const vec &ut0 ) { |
---|
| 148 | bdm_assert_debug ( ut0.length() == ut.length(), "mexDS: Incompatible input vector" ); |
---|
| 149 | ut = ut0; |
---|
[706] | 150 | } |
---|
[737] | 151 | void getdata ( vec &dt_out ) const { |
---|
| 152 | bdm_assert_debug ( dt_out.length() == dt.length(), "mexDS: Incompatible output vector" ); |
---|
| 153 | dt_out = dt; |
---|
[706] | 154 | } |
---|
| 155 | |
---|
| 156 | void validate() { |
---|
[737] | 157 | dt = zeros ( dtsize ); |
---|
| 158 | ut = zeros ( utsize ); |
---|
[706] | 159 | } |
---|
| 160 | |
---|
| 161 | // TODO dodelat void to_setting( Setting &set ) const; |
---|
| 162 | }; |
---|
| 163 | |
---|
| 164 | UIREGISTER ( mexDS ); |
---|
| 165 | SHAREDPTR ( mexDS ); |
---|
| 166 | |
---|
| 167 | } |
---|
| 168 | #endif //MXDS_H |
---|