00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <ctype.h>
00005 #include <errno.h>
00006
00007 #include "mex.h"
00008
00009 #ifdef MX_API_VER
00010 #if MX_API_VER < 0x07030000
00011 typedef int mwIndex;
00012 #endif
00013 #endif
00014 #ifndef max
00015 #define max(x,y) (((x)>(y))?(x):(y))
00016 #endif
00017 #ifndef min
00018 #define min(x,y) (((x)<(y))?(x):(y))
00019 #endif
00020
00021 void exit_with_help()
00022 {
00023 mexPrintf(
00024 "Usage: [label_vector, instance_matrix] = libsvmread('filename');\n"
00025 );
00026 }
00027
00028 static void fake_answer(int nlhs, mxArray *plhs[])
00029 {
00030 int i;
00031 for(i=0;i<nlhs;i++)
00032 plhs[i] = mxCreateDoubleMatrix(0, 0, mxREAL);
00033 }
00034
00035 static char *line;
00036 static int max_line_len;
00037
00038 static char* readline(FILE *input)
00039 {
00040 int len;
00041
00042 if(fgets(line,max_line_len,input) == NULL)
00043 return NULL;
00044
00045 while(strrchr(line,'\n') == NULL)
00046 {
00047 max_line_len *= 2;
00048 line = (char *) realloc(line, max_line_len);
00049 len = (int) strlen(line);
00050 if(fgets(line+len,max_line_len-len,input) == NULL)
00051 break;
00052 }
00053 return line;
00054 }
00055
00056
00057 void read_problem(const char *filename, int nlhs, mxArray *plhs[])
00058 {
00059 int max_index, min_index, inst_max_index;
00060 size_t elements, k, i, l=0;
00061 FILE *fp = fopen(filename,"r");
00062 char *endptr;
00063 mwIndex *ir, *jc;
00064 double *labels, *samples;
00065
00066 if(fp == NULL)
00067 {
00068 mexPrintf("can't open input file %s\n",filename);
00069 fake_answer(nlhs, plhs);
00070 return;
00071 }
00072
00073 max_line_len = 1024;
00074 line = (char *) malloc(max_line_len*sizeof(char));
00075
00076 max_index = 0;
00077 min_index = 1;
00078 elements = 0;
00079 while(readline(fp) != NULL)
00080 {
00081 char *idx, *val;
00082
00083 int index = 0;
00084
00085 inst_max_index = -1;
00086 strtok(line," \t");
00087 while (1)
00088 {
00089 idx = strtok(NULL,":");
00090 val = strtok(NULL," \t");
00091 if(val == NULL)
00092 break;
00093
00094 errno = 0;
00095 index = (int) strtol(idx,&endptr,10);
00096 if(endptr == idx || errno != 0 || *endptr != '\0' || index <= inst_max_index)
00097 {
00098 mexPrintf("Wrong input format at line %d\n",l+1);
00099 fake_answer(nlhs, plhs);
00100 return;
00101 }
00102 else
00103 inst_max_index = index;
00104
00105 min_index = min(min_index, index);
00106 elements++;
00107 }
00108 max_index = max(max_index, inst_max_index);
00109 l++;
00110 }
00111 rewind(fp);
00112
00113
00114 plhs[0] = mxCreateDoubleMatrix(l, 1, mxREAL);
00115
00116 if (min_index <= 0)
00117 plhs[1] = mxCreateSparse(max_index-min_index+1, l, elements, mxREAL);
00118 else
00119 plhs[1] = mxCreateSparse(max_index, l, elements, mxREAL);
00120
00121 labels = mxGetPr(plhs[0]);
00122 samples = mxGetPr(plhs[1]);
00123 ir = mxGetIr(plhs[1]);
00124 jc = mxGetJc(plhs[1]);
00125
00126 k=0;
00127 for(i=0;i<l;i++)
00128 {
00129 char *idx, *val, *label;
00130 jc[i] = k;
00131
00132 readline(fp);
00133
00134 label = strtok(line," \t\n");
00135 if(label == NULL)
00136 {
00137 mexPrintf("Empty line at line %d\n",i+1);
00138 fake_answer(nlhs, plhs);
00139 return;
00140 }
00141 labels[i] = strtod(label,&endptr);
00142 if(endptr == label || *endptr != '\0')
00143 {
00144 mexPrintf("Wrong input format at line %d\n",i+1);
00145 fake_answer(nlhs, plhs);
00146 return;
00147 }
00148
00149
00150 while(1)
00151 {
00152 idx = strtok(NULL,":");
00153 val = strtok(NULL," \t");
00154 if(val == NULL)
00155 break;
00156
00157 ir[k] = (mwIndex) (strtol(idx,&endptr,10) - min_index);
00158
00159 errno = 0;
00160 samples[k] = strtod(val,&endptr);
00161 if (endptr == val || errno != 0 || (*endptr != '\0' && !isspace(*endptr)))
00162 {
00163 mexPrintf("Wrong input format at line %d\n",i+1);
00164 fake_answer(nlhs, plhs);
00165 return;
00166 }
00167 ++k;
00168 }
00169 }
00170 jc[l] = k;
00171
00172 fclose(fp);
00173 free(line);
00174
00175 {
00176 mxArray *rhs[1], *lhs[1];
00177 rhs[0] = plhs[1];
00178 if(mexCallMATLAB(1, lhs, 1, rhs, "transpose"))
00179 {
00180 mexPrintf("Error: cannot transpose problem\n");
00181 fake_answer(nlhs, plhs);
00182 return;
00183 }
00184 plhs[1] = lhs[0];
00185 }
00186 }
00187
00188 void mexFunction( int nlhs, mxArray *plhs[],
00189 int nrhs, const mxArray *prhs[] )
00190 {
00191 char filename[256];
00192
00193 if(nrhs != 1 || nlhs != 2)
00194 {
00195 exit_with_help();
00196 fake_answer(nlhs, plhs);
00197 return;
00198 }
00199
00200 mxGetString(prhs[0], filename, mxGetN(prhs[0]) + 1);
00201
00202 if(filename == NULL)
00203 {
00204 mexPrintf("Error: filename is NULL\n");
00205 return;
00206 }
00207
00208 read_problem(filename, nlhs, plhs);
00209
00210 return;
00211 }
00212