From a42fdf0deea31d3921800d2331de05d6a095aa65 Mon Sep 17 00:00:00 2001
From: Jakhes <dean.schmitz@schmitzbauer.de>
Date: Sat, 12 Nov 2022 00:14:32 +0100
Subject: [PATCH] Updating lars tests

---
 src/methods/lars/lars.cpp     | 120 +++++++++++++++++++++++++++++-----
 src/methods/lars/lars_test.pl |  65 +++++++++---------
 2 files changed, 135 insertions(+), 50 deletions(-)

diff --git a/src/methods/lars/lars.cpp b/src/methods/lars/lars.cpp
index ee00d50..b16291e 100644
--- a/src/methods/lars/lars.cpp
+++ b/src/methods/lars/lars.cpp
@@ -17,6 +17,7 @@ using namespace mlpack::regression;
 
 // Global Variable of the Lars regressor object so it can be accessed from all functions
 LARS regressor;
+bool isModelTrained = false;
 
 // input:	const bool 		useCholesky, 
 //			const double 	lambda1, 
@@ -27,6 +28,7 @@ void initModelNoDataNoGram(SP_integer useCholesky,
 							double lambda1, double lambda2, double tol)
 {
 	regressor = new LARS((useCholesky == 1), lambda1, lambda2, tol);
+	isModelTrained = false;
 }
 
 // input:	const bool 			useCholesky, 
@@ -42,6 +44,7 @@ void initModelNoDataWithGram(SP_integer useCholesky,
 	mat gramMatrix = convertArrayToMat(gramArr, gramSize, gramRowNum);
 
 	regressor = new LARS((useCholesky == 1), gramMatrix, lambda1, lambda2, tol);
+	isModelTrained = false;
 }
 
 // input:	const arma::mat & 		dataMatrix, 
@@ -58,18 +61,29 @@ void initModelWithDataNoGram(float *dataMatArr, SP_integer dataMatSize, SP_integ
 								SP_integer useCholesky, 
 								double lambda1, double lambda2, double tol)
 {
-	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 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 = new LARS(data, responsesVector, (transposeData == 1), (useCholesky == 1), lambda1, lambda2, tol);
+	
+	try
+    {
+        regressor = new LARS(data, responsesVector, (transposeData == 1), (useCholesky == 1), lambda1, lambda2, tol);
+    }
+    catch(const std::exception& e)
+    {
+        raisePrologSystemExeption(e.what());
+        return;
+    }
+	isModelTrained = true;
 }
 
 // input:	const arma::mat & 		dataMatrix, 
@@ -88,20 +102,31 @@ void initModelWithDataWithGram(float *dataMatArr, SP_integer dataMatSize, SP_int
 								float *gramMatArr, SP_integer gramMatSize, SP_integer gramMatRowNum, 
 								double lambda1, double lambda2, double tol)
 {
-	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 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);
 	// convert the Prolog array to arma::mat
 	mat gram = convertArrayToMat(gramMatArr, gramMatSize, gramMatRowNum);
 
 
-	regressor = new LARS(data, responsesVector, (transposeData == 1), (useCholesky == 1), gram, lambda1, lambda2, tol);
+	try
+    {
+        regressor = new LARS(data, responsesVector, (transposeData == 1), (useCholesky == 1), gram, lambda1, lambda2, tol);
+    }
+    catch(const std::exception& e)
+    {
+        raisePrologSystemExeption(e.what());
+        return;
+    }
+	isModelTrained = true;
 }
 
 // input:
@@ -120,8 +145,14 @@ void activeSet(float **activeSetArr, SP_integer *activeSetSize)
 // output: arma::vec& 
 void beta(float **betaArr, SP_integer *betaArrSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not trained!");
+        return;
+	}
+	
 	// create the ReturnVector
-	rowvec betaReturnVector = regressor.Beta();
+	vec betaReturnVector = regressor.Beta();
 
 	// return the Vector
 	returnVectorInformation(betaReturnVector, betaArr, betaArrSize);
@@ -131,6 +162,11 @@ void beta(float **betaArr, SP_integer *betaArrSize)
 // output: std::vector<arma::vec>&
 void betaPath(float **betaPathArr, SP_integer *betaPathColNum, SP_integer *betaPathRowNum)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not trained!");
+        return;
+	}
 	// get the betaPath matrix
 	vector<vec> matrix = regressor.BetaPath();
 
@@ -150,6 +186,11 @@ void betaPath(float **betaPathArr, SP_integer *betaPathColNum, SP_integer *betaP
 double computeError(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, 
 								float *responsesArr, SP_integer responsesArrSize, SP_integer rowMajor)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not trained!");
+        return 0.0;
+	}
 	if(dataMatSize / dataMatRowNum != responsesArrSize)
 	{
 		cout << "Target dim doesnt fit to the Data dim" << endl;
@@ -161,13 +202,28 @@ double computeError(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMa
 	rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize);
 
 	// run the model function
-	return regressor.ComputeError(data, responsesVector, (rowMajor == 1));
+	double result;
+	try
+	{
+		result = regressor.ComputeError(data, responsesVector, (rowMajor == 1));
+	}
+	catch(const std::exception& e)
+	{
+	    raisePrologSystemExeption(e.what());
+	    return 0.0;
+	}
+	return result;
 }
 
 // input:
 // output: std::vector<double>&
 void lambdaPath(float **lambdaPathArr, SP_integer *lambdaPathSize)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not trained!");
+        return;
+	}
 	std::vector<double> lambdaPathVec = regressor.LambdaPath();
 
 	// give back the sizes and the converted results as arrays
@@ -181,6 +237,11 @@ void lambdaPath(float **lambdaPathArr, SP_integer *lambdaPathSize)
 // output: arma::mat& upper triangular cholesky factor
 void matUtriCholFactor(float **factorMatArr, SP_integer *factorMatColNum, SP_integer *factorMatRowNum)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not trained!");
+        return;
+	}
 	// create the ReturnMat
 	mat factorReturnMat = regressor.MatUtriCholFactor();
 	
@@ -194,13 +255,26 @@ void matUtriCholFactor(float **factorMatArr, SP_integer *factorMatColNum, SP_int
 // output:
 void predict(float *pointsMatArr, SP_integer pointsMatSize, SP_integer pointsMatRowNum, float **predicArr, SP_integer *predicArrSize, SP_integer rowMajor)
 {
+	if (!isModelTrained)
+	{
+		raisePrologSystemExeption("The Model is not trained!");
+        return;
+	}
 	// convert the Prolog array to arma::mat
 	mat points = convertArrayToMat(pointsMatArr, pointsMatSize, pointsMatRowNum);
 	// create the ReturnVector
 	rowvec predicReturnVector;
 	
-	
-	regressor.Predict(points, predicReturnVector, (rowMajor == 1));
+
+	try
+	{
+		regressor.Predict(points, predicReturnVector, (rowMajor == 1));
+	}
+	catch(const std::exception& e)
+	{
+		raisePrologSystemExeption(e.what());
+        return;
+	}
 
 
 	// return the Vector
@@ -233,10 +307,20 @@ double train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum
 	
 
 	// run the model function
-	double error = regressor.Train(data, responsesVector, betaReturnVector, (transposeData == 1));
-
+	double error;
+	try
+	{
+		error = regressor.Train(data, responsesVector, betaReturnVector, (transposeData == 1));
+	}
+	catch(const std::exception& e)
+	{
+		raisePrologSystemExeption(e.what());
+        return 0.0;
+	}
+	
 
 	// return the Vector
 	returnVectorInformation(betaReturnVector, betaArr, betaArrSize);
+	isModelTrained = true;
 	return error;
 }
diff --git a/src/methods/lars/lars_test.pl b/src/methods/lars/lars_test.pl
index 4d401ef..f3bb0e4 100644
--- a/src/methods/lars/lars_test.pl
+++ b/src/methods/lars/lars_test.pl
@@ -68,25 +68,26 @@ test(lars_InitModelNoDataWithGram_Alternative_Use) :-
 :- begin_tests(lars_initModelWithDataNoGram).      
 
 %% Failure Tests
-                                            
+                                             
 test(lars_InitModelWithDataNoGram_Negative_Tolerance, fail) :-
         lars_initModelWithDataNoGram([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, 0, 0.0, 0.0, -1.0e-16).
 
 
-test(lars_InitModelWithDataNoGram_Too_Few_Labels, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataNoGram([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, 0.0, 0.0, -1.0e-16).
+test(lars_InitModelWithDataNoGram_Too_Few_Labels, [error(_,system_error('The number of data points does not match the number of labels!'))]) :-
+        lars_initModelWithDataNoGram([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, 0.0, 0.0, 1.0e-16).
 
-test(lars_InitModelWithDataNoGram_Too_Many_Labels, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataNoGram([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, 0.0, 0.0, -1.0e-16).
+test(lars_InitModelWithDataNoGram_Too_Many_Labels, [error(_,system_error('The number of data points does not match the number of labels!'))]) :-
+        lars_initModelWithDataNoGram([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, 0.0, 0.0, 1.0e-16).
 
-test(lars_InitModelWithDataNoGram_Too_Many_Labelclasses, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataNoGram([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, 0.0, 0.0, -1.0e-16).
+%% doesnt cause error
+test(lars_InitModelWithDataNoGram_Too_Many_Labelclasses) :-
+        lars_initModelWithDataNoGram([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, 0, 0.0, 0.0, 1.0e-16).
 
 
 %% Successful Tests
 
 test(lars_InitModelWithDataNoGram_Normal_Use) :-
-        lars_initModelWithDataNoGram([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, 0, 0.0, 0.0, 1.0e-16).
+        lars_initModelWithDataNoGram([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], 1, 0, 0.0, 0.0, 1.0e-16).
 
 test(lars_InitModelWithDataNoGram_Alternative_Use) :-
         lars_initModelWithDataNoGram([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], 1, 1, 1.0, -1.0, 1.0e-16).
@@ -106,24 +107,24 @@ test(lars_InitModelWithDataWithGram_Negative_Tolerance, fail) :-
         lars_initModelWithDataWithGram([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, 0, [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, -1.0e-16).
 
 
-test(lars_InitModelWithDataWithGram_Too_Few_Labels, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataWithGram([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, [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, -1.0e-16).
+test(lars_InitModelWithDataWithGram_Too_Few_Labels, [error(_,system_error('The number of data points does not match the number of labels!'))]) :-
+        lars_initModelWithDataWithGram([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, [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, 1.0e-16).
 
-test(lars_InitModelWithDataWithGram_Too_Many_Labels, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataWithGram([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, [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, -1.0e-16).
+test(lars_InitModelWithDataWithGram_Too_Many_Labels, [error(_,system_error('The number of data points does not match the number of labels!'))]) :-
+        lars_initModelWithDataWithGram([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, [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, 1.0e-16).
 
 test(lars_InitModelWithDataWithGram_Too_Many_Labelclasses, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataWithGram([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, [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, -1.0e-16).
+        lars_initModelWithDataWithGram([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, 0, [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, 1.0e-16).
 
 
 test(lars_InitModelWithDataWithGram_Diffrent_Dimensions, [error(_,system_error('Error'))]) :-
-        lars_initModelWithDataWithGram([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, 0, [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.0, 0.0, -1.0e-16).
+        lars_initModelWithDataWithGram([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], 1, 0, [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.0, 0.0, 1.0e-16).
 
 
 %% Successful Tests
 
 test(lars_InitModelWithDataWithGram_Normal_Use) :-
-        lars_initModelWithDataWithGram([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, 0, [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, 1.0e-16).
+        lars_initModelWithDataWithGram([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], 1, 0, [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, 1.0e-16).
 
 test(lars_InitModelWithDataWithGram_Alternative_Use) :-
         lars_initModelWithDataWithGram([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], 1, 0, [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, 1.0, -1.0, 1.0e-16).
@@ -139,7 +140,7 @@ test(lars_InitModelWithDataWithGram_Alternative_Use) :-
 
 %% Failure Tests
                                             
-test(lars_ActiveSet_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_ActiveSet_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
         lars_activeSet(_).
         
@@ -163,18 +164,18 @@ test(lars_ActiveSet_Normal_Use) :-
 
 %% Failure Tests
                                             
-test(lars_Beta_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_Beta_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
         lars_beta(_).
         
 
 %% Successful Tests
 
-test(lars_Beta_Normal_Use) :-
-        reset_Model_WithTrain,
-        lars_beta(BetaList),
-        print('\nBeta : '),
-        print(BetaList).
+%%test(lars_Beta_Normal_Use) :-
+%%        reset_Model_WithTrain,
+%%        lars_beta(BetaList),
+%%        print('\nBeta : '),
+%%        print(BetaList).
 
 :- end_tests(lars_beta).
 
@@ -187,7 +188,7 @@ test(lars_Beta_Normal_Use) :-
 
 %% Failure Tests
                                             
-test(lars_BetaPath_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_BetaPath_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
         lars_betaPath(_, _).
         
@@ -211,7 +212,7 @@ test(lars_BetaPath_Normal_Use) :-
 
 %% Failure Tests
 
-test(lars_ComputeError_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_ComputeError_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
         lars_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, _).
 
@@ -262,7 +263,7 @@ test(lars_ComputeError_CSV_Input) :-
 
 %% Failure Tests
                                             
-test(lars_LambdaPath_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_LambdaPath_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
         lars_lambdaPath(_).
         
@@ -286,7 +287,7 @@ test(lars_LambdaPath_Normal_Use) :-
 
 %% Failure Tests
                                             
-test(lars_MatUtriCholFactor_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_MatUtriCholFactor_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
         lars_matUtriCholFactor(_, _).
         
@@ -310,21 +311,21 @@ test(lars_MatUtriCholFactor_Normal_Use) :-
 
 %% Failure Tests
 
-test(lars_Predict_Before_Train, [error(_,system_error('Error'))]) :-
+test(lars_Predict_Before_Train, [error(_,system_error('The Model is not trained!'))]) :-
         reset_Model_NoTrain,
-        lars_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, 0, _).
+        lars_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, 1, _).
 
 
 test(lars_Predict_Diffrent_Dims, [error(_,system_error('Error'))]) :-
         reset_Model_WithTrain,
-        lars_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, 0, _).
+        lars_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, 1, _).
 
 
 %% Successful Tests
 
 test(lars_Predict_Normal_Use) :-
         reset_Model_WithTrain,
-        lars_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, 0, PredictList),
+        lars_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, 1, PredictList),
         print('\nPrediction: '),
         print(PredictList).
 
@@ -338,7 +339,7 @@ test(lars_Predict_CSV_Input) :-
         reset_Model_WithTrain,
         open('src/data_csv/iris2.csv', read, File),
         take_csv_row(File, skipFirstRow,10, Data),
-        lars_predict(Data, 4, 0, PredictList),
+        lars_predict(Data, 4, 1, PredictList),
         print('\nPrediction: '),
         print(PredictList).
 
@@ -410,4 +411,4 @@ test(lars_Train_CSV_Input) :-
 :- end_tests(lars_train).
 
 run_lars_tests :-
-        run_tests.
\ No newline at end of file
+        run_tests(lars_predict).
\ No newline at end of file
-- 
GitLab