diff --git a/src/methods/lars/Makefile b/src/methods/lars/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c95df91abedbee8c1261c05e25ef6db73032d7d4 --- /dev/null +++ b/src/methods/lars/Makefile @@ -0,0 +1,8 @@ +splfr=/usr/local/sicstus4.7.1/bin/splfr + +METHOD_NAME=new_method + +$(METHOD_NAME).so: $(METHOD_NAME).pl $(METHOD_NAME).cpp + $(splfr) -larmadillo -fopenmp -lmlpack -lstdc++ -cxx --struct $(METHOD_NAME).pl $(METHOD_NAME).cpp ../../helper_files/helper.cpp +clean: + rm $(METHOD_NAME).so diff --git a/src/methods/lars/new_method.cpp b/src/methods/lars/new_method.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dba044b94fdbb2bdc397bc75fab7a829824fd6a5 --- /dev/null +++ b/src/methods/lars/new_method.cpp @@ -0,0 +1,196 @@ +#include <sicstus/sicstus.h> +/* ex_glue.h is generated by splfr from the foreign/[2,3] facts. + Always include the glue header in your foreign resource code. +*/ +#include "new_method_glue.h" +#include <mlpack/methods/new_method.hpp> +#include <mlpack/core.hpp> + +// including helper functions for converting between arma structures and arrays +#include "../../helper_files/helper.hpp" + +using namespace arma; +using namespace mlpack; +using namespace std; +using namespace mlpack::regression; + +// Global Variable of the BayesianLinearRegression object so it can be accessed from all functions +BayesianLinearRegression regressor; + + +// input: const bool , const bool , const size_t , const double +// output: double +void initModel(SP_integer centerData, SP_integer scaleData, SP_integer nIterMax, double tol) +{ + regressor = new BayesianLinearRegression((centerData == 1), (scaleData == 1), nIterMax, tol); +} + +// input: +// output: double +SP_integer alpha() +{ + return regressor.Alpha(); +} + +// input: +// output: double +SP_integer beta() +{ + return regressor.Beta(); +} + +// input: +// output: const arma::colvec & +float * dataOffset(SP_integer *arraySize) +{ + // save the DataOffset output in colvec + colvec armaDataOffset = regressor.DataOffset(); + + *arraySize = armaDataOffset.n_elem; + + return convertArmaToArray(armaDataOffset); +} + +// input: +// output: const arma::colvec & +float * dataScale(SP_integer *arraySize) +{ + // save the DataScale output in colvec + colvec armaDataScale = regressor.DataScale(); + + *arraySize = armaDataScale.n_elem; + + return convertArmaToArray(armaDataScale); +} + +// input: +// output: const arma::colvec & +float * omega(SP_integer *arraySize) +{ + // save the Omega output in colvec + colvec armaOmega = regressor.Omega(); + + *arraySize = armaOmega.n_elem; + + return convertArmaToArray(armaOmega); +} + +// input: const arma::mat &points, arma::rowvec &predictions +// output: +void predict(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, float **predicArr, SP_integer *predicSize) +{ + // convert the Prolog arrays to std::vec for easy conversion to arma::mat + mat data = convertArrayToMat(pointsArr, pointsSize, pointsRowNum); + + // run the prediction and save the result in arma::rowvec + rowvec predictions; + regressor.Predict(data, predictions); + + + // give back the sizes and the converted results as arrays + *predicSize = predictions.n_elem; + + *predicArr = convertArmaToArray(predictions); +} + +// input: const arma::mat &points, arma::rowvec &predictions, arma::rowvec &std +// output: +void predictWithStd(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, float **predicArr, SP_integer *predicSize, float **stdArr, SP_integer *stdSize) +{ + // convert the Prolog arrays to std::vec for easy conversion to arma::mat + mat data = convertArrayToMat(pointsArr, pointsSize, pointsRowNum); + + // run the prediction and save the results in arma::rowvecs + rowvec predictions; + rowvec std; + regressor.Predict(data, predictions, std); + + // give back the sizes and the converted results as arrays + *predicSize = predictions.n_elem; + *stdSize = std.n_elem; + + *predicArr = convertArmaToArray(predictions); + *stdArr = convertArmaToArray(std); +} + + +// input: +// output: double +SP_integer responsesOffset() +{ + return regressor.ResponsesOffset(); +} + +// input: const arma::mat &data, const arma::rowvec &responses +// output: double +SP_integer rmse(float *matrix, SP_integer matSize, SP_integer matRowNum, float *arr, SP_integer vecSize) +{ + // convert the Prolog arrays to arma::rowvec and arma::mat + rowvec responses = convertArrayToRowvec(arr, vecSize); + mat data = convertArrayToMat(matrix, matSize, matRowNum); + + // run the model function and return the error + return regressor.RMSE(data, responses); +} + +// input: const arma::mat &data, const arma::rowvec &responses +// output: +void train(float *matrix, SP_integer matSize, SP_integer matRowNum, float *arr, SP_integer vecSize) +{ + if(matSize / matRowNum != vecSize) + { + cout << "Target dim doesnt fit to the Data dim" << endl; + return; + } + // convert the Prolog arrays to arma::rowvec and arma::mat + rowvec responses = convertArrayToRowvec(arr, vecSize); + mat data = convertArrayToMat(matrix, matSize, matRowNum); + + // run the model function + regressor.Train(data, responses); +} + +// input: +// output: double +SP_integer variance() +{ + return regressor.Variance(); +} + +/* +void testing() +{ + // load the iris data + mat dataset; + bool loaded = mlpack::data::Load("iris.csv", dataset); + + // split the data into train and test + mat trainData = dataset.cols(1, 4); + trainData.shed_row(trainData.n_rows - 1); + rowvec trainTarget = trainData.row(trainData.n_rows - 1); + trainData.shed_row(trainData.n_rows - 1); + + mat testData = dataset.col(dataset.n_cols - 1); + testData.shed_row(testData.n_rows - 1); + rowvec testTarget = testData.row(testData.n_rows - 1); + testData.shed_row(testData.n_rows - 1); + + + // init the bayesian linear regressor model + + + // train the model + regressor.Train(trainData, trainTarget); + + // predict with the test data + rowvec prediction; + regressor.Predict(testData, prediction); + + + // compare test target and prediction + cout << "Train Data: " << trainData << endl; + cout << "Train Target: " << trainTarget << endl; + cout << "Alpha" << alpha() << endl; + cout << "Beta" << beta() << endl; +} +*/ diff --git a/src/methods/lars/new_method.pl b/src/methods/lars/new_method.pl new file mode 100644 index 0000000000000000000000000000000000000000..2ba4630ba07bc285076c0bce10f0231484ea8cd3 --- /dev/null +++ b/src/methods/lars/new_method.pl @@ -0,0 +1,29 @@ +:- module(new_method, [function/4, function/1, function/2, function/6]). + +:- load_files(library(str_decl), + [when(compile_time), if(changed)]). + +%% needed for using the array type and for reading from csv +:- use_module(library(structs)). +:- use_module('../../helper_files/helper.pl'). + +%% type definitions for the float array +:- foreign_type + float32 = float_32, + float_array = array(float32). + +%% definitions for the connected function and what there inputs and output arguments are + +%% Funktion that takes data from Prolog +foreign(function, c, function(+integer, +integer, +integer, +float32)). +%% Funktion that return data to Prolog +foreign(function, c, function([-integer])). +%% Funktion that returns a array +foreign(function, c, function(-integer, [-pointer(float_array)])). +%% Funktion that takes a Matrix and a Array +foreign(function, c, function(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, [-integer])). + +%% Defines what functions should be connected from main.cpp +foreign_resource(new_method, [function, function, function, function]). + +:- load_foreign_resource(new_method). \ No newline at end of file diff --git a/src/methods/lars/test.pl b/src/methods/lars/test.pl new file mode 100644 index 0000000000000000000000000000000000000000..533981b96bd761d4bf07a5ed061a96a87db12f6f --- /dev/null +++ b/src/methods/lars/test.pl @@ -0,0 +1,56 @@ +:- use_module(library(plunit)). + +:- use_module(new_method). +:- 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) :- + reset_Model, + alpha(1). +test(alpha_after_train, A =:= 9223372036854775808) :- + 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). + +%% train tests +test(correct_train) :- + 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) :- + 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) :- + 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) :- + 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) :- + 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) :- + 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). \ No newline at end of file