?? libsvmaux.c
字號(hào):
/*============================================================================*\| MATLAB Interface for LIBSVM, Version 1.2 || || Copyright (C) 2004-2005 Michael Vogt || Written by Michael Vogt, Atanas Ayarov and Bennet Gedan || || This program is free software; you can redistribute it and/or modify it || under the terms of the GNU General Public License as published by the Free || Software Foundation; either version 2 of the License, or (at your option) || any later version. |\*============================================================================*/#include <string.h>#include <math.h>#include "mex.h"#include "libsvmaux.h"/*----------------------------------------------------------------------------*\| Fetch kernel function from MATLAB. |\*----------------------------------------------------------------------------*/int getKernel( /* Return: 0 on success, 1 on failure */ kernel *ker, /* [out] kernel as needed by the algorithms */ const mxArray *mlker, /* [in] kernel as provided by MATLAB */ long n ) /* [in] input dimension (n<=0: adjust it to mlker) */{ long k, m; /* counters */ int d; /* flag */ char strbuf[mxMAXNAM]; /* buffer for contents of type field */ mxArray *F, *F2; /* fields of MATLAB struct */ /* --- check if type field is a string --- */ if ( (F=mxGetField(mlker,0,FNAME_TYPE)) == NULL || mxIsEmpty(F) || mxGetNumberOfDimensions(F) > 2 || !mxIsChar(F) ) return 1; else mxGetString(F,strbuf,mxMAXNAM+1); /* --- check if "mlker" is a valid linear kernel --- */ if ( !strcmp(strbuf,KNAME_LINEAR) ) { ker->type = KERNEL_LINEAR; return 0; } /* --- check if "mlker" is a valid polynomial kernel --- */ else if ( !strcmp(strbuf,KNAME_POLY) && (F=mxGetField(mlker,0,FNAME_DEGR)) != NULL && mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 1 && (F2=mxGetField(mlker,0,FNAME_OFFSET)) != NULL && mxGetNumberOfElements(F2) == 1 && mxIsDouble(F2) && !mxIsComplex(F2)) { if ( (int)mxGetScalar(F) == 1 && mxGetScalar(F2) == 0.0 ) ker->type = KERNEL_LINEAR; else { ker->type = KERNEL_POLY; ker->degree = (int)mxGetScalar(F); ker->offset = mxGetScalar(F2); } return 0; } /* --- check if "mlker" is a valid Gauss kernel --- */ else if ( !strcmp(strbuf,KNAME_GAUSS) && (F=mxGetField(mlker,0,FNAME_WIDTH)) != NULL && !mxIsEmpty(F) && mxGetNumberOfDimensions(F) <= 2 && (mxGetN(F) == 1 || mxGetM(F) == 1) && mxIsDouble(F) && !mxIsComplex(F) ) { m = mxGetNumberOfElements(F); if (n<1) /* if n is not specified: */ n = m; /* take it from MATLAB struct */ else if (m>n) /* if more widths than dimensions: */ m = n; /* ignore the rest */ for (k=0; k<m; k++) { /* all widths positive? */ if (mxGetPr(F)[k] <= 0) return 1; } d = 0; /* different vector elements? */ for (k=1; k<m; k++) { if (mxGetPr(F)[k] != mxGetScalar(F)) d = 1; } if (m == 1 || d == 0) { /* use scalar gamma */ ker->type = KERNEL_RADIAL; ker->gamma = 0.5/(mxGetScalar(F)*mxGetScalar(F)); } else { /* use gamma vector */ ker->type = KERNEL_GAUSS; ker->gamman = n; ker->gammav = mxMalloc(n*sizeof(double)); for (k=0; k<m; k++) ker->gammav[k] = 0.5/(mxGetPr(F)[k]*mxGetPr(F)[k]); for ( ; k<n; k++) ker->gammav[k] = ker->gammav[m-1]; } return 0; } /* --- check if "mlker" is a valid tanh kernel --- */ else if ( !strcmp(strbuf,KNAME_TANH) && (F=mxGetField(mlker,0,FNAME_GAMMA)) != NULL && mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) > 0 && (F2=mxGetField(mlker,0,FNAME_OFFSET)) != NULL && mxGetNumberOfElements(F2) == 1 && mxIsDouble(F2) && !mxIsComplex(F2) && mxGetScalar(F2) < 0 ) { ker->type = KERNEL_TANH; ker->gamma = mxGetScalar(F); ker->offset = mxGetScalar(F2); return 0; } /* --- otherwise return an error --- */}/*----------------------------------------------------------------------------*\| Fetch MATLAB SVM struct into multiple variables. |\*----------------------------------------------------------------------------*/int getSvm( /* Return: 0 on success, 1 on failure */ const mxArray *mlsvm, /* [in] SVM as provided by MATLAB */ double **a, /* [out] *a points to the SVM coefficients */ double **xs, /* [out] *xs points to the support vectors */ long *Ns, /* [out] number of support vectors */ long *n, /* [out] input dimension */ double *b, /* [out] bias term */ kernel *ker ) /* [out] kernel function struct */{ mxArray *F; /* field of MATLAB struct */ /* --- check for valid SVM coefficients --- */ if ( (F=mxGetField(mlsvm,0,FNAME_COEF)) == NULL || mxIsEmpty(F) || mxGetNumberOfDimensions(F) > 2 || !mxIsDouble(F) || mxIsComplex(F) ) return 1; /* --- check for valid support vectors --- */ if ( (F=mxGetField(mlsvm,0,FNAME_VECT)) == NULL || mxIsEmpty(F) || mxGetNumberOfDimensions(F) > 2 || !mxIsDouble(F) || mxIsComplex(F) || mxGetM(F) != mxGetM(mxGetField(mlsvm,0,FNAME_COEF)) ) return 1; /* --- check for valid bias term --- */ if ( (F=mxGetField(mlsvm,0,FNAME_BIAS)) == NULL || mxGetNumberOfElements(F) != 1 || !mxIsDouble(F) || mxIsComplex(F) ) return 1; /* --- try to get kernel struct using getKernel() --- */ if ( (F=mxGetField(mlsvm,0,FNAME_KER)) == NULL || getKernel(ker,F,mxGetN(mxGetField(mlsvm,0,FNAME_VECT))) ) return 1; /* --- get all other data --- */ *a = mxGetPr(mxGetField(mlsvm,0,FNAME_COEF)); *xs = mxGetPr(mxGetField(mlsvm,0,FNAME_VECT)); *Ns = mxGetM(mxGetField(mlsvm,0,FNAME_VECT)); *n = mxGetN(mxGetField(mlsvm,0,FNAME_VECT)); *b = mxGetScalar(mxGetField(mlsvm,0,FNAME_BIAS)); return 0;}/*----------------------------------------------------------------------------*\| Get pointer to MATLAB option struct; convert key/value pairs if necessary. |\*----------------------------------------------------------------------------*/int getOptionsStruct( /* Return: always 0 */ const mxArray **mlopt, /* [out] pointer to MATLAB options struct */ const mxArray *optlist[], /* [in] pointer to the element after the kernel */ int nopt ) /* [in] number of elements after the kernel */{ /* --- in case of input struct pass struct to getOptions -- */ if (mxIsStruct(optlist[0])) { if (nopt == 1 && mxGetNumberOfElements(optlist[0]) == 1) *mlopt = optlist[0]; else mexErrMsgTxt("Invalid argument (options)."); } /* --- check for key/value structure --- */ else { mxArray *temp; /* needed since **mlopt must not be changed */ char strbuf[mxMAXNAM]; /* string buffer */ int k; if (nopt % 2 == 1) mexErrMsgTxt("Invalid options structure (string,value)"); for (k=0; k<nopt; k+=2) { if ( !mxIsChar(optlist[k]) || mxGetM(optlist[k]) != 1 && mxGetN(optlist[k]) != 1 ) mexErrMsgTxt("Invalid options structure (string,value)"); } temp = mxCreateStructMatrix(1,1,0,NULL); for (k=0; k<nopt; k+=2) { mxGetString(optlist[k],strbuf,mxMAXNAM+1); mxSetFieldByNumber(temp, 0, mxAddField(temp, strbuf), mxDuplicateArray(optlist[k+1])); } *mlopt = temp; } return 0;}/*----------------------------------------------------------------------------*\| Fetch MATLAB options into struct variable. |\*----------------------------------------------------------------------------*/int getOptions( /* Return: 0 on success, 1 on failure */ options *opt, /* [out] struct for optimizer options */ const mxArray *mlopt, /* [in] options as provided by MATLAB */ long N ) /* [in] number of data */{ int k,l; /* counter */ mxArray *F; /* field of options struct */ char strbuf[mxMAXNAM]; char strbuf2[mxMAXNAM]; float temp; for (k=0; k<mxGetNumberOfFields(mlopt); k++) { F = mxGetFieldByNumber(mlopt,0,k); /* --- Treat option FNAME_TOL --- */ if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_TOL) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 0 ) opt->tol = mxGetScalar(F); else mexWarnMsgTxt("Invalid option \"" FNAME_TOL "\" ignored."); } /* --- Treat option FNAME_CACHE --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_CACHE) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 1 ) opt->cache = (double)(sizeof(double)*N*(long)mxGetScalar(F))/(1024.0*1024.0); else if ( mxIsChar(F) && !mxIsEmpty(F) && mxGetM(F) == 1 && mxGetNumberOfDimensions(F) == 2 ) { mxGetString(F,strbuf,mxMAXNAM+1); for (l=0;l<mxMAXNAM;l++) strbuf[l]=tolower(strbuf[l]); if ( sscanf(strbuf,"%g",&temp) != EOF && sscanf(strbuf,"%*g %s",strbuf2) != EOF ) { if ( strcmp(strbuf2,"mb") == 0 ) opt->cache = (double)temp; else if ( strcmp(strbuf2,"kb") == 0 ) opt->cache = (double)temp/1024; else mexWarnMsgTxt("Invalid option \"" FNAME_CACHE "\" ignored."); } else mexWarnMsgTxt("Invalid option \"" FNAME_CACHE "\" ignored."); } else mexWarnMsgTxt("Invalid option \"" FNAME_CACHE "\" ignored."); } /* --- Treat option FNAME_SHRINK --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_SHRINK) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 0 ) opt->shrink = (int)mxGetScalar(F); else mexWarnMsgTxt("Invalid option \"" FNAME_SHRINK "\" ignored."); } /* --- Treat option FNAME_WEIGHT --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_WEIGHT) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 0 ) opt->weight = mxGetScalar(F); else mexWarnMsgTxt("Invalid option \"" FNAME_WEIGHT "\" ignored."); } /* --- Treat option FNAME_WLABEL --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_WLABEL) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) ) opt->wlabel = (int)mxGetScalar(F); else mexWarnMsgTxt("Invalid option \"" FNAME_WLABEL "\" ignored."); } /* --- Treat option FNAME_VERBOSE --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_VERBOSE) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 0 ) opt->verbose = (int)mxGetScalar(F); else mexWarnMsgTxt("Invalid option \"" FNAME_VERBOSE "\" ignored."); } /* --- Treat option FNAME_STYLE --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_STYLE) ) { if ( mxIsChar(F) && !mxIsEmpty(F) && mxGetM(F) == 1 && mxGetNumberOfDimensions(F) == 2) { if (mxGetScalar(F) == 'n') opt->style = 1; else opt->style = 0; } else mexWarnMsgTxt("Invalid option \"" FNAME_STYLE "\" ignored."); } /* --- Treat option FNAME_PROBOPT --- */ else if ( !strcmp(mxGetFieldNameByNumber(mlopt,k),FNAME_PROBOPT) ) { if ( mxGetNumberOfElements(F) == 1 && mxIsDouble(F) && !mxIsComplex(F) && mxGetScalar(F) >= 0 ) opt->prob = (int)mxGetScalar(F); else mexWarnMsgTxt("Invalid option \"" FNAME_PROBOPT "\" ignored."); } } return 0;}/*----------------------------------------------------------------------------*\| Dump information about settings into MATLAB window. |\*----------------------------------------------------------------------------*/int dumpOptions( /* Return: always 0 */ kernel *ker, /* [in] kernel struct */ options *opt, /* [in] option struct */ double C, /* [in] C or nu */ double e, /* [in] epsilon or nu */ int svmproblem ) /* [in] 0: SVR, 1: SVC, 2: One-Class */{ mexPrintf("--------------------\n"); mexPrintf("OPTIONS\n"); switch ( svmproblem ) { case 0: if (opt->style == 0) {
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -