00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "mex.h"
00021 #include <mexutils.h>
00022 #include <vl/svms.h>
00023
00024
00032 void setDoubleValue(mxArray* array, double value)
00033 {
00034 double* temp = (double*) mxGetData(array) ;
00035 *temp = value ;
00036 }
00037
00047 void setUintValue(mxArray* array, vl_uint32 value)
00048 {
00049 vl_uint32 * temp = (vl_uint32*) mxGetData(array) ;
00050 *temp = value ;
00051 }
00052
00053
00061 mxArray * createInfoStruct(VlSvm* svm)
00062 {
00063 mwSize dims[] = {1 , 1} ;
00064
00065 mxArray *model, *bias;
00066 mxArray *output, *dimension, *iterations, *maxIterations, *epsilon ;
00067 mxArray *lambda, *biasMultiplier ;
00068 mxArray *biasPreconditioner, *energyFrequency, *elapsedTime ;
00069
00070 if (svm->type == VL_SVM_SGD) {
00071
00072 const char* names [17] = {"model","bias","dimension", "iterations","maxIterations",
00073 "epsilon", "lambda", "biasMultiplier",
00074 "elapsedTime","energy","regularizerTerm", "lossPos",
00075 "lossNeg", "hardLossPos", "hardLossNeg",
00076 "biasPreconditioner", "energyFrequency"
00077 };
00078 output = mxCreateStructArray(1, dims, 17, names);
00079
00080
00081 biasPreconditioner = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00082 setDoubleValue(biasPreconditioner,svm->biasPreconditioner) ;
00083 mxSetField(output, 0, "biasPreconditioner", biasPreconditioner) ;
00084
00085 energyFrequency = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;
00086 mxSetField(output, 0, "energyFrequency", energyFrequency) ;
00087 setUintValue(energyFrequency,svm->energyFrequency) ;
00088
00089
00090 } else {
00091
00092 const char* names [15] = {"model","bias","dimension", "iterations","maxIterations",
00093 "epsilon", "lambda", "biasMultiplier",
00094 "elapsedTime","energy","regularizerTerm", "lossPos",
00095 "lossNeg", "hardLossPos", "hardLossNeg"};
00096 output = mxCreateStructArray(1, dims, 15, names);
00097
00098 }
00099
00100
00101
00102 mwSize mdims[2] ;
00103 double * tempBuffer ;
00104 mdims[0] = svm->dimension ;
00105 mdims[1] = 1 ;
00106 model = mxCreateNumericArray(2, mdims, mxDOUBLE_CLASS, mxREAL) ;
00107 tempBuffer = (double*) mxGetData(model) ;
00108 memcpy(tempBuffer,svm->model,svm->dimension * sizeof(double)) ;
00109 mxSetField(output, 0, "model", model) ;
00110
00111
00112 bias = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00113 setDoubleValue(bias,svm->bias) ;
00114 mxSetField(output, 0, "bias", bias) ;
00115
00116 dimension = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;
00117 setUintValue(dimension,svm->dimension) ;
00118 mxSetField(output, 0, "dimension", dimension) ;
00119
00120 iterations = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;
00121 setUintValue(iterations,svm->iterations) ;
00122 mxSetField(output, 0, "iterations", iterations) ;
00123
00124 maxIterations = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;
00125 setUintValue(maxIterations,svm->maxIterations) ;
00126 mxSetField(output, 0, "maxIterations", maxIterations) ;
00127
00128 epsilon = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00129 setDoubleValue(epsilon,svm->epsilon) ;
00130 mxSetField(output, 0, "epsilon", epsilon) ;
00131
00132 lambda = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00133 setDoubleValue(lambda,svm->lambda) ;
00134 mxSetField(output, 0, "lambda", lambda) ;
00135
00136 biasMultiplier = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00137 setDoubleValue(biasMultiplier,svm->biasMultiplier) ;
00138 mxSetField(output, 0, "biasMultiplier", biasMultiplier) ;
00139
00140 elapsedTime = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00141 setDoubleValue(elapsedTime,svm->elapsedTime) ;
00142 mxSetField(output, 0, "elapsedTime", elapsedTime) ;
00143
00144 if (svm->objective) {
00145 mxArray * energy, *regularizerTerm, *lossPos, *lossNeg, *hardLossPos, *hardLossNeg ;
00146
00147 energy = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00148 setDoubleValue(energy,svm->objective->energy) ;
00149
00150 regularizerTerm = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00151 setDoubleValue(regularizerTerm,svm->objective->regularizer) ;
00152
00153 lossPos = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00154 setDoubleValue(lossPos,svm->objective->lossPos) ;
00155
00156 lossNeg = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00157 setDoubleValue(lossNeg,svm->objective->lossNeg) ;
00158
00159 hardLossPos = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00160 setDoubleValue(hardLossPos,svm->objective->hardLossPos) ;
00161
00162 hardLossNeg = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;
00163 setDoubleValue(hardLossNeg,svm->objective->hardLossNeg) ;
00164
00165 mxSetField(output, 0, "energy", energy) ;
00166 mxSetField(output, 0, "regularizerTerm", regularizerTerm) ;
00167 mxSetField(output, 0, "lossPos", lossPos) ;
00168 mxSetField(output, 0, "lossNeg", lossNeg) ;
00169 mxSetField(output, 0, "hardLossPos", hardLossPos) ;
00170 mxSetField(output, 0, "hardLossNeg", hardLossNeg) ;
00171 }
00172
00173 return output ;
00174 }
00175
00176
00177 VL_INLINE
00178 void diagnosticDispatcher(VlSvm* svm)
00179 {
00180 if (svm->diagnosticFunction) {
00181 mxArray *rhs[2] ;
00182
00183 rhs[0] = (mxArray*) svm->diagnosticFunction ;
00184 rhs[1] = createInfoStruct(svm) ;
00185
00186 if( mxIsClass( rhs[0] , "function_handle")) {
00187 mexCallMATLAB(0,NULL,2,rhs,"feval");
00188 }
00189
00190 mxDestroyArray(rhs[1]) ;
00191 }
00192 }
00193
00194
00211 void getTrainingData(const mxArray* trainingData, void** data, vl_size* dataDimension, vl_type* dataType, vl_size* numSamples, vl_int8** labels)
00212 {
00213 mxClassID dataClass ;
00214 mxArray* field = NULL ;
00215
00216 if (! mxIsStruct(trainingData))
00217 vlmxError(vlmxErrInvalidArgument,"DATA must be a valid TRAINING SET Struct.") ;
00218
00219
00220 field = mxGetField(trainingData, 0, "data") ;
00221 if (field == NULL)
00222 vlmxError(vlmxErrInvalidArgument, "DATA array missing in TRAINING SET Struct.") ;
00223 *data = mxGetData (field) ;
00224
00225 *dataDimension = mxGetM(field) ;
00226 *numSamples = mxGetN(field) ;
00227
00228 dataClass = mxGetClassID(field) ;
00229
00230 switch (dataClass) {
00231 case mxSINGLE_CLASS : *dataType = VL_TYPE_FLOAT ; break ;
00232 case mxDOUBLE_CLASS : *dataType = VL_TYPE_DOUBLE ; break ;
00233 default:
00234 vlmxError(vlmxErrInvalidArgument,
00235 "DATA must be either SINGLE or DOUBLE.") ;
00236 }
00237
00238
00239 field = mxGetField(trainingData, 0, "labels") ;
00240 if (field == NULL)
00241 vlmxError(vlmxErrInvalidArgument,
00242 "DATA array missing in TRAINING SET Struct.") ;
00243 if (mxGetClassID(field) != mxINT8_CLASS)
00244 vlmxError(vlmxErrInvalidArgument, "LABELS must be INT8.") ;
00245
00246 if (! vlmxIsVector(field, *numSamples)) {
00247 vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;
00248 }
00249
00250 *labels = (vl_int8*) mxGetData(field) ;
00251 }