GPHIKClassifierMex.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. #ifdef NICE_USELIB_MEX
  2. /**
  3. * @file GPHIKClassifierMex.cpp
  4. * @author Alexander Freytag
  5. * @date 07-01-2014 (dd-mm-yyyy)
  6. * @brief Matlab-Interface of our GPHIKClassifier, allowing for training, classification, optimization, variance prediction, incremental learning, and storing/re-storing.
  7. */
  8. // STL includes
  9. #include <math.h>
  10. #include <matrix.h>
  11. #include <mex.h>
  12. // NICE-core includes
  13. #include <core/basics/Config.h>
  14. #include <core/basics/Timer.h>
  15. #include <core/vector/MatrixT.h>
  16. #include <core/vector/VectorT.h>
  17. // gp-hik-core includes
  18. #include "gp-hik-core/GPHIKClassifier.h"
  19. // Interface for conversion between Matlab and C objects
  20. #include "gp-hik-core/matlab/classHandleMtoC.h"
  21. #include "gp-hik-core/matlab/ConverterMatlabToNICE.h"
  22. #include "gp-hik-core/matlab/ConverterNICEToMatlab.h"
  23. using namespace std; //C basics
  24. using namespace NICE; // nice-core
  25. NICE::Config parseParametersGPHIKClassifier(const mxArray *prhs[], int nrhs)
  26. {
  27. NICE::Config conf;
  28. // if first argument is the filename of an existing config file,
  29. // read the config accordingly
  30. int i_start ( 0 );
  31. std::string variable = MatlabConversion::convertMatlabToString(prhs[i_start]);
  32. if(variable == "conf")
  33. {
  34. conf = NICE::Config ( MatlabConversion::convertMatlabToString( prhs[i_start+1] ) );
  35. i_start = i_start+2;
  36. }
  37. // now run over all given parameter specifications
  38. // and add them to the config
  39. for( int i=i_start; i < nrhs; i+=2 )
  40. {
  41. std::string variable = MatlabConversion::convertMatlabToString(prhs[i]);
  42. /////////////////////////////////////////
  43. // READ STANDARD BOOLEAN VARIABLES
  44. /////////////////////////////////////////
  45. if( (variable == "verboseTime") || (variable == "verbose") ||
  46. (variable == "optimize_noise") || (variable == "uncertaintyPredictionForClassification") ||
  47. (variable == "use_quantization") || (variable == "ils_verbose")
  48. )
  49. {
  50. if ( mxIsChar( prhs[i+1] ) )
  51. {
  52. string value = MatlabConversion::convertMatlabToString( prhs[i+1] );
  53. if ( (value != "true") && (value != "false") )
  54. {
  55. std::string errorMsg = "Unexpected parameter value for \'" + variable + "\'. In string modus, \'true\' or \'false\' expected.";
  56. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  57. }
  58. if( value == "true" )
  59. conf.sB("GPHIKClassifier", variable, true);
  60. else
  61. conf.sB("GPHIKClassifier", variable, false);
  62. }
  63. else if ( mxIsLogical( prhs[i+1] ) )
  64. {
  65. bool value = MatlabConversion::convertMatlabToBool( prhs[i+1] );
  66. conf.sB("GPHIKClassifier", variable, value);
  67. }
  68. else
  69. {
  70. std::string errorMsg = "Unexpected parameter value for \'" + variable + "\'. \'true\', \'false\', or logical expected.";
  71. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  72. }
  73. }
  74. /////////////////////////////////////////
  75. // READ STANDARD INT VARIABLES
  76. /////////////////////////////////////////
  77. if ( (variable == "nrOfEigenvaluesToConsiderForVarApprox")
  78. )
  79. {
  80. if ( mxIsDouble( prhs[i+1] ) )
  81. {
  82. double value = MatlabConversion::convertMatlabToDouble(prhs[i+1]);
  83. conf.sI("GPHIKClassifier", variable, (int) value);
  84. }
  85. else if ( mxIsInt32( prhs[i+1] ) )
  86. {
  87. int value = MatlabConversion::convertMatlabToInt32(prhs[i+1]);
  88. conf.sI("GPHIKClassifier", variable, value);
  89. }
  90. else
  91. {
  92. std::string errorMsg = "Unexpected parameter value for \'" + variable + "\'. Int32 or Double expected.";
  93. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  94. }
  95. }
  96. /////////////////////////////////////////
  97. // READ STRICT POSITIVE INT VARIABLES
  98. /////////////////////////////////////////
  99. if ( (variable == "num_bins") || (variable == "ils_max_iterations")
  100. )
  101. {
  102. if ( mxIsDouble( prhs[i+1] ) )
  103. {
  104. double value = MatlabConversion::convertMatlabToDouble(prhs[i+1]);
  105. if( value < 1 )
  106. {
  107. std::string errorMsg = "Expected parameter value larger than 0 for \'" + variable + "\'.";
  108. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  109. }
  110. conf.sI("GPHIKClassifier", variable, (int) value);
  111. }
  112. else if ( mxIsInt32( prhs[i+1] ) )
  113. {
  114. int value = MatlabConversion::convertMatlabToInt32(prhs[i+1]);
  115. if( value < 1 )
  116. {
  117. std::string errorMsg = "Expected parameter value larger than 0 for \'" + variable + "\'.";
  118. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  119. }
  120. conf.sI("GPHIKClassifier", variable, value);
  121. }
  122. else
  123. {
  124. std::string errorMsg = "Unexpected parameter value for \'" + variable + "\'. Int32 or Double expected.";
  125. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  126. }
  127. }
  128. /////////////////////////////////////////
  129. // READ POSITIVE DOUBLE VARIABLES
  130. /////////////////////////////////////////
  131. if ( (variable == "ils_min_delta") || (variable == "ils_min_residual") ||
  132. (variable == "noise")
  133. )
  134. {
  135. if ( mxIsDouble( prhs[i+1] ) )
  136. {
  137. double value = MatlabConversion::convertMatlabToDouble(prhs[i+1]);
  138. if( value < 0.0 )
  139. {
  140. std::string errorMsg = "Expected parameter value larger than 0 for \'" + variable + "\'.";
  141. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  142. }
  143. conf.sD("GPHIKClassifier", variable, value);
  144. }
  145. else
  146. {
  147. std::string errorMsg = "Unexpected parameter value for \'" + variable + "\'. Double expected.";
  148. mexErrMsgIdAndTxt( "mexnice:error", errorMsg.c_str() );
  149. }
  150. }
  151. /////////////////////////////////////////
  152. // READ REMAINING SPECIFIC VARIABLES
  153. /////////////////////////////////////////
  154. if(variable == "ils_method")
  155. {
  156. string value = MatlabConversion::convertMatlabToString(prhs[i+1]);
  157. if(value != "CG" && value != "CGL" && value != "SYMMLQ" && value != "MINRES")
  158. mexErrMsgIdAndTxt("mexnice:error","Unexpected parameter value for \'ils_method\'. \'CG\', \'CGL\', \'SYMMLQ\' or \'MINRES\' expected.");
  159. conf.sS("GPHIKClassifier", variable, value);
  160. }
  161. if(variable == "optimization_method")
  162. {
  163. string value = MatlabConversion::convertMatlabToString(prhs[i+1]);
  164. if(value != "greedy" && value != "downhillsimplex" && value != "none")
  165. mexErrMsgIdAndTxt("mexnice:error","Unexpected parameter value for \'optimization_method\'. \'greedy\', \'downhillsimplex\' or \'none\' expected.");
  166. conf.sS("GPHIKClassifier", variable, value);
  167. }
  168. if(variable == "transform")
  169. {
  170. string value = MatlabConversion::convertMatlabToString( prhs[i+1] );
  171. if(value != "absexp" && value != "exp" && value != "MKL" && value != "WeightedDim")
  172. mexErrMsgIdAndTxt("mexnice:error","Unexpected parameter value for \'transform\'. \'absexp\', \'exp\' , \'MKL\' or \'WeightedDim\' expected.");
  173. conf.sS("GPHIKClassifier", variable, value);
  174. }
  175. if(variable == "varianceApproximation")
  176. {
  177. string value = MatlabConversion::convertMatlabToString(prhs[i+1]);
  178. if(value != "approximate_fine" && value != "approximate_rough" && value != "exact" && value != "none")
  179. mexErrMsgIdAndTxt("mexnice:error","Unexpected parameter value for \'varianceApproximation\'. \'approximate_fine\', \'approximate_rough\', \'none\' or \'exact\' expected.");
  180. conf.sS("GPHIKClassifier", variable, value);
  181. }
  182. }
  183. return conf;
  184. }
  185. // MAIN MATLAB FUNCTION
  186. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  187. {
  188. // get the command string specifying what to do
  189. if (nrhs < 1)
  190. mexErrMsgTxt("No commands and options passed... Aborting!");
  191. if( !mxIsChar( prhs[0] ) )
  192. mexErrMsgTxt("First argument needs to be the command, ie.e, the class method to call... Aborting!");
  193. std::string cmd = MatlabConversion::convertMatlabToString( prhs[0] );
  194. // create object
  195. if ( !strcmp("new", cmd.c_str() ) )
  196. {
  197. // check output variable
  198. if (nlhs != 1)
  199. mexErrMsgTxt("New: One output expected.");
  200. // read config settings
  201. NICE::Config conf = parseParametersGPHIKClassifier(prhs+1,nrhs-1);
  202. // create class instance
  203. NICE::GPHIKClassifier * classifier = new NICE::GPHIKClassifier ( &conf, "GPHIKClassifier" /*sectionName in config*/ );
  204. // handle to the C++ instance
  205. plhs[0] = MatlabConversion::convertPtr2Mat<NICE::GPHIKClassifier>( classifier );
  206. return;
  207. }
  208. // in all other cases, there should be a second input,
  209. // which the be the class instance handle
  210. if (nrhs < 2)
  211. mexErrMsgTxt("Second input should be a class instance handle.");
  212. // delete object
  213. if ( !strcmp("delete", cmd.c_str() ) )
  214. {
  215. // Destroy the C++ object
  216. MatlabConversion::destroyObject<NICE::GPHIKClassifier>(prhs[1]);
  217. return;
  218. }
  219. // get the class instance pointer from the second input
  220. // every following function needs the classifier object
  221. NICE::GPHIKClassifier * classifier = MatlabConversion::convertMat2Ptr<NICE::GPHIKClassifier>(prhs[1]);
  222. ////////////////////////////////////////
  223. // Check which class method to call //
  224. ////////////////////////////////////////
  225. // standard train - assumes initialized object
  226. if (!strcmp("train", cmd.c_str() ))
  227. {
  228. // Check parameters
  229. if (nlhs < 0 || nrhs < 4)
  230. {
  231. mexErrMsgTxt("Train: Unexpected arguments.");
  232. }
  233. //------------- read the data --------------
  234. std::vector< const NICE::SparseVector *> examplesTrain;
  235. NICE::Vector yMultiTrain;
  236. if ( mxIsSparse( prhs[2] ) )
  237. {
  238. examplesTrain = MatlabConversion::convertSparseMatrixToNice( prhs[2] );
  239. }
  240. else
  241. {
  242. NICE::Matrix dataTrain;
  243. dataTrain = MatlabConversion::convertDoubleMatrixToNice(prhs[2]);
  244. //----------------- convert data to sparse data structures ---------
  245. examplesTrain.resize( dataTrain.rows() );
  246. std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin();
  247. for (int i = 0; i < (int)dataTrain.rows(); i++, exTrainIt++)
  248. {
  249. *exTrainIt = new NICE::SparseVector( dataTrain.getRow(i) );
  250. }
  251. }
  252. yMultiTrain = MatlabConversion::convertDoubleVectorToNice(prhs[3]);
  253. //----------------- train our classifier -------------
  254. classifier->train ( examplesTrain , yMultiTrain );
  255. //----------------- clean up -------------
  256. for(int i=0;i<examplesTrain.size();i++)
  257. delete examplesTrain[i];
  258. return;
  259. }
  260. // Classify
  261. if ( !strcmp("classify", cmd.c_str() ) )
  262. {
  263. // Check parameters
  264. if ( (nlhs < 0) || (nrhs < 2) )
  265. {
  266. mexErrMsgTxt("Test: Unexpected arguments.");
  267. }
  268. //------------- read the data --------------
  269. int result;
  270. NICE::SparseVector scores;
  271. double uncertainty;
  272. if ( mxIsSparse( prhs[2] ) )
  273. {
  274. NICE::SparseVector * example;
  275. example = new NICE::SparseVector ( MatlabConversion::convertSparseVectorToNice( prhs[2] ) );
  276. classifier->classify ( example, result, scores, uncertainty );
  277. //----------------- clean up -------------
  278. delete example;
  279. }
  280. else
  281. {
  282. NICE::Vector * example;
  283. example = new NICE::Vector ( MatlabConversion::convertDoubleVectorToNice(prhs[2]) );
  284. classifier->classify ( example, result, scores, uncertainty );
  285. //----------------- clean up -------------
  286. delete example;
  287. }
  288. // output
  289. plhs[0] = mxCreateDoubleScalar( result );
  290. if(nlhs >= 2)
  291. {
  292. plhs[1] = MatlabConversion::convertSparseVectorFromNice( scores, true /*b_adaptIndex*/);
  293. }
  294. if(nlhs >= 3)
  295. {
  296. plhs[2] = mxCreateDoubleScalar( uncertainty );
  297. }
  298. return;
  299. }
  300. // Uncertainty prediction
  301. if ( !strcmp("uncertainty", cmd.c_str() ) )
  302. {
  303. // Check parameters
  304. if ( (nlhs < 0) || (nrhs < 2) )
  305. {
  306. mexErrMsgTxt("Test: Unexpected arguments.");
  307. }
  308. double uncertainty;
  309. //------------- read the data --------------
  310. if ( mxIsSparse( prhs[2] ) )
  311. {
  312. NICE::SparseVector * example;
  313. example = new NICE::SparseVector ( MatlabConversion::convertSparseVectorToNice( prhs[2] ) );
  314. classifier->predictUncertainty( example, uncertainty );
  315. //----------------- clean up -------------
  316. delete example;
  317. }
  318. else
  319. {
  320. NICE::Vector * example;
  321. example = new NICE::Vector ( MatlabConversion::convertDoubleVectorToNice(prhs[2]) );
  322. classifier->predictUncertainty( example, uncertainty );
  323. //----------------- clean up -------------
  324. delete example;
  325. }
  326. // output
  327. plhs[0] = mxCreateDoubleScalar( uncertainty );
  328. return;
  329. }
  330. // Test - evaluate classifier on whole test set
  331. if ( !strcmp("test", cmd.c_str() ) )
  332. {
  333. // Check parameters
  334. if (nlhs < 0 || nrhs < 4)
  335. mexErrMsgTxt("Test: Unexpected arguments.");
  336. //------------- read the data --------------
  337. bool dataIsSparse ( mxIsSparse( prhs[2] ) );
  338. std::vector< const NICE::SparseVector *> dataTest_sparse;
  339. NICE::Matrix dataTest_dense;
  340. if ( dataIsSparse )
  341. {
  342. dataTest_sparse = MatlabConversion::convertSparseMatrixToNice( prhs[2] );
  343. }
  344. else
  345. {
  346. dataTest_dense = MatlabConversion::convertDoubleMatrixToNice(prhs[2]);
  347. }
  348. NICE::Vector yMultiTest;
  349. yMultiTest = MatlabConversion::convertDoubleVectorToNice(prhs[3]);
  350. // ------------------------------------------
  351. // ------------- PREPARATION --------------
  352. // ------------------------------------------
  353. // determine classes known during training and corresponding mapping
  354. // thereby allow for non-continous class labels
  355. std::set<int> classesKnownTraining = classifier->getKnownClassNumbers();
  356. int noClassesKnownTraining ( classesKnownTraining.size() );
  357. std::map<int,int> mapClNoToIdxTrain;
  358. std::set<int>::const_iterator clTrIt = classesKnownTraining.begin();
  359. for ( int i=0; i < noClassesKnownTraining; i++, clTrIt++ )
  360. mapClNoToIdxTrain.insert ( std::pair<int,int> ( *clTrIt, i ) );
  361. // determine classes known during testing and corresponding mapping
  362. // thereby allow for non-continous class labels
  363. std::set<int> classesKnownTest;
  364. classesKnownTest.clear();
  365. // determine which classes we have in our label vector
  366. // -> MATLAB: myClasses = unique(y);
  367. for ( NICE::Vector::const_iterator it = yMultiTest.begin(); it != yMultiTest.end(); it++ )
  368. {
  369. if ( classesKnownTest.find ( *it ) == classesKnownTest.end() )
  370. {
  371. classesKnownTest.insert ( *it );
  372. }
  373. }
  374. int noClassesKnownTest ( classesKnownTest.size() );
  375. std::map<int,int> mapClNoToIdxTest;
  376. std::set<int>::const_iterator clTestIt = classesKnownTest.begin();
  377. for ( int i=0; i < noClassesKnownTest; i++, clTestIt++ )
  378. mapClNoToIdxTest.insert ( std::pair<int,int> ( *clTestIt, i ) );
  379. int i_numTestSamples;
  380. if ( dataIsSparse )
  381. i_numTestSamples = dataTest_sparse.size();
  382. else
  383. i_numTestSamples = (int) dataTest_dense.rows();
  384. NICE::Matrix confusionMatrix( noClassesKnownTraining, noClassesKnownTest, 0.0);
  385. NICE::Matrix scores( i_numTestSamples, noClassesKnownTraining, 0.0);
  386. // ------------------------------------------
  387. // ------------- CLASSIFICATION --------------
  388. // ------------------------------------------
  389. NICE::Timer t;
  390. double testTime (0.0);
  391. for (int i = 0; i < i_numTestSamples; i++)
  392. {
  393. //----------------- convert data to sparse data structures ---------
  394. int result;
  395. NICE::SparseVector exampleScoresSparse;
  396. if ( dataIsSparse )
  397. {
  398. // and classify
  399. t.start();
  400. classifier->classify( dataTest_sparse[ i ], result, exampleScoresSparse );
  401. t.stop();
  402. testTime += t.getLast();
  403. }
  404. else
  405. {
  406. NICE::Vector example ( dataTest_dense.getRow(i) );
  407. // and classify
  408. t.start();
  409. classifier->classify( &example, result, exampleScoresSparse );
  410. t.stop();
  411. testTime += t.getLast();
  412. }
  413. confusionMatrix( mapClNoToIdxTrain.find(result)->second, mapClNoToIdxTest.find(yMultiTest[i])->second ) += 1.0;
  414. int scoreCnt ( 0 );
  415. for ( NICE::SparseVector::const_iterator scoreIt = exampleScoresSparse.begin(); scoreIt != exampleScoresSparse.end(); scoreIt++, scoreCnt++ )
  416. {
  417. scores(i,scoreCnt) = scoreIt->second;
  418. }
  419. }
  420. std::cerr << "Time for testing: " << testTime << std::endl;
  421. // clean up
  422. if ( dataIsSparse )
  423. {
  424. for ( std::vector<const NICE::SparseVector *>::iterator it = dataTest_sparse.begin(); it != dataTest_sparse.end(); it++)
  425. delete *it;
  426. }
  427. confusionMatrix.normalizeColumnsL1();
  428. double recRate = confusionMatrix.trace()/confusionMatrix.cols();
  429. plhs[0] = mxCreateDoubleScalar( recRate );
  430. if(nlhs >= 2)
  431. plhs[1] = MatlabConversion::convertMatrixFromNice(confusionMatrix);
  432. if(nlhs >= 3)
  433. plhs[2] = MatlabConversion::convertMatrixFromNice(scores);
  434. return;
  435. }
  436. ///////////////////// INTERFACE ONLINE LEARNABLE /////////////////////
  437. // interface specific methods for incremental extensions
  438. ///////////////////// INTERFACE ONLINE LEARNABLE /////////////////////
  439. // addExample
  440. if ( !strcmp("addExample", cmd.c_str() ) )
  441. {
  442. // Check parameters
  443. if ( (nlhs < 0) || (nrhs < 4) )
  444. {
  445. mexErrMsgTxt("Test: Unexpected arguments.");
  446. }
  447. //------------- read the data --------------
  448. NICE::SparseVector * newExample;
  449. double newLabel;
  450. if ( mxIsSparse( prhs[2] ) )
  451. {
  452. newExample = new NICE::SparseVector ( MatlabConversion::convertSparseVectorToNice( prhs[2] ) );
  453. }
  454. else
  455. {
  456. NICE::Vector * example;
  457. example = new NICE::Vector ( MatlabConversion::convertDoubleVectorToNice(prhs[2]) );
  458. newExample = new NICE::SparseVector ( *example );
  459. //----------------- clean up -------------
  460. delete example;
  461. }
  462. newLabel = MatlabConversion::convertMatlabToDouble( prhs[3] );
  463. // setting performOptimizationAfterIncrement is optional
  464. if ( nrhs > 4 )
  465. {
  466. bool performOptimizationAfterIncrement;
  467. performOptimizationAfterIncrement = MatlabConversion::convertMatlabToBool( prhs[4] );
  468. classifier->addExample ( newExample, newLabel, performOptimizationAfterIncrement );
  469. }
  470. else
  471. {
  472. classifier->addExample ( newExample, newLabel );
  473. }
  474. //----------------- clean up -------------
  475. delete newExample;
  476. return;
  477. }
  478. // addMultipleExamples
  479. if ( !strcmp("addMultipleExamples", cmd.c_str() ) )
  480. {
  481. // Check parameters
  482. if ( (nlhs < 0) || (nrhs < 4) )
  483. {
  484. mexErrMsgTxt("Test: Unexpected arguments.");
  485. }
  486. //------------- read the data --------------
  487. std::vector< const NICE::SparseVector *> newExamples;
  488. NICE::Vector newLabels;
  489. if ( mxIsSparse( prhs[2] ) )
  490. {
  491. newExamples = MatlabConversion::convertSparseMatrixToNice( prhs[2] );
  492. }
  493. else
  494. {
  495. NICE::Matrix newData;
  496. newData = MatlabConversion::convertDoubleMatrixToNice(prhs[2]);
  497. //----------------- convert data to sparse data structures ---------
  498. newExamples.resize( newData.rows() );
  499. std::vector< const NICE::SparseVector *>::iterator exTrainIt = newExamples.begin();
  500. for (int i = 0; i < (int)newData.rows(); i++, exTrainIt++)
  501. {
  502. *exTrainIt = new NICE::SparseVector( newData.getRow(i) );
  503. }
  504. }
  505. newLabels = MatlabConversion::convertDoubleVectorToNice(prhs[3]);
  506. // setting performOptimizationAfterIncrement is optional
  507. if ( nrhs > 4 )
  508. {
  509. bool performOptimizationAfterIncrement;
  510. performOptimizationAfterIncrement = MatlabConversion::convertMatlabToBool( prhs[4] );
  511. classifier->addMultipleExamples ( newExamples, newLabels, performOptimizationAfterIncrement );
  512. }
  513. else
  514. {
  515. classifier->addMultipleExamples ( newExamples, newLabels );
  516. }
  517. //----------------- clean up -------------
  518. for ( std::vector< const NICE::SparseVector *>::iterator exIt = newExamples.begin();
  519. exIt != newExamples.end(); exIt++
  520. )
  521. {
  522. delete *exIt;
  523. }
  524. return;
  525. }
  526. ///////////////////// INTERFACE PERSISTENT /////////////////////
  527. // interface specific methods for store and restore
  528. ///////////////////// INTERFACE PERSISTENT /////////////////////
  529. // store the classifier to an external file
  530. if ( !strcmp("store", cmd.c_str() ) || !strcmp("save", cmd.c_str() ) )
  531. {
  532. // Check parameters
  533. if ( nrhs < 3 )
  534. mexErrMsgTxt("store: no destination given.");
  535. std::string s_destination = MatlabConversion::convertMatlabToString( prhs[2] );
  536. std::filebuf fb;
  537. fb.open ( s_destination.c_str(), ios::out );
  538. std::ostream os(&fb);
  539. //
  540. classifier->store( os );
  541. //
  542. fb.close();
  543. return;
  544. }
  545. // load classifier from external file
  546. if ( !strcmp("restore", cmd.c_str() ) || !strcmp("load", cmd.c_str() ) )
  547. {
  548. // Check parameters
  549. if ( nrhs < 3 )
  550. mexErrMsgTxt("restore: no destination given.");
  551. std::string s_destination = MatlabConversion::convertMatlabToString( prhs[2] );
  552. std::cerr << " aim at restoring the classifier from " << s_destination << std::endl;
  553. std::filebuf fbIn;
  554. fbIn.open ( s_destination.c_str(), ios::in );
  555. std::istream is (&fbIn);
  556. //
  557. classifier->restore( is );
  558. //
  559. fbIn.close();
  560. return;
  561. }
  562. // Got here, so command not recognized
  563. std::string errorMsg (cmd.c_str() );
  564. errorMsg += " -- command not recognized.";
  565. mexErrMsgTxt( errorMsg.c_str() );
  566. }
  567. #endif