Marsyas
0.6.0-alpha
|
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