diff --git a/src/methods/linear_regression/linear_regression.cpp b/src/methods/linear_regression/linear_regression.cpp index e71c0aa021478f52ce8aaf0a4b7d8ec376d9be7e..1042df5bb00751b6753625d6078a59476eafde5d 100644 --- a/src/methods/linear_regression/linear_regression.cpp +++ b/src/methods/linear_regression/linear_regression.cpp @@ -16,6 +16,7 @@ using namespace mlpack::regression; // Global Variable of the LinearRegression object so it can be accessed from all functions LinearRegression regressor; +int trainingDimension = 0; // input: const arma::mat &data, // const arma::rowvec &responses, @@ -27,19 +28,29 @@ void initModel(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowN double lambda, SP_integer bool_intercept) { - if(dataMatSize / dataMatRowNum != responsesArrSize) - { - cout << "Target dim doesnt fit to the Data dim" << endl; - return; - } // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if labels and weights fit the data + if (data.n_cols != responsesArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return; + } // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); - regressor = LinearRegression(data, responsesVector, lambda, bool_intercept); + try + { + regressor = LinearRegression(data, responsesVector, lambda, bool_intercept); + } + catch(const std::exception& e) + { + raisePrologSystemExeption(e.what()); + return; + } + trainingDimension = data.n_rows; } // input: const arma::mat &data, @@ -54,19 +65,35 @@ void initModelWithWeights(float *dataMatArr, SP_integer dataMatSize, SP_integer double lambda, SP_integer bool_intercept) { - if(dataMatSize / dataMatRowNum != responsesArrSize) - { - cout << "Target dim doesnt fit to the Data dim" << endl; - return; - } // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if labels and weights fit the data + if (data.n_cols != responsesArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return; + } + if (data.n_cols != weightsArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of weights!"); + return; + } + // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); rowvec weightsVector = convertArrayToRowvec(weightsArr, weightsArrSize); - regressor = LinearRegression(data, responsesVector, weightsVector, lambda, bool_intercept); + try + { + regressor = LinearRegression(data, responsesVector, weightsVector, lambda, bool_intercept); + } + catch(const std::exception& e) + { + raisePrologSystemExeption(e.what()); + return; + } + trainingDimension = data.n_rows; } // input: const arma::mat &points, @@ -75,19 +102,29 @@ void initModelWithWeights(float *dataMatArr, SP_integer dataMatSize, SP_integer double computeError(float *pointsMatArr, SP_integer pointsMatSize, SP_integer pointsMatRowNum, float *responsesArr, SP_integer responsesArrSize) { - if(pointsMatSize / pointsMatRowNum != responsesArrSize) - { - cout << "Target dim doesnt fit to the Data dim" << endl; - return 0; - } // convert the Prolog array to arma::mat mat points = convertArrayToMat(pointsMatArr, pointsMatSize, pointsMatRowNum); + // check if labels fit the data + if (points.n_cols != responsesArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return 0.0; + } + // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); // run the model function - return regressor.ComputeError(points, responsesVector); + try + { + return regressor.ComputeError(points, responsesVector); + } + catch(const std::exception& e) + { + raisePrologSystemExeption(e.what()); + return 0.0; + } } // input: @@ -95,7 +132,7 @@ double computeError(float *pointsMatArr, SP_integer pointsMatSize, SP_integer po void parameters(float **bArr, SP_integer *bArrSize) { // create the ReturnVector - rowvec bReturnVector = regressor.Parameters(); + vec bReturnVector = regressor.Parameters(); // return the Vector returnVectorInformation(bReturnVector, bArr, bArrSize); @@ -106,7 +143,7 @@ void parameters(float **bArr, SP_integer *bArrSize) void modifyParameters(float *newBArr, SP_integer newBArrSize) { // convert the Prolog array to arma::rowvec - vec newBVector = convertArrayToRowvec(newBArr, newBArrSize); + vec newBVector = convertArrayToColvec(newBArr, newBArrSize); // get parameter b vector ref @@ -124,13 +161,27 @@ void predict(float *pointsMatArr, SP_integer pointsMatSize, SP_integer pointsMat { // convert the Prolog array to arma::mat mat points = convertArrayToMat(pointsMatArr, pointsMatSize, pointsMatRowNum); + if (points.n_rows != trainingDimension) + { + raisePrologSystemExeption("The given Points have a diffrent Dimension than the trained Model!"); + return; + } + // create the ReturnVector rowvec predicReturnVector; // run the predict function on the model - regressor.Predict(points, predicReturnVector); + try + { + regressor.Predict(points, predicReturnVector); + } + catch(const std::exception& e) + { + raisePrologSystemExeption(e.what()); + return; + } // return the Vector @@ -145,19 +196,30 @@ double train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum float *responsesArr, SP_integer responsesArrSize, SP_integer bool_intercept) { - if(dataMatSize / dataMatRowNum != responsesArrSize) - { - cout << "Target dim doesnt fit to the Data dim" << endl; - return 0; - } // convert the Prolog array to arma::mat - mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if labels fit the data + if (data.n_cols != responsesArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return 0.0; + } + // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); // run the model train function - return regressor.Train(data, responsesVector, (bool_intercept == 1)); + try + { + return regressor.Train(data, responsesVector, (bool_intercept == 1)); + } + catch(const std::exception& e) + { + raisePrologSystemExeption(e.what()); + return 0.0; + } + trainingDimension = data.n_rows; } // input: const arma::mat &data, @@ -170,17 +232,33 @@ double trainWithWeights(float *dataMatArr, SP_integer dataMatSize, SP_integer da float *weightsArr, SP_integer weightsArrSize, SP_integer bool_intercept) { - if(dataMatSize / dataMatRowNum != responsesArrSize) - { - cout << "Target dim doesnt fit to the Data dim" << endl; - return 0; - } // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + // check if labels and weights fit the data + if (data.n_cols != responsesArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of labels!"); + return 0.0; + } + if (data.n_cols != weightsArrSize) + { + raisePrologSystemExeption("The number of data points does not match the number of weights!"); + return 0.0; + } + // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); rowvec weightsVector = convertArrayToRowvec(weightsArr, weightsArrSize); // run the model train function - return regressor.Train(data, responsesVector, weightsVector, (bool_intercept == 1)); + try + { + return regressor.Train(data, responsesVector, weightsVector, (bool_intercept == 1)); + } + catch(const std::exception& e) + { + raisePrologSystemExeption(e.what()); + return 0.0; + } + trainingDimension = data.n_rows; } diff --git a/src/methods/linear_regression/linear_regression_test.pl b/src/methods/linear_regression/linear_regression_test.pl index f3b920ccda332eadbfaec09e83e70f268e4f36fa..507c2546697122a8889f6472968ce7b9dfc37a76 100644 --- a/src/methods/linear_regression/linear_regression_test.pl +++ b/src/methods/linear_regression/linear_regression_test.pl @@ -21,13 +21,14 @@ reset_Model_WithWeights :- %% Failure Tests -test(linear_regression_InitModel_Too_Few_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_InitModel_Too_Few_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_initModel([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], 0.0, 1). -test(linear_regression_InitModel_Too_Many_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_InitModel_Too_Many_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_initModel([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], 0.0, 1). -test(linear_regression_InitModel_Too_Many_Labelclasses, [error(_, system_error('Error'))]) :- +%% doesnt cause error +test(linear_regression_InitModel_Too_Many_Labelclasses) :- linear_regression_initModel([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], 0.0, 1). @@ -52,20 +53,21 @@ test(linear_regression_InitModel_CSV_Input) :- %% Failure Tests -test(linear_regression_InitModelWithWeights_Too_Few_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_InitModelWithWeights_Too_Few_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_initModelWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], [0.2,0.1,0.2,0.5], 0.0, 1). -test(linear_regression_InitModelWithWeights_Too_Many_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_InitModelWithWeights_Too_Many_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_initModelWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], [0.2,0.1,0.2,0.5], 0.0, 1). -test(linear_regression_InitModelWithWeights_Too_Many_Labelclasses, [error(_, system_error('Error'))]) :- +%% doesnt cause error +test(linear_regression_InitModelWithWeights_Too_Many_Labelclasses) :- linear_regression_initModelWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], [0.2,0.1,0.2,0.5], 0.0, 1). -test(linear_regression_InitModelWithWeights_Too_Few_Weights, [error(_, system_error('Error'))]) :- +test(linear_regression_InitModelWithWeights_Too_Few_Weights, [error(_, system_error('The number of data points does not match the number of weights!'))]) :- linear_regression_initModelWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], [0.2,0.5], 0.0, 1). -test(linear_regression_InitModelWithWeights_Too_Many_Weights, [error(_, system_error('Error'))]) :- +test(linear_regression_InitModelWithWeights_Too_Many_Weights, [error(_, system_error('The number of data points does not match the number of weights!'))]) :- linear_regression_initModelWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], [0.2,0.1,0.2,0.1,0.2,0.5], 0.0, 1). @@ -90,15 +92,16 @@ test(linear_regression_InitModelWithWeights_CSV_Input) :- %% Failure Tests -test(linear_regression_ComputeError_Too_Few_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_ComputeError_Too_Few_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- reset_Model, linear_regression_computeError([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], _). -test(linear_regression_ComputeError_Too_Many_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_ComputeError_Too_Many_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- reset_Model, linear_regression_computeError([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], _). -test(linear_regression_ComputeError_Too_Many_Labelclasses, [error(_, system_error('Error'))]) :- +%% doesnt cause error +test(linear_regression_ComputeError_Too_Many_Labelclasses) :- reset_Model, linear_regression_computeError([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], _). @@ -143,21 +146,21 @@ test(linear_regression_Parameters_Normal_Use) :- %% Failure Tests -test(linear_regression_ModifyParameters_Too_Few_Parameters, [error(_, system_error('Error'))]) :- +test(linear_regression_ModifyParameters_Too_Few_Parameters) :- reset_Model, linear_regression_modifyParameters([3,4]), linear_regression_parameters(Parameters), print('\nParameters: '), print(Parameters). -test(linear_regression_ModifyParameters_Too_Many_Parameters, [error(_, system_error('Error'))]) :- +test(linear_regression_ModifyParameters_Too_Many_Parameters) :- reset_Model, linear_regression_modifyParameters([1,2,1,2,3,4]), linear_regression_parameters(Parameters), print('\nParameters: '), print(Parameters). -test(linear_regression_ModifyParameters_Bad_Parameter_Value, [error(_, system_error('Error'))]) :- +test(linear_regression_ModifyParameters_Bad_Parameter_Value) :- reset_Model, linear_regression_modifyParameters([1,2,-3,4]), linear_regression_parameters(Parameters), @@ -185,7 +188,7 @@ test(linear_regression_ModifyParameters_Normal_Use) :- %% Failure Tests -test(linear_regression_Predict_Diffrent_Dims_Than_Trained) :- +test(linear_regression_Predict_Diffrent_Dims_Than_Trained, [error(_, system_error('The given Points have a diffrent Dimension than the trained Model!'))]) :- reset_Model, linear_regression_predict([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 4, _). @@ -215,13 +218,14 @@ test(linear_regression_Predict_Normal_Use) :- %% Failure Tests -test(linear_regression_Train_Too_Few_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_Train_Too_Few_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], 1, _). -test(linear_regression_Train_Too_Many_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_Train_Too_Many_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], 1, _). -test(linear_regression_Train_Too_Many_Labelclasses, [error(_, system_error('Error'))]) :- +%% doesnt cause error +test(linear_regression_Train_Too_Many_Labelclasses) :- linear_regression_train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], 1, _). @@ -250,20 +254,21 @@ test(linear_regression_Train_CSV_Input) :- %% Failure Tests -test(linear_regression_TrainWithWeights_Too_Few_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_TrainWithWeights_Too_Few_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_trainWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], [0.2,0.1,0.2,0.5], 1 ,_). -test(linear_regression_TrainWithWeights_Too_Many_Labels, [error(_, system_error('Error'))]) :- +test(linear_regression_TrainWithWeights_Too_Many_Labels, [error(_, system_error('The number of data points does not match the number of labels!'))]) :- linear_regression_trainWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], [0.2,0.1,0.2,0.5], 1 ,_). -test(linear_regression_TrainWithWeights_Too_Many_Labelclasses, [error(_, system_error('Error'))]) :- +%% doesnt cause error +test(linear_regression_TrainWithWeights_Too_Many_Labelclasses) :- linear_regression_trainWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], [0.2,0.1,0.2,0.5], 1 ,_). -test(linear_regression_TrainWithWeights_Too_Few_Weights, [error(_, system_error('Error'))]) :- +test(linear_regression_TrainWithWeights_Too_Few_Weights, [error(_, system_error('The number of data points does not match the number of weights!'))]) :- linear_regression_trainWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], [0.2,0.5], 1 ,_). -test(linear_regression_TrainWithWeights_Too_Many_Weights, [error(_, system_error('Error'))]) :- +test(linear_regression_TrainWithWeights_Too_Many_Weights, [error(_, system_error('The number of data points does not match the number of weights!'))]) :- linear_regression_trainWithWeights([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], [0.2,0.1,0.2,0.1,0.2,0.5], 1 ,_).