From 89d3a7ced5b9d26ecac7b0a30420e402bc11869c Mon Sep 17 00:00:00 2001
From: Jakhes <dean.schmitz@schmitzbauer.de>
Date: Wed, 26 Oct 2022 22:09:22 +0200
Subject: [PATCH] Adding bayesian_linear_regression tests

---
 .../bayesian_linear_regression.cpp            |  54 ++-
 .../bayesian_linear_regression.pl             |  83 +++-
 .../bayesian_linear_regression_test.pl        | 408 +++++++++++++++---
 3 files changed, 469 insertions(+), 76 deletions(-)

diff --git a/src/methods/bayesian_linear_regression/bayesian_linear_regression.cpp b/src/methods/bayesian_linear_regression/bayesian_linear_regression.cpp
index 0dd644f..96b3b26 100644
--- a/src/methods/bayesian_linear_regression/bayesian_linear_regression.cpp
+++ b/src/methods/bayesian_linear_regression/bayesian_linear_regression.cpp
@@ -16,6 +16,7 @@ using namespace mlpack::regression;
 
 // Global Variable of the BayesianLinearRegression object so it can be accessed from all functions
 BayesianLinearRegression regressor;
+bool isModelTrained = false;
 
 // input:	const bool 		centerData, 
 //			const bool 		scaleData, 
@@ -25,6 +26,7 @@ BayesianLinearRegression regressor;
 void initModel(SP_integer centerData, SP_integer scaleData, SP_integer nIterMax, double tol)
 {
 	regressor = new BayesianLinearRegression((centerData == 1), (scaleData == 1), nIterMax, tol);
+	isModelTrained = false;
 }
 
 // input:
@@ -45,8 +47,13 @@ double beta()
 // output: const arma::colvec &	dataOffset
 void dataOffset(float **dataOffsetArr, SP_integer *dataOffsetArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return;
+	}
 	// create the ReturnVector
-	rowvec dataOffsetReturnVector = regressor.DataOffset();
+	vec dataOffsetReturnVector = regressor.DataOffset();
 	
 	// return the Vector
 	returnVectorInformation(dataOffsetReturnVector, dataOffsetArr, dataOffsetArrSize);
@@ -56,8 +63,13 @@ void dataOffset(float **dataOffsetArr, SP_integer *dataOffsetArrSize)
 // output: const arma::colvec &	dataScale
 void dataScale(float **dataScaleArr, SP_integer *dataScaleArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return;
+	}
 	// create the ReturnVector
-	rowvec dataScaleReturnVector = regressor.DataScale();
+	vec dataScaleReturnVector = regressor.DataScale();
 	
 	// return the Vector
 	returnVectorInformation(dataScaleReturnVector, dataScaleArr, dataScaleArrSize);
@@ -67,8 +79,13 @@ void dataScale(float **dataScaleArr, SP_integer *dataScaleArrSize)
 // output: const arma::colvec &	omega
 void omega(float **omegaArr, SP_integer *omegaArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return;
+	}
 	// create the ReturnVector
-	rowvec omegaReturnVector = regressor.Omega();
+	vec omegaReturnVector = regressor.Omega();
 	
 	// return the Vector
 	returnVectorInformation(omegaReturnVector, omegaArr, omegaArrSize);
@@ -80,6 +97,11 @@ void omega(float **omegaArr, SP_integer *omegaArrSize)
 void predict(float *pointsMatArr, SP_integer pointsMatSize, SP_integer pointsMatRowNum, 
 				float **predictionsArr, SP_integer *predictionsArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return;
+	}
 	// convert the Prolog array to arma::mat
 	mat points = convertArrayToMat(pointsMatArr, pointsMatSize, pointsMatRowNum);
 	
@@ -98,7 +120,7 @@ void predict(float *pointsMatArr, SP_integer pointsMatSize, SP_integer pointsMat
 		return;
 	}
 
-
+	cout << points << endl;
 	// return the Vector
 	returnVectorInformation(predictionsReturnVector, predictionsArr, predictionsArrSize);
 }
@@ -111,6 +133,11 @@ void predictWithStd(float *pointsMatArr, SP_integer pointsMatSize, SP_integer po
 					float **predictionsArr, SP_integer *predictionsArrSize, 
 					float **stdArr, SP_integer *stdArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return;
+	}
 	// convert the Prolog array to arma::mat
 	mat points = convertArrayToMat(pointsMatArr, pointsMatSize, pointsMatRowNum);
 	
@@ -141,6 +168,11 @@ void predictWithStd(float *pointsMatArr, SP_integer pointsMatSize, SP_integer po
 // output: double
 double responsesOffset()
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return 0.0;
+	}
 	return regressor.ResponsesOffset();
 }
 
@@ -150,6 +182,11 @@ double responsesOffset()
 double rmse(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, 
 			float *responsesArr, SP_integer responsesArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return 0.0;
+	}
 	// convert the Prolog array to arma::mat
 	mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
 	
@@ -177,7 +214,7 @@ void train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum,
 {
 	if(dataMatSize / dataMatRowNum != responsesArrSize)
 	{
-		cout << "Target dim doesnt fit to the Data dim" << endl;
+		raisePrologSystemExeption("Target dim doesnt fit to the Data dim");
 		return;
 	}
 	// convert the Prolog array to arma::mat
@@ -197,12 +234,19 @@ void train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum,
 		raisePrologSystemExeption(e.what());
 		return;
 	}
+	isModelTrained = true;
 }
 
 // input:
 // output: double
 double variance()
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not Trained!");
+		return 0.0;
+	}
+	
 	return regressor.Variance();
 }
 
diff --git a/src/methods/bayesian_linear_regression/bayesian_linear_regression.pl b/src/methods/bayesian_linear_regression/bayesian_linear_regression.pl
index ca2f5db..410a4dd 100644
--- a/src/methods/bayesian_linear_regression/bayesian_linear_regression.pl
+++ b/src/methods/bayesian_linear_regression/bayesian_linear_regression.pl
@@ -2,13 +2,13 @@
 :- module(bayesian_linear_regression, [ initModel/4, 
                                         alpha/1, 
                                         beta/1, 
-                                        dataOffset/2, 
-                                        dataScale/2, 
-                                        omega/2, 
-                                        predict/5, 
-                                        predictWithStd/7, 
-                                        rmse/6, 
-                                        train/5, 
+                                        dataOffset/1, 
+                                        dataScale/1, 
+                                        omega/1, 
+                                        predict/3, 
+                                        predictWithStd/4, 
+                                        rmse/4, 
+                                        train/3, 
                                         variance/1]).
 
 :- load_files(library(str_decl),
@@ -39,7 +39,12 @@
 %%              Initiates the Model so now train/5 can be called.
 %%              Before predict/5 or predictWitStd/7 can be used train/5 has to be called before
 %%
-foreign(initModel,  c, initModel(       +integer, 
+initModel(CenterData, ScaleData, NIterMax, Tol) :-
+        NIterMax >= 0,
+        Tol > 0,
+        initModelI(CenterData, ScaleData, NIterMax, Tol).
+
+foreign(initModel,  c, initModelI(      +integer, 
                                         +integer, 
                                         +integer, +float32)).
 
@@ -53,7 +58,10 @@ foreign(initModel,  c, initModel(       +integer,
 %%              Get the precision (or inverse variance) of the gaussian prior.
 %%              train/5 should be called before.
 %%
-foreign(alpha,  c, alpha([-float32])).
+alpha(Alpha) :-
+        alphaI(Alpha).
+
+foreign(alpha,  c, alphaI([-float32])).
 
 
 %% --Input--
@@ -65,7 +73,10 @@ foreign(alpha,  c, alpha([-float32])).
 %%              Get the precision (or inverse variance) beta of the model.
 %%              train/5 should be called before.
 %%
-foreign(beta,  c, beta([-float32])).
+beta(Beta) :-
+        betaI(Beta).
+
+foreign(beta,  c, betaI([-float32])).
 
 
 %% --Input--
@@ -76,7 +87,11 @@ foreign(beta,  c, beta([-float32])).
 %% --Description--
 %%              Get the mean vector computed on the features over the training points.
 %%
-foreign(dataOffset, c, dataOffset(-pointer(float_array), -integer)).
+dataOffset(ResponsesList) :-
+        dataOffsetI(X, Xsize),
+        convert_float_array_to_list(X, Xsize, ResponsesList).
+
+foreign(dataOffset, c, dataOffsetI(-pointer(float_array), -integer)).
 
 
 %% --Input--
@@ -87,7 +102,11 @@ foreign(dataOffset, c, dataOffset(-pointer(float_array), -integer)).
 %% --Description--
 %%              Get the vector of standard deviations computed on the features over the training points.
 %%
-foreign(dataScale, c, dataScale(-pointer(float_array), -integer)).
+dataScale(DataOffsetList) :-
+        dataScaleI(X, Xsize),
+        convert_float_array_to_list(X, Xsize, DataOffsetList).
+
+foreign(dataScale, c, dataScaleI(-pointer(float_array), -integer)).
 
 
 %% --Input--
@@ -98,7 +117,11 @@ foreign(dataScale, c, dataScale(-pointer(float_array), -integer)).
 %% --Description--
 %%              Get the solution vector.
 %%
-foreign(omega, c, omega(-pointer(float_array), -integer)).
+omega(OmegaList) :-
+        omegaI(X, Xsize),
+        convert_float_array_to_list(X, Xsize, OmegaList).
+
+foreign(omega, c, omegaI(-pointer(float_array), -integer)).
 
 
 %% --Input--
@@ -110,7 +133,12 @@ foreign(omega, c, omega(-pointer(float_array), -integer)).
 %% --Description--
 %%              Predict yi for each data point in the given data matrix using the currently-trained Bayesian Ridge model.
 %%
-foreign(predict,  c, predict(   +pointer(float_array), +integer, +integer, 
+predict(PointsList, PointsRows, PredictionsList) :-
+        convert_list_to_float_array(PointsList, PointsRows, array(Xsize, Xrows, X)),
+        predictI(X, Xsize, Xrows, Y, Ysize),
+        convert_float_array_to_list(Y, Ysize, PredictionsList).
+
+foreign(predict,  c, predictI(  +pointer(float_array), +integer, +integer, 
                                 -pointer(float_array), -integer)).
 
 
@@ -124,7 +152,13 @@ foreign(predict,  c, predict(   +pointer(float_array), +integer, +integer,
 %% --Description--
 %%              Predict yi and the standard deviation of the predictive posterior distribution for each data point in the given data matrix, using the currently-trained Bayesian Ridge estimator.
 %%
-foreign(predictWithStd,  c, predictWithStd(     +pointer(float_array), +integer, +integer, 
+predictWithStd(PointsList, PointsRows, PredictionsList, STDList) :-
+        convert_list_to_float_array(PointsList, PointsRows, array(Xsize, Xrows, X)),
+        predictWithStdI(X, Xsize, Xrows, Y, Ysize, Z, Zsize),
+        convert_float_array_to_list(Y, Ysize, PredictionsList),
+        convert_float_array_to_list(Z, Zsize, STDList).
+
+foreign(predictWithStd,  c, predictWithStdI(    +pointer(float_array), +integer, +integer, 
                                                 -pointer(float_array), -integer, 
                                                 -pointer(float_array), -integer)).
 
@@ -139,7 +173,12 @@ foreign(predictWithStd,  c, predictWithStd(     +pointer(float_array), +integer,
 %% --Description--
 %%              Compute the Root Mean Square Error between the predictions returned by the model and the true responses.
 %%
-foreign(rmse,  c, rmse( +pointer(float_array), +integer, +integer, 
+rmse(DataList, DataRows, ResponsesList, RMSE) :-
+        convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrows, X)),
+        convert_list_to_float_array(ResponsesList, array(Ysize, Y)),
+        rmseI(X, Xsize, Xrows, Y, Ysize, RMSE).
+
+foreign(rmse,  c, rmseI(+pointer(float_array), +integer, +integer, 
                         +pointer(float_array), +integer, 
                         [-float32])).
 
@@ -154,7 +193,12 @@ foreign(rmse,  c, rmse( +pointer(float_array), +integer, +integer,
 %%              Run BayesianLinearRegression.
 %%              The input matrix (like all mlpack matrices) should be column-major each column is an observation and each row is a dimension.
 %%
-foreign(train,  c, train(       +pointer(float_array), +integer, +integer, 
+train(DataList, DataRows, ResponsesList) :-
+        convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrows, X)),
+        convert_list_to_float_array(ResponsesList, array(Ysize, Y)),
+        trainI(X, Xsize, Xrows, Y, Ysize).
+
+foreign(train,  c, trainI(      +pointer(float_array), +integer, +integer, 
                                 +pointer(float_array), +integer)).
 
 
@@ -167,7 +211,10 @@ foreign(train,  c, train(       +pointer(float_array), +integer, +integer,
 %%              Get the estimate variance.
 %%              train/5 should be called before.
 %%
-foreign(variance,  c, variance([-float32])).
+variance(Variance) :-
+        varianceI(Variance).
+
+foreign(variance,  c, varianceI([-float32])).
 
 %% Defines what functions should be connected from main.cpp
 foreign_resource(bayesian_linear_regression, [  initModel, 
diff --git a/src/methods/bayesian_linear_regression/bayesian_linear_regression_test.pl b/src/methods/bayesian_linear_regression/bayesian_linear_regression_test.pl
index 264118c..62eb00c 100644
--- a/src/methods/bayesian_linear_regression/bayesian_linear_regression_test.pl
+++ b/src/methods/bayesian_linear_regression/bayesian_linear_regression_test.pl
@@ -8,88 +8,390 @@
 :- use_module('../../helper_files/helper.pl').
 
 
-
 reset_Model :-
         initModel(1,0,50,0.0001).
 
-:- begin_tests(lists).
 
-%% alpha tests
-test(alpha_std_init) :-
-        reset_Model,
-        alpha(0).
-test(alpha_wrong_input, fail) :-
+%%
+%% TESTING predicate initModel/4
+%%
+:- begin_tests(initModel).      
+
+%% Failure Tests
+                                            
+test(bay_lin_reg_InitModel_Negative_NIterMax, fail) :-
+        initModel(0,0,-50,0.0001).
+
+test(bay_lin_reg_InitModel_Negative_Tolerance, fail) :-
+        initModel(0,0,50,-0.0001).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_InitModel_Default_Inputs) :-
+        initModel(1,0,50,0.0001).
+
+test(bay_lin_reg_InitModel_Alternative_Inputs) :-
+        initModel(1,1,0,0.0071).
+
+:- end_tests(initModel).
+
+
+
+%%
+%% TESTING predicate alpha/1
+%%
+:- begin_tests(alpha).      
+
+%% Failure Tests
+
+test(bay_lin_reg_Alpha_Wrong_Input, fail) :-
         reset_Model,
         alpha(1).
-test(alpha_after_train, [true(A =:= -9223372036854775808)]) :-
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_Alpha_Std_init, [true(Alpha =:= 0.0)]) :-
         reset_Model,
-        convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize),
-        alpha(A).
+        alpha(Alpha).
 
-%% train tests
-test(correct_train) :-
+test(bay_lin_reg_Alpha_After_Train, [true(Alpha =:= 0.12986500952614138)]) :-
         reset_Model,
-        convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize).
-test(false_train, fail) :-
+        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]),
+        alpha(Alpha).
+        
+:- end_tests(alpha).
+
+
+
+%%
+%% TESTING predicate beta/1
+%%
+:- begin_tests(beta).      
+
+%% Failure Tests
+
+test(bay_lin_reg_Beta_Wrong_Input, fail) :-
         reset_Model,
-        convert_list_to_float_array([],3, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize).
-test(false_train2, fail) :-
+        beta(1).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_Beta_Std_init, [true(Beta =:= 0.0)]) :-
         reset_Model,
-        convert_list_to_float_array([],0, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize).
-test(false_train3, fail) :-
+        beta(Beta).
+
+test(bay_lin_reg_Beta_After_Train, [true(Beta =:= 2.317989668988762E+31)]) :-
         reset_Model,
-        convert_list_to_float_array([1,2],0, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize).
-test(false_train3, fail) :-
+        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]),
+        beta(Beta).
+        
+:- end_tests(beta).
+
+
+
+%%
+%% TESTING predicate dataOffset/1
+%%
+:- begin_tests(dataOffset).      
+
+%% Failure Tests
+                                            
+test(bay_lin_reg_DataOffset_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
         reset_Model,
-        convert_list_to_float_array([1,2,44,3],3, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize).
-test(false_train4) :-
+        dataOffset(_).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_DataOffset_DirektInput) :-
         reset_Model,
-        convert_list_to_float_array([1,2,44,3],2, array(Xsize, Xrownum, X)),
-        convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
-        train(X,Xsize, Xrownum,Y, Ysize).
-:- end_tests(lists).
+        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]),
+        dataOffset(ResponsesOffsetList),
+        print('\nResponsesOffset: '),
+        print(ResponsesOffsetList).
+
+test(bay_lin_reg_DataOffset_CSV_Input) :-
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,10, Data),
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]),
+        dataOffset(ResponsesOffsetList),
+        print('\nResponsesOffset: '),
+        print(ResponsesOffsetList).
+        
+:- end_tests(dataOffset).
+
+
 
 %%
-%% TESTING predicate predicate/10
+%% TESTING predicate dataScale/1
 %%
-:- begin_tests(predicate).      
+:- begin_tests(dataScale).      
 
 %% Failure Tests
                                             
-test(testDescription, [error(domain_error('expectation' , culprit), _)]) :-
-        reset_Model_No_Train(perceptron),
-        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,0,0,0], 2, culprit, 50, 0.0001, _).
+test(bay_lin_reg_DataScale_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
+        reset_Model,
+        dataScale(_).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_DataScale_DirektInput) :-
+        reset_Model,
+        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]),
+        dataScale(DataOffsetList),
+        print('\nDataOffset: '),
+        print(DataOffsetList).
 
-test(testDescription2, [error(_,system_error('The values of the Label have to start at 0 and be >= 0 and < the given numClass!'))]) :-
-        reset_Model_No_Train(perceptron),
-        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,2], 2, perceptron, 50, 0.0001, _).
+test(bay_lin_reg_DataScale_CSV_Input) :-
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,10, Data),
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]),
+        dataScale(DataOffsetList),
+        print('\nDataOffset: '),
+        print(DataOffsetList).
+        
+:- end_tests(dataScale).
+
+
+
+%%
+%% TESTING predicate omega/1
+%%
+:- begin_tests(omega).      
+
+%% Failure Tests
+                                            
+test(bay_lin_reg_Omega_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
+        reset_Model,
+        omega(_).
         
 
 %% Successful Tests
 
-test(testDescription3, [true(Error =:= 1)]) :-
-        reset_Model_No_Train(perceptron),
-        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,0,0,0], 2, perceptron, 50, 0.0001, Error).
+test(bay_lin_reg_Omega_DirektInput) :-
+        reset_Model,
+        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]),
+        omega(OmegaList),
+        print('\nOmega: '),
+        print(OmegaList).
 
-test(testDescription4, [true(Error =:= 0.9797958971132711)]) :-
-        reset_Model_No_Train(perceptron),
+test(bay_lin_reg_Omega_CSV_Input) :-
         open('src/data_csv/iris2.csv', read, File),
         take_csv_row(File, skipFirstRow,10, Data),
-        train(Data, 4, [0,1,0,1,1,0,1,1,1,0], 2, perceptron, 50, 0.0001, Error).
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]),
+        omega(OmegaList),
+        print('\nOmega: '),
+        print(OmegaList).
+        
+:- end_tests(omega).
+
+
+
+%%
+%% TESTING predicate predict/3
+%%
+:- begin_tests(predict).      
+
+%% Failure Tests
+                                            
+test(bay_lin_reg_Predict_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
+        reset_Model,
+        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], 3, _).
+
+test(bay_lin_reg_Predict_Different_Dims_Than_Trained, [error(_,system_error('each_col(): incompatible size; expected 4x1, got 3x1'))]) :-
+        reset_Model,
+        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]),
+        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, _).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_Predict_Direct_Input) :-
+        reset_Model,
+        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]),
+        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], 3, PredictionsList),
+        print('\nPredictions: '),
+        print(PredictionsList).
+
+test(bay_lin_reg_Predict_CSV_Input) :-
+        reset_Model,
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,10, Data),
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]),
+        predict([3, 2, 0, 5, 1, 4, 1, 0, 4, 3, 3, 5, 0, 5, 5, 2, 5, 5, 0, 2], 4, PredictionsList),
+        print('\nPredictions: '),
+        print(PredictionsList).
+        
+:- end_tests(predict).
+
+
+
+%%
+%% TESTING predicate predictWithStd/3
+%%
+:- begin_tests(predictWithStd).      
+
+%% Failure Tests
+                                            
+test(bay_lin_reg_PredictWithStd_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
+        reset_Model,
+        predictWithStd([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, _, _).
+
+test(bay_lin_reg_PredictWithStd_Different_Dims_Than_Trained, [error(_,system_error('each_col(): incompatible size; expected 4x1, got 3x1'))]) :-
+        reset_Model,
+        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]),
+        predictWithStd([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, _, _).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_PredictWithStd_Direct_Input) :-
+        reset_Model,
+        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]),
+        predictWithStd([3, 2, 0, 5, 1, 4, 0, 0, 4, 3, 3, 5, 0, 5, 5], 3, PredictionsList, STDList),
+        print('\nPredictions: '),
+        print(PredictionsList),
+        print('\nSTD: '),
+        print(STDList).
+
+test(bay_lin_reg_PredictWithStd_CSV_Input) :-
+        reset_Model,
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,10, Data),
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]),
+        predictWithStd([3, 2, 0, 5, 1, 4, 1, 0, 4, 3, 3, 5, 0, 5, 5, 2, 5, 5, 0, 2], 4, PredictionsList, STDList),
+        print('\nPredictions: '),
+        print(PredictionsList),
+        print('\nSTD: '),
+        print(STDList).
+        
+:- end_tests(predictWithStd).
+
+
+
+%%
+%% TESTING predicate rmse/4
+%%
+:- begin_tests(rmse).      
+
+%% Failure Tests
+                                            
+test(bay_lin_reg_RMSE_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
+        reset_Model,
+        rmse([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,0,0,0], _).
+
+test(bay_lin_reg_RMSE_Too_Small_Label_Dims, [error(_,system_error('subtraction: incompatible matrix dimensions: 1x2 and 1x4'))]) :-
+        reset_Model,
+        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]),
+        rmse([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(bay_lin_reg_RMSE_Too_Large_Label_Dims, [error(_,system_error('subtraction: incompatible matrix dimensions: 1x6 and 1x4'))]) :-
+        reset_Model,
+        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]),
+        rmse([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,0,1,0,0,0], _).
+
+%% doesnt cause an exception
+test(bay_lin_reg_RMSE_Wrong_Label_Value) :-
+        reset_Model,
+        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]),
+        rmse([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,5,0,-1], _).
+        
+test(bay_lin_reg_RMSE_Wrong_Data_Dims, [error(_,system_error('each_col(): incompatible size; expected 4x1, got 3x1'))]) :-
+        reset_Model,
+        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]),
+        rmse([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, [0,1,0,1], _).
+
+test(bay_lin_reg_RMSE_Wrong_Amount_Off_DataPoints, [error(_,system_error('subtraction: incompatible matrix dimensions: 1x10 and 1x5'))]) :-
+        reset_Model,
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,10, Data),
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]),
+        rmse([3, 2, 0, 5, 1, 4, 1, 0, 4, 3, 3, 5, 0, 5, 5, 2, 5, 5, 0, 2], 4, [0,1,0,1,1,0,1,1,1,0], _).
+
+
+%% Successful Tests
+
+test(bay_lin_reg_RMSE_Direct_Input) :-
+        reset_Model,
+        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]),
+        rmse([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], RMSE),
+        print('\nRMSE: '),
+        print(RMSE).
+
+test(bay_lin_reg_RMSE_CSV_Input) :-
+        reset_Model,
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,5, Data),
+        train(Data, 4, [0,1,0,1,1]),
+        rmse([3, 2, 0, 5, 1, 4, 1, 0, 4, 3, 3, 5, 0, 5, 5, 2, 5, 5, 0, 2], 4, [0,1,0,1,1], RMSE),
+        print('\nRMSE: '),
+        print(RMSE).
+        
+:- end_tests(rmse).
+
+
+
+%%
+%% TESTING predicate train/3
+%%
+:- begin_tests(train).      
+
+%% Failure Tests
+
+test(bay_lin_reg_Train_Too_Small_Label_Dims, [error(_,system_error('Target dim doesnt fit to the Data dim'))]) :-
+        reset_Model,
+        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]).
+
+test(bay_lin_reg_Train_Too_Large_Label_Dims, [error(_,system_error('Target dim doesnt fit to the Data dim'))]) :-
+        reset_Model,
+        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,0,1,0,0,0]).
+
+%% doesnt cause an Exception
+test(bay_lin_reg_Train_Wrong_Label_Value) :-
+        reset_Model,
+        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,5,0,-1]).
+
+%% Successful Tests
+
+test(bay_lin_reg_Train_Direct_Input) :-
+        reset_Model,
+        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]).
+
+test(bay_lin_reg_Train_CSV_Input) :-
+        reset_Model,
+        open('src/data_csv/iris2.csv', read, File),
+        take_csv_row(File, skipFirstRow,10, Data),
+        train(Data, 4, [0,1,0,1,1,0,1,1,1,0]).
+        
+:- end_tests(train).
+
+
+
+%%
+%% TESTING predicate variance/1
+%%
+:- begin_tests(variance).      
+
+%% Failure Tests
+
+test(bay_lin_reg_Variance_Before_Train, [error(_,system_error('The Model is not Trained!'))]) :-
+        reset_Model,
+        variance(_).
+        
+
+%% Successful Tests
+
+test(bay_lin_reg_Variance_After_Train, [true(Variance =:= 4.3140830754274083E-32)]) :-
+        reset_Model,
+        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]),
+        variance(Variance).
+        
+:- end_tests(variance).
 
-:- end_tests(predicate).
 
 run_bayesian_linear_regression_tests :-
         run_tests.
-- 
GitLab