|
|
@@ -0,0 +1,119 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
#include "mex.h" |
|
|
|
|
|
|
|
#ifdef MX_API_VER |
|
|
|
#if MX_API_VER < 0x07030000 |
|
|
|
typedef int mwIndex; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
void exit_with_help() |
|
|
|
{ |
|
|
|
mexPrintf( |
|
|
|
"Usage: libsvmwrite('filename', label_vector, instance_matrix);\n" |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
static void fake_answer(int nlhs, mxArray *plhs[]) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
for(i=0;i<nlhs;i++) |
|
|
|
plhs[i] = mxCreateDoubleMatrix(0, 0, mxREAL); |
|
|
|
} |
|
|
|
|
|
|
|
void libsvmwrite(const char *filename, const mxArray *label_vec, const mxArray *instance_mat) |
|
|
|
{ |
|
|
|
FILE *fp = fopen(filename,"w"); |
|
|
|
mwIndex *ir, *jc, k, low, high; |
|
|
|
size_t i, l, label_vector_row_num; |
|
|
|
double *samples, *labels; |
|
|
|
mxArray *instance_mat_col; // instance sparse matrix in column format |
|
|
|
|
|
|
|
if(fp ==NULL) |
|
|
|
{ |
|
|
|
mexPrintf("can't open output file %s\n",filename); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// transpose instance matrix |
|
|
|
{ |
|
|
|
mxArray *prhs[1], *plhs[1]; |
|
|
|
prhs[0] = mxDuplicateArray(instance_mat); |
|
|
|
if(mexCallMATLAB(1, plhs, 1, prhs, "transpose")) |
|
|
|
{ |
|
|
|
mexPrintf("Error: cannot transpose instance matrix\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
instance_mat_col = plhs[0]; |
|
|
|
mxDestroyArray(prhs[0]); |
|
|
|
} |
|
|
|
|
|
|
|
// the number of instance |
|
|
|
l = mxGetN(instance_mat_col); |
|
|
|
label_vector_row_num = mxGetM(label_vec); |
|
|
|
|
|
|
|
if(label_vector_row_num!=l) |
|
|
|
{ |
|
|
|
mexPrintf("Length of label vector does not match # of instances.\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// each column is one instance |
|
|
|
labels = mxGetPr(label_vec); |
|
|
|
samples = mxGetPr(instance_mat_col); |
|
|
|
ir = mxGetIr(instance_mat_col); |
|
|
|
jc = mxGetJc(instance_mat_col); |
|
|
|
|
|
|
|
for(i=0;i<l;i++) |
|
|
|
{ |
|
|
|
fprintf(fp,"%g", labels[i]); |
|
|
|
|
|
|
|
low = jc[i], high = jc[i+1]; |
|
|
|
for(k=low;k<high;k++) |
|
|
|
fprintf(fp," %lu:%g", (size_t)ir[k]+1, samples[k]); |
|
|
|
|
|
|
|
fprintf(fp,"\n"); |
|
|
|
} |
|
|
|
|
|
|
|
fclose(fp); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
void mexFunction( int nlhs, mxArray *plhs[], |
|
|
|
int nrhs, const mxArray *prhs[] ) |
|
|
|
{ |
|
|
|
if(nlhs > 0) |
|
|
|
{ |
|
|
|
exit_with_help(); |
|
|
|
fake_answer(nlhs, plhs); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// Transform the input Matrix to libsvm format |
|
|
|
if(nrhs == 3) |
|
|
|
{ |
|
|
|
char filename[256]; |
|
|
|
if(!mxIsDouble(prhs[1]) || !mxIsDouble(prhs[2])) |
|
|
|
{ |
|
|
|
mexPrintf("Error: label vector and instance matrix must be double\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
mxGetString(prhs[0], filename, mxGetN(prhs[0])+1); |
|
|
|
|
|
|
|
if(mxIsSparse(prhs[2])) |
|
|
|
libsvmwrite(filename, prhs[1], prhs[2]); |
|
|
|
else |
|
|
|
{ |
|
|
|
mexPrintf("Instance_matrix must be sparse\n"); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
exit_with_help(); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |