#ifndef MXDS_H #define MXDS_H #include "../bdm/bdmerror.h" #include "../bdm/base/datasources.h" #include "mex_parser.h" namespace bdm { /*! * \brief Memory storage of off-line data column-wise 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. The data can be loaded from a file. */ class mxArrayDS : public MemDS { public: //!Default constructor mxArrayDS () : MemDS() {}; /*! \brief Create memory data source from mxArray \code system={ type="mexDS"; varname=""; // name of workspace variable row_rv = {class='RV',...} // definition of }; \endcode MemDS with the above fields will be created; */ void from_setting ( const Setting &set ) { Data = mxArray2mat ( mexGetVariable ( "base", set["varname"] ) ); /* UI::get ( rowid, set, "rids" , UI::compulsory ); bdm_assert_debug ( max ( rowid ) <= Data.rows(), "MemDS rowid is too high for given Dat." ); UI::get ( delays, set, "tds", UI::compulsory ); time = max ( delays ); bdm_assert_debug ( time < Data.cols(), "MemDS delays are too high." ); */ //set MemDS rowid = linspace ( 0, Data.rows() - 1 ); dtsize = rowid.length(); utsize = 0; shared_ptr r = UI::build ( set, "rv", UI::optional ); RV ru = RV(); if ( r ) { set_drv ( *r, ru ); } else { RV def ( ( const char* ) set["varname"], Data.rows() ); set_drv ( def, ru ); } } // TODO dodelat void to_setting( Setting &set ) const; }; UIREGISTER ( mxArrayDS ); SHAREDPTR ( mxArrayDS ); /*! * \brief Matlab wrapper for DS mapping functions step() to a matlab function The identifier of matlab function is stored in attribute \c name. This identifier defines: \li function to call to do a step(): name_step.m \li workspace variable to write input to: name_input */ class mexDS : public DS { protected: //! identifier of matlab function string step_name; //! identifier of matlab input variabel string input_name; //! cache of results from name_step vec dt; //! cache of inputs vec ut; public: //!Default constructor mexDS () : DS() {}; /*! \brief Data source computed by matlab function \code system={ class="mexDS"; step_name=""; // name of function to call input_name=""; // name of workspace variable where inputs are written drv = {class='RV',...} // identification of outputs urv = {class='RV',...} // identification of inputs }; \endcode MemDS with the above fields will be created; */ void from_setting ( const Setting &set ) { UI::get ( step_name, set, "step_name", UI::compulsory ); UI::get ( input_name, set, "input_name", UI::compulsory ); shared_ptr rd = UI::build ( set, "drv", UI::compulsory ); shared_ptr ru = UI::build ( set, "urv", UI::compulsory ); dtsize = rd->_dsize(); utsize = ru->_dsize(); set_drv ( *rd, *ru ); validate(); } virtual void getdata ( vec &dt, const ivec &indices ) NOT_IMPLEMENTED_VOID; virtual void write ( const vec &ut, const ivec &indices ) NOT_IMPLEMENTED_VOID; void step() { mxArray* tmp; mxArray* dummy = NULL; // write inputs to variable input_name mxArray* mxinp = mexGetVariable ( "global", input_name.c_str() ) ; if ( mxinp ) { if ( ( int ) mxGetM ( mxinp ) != utsize || ( int ) mxGetN ( mxinp ) != utsize ) { // mxinp is invalid - create new one mxDestroyArray ( mxinp ); mxinp = mxCreateDoubleMatrix ( utsize, 1, mxREAL ); } } else { mxinp = mxCreateDoubleMatrix ( utsize, 1, mxREAL ); } vec2mxArray ( ut, mxinp ); mexPutVariable ( "global", input_name.c_str(), mxinp ); // call function step_name mexCallMATLAB ( 1, &tmp, 0, ( mxArray ** ) &dummy, step_name.c_str() ); // save its results bdm_assert_debug ( ( int ) mxGetM ( tmp ) == dtsize || ( int ) mxGetN ( tmp ) == dtsize, "mexDS.step() expected return vector of length " + num2str ( dtsize ) + "got vector " + num2str ( ( int ) mxGetM ( tmp ) ) + "x" + num2str ( ( int ) mxGetN ( tmp ) ) ); //write y dt.set_subvector ( 0, mxArray2vec ( tmp ) ); //write u } void write ( const vec &ut0 ) { bdm_assert_debug ( ut0.length() == ut.length(), "mexDS: Incompatible input vector" ); ut = ut0; } void getdata ( vec &dt_out ) const { bdm_assert_debug ( dt_out.length() == dt.length(), "mexDS: Incompatible output vector" ); dt_out = dt; } void validate() { dt = zeros ( dtsize ); ut = zeros ( utsize ); } // TODO dodelat void to_setting( Setting &set ) const; }; UIREGISTER ( mexDS ); SHAREDPTR ( mexDS ); } #endif //MXDS_H