x[j].index = -1;
}
-static void fake_answer(mxArray *plhs[])
+static void fake_answer(int nlhs, mxArray *plhs[])
{
- plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
- plhs[1] = mxCreateDoubleMatrix(0, 0, mxREAL);
- plhs[2] = mxCreateDoubleMatrix(0, 0, mxREAL);
+ int i;
+ for(i=0;i<nlhs;i++)
+ plhs[i] = mxCreateDoubleMatrix(0, 0, mxREAL);
}
-void do_predict(mxArray *plhs[], const mxArray *prhs[], struct model *model_, const int predict_probability_flag)
+void do_predict(int nlhs, mxArray *plhs[], const mxArray *prhs[], struct model *model_, const int predict_probability_flag)
{
int label_vector_row_num, label_vector_col_num;
int feature_number, testing_instance_number;
double *ptr_prob_estimates, *ptr_dec_values, *ptr;
struct feature_node *x;
mxArray *pplhs[1]; // instance sparse matrix in row format
+ mxArray *tplhs[3]; // temporary storage for plhs[]
int correct = 0;
int total = 0;
if(label_vector_row_num!=testing_instance_number)
{
mexPrintf("Length of label vector does not match # of instances.\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
if(label_vector_col_num!=1)
{
mexPrintf("label (1st argument) should be a vector (# of column is 1).\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
{
mexPrintf("Error: cannot transpose testing instance matrix\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
}
prob_estimates = Malloc(double, nr_class);
- plhs[0] = mxCreateDoubleMatrix(testing_instance_number, 1, mxREAL);
+ tplhs[0] = mxCreateDoubleMatrix(testing_instance_number, 1, mxREAL);
if(predict_probability_flag)
- plhs[2] = mxCreateDoubleMatrix(testing_instance_number, nr_class, mxREAL);
+ tplhs[2] = mxCreateDoubleMatrix(testing_instance_number, nr_class, mxREAL);
else
- plhs[2] = mxCreateDoubleMatrix(testing_instance_number, nr_w, mxREAL);
+ tplhs[2] = mxCreateDoubleMatrix(testing_instance_number, nr_w, mxREAL);
- ptr_predict_label = mxGetPr(plhs[0]);
- ptr_prob_estimates = mxGetPr(plhs[2]);
- ptr_dec_values = mxGetPr(plhs[2]);
+ ptr_predict_label = mxGetPr(tplhs[0]);
+ ptr_prob_estimates = mxGetPr(tplhs[2]);
+ ptr_dec_values = mxGetPr(tplhs[2]);
x = Malloc(struct feature_node, feature_number+2);
for(instance_index=0;instance_index<testing_instance_number;instance_index++)
{
info("Accuracy = %g%% (%d/%d)\n", (double) correct/total*100,correct,total);
// return accuracy, mean squared error, squared correlation coefficient
- plhs[1] = mxCreateDoubleMatrix(3, 1, mxREAL);
- ptr = mxGetPr(plhs[1]);
+ tplhs[1] = mxCreateDoubleMatrix(3, 1, mxREAL);
+ ptr = mxGetPr(tplhs[1]);
ptr[0] = (double)correct/total*100;
ptr[1] = error/total;
ptr[2] = ((total*sumpt-sump*sumt)*(total*sumpt-sump*sumt))/
free(x);
if(prob_estimates != NULL)
free(prob_estimates);
+
+ switch(nlhs){
+ case 3: plhs[2] = tplhs[2];
+ plhs[1] = tplhs[1];
+ case 1:
+ case 0: plhs[0] = tplhs[0];
+ }
}
void exit_with_help()
{
mexPrintf(
"Usage: [predicted_label, accuracy, decision_values/prob_estimates] = predict(testing_label_vector, testing_instance_matrix, model, 'liblinear_options','col')\n"
+ " [predicted_label] = predict(testing_label_vector, testing_instance_matrix, model, 'liblinear_options','col')\n"
"liblinear_options:\n"
"-b probability_estimates: whether to output probability estimates, 0 or 1 (default 0); currently for logistic regression only\n"
"-q quiet mode (no outputs)\n"
info = &mexPrintf;
col_format_flag = 0;
- if(nrhs > 5 || nrhs < 3)
+ if(nlhs == 2 || nlhs > 3 || nrhs > 5 || nrhs < 3)
{
exit_with_help();
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
if(nrhs == 5)
if(!mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1])) {
mexPrintf("Error: label vector and instance matrix must be double\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
if(i>=argc && argv[i-1][1] != 'q')
{
exit_with_help();
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
switch(argv[i-1][1])
default:
mexPrintf("unknown option\n");
exit_with_help();
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
}
{
mexPrintf("Error: can't read model: %s\n", error_msg);
free_and_destroy_model(&model_);
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
}
if(mxIsSparse(prhs[1]))
- do_predict(plhs, prhs, model_, prob_estimate_flag);
+ do_predict(nlhs, plhs, prhs, model_, prob_estimate_flag);
else
{
mexPrintf("Testing_instance_matrix must be sparse; "
"use sparse(Testing_instance_matrix) first\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
}
// destroy model_
else
{
mexPrintf("model file should be a struct array\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
}
return;
return 0;
}
-static void fake_answer(mxArray *plhs[])
+static void fake_answer(int nlhs, mxArray *plhs[])
{
- plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
+ int i;
+ for(i=0;i<nlhs;i++)
+ plhs[i] = mxCreateDoubleMatrix(0, 0, mxREAL);
}
int read_problem_sparse(const mxArray *label_vec, const mxArray *instance_mat)
// (for cross validation)
srand(1);
+ if(nlhs > 1)
+ {
+ exit_with_help();
+ fake_answer(nlhs, plhs);
+ return;
+ }
+
// Transform the input Matrix to libsvm format
if(nrhs > 1 && nrhs < 5)
{
if(!mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1])) {
mexPrintf("Error: label vector and instance matrix must be double\n");
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
{
exit_with_help();
destroy_param(¶m);
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
mexPrintf("Training_instance_matrix must be sparse; "
"use sparse(Training_instance_matrix) first\n");
destroy_param(¶m);
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
free(prob.y);
free(prob.x);
free(x_space);
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
else
{
exit_with_help();
- fake_answer(plhs);
+ fake_answer(nlhs, plhs);
return;
}
}