From 3a30c797bd2e570dfcb736475264f25d0bf79e99 Mon Sep 17 00:00:00 2001 From: Chun-Heng Huang Date: Mon, 11 Mar 2013 12:20:04 +0800 Subject: [PATCH] Matlab interface parameter checking Check 'nlhs' argument. Allow various output size for predict. --- matlab/README | 1 + matlab/predict.c | 59 ++++++++++++++++++++++++----------------- matlab/train.c | 23 +++++++++++----- windows/predict.mexw64 | Bin 16384 -> 16384 bytes windows/train.mexw64 | Bin 60928 -> 60928 bytes 5 files changed, 51 insertions(+), 32 deletions(-) diff --git a/matlab/README b/matlab/README index 3c8b0eb..3259bdf 100644 --- a/matlab/README +++ b/matlab/README @@ -95,6 +95,7 @@ matlab> model = train(training_label_vector, training_instance_matrix [,'libline if 'col' is set, each column of training_instance_matrix is a data instance. Otherwise each row is a data instance. matlab> [predicted_label, accuracy, decision_values/prob_estimates] = predict(testing_label_vector, testing_instance_matrix, model [, 'liblinear_options', 'col']); +matlab> [predicted_label] = predict(testing_label_vector, testing_instance_matrix, model [, 'liblinear_options', 'col']); -testing_label_vector: An m by 1 vector of prediction labels. If labels of test diff --git a/matlab/predict.c b/matlab/predict.c index b1d56d5..2fd992e 100644 --- a/matlab/predict.c +++ b/matlab/predict.c @@ -49,14 +49,14 @@ void read_sparse_instance(const mxArray *prhs, int index, struct feature_node *x 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 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) @@ -242,7 +251,7 @@ void mexFunction( int nlhs, mxArray *plhs[], 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; } @@ -269,7 +278,7 @@ void mexFunction( int nlhs, mxArray *plhs[], if(i>=argc && argv[i-1][1] != 'q') { exit_with_help(); - fake_answer(plhs); + fake_answer(nlhs, plhs); return; } switch(argv[i-1][1]) @@ -284,7 +293,7 @@ void mexFunction( int nlhs, mxArray *plhs[], default: mexPrintf("unknown option\n"); exit_with_help(); - fake_answer(plhs); + fake_answer(nlhs, plhs); return; } } @@ -296,7 +305,7 @@ void mexFunction( int nlhs, mxArray *plhs[], { mexPrintf("Error: can't read model: %s\n", error_msg); free_and_destroy_model(&model_); - fake_answer(plhs); + fake_answer(nlhs, plhs); return; } @@ -310,12 +319,12 @@ void mexFunction( int nlhs, mxArray *plhs[], } 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_ @@ -324,7 +333,7 @@ void mexFunction( int nlhs, mxArray *plhs[], else { mexPrintf("model file should be a struct array\n"); - fake_answer(plhs); + fake_answer(nlhs, plhs); } return; diff --git a/matlab/train.c b/matlab/train.c index 6351dab..1301ed5 100644 --- a/matlab/train.c +++ b/matlab/train.c @@ -243,9 +243,11 @@ int parse_command_line(int nrhs, const mxArray *prhs[], char *model_file_name) 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 1) + { + exit_with_help(); + fake_answer(nlhs, plhs); + return; + } + // Transform the input Matrix to libsvm format if(nrhs > 1 && nrhs < 5) { @@ -349,7 +358,7 @@ void mexFunction( int nlhs, mxArray *plhs[], 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; } @@ -357,7 +366,7 @@ void mexFunction( int nlhs, mxArray *plhs[], { exit_with_help(); destroy_param(¶m); - fake_answer(plhs); + fake_answer(nlhs, plhs); return; } @@ -368,7 +377,7 @@ void mexFunction( int nlhs, mxArray *plhs[], 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; } @@ -383,7 +392,7 @@ void mexFunction( int nlhs, mxArray *plhs[], free(prob.y); free(prob.x); free(x_space); - fake_answer(plhs); + fake_answer(nlhs, plhs); return; } @@ -412,7 +421,7 @@ void mexFunction( int nlhs, mxArray *plhs[], else { exit_with_help(); - fake_answer(plhs); + fake_answer(nlhs, plhs); return; } } diff --git a/windows/predict.mexw64 b/windows/predict.mexw64 index 1a64777a9a8dffe0740d0b00dfe8e72662981cc7..4a7592cf9175a36b7f124799170515d54e757ad9 100755 GIT binary patch delta 6248 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 delta 10378 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 F{10GY<^2Ev -- 2.50.1