Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/MATLABengine.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 
00033 #include "common_source.h"
00034 #include "MATLABengine.h"
00035 
00036 #ifdef MARSYAS_MATLAB
00037 using std::vector;
00038 using std::complex;
00039 
00040 
00041 using namespace Marsyas;
00042 
00043 MATLABengine * MATLABengine::instance_ = 0;
00044 
00045 MATLABengine::MATLABengine()
00046 {
00047   if (!(engine_ = engOpen("\0")))
00048   {
00049     MRSERR("Can't start MATLAB Engine! Check MATLAB install and configuration!\n");
00050     return;
00051   }
00052   instance_ = this;
00053 
00054   /*int BUFSIZE=200;
00055     buffer_ = new char[BUFSIZE];
00056     buffer_[BUFSIZE] = '\0';
00057     engOutputBuffer(engine_, buffer_, BUFSIZE);*/
00058 }
00059 
00060 
00061 MATLABengine::~MATLABengine()
00062 {
00063 //  delete [] buffer_;
00064   engClose(engine_);
00065 }
00066 
00067 MATLABengine*
00068 MATLABengine::getMatlabEng()
00069 {
00070   if(!instance_)
00071     instance_ = new MATLABengine();
00072 
00073   return instance_;
00074 }
00075 
00076 
00077 void
00078 MATLABengine::closeMatlabEng()
00079 {
00080   delete instance_;
00081   instance_=0;
00082 }
00083 
00084 
00085 //-------------------------------------------------------------------
00086 //                  setters
00087 //-------------------------------------------------------------------
00088 void
00089 MATLABengine::evalString(const std::ostringstream& MATLABcmd)
00090 {
00091   engEvalString(engine_, MATLABcmd.str().c_str());
00092   // cout << buffer_ << endl;
00093 }
00094 
00095 void
00096 MATLABengine::putVariable(const mrs_string value, mrs_string MATLABname)
00097 {
00098   //-----------------------------------
00099   //send C/C++ string to MATLAB string
00100   //-----------------------------------
00101 
00102   mxArray *mxVector = mxCreateString(value.c_str());
00103   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00104 
00105   mxDestroyArray(mxVector);
00106 }
00107 
00108 void
00109 MATLABengine::putVariable(const long *const value, unsigned int size, mrs_string MATLABname)
00110 {
00111   //-----------------------------------
00112   //send C/C++ vector to MATLAB vector
00113   //-----------------------------------
00114   mwSize dims[2];
00115   dims[0] = 1; //row vector
00116   dims[1] = size;
00117 
00118   mxArray *mxVector = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
00119   memcpy(mxGetData(mxVector), (void *)value, size*mxGetElementSize(mxVector));
00120   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00121 
00122   //Convert to MATLAB double type
00123   mrs_string MatCmd = MATLABname + "=double(" + MATLABname + ");";
00124   engEvalString(engine_, MatCmd.c_str());
00125 
00126   mxDestroyArray(mxVector);
00127 }
00128 
00129 void
00130 MATLABengine::putVariable(const float *const value, unsigned int size, mrs_string MATLABname)
00131 {
00132   //-----------------------------------
00133   //send C/C++ vector to MATLAB vector
00134   //-----------------------------------
00135   mwSize dims[2];
00136   dims[0] = 1; //row vector
00137   dims[1] = size;
00138 
00139   mxArray *mxVector = mxCreateNumericArray(2, dims, mxSINGLE_CLASS, mxREAL);
00140   memcpy(mxGetData(mxVector), (void *)value, size*mxGetElementSize(mxVector));
00141   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00142 
00143   //Convert to MATLAB double type
00144   mrs_string MatCmd = MATLABname + "=double(" + MATLABname + ");";
00145   engEvalString(engine_, MatCmd.c_str());
00146 
00147   mxDestroyArray(mxVector);
00148 }
00149 
00150 
00151 void
00152 MATLABengine::putVariable(const double *const value, unsigned int size, mrs_string MATLABname)
00153 {
00154   //-----------------------------------
00155   //send C/C++ vector to MATLAB vector
00156   //-----------------------------------
00157   mwSize dims[2];
00158   dims[0] = 1; //row vector
00159   dims[1] = size;
00160 
00161   mxArray *mxVector = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
00162   memcpy(mxGetData(mxVector), (void *)value, size*mxGetElementSize(mxVector));
00163   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00164 
00165   mxDestroyArray(mxVector);
00166 }
00167 
00168 
00169 void
00170 MATLABengine::putVariable(mrs_natural value, mrs_string MATLABname)
00171 {
00172   long lvalue = (long)value;
00173   putVariable(&lvalue,1, MATLABname);
00174 }
00175 void
00176 MATLABengine::putVariable(mrs_real value, mrs_string MATLABname)
00177 {
00178   double dvalue = (double)value;
00179   putVariable(&dvalue,1, MATLABname);
00180 }
00181 
00182 void
00183 MATLABengine::putVariable(mrs_complex value, mrs_string MATLABname)
00184 {
00185   mwSize dims[2];
00186   dims[0] = 1;
00187   dims[1] = 1;
00188 
00189   mxArray *mxVector = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxCOMPLEX);
00190   double *xr = mxGetPr(mxVector);
00191   double *xi = mxGetPi(mxVector);
00192 
00193   *xr = (double)value.real();
00194   *xi = (double)value.imag();
00195 
00196   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00197 
00198   mxDestroyArray(mxVector);
00199 }
00200 
00201 
00202 
00203 void
00204 MATLABengine::putVariable(realvec value, mrs_string MATLABname)
00205 {
00206   //----------------------------------
00207   // send a realvec to a MATLAB matrix
00208   //----------------------------------
00209   mwSize dims[2]; //realvec is 2D
00210   dims[0] = value.getRows();
00211   dims[1] = value.getCols();
00212 
00213   //realvec are by default double precision matrices => mxDOUBLE_CLASS
00214   mxArray *mxMatrix = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
00215   mrs_real *data = value.getData();
00216   memcpy((void *)mxGetPr(mxMatrix), (void *)(data), dims[0]*dims[1]*mxGetElementSize(mxMatrix));
00217   engPutVariable(engine_, MATLABname.c_str(), mxMatrix);
00218 
00219   mxDestroyArray(mxMatrix);
00220 }
00221 
00222 void
00223 MATLABengine::putVariable(vector<mrs_natural> value, mrs_string MATLABname)
00224 {
00225   mwSize dims[2];
00226   dims[0] = 1; //row vector
00227   dims[1] = (mwSize)value.size();
00228 
00229   mxArray *mxVector = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
00230   double *x = mxGetPr(mxVector);
00231 
00232   for(unsigned int i = 0; i < value.size(); ++i)
00233   {
00234     *(x + i) = (double)value[i];
00235   }
00236 
00237   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00238 
00239   mxDestroyArray(mxVector);
00240 }
00241 
00242 
00243 void
00244 MATLABengine::putVariable(vector<mrs_real> value, mrs_string MATLABname)
00245 {
00246   mwSize dims[2];
00247   dims[0] = 1; //row vector
00248   dims[1] = (mwSize)value.size();
00249 
00250   mxArray *mxVector = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
00251   double *x = mxGetPr(mxVector);
00252 
00253   for(unsigned int i = 0; i < value.size(); ++i)
00254   {
00255     *(x + i) = (double)value[i];
00256   }
00257 
00258   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00259 
00260   mxDestroyArray(mxVector);
00261 }
00262 
00263 void
00264 MATLABengine::putVariable(vector<mrs_complex> value, mrs_string MATLABname)
00265 {
00266   mwSize dims[2];
00267   dims[0] = 1; //row vector
00268   dims[1] = (mwSize)value.size();
00269 
00270   mxArray *mxVector = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxCOMPLEX);
00271   double *xr = mxGetPr(mxVector);
00272   double *xi = mxGetPi(mxVector);
00273 
00274   for(unsigned int i = 0; i < value.size(); ++i)
00275   {
00276     *(xr + i) = (double)value[i].real();
00277     *(xi + i) = (double)value[i].imag();
00278   }
00279 
00280   engPutVariable(engine_, MATLABname.c_str(), mxVector);
00281 
00282   mxDestroyArray(mxVector);
00283 }
00284 
00285 
00286 //-------------------------------------------------------------------
00287 //                  getters
00288 //-------------------------------------------------------------------
00289 int
00290 MATLABengine::getVariable(std::string MATLABname, mrs_natural& value)
00291 {
00292   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00293 
00294   if (mxVector == NULL)
00295   {
00296     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_natural&) error: failed getting MATLAB var!");
00297     return -1;
00298   }
00299   else {
00300     if (mxGetNumberOfElements(mxVector) > 1)
00301     {
00302       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_natural&): MATLAB array => getting first element only!");
00303     }
00304 
00305     if(mxIsComplex(mxVector))
00306     {
00307       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_natural&): MATLAB complex number => getting real part only!");
00308     }
00309 
00310     value = (mrs_natural)mxGetScalar(mxVector);
00311     mxDestroyArray(mxVector);
00312     return 0;
00313   }
00314 }
00315 
00316 int
00317 MATLABengine::getVariable(std::string MATLABname, mrs_real& value)
00318 {
00319   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00320 
00321   if (mxVector == NULL)
00322   {
00323     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_real&) error: failed getting MATLAB var!");
00324     return -1;
00325   }
00326   else {
00327     if (mxGetNumberOfElements(mxVector) > 1)
00328     {
00329       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_real&): MATLAB array => getting first element only!");
00330     }
00331 
00332     if(mxIsComplex(mxVector))
00333     {
00334       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_real&): MATLAB complex number => getting real part only!");
00335     }
00336 
00337     value = (mrs_real)mxGetScalar(mxVector);
00338     mxDestroyArray(mxVector);
00339     return 0;
00340   }
00341 }
00342 
00343 int
00344 MATLABengine::getVariable(std::string MATLABname, mrs_complex& value)
00345 {
00346   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00347 
00348   if (mxVector == NULL)
00349   {
00350     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_complex&) error: failed getting MATLAB var!");
00351     return -1;
00352   }
00353   else
00354   {
00355     if (mxGetNumberOfElements(mxVector) > 1)
00356     {
00357       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_real&): MATLAB array => getting first element only!");
00358     }
00359 
00360     if(mxIsComplex(mxVector))
00361       value = mrs_complex((mrs_real)(*mxGetPr(mxVector)),(mrs_real)(*mxGetPi(mxVector)));
00362     else
00363     {
00364       value = mrs_complex((mrs_real)(*mxGetPr(mxVector)),0);
00365       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", mrs_complex&): MATLAB real number => setting imaginary part to zero!");
00366     }
00367 
00368     mxDestroyArray(mxVector);
00369     return 0;
00370   }
00371 }
00372 
00373 int
00374 MATLABengine::getVariable(std::string MATLABname, realvec& value)
00375 {
00376   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00377 
00378   if (mxVector == NULL)
00379   {
00380     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", realvec&) error: variable does not exist in MATLAB!");
00381     return -1;
00382   }
00383   else {
00384     if (mxGetNumberOfDimensions(mxVector) > 2)
00385     {
00386       MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", realvecl&): MATLAB array with more than 2 dimensions!");
00387       return -1;
00388     }
00389 
00390     if(mxIsComplex(mxVector))
00391     {
00392       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", realvec&): MATLAB complex array => getting real part only!");
00393     }
00394 
00395     //number of rows and cols for the 2D MATLAB array
00396     //resize realvec accordingly
00397     value.create(mxGetDimensions(mxVector)[0],mxGetDimensions(mxVector)[1]);
00398     for(unsigned int i= 0; i < mxGetNumberOfElements(mxVector); ++i)
00399     {
00400       //both Marsyas realvec and MATLAB arrays are column-wise,
00401       //so they can be copied as linear vectors
00402       value(i) = (mrs_real)(*(mxGetPr(mxVector)+i));
00403     }
00404 
00405     mxDestroyArray(mxVector);
00406     return 0;
00407   }
00408 }
00409 
00410 int
00411 MATLABengine::getVariable(std::string MATLABname, vector<mrs_natural>& value)
00412 {
00413   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00414 
00415   if (mxVector == NULL) {
00416     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_natural>&) error: Get Array Failed!");
00417     return -1;
00418   }
00419   else
00420   {
00421     if (mxGetNumberOfDimensions(mxVector) > 2)
00422     {
00423       MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_natural>&): MATLAB array with more than 2 dimensions!");
00424       return -1;
00425     }
00426 
00427     if(mxIsComplex(mxVector))
00428     {
00429       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_natural>&): MATLAB complex data => getting real part only!");
00430     }
00431 
00432     if(mxGetM(mxVector) > 1 && mxGetN(mxVector) > 1)
00433     {
00434       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_natural>&): MATLAB array => will be got as a column-wise vector!");
00435     }
00436 
00437     value.clear();
00438     value.reserve(mxGetNumberOfElements(mxVector));
00439 
00440     for(unsigned int i= 0; i < mxGetNumberOfElements(mxVector); ++i)
00441     {
00442       //if MATLAB variable is an array, it will be got as a column-wise vector
00443       value.push_back((mrs_natural)(*(mxGetPr(mxVector)+i)));
00444     }
00445 
00446     mxDestroyArray(mxVector);
00447     return 0;
00448   }
00449 }
00450 
00451 int
00452 MATLABengine::getVariable(std::string MATLABname, vector<mrs_real>& value)
00453 {
00454   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00455 
00456   if (mxVector == NULL) {
00457     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_real>&) error: Get Array Failed");
00458     return -1;
00459   }
00460   else
00461   {
00462     if (mxGetNumberOfDimensions(mxVector) > 2)
00463     {
00464       MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_real>&): MATLAB array with more than 2 dimensions!");
00465       return -1;
00466     }
00467 
00468     if(mxIsComplex(mxVector))
00469     {
00470       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_real>&): MATLAB complex data => getting real part only!");
00471     }
00472 
00473     if(mxGetM(mxVector) > 1 && mxGetN(mxVector) > 1)
00474     {
00475       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_real>&): MATLAB array => will be got as a column-wise vector!");
00476     }
00477 
00478     value.clear();
00479     value.reserve(mxGetNumberOfElements(mxVector));
00480 
00481     for(unsigned int i= 0; i < mxGetNumberOfElements(mxVector); ++i)
00482     {
00483       //if MATLAB variable is an array, it will be got as a column-wise vector
00484       value.push_back((mrs_real)(*(mxGetPr(mxVector)+i)));
00485     }
00486 
00487     mxDestroyArray(mxVector);
00488     return 0;
00489   }
00490 }
00491 
00492 int
00493 MATLABengine::getVariable(std::string MATLABname, vector<mrs_complex>& value)
00494 {
00495   mxArray* mxVector = engGetVariable(engine_, MATLABname.c_str());
00496 
00497   if (mxVector == NULL) {
00498     MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_complex>&) error: Get Array Failed");
00499     return -1;
00500   }
00501   else
00502   {
00503     if (mxGetNumberOfDimensions(mxVector) > 2)
00504     {
00505       MRSERR("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_complex>&): MATLAB array with more than 2 dimensions!");
00506       return -1;
00507     }
00508 
00509     if(mxGetM(mxVector) > 1 && mxGetN(mxVector) > 1)
00510     {
00511       MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_complex>&): MATLAB array => will be got as a column-wise vector!");
00512     }
00513 
00514     value.clear();
00515     value.reserve(mxGetNumberOfElements(mxVector));
00516 
00517     for(unsigned int i= 0; i < mxGetNumberOfElements(mxVector); ++i)
00518     {
00519       //if MATLAB variable is an array, it will be got as a column-wise vector
00520       if(mxIsComplex(mxVector))
00521         value.push_back( mrs_complex( (mrs_real)(*(mxGetPr(mxVector)+i)), (mrs_real)(*(mxGetPi(mxVector)+i)) ));
00522       else
00523       {
00524         value.push_back(mrs_complex( (mrs_real)(*(mxGetPr(mxVector)+i)), 0 ));
00525         MRSWARN("MATLABengine::getVariable(\"" << MATLABname << "\", vector<mrs_complex>&): MATLAB real numbers => setting imaginary parts to zero!");
00526       }
00527     }
00528 
00529     mxDestroyArray(mxVector);
00530     return 0;
00531   }
00532 }
00533 
00534 
00535 #endif //_MATLAB_ENGINE