mixpp: mex_parser.h Source File

mex_parser.h

00001 #ifndef MXPARSE_H
00002 #define MXPARSE_H
00003 
00004
00005 #include "base/libconfig/lib/libconfig.h++"
00006 #include <itpp/itbase.h>
00007 #include <itpp/itmex.h>
00008 #include <stdlib.h>
00009
00010
00011 using namespace itpp;
00012 using namespace std;
00013 using namespace libconfig;
00014
00016 class UImxArray : public Config {
00017 public:
00019     UImxArray ( const mxArray *mxarray ) : Config() {
00020         Setting & setting = this->getRoot(); //setting is a group
00021         if ( !mxIsStruct ( mxarray ) ) {
00022             mexErrMsgTxt ( "Given mxArray is not a struct." );
00023         };
00024
00025         //mexCallMATLAB(0, NULL, 1, (mxArray **) &mxarray, "dump");
00026         fillGroup ( setting, mxarray );
00027         setAutoConvert ( true );
00028     }
00029     UImxArray() : Config() {
00030         setAutoConvert ( true );
00031     }
00033     void addList ( const mxArray *mxarray, const char* name ) {
00034         Setting & setting = this->getRoot(); //setting is a group
00035         Setting & child = setting.add ( name, Setting::TypeList );
00036         fillList ( child, mxarray );
00037     }
00039     void addGroup ( const mxArray *mxarray, const char* name ) {
00040         Setting & setting = this->getRoot(); //setting is a group
00041         Setting & child = setting.add ( name, Setting::TypeGroup );
00042         fillGroup ( child, mxarray );
00043     }
00045     operator Setting&() {
00046         return getRoot();
00047     }
00048
00049 private:
00050     void storeNumeric ( Setting &setting, const mxArray *value, string key = "" ) {
00051         //TODO: integer matrices
00052         if ( !mxIsNumeric ( value ) ) {
00053             mexErrMsgTxt ( "Given mxArray is not numeric." );
00054         };
00055         //treat empty matrices independently
00056         mat val;
00057         if ( mxGetM ( value ) > 0 && mxGetN(value)>0) {
00058             val = mxArray2mat ( value );
00059         }
00060         if ( ( val.rows() == 1 ) && ( val.cols() == 1 ) ) {
00061             Setting &child = ( key == "" ) ? setting.add ( Setting::TypeFloat )
00062                              : setting.add ( key, Setting::TypeFloat );
00063             child = val ( 0, 0 );
00064         } else {
00065             Setting &child = ( key == "" ) ? setting.add ( Setting::TypeList )
00066                              : setting.add ( key, Setting::TypeList );
00067             Setting &label = child.add ( Setting::TypeString );
00068             label = "matrix";
00069             Setting &rows = child.add ( Setting::TypeInt );
00070             Setting &cols = child.add ( Setting::TypeInt );
00071             Setting &elements = child.add ( Setting::TypeArray );
00072             cols = val.cols();
00073             rows = val.rows();
00074             for ( int i = 0; i < val.rows(); i++ ) {
00075                 for ( int j = 0; j < val.cols(); j++ ) {
00076                     Setting &el = elements.add ( Setting::TypeFloat );
00077                     el = val ( i, j );
00078                 }
00079             }
00080         }
00081     }
00082
00083     void fillGroup ( Setting &setting, const mxArray *mxarray ) {
00084         if ( !mxIsStruct ( mxarray ) ) {
00085             mexErrMsgTxt ( "Given mxArray is not a struct." );
00086         };
00087         for ( int i = 0; i < mxGetNumberOfFields ( mxarray ); i++ ) {
00088             const char *key = mxGetFieldNameByNumber ( mxarray, i );
00089             mxArray *value = mxGetField ( mxarray, 0, key );
00090             if ( mxIsChar ( value ) ) {
00091                 Setting &child = setting.add ( key, Setting::TypeString );
00092                 child = mxArray2string ( value );
00093             } else {
00094                 if ( mxIsLogical ( value ) ) {
00095                     Setting &child = setting.add ( key, Setting::TypeBoolean );
00096                     child = ( bool ) mxArray2bin ( value );
00097                 } else {
00098                     if ( mxIsStruct ( value ) ) {
00099                         Setting &child = setting.add ( key, Setting::TypeGroup );
00100                         fillGroup ( child, value );
00101                     } else {
00102                         if ( mxIsCell ( value ) ) {
00103                             Setting &child = setting.add ( key, Setting::TypeList );
00104                             fillList ( child, value );
00105                         } else {
00106                             if ( mxIsNumeric ( value ) ) {
00107                                 storeNumeric ( setting, value, ( string ) key );
00108                             } else {
00109                                 // it is neither of above - treat it as an address
00110                                 // if (mxIsObject(value)){ <== should be tested but it is broken in matlab...
00111
00112                                 Setting &child = setting.add(key, Setting::TypeInt64);
00113                                 child = (long long)value;
00114                             }
00115                         }
00116                     }
00117                 }
00118             }
00119         }
00120     }
00121
00122     void fillList ( Setting &setting, const mxArray *mxarray ) {
00123         if ( !mxIsCell ( mxarray ) ) {
00124             mexErrMsgTxt ( "Given mxArray is not a cell." );
00125         };
00126         for ( unsigned int i = 0; i < ( unsigned int ) mxGetNumberOfElements ( mxarray ); i++ ) {
00127             mxArray *value = mxGetCell ( mxarray, i );
00128             if ( mxIsChar ( value ) ) {
00129                 Setting &child = setting.add ( Setting::TypeString );
00130                 child = mxArray2string ( value );
00131             }
00132             if ( mxIsLogical ( value ) ) {
00133                 Setting &child = setting.add ( Setting::TypeBoolean );
00134                 child = ( bool ) mxArray2bin ( value );
00135             }
00136             if ( mxIsStruct ( value ) ) {
00137                 Setting &child = setting.add ( Setting::TypeGroup );
00138                 fillGroup ( child, value );
00139             }
00140             if ( mxIsCell ( value ) ) {
00141                 Setting &child = setting.add ( Setting::TypeList );
00142                 fillList ( child, value );
00143             }
00144             if ( mxIsNumeric ( value ) ) {
00145                 storeNumeric ( setting, value );
00146             }
00147         }
00148     }
00149
00150 public:
00152     static mxArray * create_mxArray( const Setting &setting )
00153     {
00154         return group2mxstruct ( setting );
00155     }
00156
00158     mxArray * create_mxArray(  )
00159     {
00160         return group2mxstruct ( *this );
00161     }
00162
00163 private:
00165     static mxArray* array2mxvector ( const Setting &setting )  {
00166         if ( !setting.isArray() ) mexErrMsgTxt ( "Given setting is not an array" );
00167         mxArray *result = mxCreateDoubleMatrix ( 1, setting.getLength(), mxREAL );
00168         double *elements = mxGetPr ( result );
00169         for ( int i = 0; i < setting.getLength(); i++ ) {
00170             if ( setting.getType() == Setting::TypeInt ) { //TODO: tady je chyba -- zaporna cisla nejsou TypeInt
00171                 elements[i] = ( int ) setting[i];
00172             } else {
00173                 elements[i] =  setting[i];
00174             }
00175         }
00176         return result;
00177     }
00178
00180     static mxArray* list2mxmatrix ( const Setting &setting )  {
00181         if ( !setting.isList() || ( strcmp ( "matrix", setting[0] ) != 0 ) )
00182             mexErrMsgTxt ( "Given setting is not a matrix" );
00183         int rows = setting[1];
00184         int cols = setting[2];
00185         if ( setting[3].getLength() != rows*cols )
00186             mexErrMsgTxt ( "Matrix elements do not fit to rows*cols" );
00187         double *elements = new double[rows*cols];
00188         for ( int i = 0; i < rows*cols; i++ ) {
00189             elements[i] = setting[3][i];
00190         }
00191         mat &m = * ( new mat ( elements, rows, cols ) );
00192         mxArray *result = mxCreateDoubleMatrix ( rows, cols, mxREAL );
00193         mat2mxArray ( m, result );
00194         delete &m;
00195         delete [] elements;
00196         return result;
00197     }
00198
00200     static mxArray* group2mxstruct ( const Setting &setting ) {
00201         if ( !setting.isGroup() ) mexErrMsgTxt ( "Given setting is not a group." );
00202         const char ** keys = new const char*[setting.getLength() ];
00203         for ( int i = 0; i < setting.getLength(); i++ ) {
00204             keys[i] = setting[i].getName();
00205         }
00206         mxArray *result = mxCreateStructMatrix ( 1, 1, setting.getLength(), keys );
00207         delete keys;
00208         for ( int i = 0; i < setting.getLength(); i++ ) {
00209             Setting &value = setting[i];
00210             mxArray *old = mxGetFieldByNumber ( result, 0, i );
00211             if ( old ) mxDestroyArray ( old );
00212             switch ( value.getType() ) {
00213             case Setting::TypeString:
00214                 mxSetFieldByNumber ( result, 0, i, mxCreateString ( value ) );
00215                 break;
00216             case Setting::TypeBoolean:
00217                 mxSetFieldByNumber ( result, 0, i, mxCreateLogicalScalar ( value ) );
00218                 break;
00219             case Setting::TypeGroup:
00220                 mxSetFieldByNumber ( result, 0, i, group2mxstruct ( value ) );
00221                 break;
00222             case Setting::TypeList:
00223                 mxSetFieldByNumber ( result, 0, i, list2mxcell ( value ) );
00224                 break;
00225             case Setting::TypeArray:
00226                 mxSetFieldByNumber ( result, 0, i, array2mxvector ( value ) );
00227                 break;
00228             case Setting::TypeInt:
00229             case Setting::TypeInt64:
00230                 mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( ( int ) value ) );
00231                 break;
00232             case Setting::TypeFloat:
00233                 mxSetFieldByNumber ( result, 0, i, mxCreateDoubleScalar ( value ) );
00234                 break;
00235             default:
00236                 //this should never happen
00237                 mexErrMsgTxt ( "Unknown type of a setting." );
00238             }
00239         }
00240         return result;
00241
00242     }
00244     static mxArray* list2mxcell ( const Setting &setting )  {
00245         if ( !setting.isList() ) mexErrMsgTxt ( "Given setting is not a list." );
00246         if ( setting.getLength() == 0 ) {
00247             mxArray *result = mxCreateCellMatrix ( 1, 0 );
00248             return result;
00249         }
00250
00251         if ( ( setting[0].getType() == Setting::TypeString ) ) {
00252             string s = ( setting[0] );
00253             if ( s == "matrix" ) {
00254                 return list2mxmatrix ( setting );
00255             }
00256         }
00257         mxArray *result = mxCreateCellMatrix ( 1, setting.getLength() );
00258         for ( int i = 0; i < setting.getLength(); i++ ) {
00259             Setting &value = setting[i];
00260             mxArray *old = mxGetCell ( result, i );
00261             if ( old ) mxDestroyArray ( old );
00262             switch ( value.getType() ) {
00263             case Setting::TypeString:
00264                 mxSetCell ( result, i, mxCreateString ( value ) );
00265                 break;
00266             case Setting::TypeBoolean:
00267                 mxSetCell ( result, i, mxCreateLogicalScalar ( value ) );
00268                 break;
00269             case Setting::TypeGroup:
00270                 mxSetCell ( result, i, group2mxstruct ( value ) );
00271                 break;
00272             case Setting::TypeList:
00273                 mxSetCell ( result, i, list2mxcell ( value ) );
00274                 break;
00275             case Setting::TypeArray:
00276                 mxSetCell ( result, i, array2mxvector ( value ) );
00277                 break;
00278             case Setting::TypeInt:
00279             case Setting::TypeInt64:
00280                 mxSetCell ( result, i, mxCreateDoubleScalar ( ( int ) value ) );
00281                 break;
00282             case Setting::TypeFloat:
00283                 mxSetCell ( result, i, mxCreateDoubleScalar ( value ) );
00284                 break;
00285             default:
00286                 //this should never happen
00287                 mexErrMsgTxt ( "Unknown type of a setting." );
00288             }
00289         }
00290         return result;
00291     }
00292 };
00293
00294 #endif //MXPARSE_H

Generated on 2 Dec 2013 for mixpp by  doxygen 1.4.7