diff --git a/src/helper_files/helper.cpp b/src/helper_files/helper.cpp index f0a4b68d859822934450f75626fdff0f323b1a70..57e3ffe7c71170be08998bf911e6e3c446b102e1 100644 --- a/src/helper_files/helper.cpp +++ b/src/helper_files/helper.cpp @@ -5,6 +5,8 @@ // Extra functions to reduce some code for the conversion between arma and float *array +// arma --> array + float *convertToArray(colvec vec) { vector<float> vectorData = conv_to<vector<float>>::from(vec); @@ -80,6 +82,9 @@ float *convertToArray(vector<vec> matrix) return convertToArray(newVec); } + +// array --> arma + rowvec convertArrayToRowvec(float *arr, int vecSize) { rowvec rVector(vecSize); @@ -90,6 +95,16 @@ rowvec convertArrayToRowvec(float *arr, int vecSize) return rVector; } +colvec convertArrayToColvec(float *arr, int vecSize) +{ + colvec rVector(vecSize); + for(int i = 0; i < vecSize; i++) + { + rVector[i] = arr[i]; + } + return rVector; +} + Row<size_t> convertArrayToVec(float *arr, int vecSize) { Row<size_t> rVector(vecSize); @@ -110,6 +125,9 @@ mat convertArrayToMat(float *arr, int vecSize, int rowCount) return matrix; } + + + void returnMatrixInformation(mat matrix, float **mat, SP_integer *matColNum, SP_integer *matRowNum) { // return the Matrix dimensions diff --git a/src/helper_files/helper.hpp b/src/helper_files/helper.hpp index 7849b48a6d4373d91a2c41b88fabc0cfdbc2151f..f76ca68802a1969b8d8a18f71b7efb18b044de2b 100644 --- a/src/helper_files/helper.hpp +++ b/src/helper_files/helper.hpp @@ -31,6 +31,8 @@ float *convertToArray(vector<vec> vec); rowvec convertArrayToRowvec(float *arr, int vecSize); +colvec convertArrayToColvec(float *arr, int vecSize); + Row<size_t> convertArrayToVec(float *arr, int vecSize); mat convertArrayToMat(float *arr, int vecSize, int rowCount); diff --git a/src/methods/adaboost/adaboost.pl b/src/methods/adaboost/adaboost.pl index a12de42f5ab70abe06ef61d4e85eb6246953a928..bd5df9ae189f00c38a26d978a05840895baa78e0 100644 --- a/src/methods/adaboost/adaboost.pl +++ b/src/methods/adaboost/adaboost.pl @@ -87,7 +87,7 @@ adaboost_classify(TestList, TestRows, PredicList, ProbsList, ZRows) :- convert_float_array_to_list(Y, Ysize, PredicList), convert_float_array_to_2d_list(Z, ZCols, ZRows, ProbsList). -foreign(classify, c, classifyI( +pointer(float_array), +integer, +integer, +foreign(classify, c, classifyI( +pointer(float_array), +integer, +integer, -pointer(float_array), -integer, -pointer(float_array), -integer, -integer)). diff --git a/src/methods/linear_SVM/linear_SVM.cpp b/src/methods/linear_SVM/linear_SVM.cpp index ae2994dc8d5a1fdd7f0720f902ffbf9d925bcea5..e7c31006913ecfad8eefcbdb3d5c1aa03000ca86 100644 --- a/src/methods/linear_SVM/linear_SVM.cpp +++ b/src/methods/linear_SVM/linear_SVM.cpp @@ -18,6 +18,7 @@ using namespace mlpack::svm; // Global Variable of the LinearSVM object so it can be accessed from all functions LinearSVM<> linearSVM; +bool isModelTrained = false; // input: const MatType & data, @@ -39,6 +40,13 @@ void initModelWithTrain(float *dataMatArr, SP_integer dataMatSize, SP_integer da { // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if labels fit the data + if (data.n_cols != labelsArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return; + } + // convert the Prolog array to arma::rowvec arma::Row<size_t> labels = convertArrayToVec(labelsArr, labelsArrSize); @@ -47,10 +55,12 @@ void initModelWithTrain(float *dataMatArr, SP_integer dataMatSize, SP_integer da if (strcmp(optimizer, "lbfgs") == 0) { linearSVM.Train<ens::L_BFGS>(data, labels, numClasses); + isModelTrained = true; } else if (strcmp(optimizer, "psgd") == 0) { linearSVM.Train<ens::ParallelSGD<>>(data, labels, numClasses, ens::ParallelSGD(100, 4)); + isModelTrained = true; } else { @@ -71,6 +81,8 @@ void initModelWithTrain(float *dataMatArr, SP_integer dataMatSize, SP_integer da void initModelNoTrain(SP_integer numClasses, double lambda, double delta, SP_integer fitIntercept) { linearSVM = LinearSVM<>(numClasses, lambda, delta, true); + + isModelTrained = false; } @@ -85,8 +97,20 @@ void classify(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNu float **labelsArr, SP_integer *labelsArrSize, float **scoresMatArr, SP_integer *scoresMatColNum, SP_integer *scoresMatRowNum) { + if (!isModelTrained) + { + raisePrologSystemExeption("The Model is not trained!"); + return; + } + // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if data has the correct feature size + if (data.n_rows != linearSVM.FeatureSize()) + { + raisePrologSystemExeption("The given Datapoints Dimension is != the trained Datapoints Dimension!"); + return; + } // get the ReturnVector arma::Row<size_t> labelsReturnVector; @@ -119,12 +143,23 @@ void classify(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNu // SP_integer classifyPoint(float *pointArr, SP_integer pointArrSize) { + if (!isModelTrained) + { + raisePrologSystemExeption("The Model is not trained!"); + return 0; + } // convert the Prolog array to arma::rowvec - rowvec pointVector = convertArrayToRowvec(pointArr, pointArrSize); + vec pointVector = convertArrayToColvec(pointArr, pointArrSize); + // check if data has the correct feature size + if (pointArrSize != linearSVM.FeatureSize()) + { + raisePrologSystemExeption("The given Datapoint Dimension is != the trained Datapoints Dimension!"); + return 0; + } try { - return linearSVM.Classify<rowvec>(pointVector); + return linearSVM.Classify<vec>(pointVector); } catch(const std::exception& e) { @@ -143,8 +178,26 @@ SP_integer classifyPoint(float *pointArr, SP_integer pointArrSize) // double computeAccuracy(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *labelsArr, SP_integer labelsArrSize) { + if (!isModelTrained) + { + raisePrologSystemExeption("The Model is not trained!"); + return 0.0; + } // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if data has the correct feature size + if (data.n_rows != linearSVM.FeatureSize()) + { + raisePrologSystemExeption("The given Datapoints Dimension is != the trained Datapoints Dimension!"); + return 0.0; + } + // check if labels fit the data + if (data.n_cols != labelsArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return 0.0; + } + // convert the Prolog array to arma::rowvec arma::Row<size_t> labels = convertArrayToVec(labelsArr, labelsArrSize); @@ -174,6 +227,13 @@ double train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum { // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if labels fit the data + if (data.n_cols != labelsArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return 0.0; + } + // convert the Prolog array to arma::rowvec arma::Row<size_t> labels = convertArrayToVec(labelsArr, labelsArrSize); @@ -181,10 +241,12 @@ double train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum { if (strcmp(optimizer, "lbfgs") == 0) { + isModelTrained = true; return linearSVM.Train<ens::L_BFGS>(data, labels, numClasses); } else if (strcmp(optimizer, "psgd") == 0) { + isModelTrained = true; return linearSVM.Train<ens::ParallelSGD<>>(data, labels, numClasses, ens::ParallelSGD(100, 4)); } else diff --git a/src/methods/lmnn/lmnn.cpp b/src/methods/lmnn/lmnn.cpp index b18b332fd429ba6f9f899c5e12ecbabf8dcf67cf..a818ebf2c2f6e6767151bd5bfcb38dd9f6e621b9 100644 --- a/src/methods/lmnn/lmnn.cpp +++ b/src/methods/lmnn/lmnn.cpp @@ -37,7 +37,12 @@ void lmnn(char const *optimizer, { // convert the Prolog arrays to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); - + // check if labels fit the data + if (data.n_cols != labelsArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return; + } // convert the Prolog arrays to arma::rowvec Row< size_t > labelsVector = convertArrayToVec(labelsArr, labelsArrSize); @@ -84,7 +89,7 @@ void lmnn(char const *optimizer, lmnn.LearnDistance(outputReturnMat); } - else if (strcmp(optimizer, "amsgrad") == 0) + else if (strcmp(optimizer, "bbsgd") == 0) { LMNN<LMetric<2>, ens::BBS_BB> lmnn(data, labelsVector, k); lmnn.Regularization() = regularization; @@ -97,7 +102,7 @@ void lmnn(char const *optimizer, lmnn.LearnDistance(outputReturnMat); } - else if (strcmp(optimizer, "amsgrad") == 0) + else if (strcmp(optimizer, "sgd") == 0) { // copied advise from the lmnn.main file // Using SGD is not recommended as the learning matrix can @@ -113,7 +118,7 @@ void lmnn(char const *optimizer, lmnn.LearnDistance(outputReturnMat); } - else if (strcmp(optimizer, "amsgrad") == 0) + else if (strcmp(optimizer, "lbfgs") == 0) { LMNN<LMetric<2>, ens::L_BFGS> lmnn(data, labelsVector, k); lmnn.Regularization() = regularization;