diff --git a/src/methods/lars/Makefile b/src/methods/lars/Makefile index c95df91abedbee8c1261c05e25ef6db73032d7d4..653dfb4247049e8feab4194d9053f4801f9c318d 100644 --- a/src/methods/lars/Makefile +++ b/src/methods/lars/Makefile @@ -1,6 +1,6 @@ splfr=/usr/local/sicstus4.7.1/bin/splfr -METHOD_NAME=new_method +METHOD_NAME=lars $(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 diff --git a/src/methods/lars/lars.cpp b/src/methods/lars/lars.cpp index 3e26a3ae41f0194b5c77a74dd7303bdbb4171639..53b8f10e656e36dc9be425a7e6c186b7af546557 100644 --- a/src/methods/lars/lars.cpp +++ b/src/methods/lars/lars.cpp @@ -1,4 +1,5 @@ #include <sicstus/sicstus.h> +//#include "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. */ @@ -26,7 +27,7 @@ void initModelNoDataNoGram(SP_integer useCholesky, double lambda1, double lambda // input: const bool useCholesky, const arma::mat & gramMatrix, const double lambda1, const double lambda2, const double tolerance // output: -void initModelNoDataWithGram(SP_integer useCholesky, float *gramArr, SP_integer gramSize, SP_integer gramRowNum, SP_integer lambda1, SP_integer lambda2, double tol) +void initModelNoDataWithGram(SP_integer useCholesky, float *gramArr, SP_integer gramSize, SP_integer gramRowNum, double lambda1, double lambda2, double tol) { mat gramMatrix = convertArrayToMat(gramArr, gramSize, gramRowNum); @@ -36,7 +37,7 @@ void initModelNoDataWithGram(SP_integer useCholesky, float *gramArr, SP_integer // input: const arma::mat & dataMatrix, const arma::rowvec & responses, const bool transposeData, const bool useCholesky, const double lambda1, const double lambda2, const double tolerance // output: void initModelWithDataNoGram(float *dataArr, SP_integer dataSize, SP_integer dataRowNum, float *responsesArr, SP_integer responsesSize, SP_integer transposeData, - SP_integer useCholesky, SP_integer lambda1, SP_integer lambda2, double tol) + SP_integer useCholesky, double lambda1, double lambda2, double tol) { if(dataSize / dataRowNum != responsesSize) { @@ -47,13 +48,13 @@ void initModelWithDataNoGram(float *dataArr, SP_integer dataSize, SP_integer dat mat data = convertArrayToMat(dataArr, dataSize, dataRowNum); rowvec responses = convertArrayToRowvec(responsesArr, responsesSize); - regressor = new LARS(data, responses, (transposedata == 1), (useCholesky == 1), lambda1, lambda2, tol); + regressor = new LARS(data, responses, (transposeData == 1), (useCholesky == 1), lambda1, lambda2, tol); } // input: const arma::mat & dataMatrix, const arma::rowvec & responses, const bool transposeData, const bool useCholesky, const arma::mat & gramMatrix, const double lambda1, const double lambda2, const double tolerance // output: void initModelWithDataWithGram(float *dataArr, SP_integer dataSize, SP_integer dataRowNum, float *responsesArr, SP_integer responsesSize, SP_integer transposeData, - SP_integer useCholesky, float *gramArr, SP_integer gramSize, SP_integer gramRowNum, SP_integer lambda1, SP_integer lambda2, double tol) + SP_integer useCholesky, float *gramArr, SP_integer gramSize, SP_integer gramRowNum, double lambda1, double lambda2, double tol) { if(dataSize / dataRowNum != responsesSize) { @@ -65,19 +66,19 @@ void initModelWithDataWithGram(float *dataArr, SP_integer dataSize, SP_integer d rowvec responses = convertArrayToRowvec(responsesArr, responsesSize); mat gramMatrix = convertArrayToMat(gramArr, gramSize, gramRowNum); - regressor = new LARS(data, responses, (transposedata == 1), (useCholesky == 1), gramMatrix, lambda1, lambda2, tol); + regressor = new LARS(data, responses, (transposeData == 1), (useCholesky == 1), gramMatrix, lambda1, lambda2, tol); } -// TODO: conversion of std::vector to array // input: // output: const std::vector<size_t>& -void activeSet(SP_integer a) +void activeSet(float **activeSetArr, SP_integer *activeSetSize) { - vector<size_t> active = regressor.ActiveSet(); - for (size_t i = 0; i < active.size(); i++) - { - cout << active[i] << endl; - } + std::vector<size_t> activeVec = regressor.ActiveSet(); + + // give back the sizes and the converted results as arrays + *activeSetSize = activeVec.size(); + + *activeSetArr = convertToArray(activeVec); } // input: @@ -85,17 +86,26 @@ void activeSet(SP_integer a) void beta( float **betaArr, SP_integer *betaSize) { rowvec betasolution = regressor.Beta(); + + // give back the sizes and the converted results as arrays *betaSize = betasolution.n_elem; *betaArr = convertToArray(betasolution); } -// TODO: adding matrix as a return // input: // output: std::vector<arma::vec>& -void betaPath() +void betaPath(float **betaPathArr, SP_integer *betaPathColNum, SP_integer *betaPathRowNum) { - + // get the betaPath matrix + vector<vec> matrix = regressor.BetaPath(); + + // return the matrix dimensions + *betaPathColNum = matrix[0].size(); + *betaPathRowNum = matrix.size(); + + // return the matrix as array + *betaPathArr = convertToArray(matrix); } // input: const arma::mat &data, const arma::rowvec &responses, const bool rowMajor @@ -115,32 +125,44 @@ SP_integer computeError(float *points_mat_arr, SP_integer dataSize, SP_integer d return regressor.ComputeError(data, responses); } -// TODO: conversion of vector to array // input: // output: std::vector<double>& -void lambdaPath() +void lambdaPath(float **lambdaPathArr, SP_integer *lambdaPathSize) { - + std::vector<double> lambdaPathVec = regressor.LambdaPath(); + + // give back the sizes and the converted results as arrays + *lambdaPathSize = lambdaPathVec.size(); + + *lambdaPathArr = convertToArray(lambdaPathVec); } -// TODO: adding matrix as a return + // input: // output: arma::mat& upper triangular cholesky factor -void matUtriCholFactor() +void matUtriCholFactor(float **factorArr, SP_integer *factorColNum, SP_integer *factorRowNum) { + // get the UtriCholFactor matrix mat UtriCholFact = regressor.MatUtriCholFactor(); + + // return the matrix dimensions + *factorColNum = UtriCholFact.n_cols; + *factorRowNum = UtriCholFact.n_rows; + + // return the matrix as array + *factorArr = convertToArray(UtriCholFact); } // input: const arma::mat &points, arma::rowvec &predictions, const bool rowMajor // output: void predict(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, float **predicArr, SP_integer *predicSize, SP_integer rowMajor) { - // convert the Prolog arrays to std::vec for easy conversion to arma::mat + // convert the array 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); + regressor.Predict(data, predictions, (rowMajor == 1)); // give back the sizes and the converted results as arrays @@ -151,34 +173,36 @@ void predict(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, f // input: const arma::mat &data, const arma::rowvec &responses, arma::vec& beta, const bool transposeData // output: double minimum cost error -void train(float *dataArr, SP_integer dataSize, SP_integer dataRowNum, float *responsesArr, SP_integer responsesSize, float **betaArr, SP_integer *betaSize, SP_integer transposeData) +SP_integer train(float *dataArr, SP_integer dataSize, SP_integer dataRowNum, float *responsesArr, SP_integer responsesSize, float **betaArr, SP_integer *betaSize, SP_integer transposeData) { if(dataSize / dataRowNum != responsesSize) { cout << "Target dim doesnt fit to the Data dim" << endl; - return; + return 0; } // convert the Prolog arrays to arma::rowvec and arma::mat mat data = convertArrayToMat(dataArr, dataSize, dataRowNum); rowvec responses = convertArrayToRowvec(responsesArr, responsesSize); + vec betaVec; + // run the model function - regressor.Train(data, responses); + return regressor.Train(data, responses, betaVec, (transposeData == 1)); } // input: const arma::mat &data, const arma::rowvec &responses, const bool transposeData // output: double minimum cost error -void trainNoBetaReturn(float *dataArr, SP_integer dataSize, SP_integer dataRowNum, float *responsesArr, SP_integer responsesSize, SP_integer transposeData) +SP_integer trainNoBetaReturn(float *dataArr, SP_integer dataSize, SP_integer dataRowNum, float *responsesArr, SP_integer responsesSize, SP_integer transposeData) { if(dataSize / dataRowNum != responsesSize) { cout << "Target dim doesnt fit to the Data dim" << endl; - return; + return 0; } // convert the Prolog arrays to arma::rowvec and arma::mat rowvec responses = convertArrayToRowvec(responsesArr, responsesSize); mat data = convertArrayToMat(dataArr, dataSize, dataRowNum); // run the model function - regressor.Train(data, responses); -} \ No newline at end of file + return regressor.Train(data, responses, (transposeData == 1)); +} diff --git a/src/methods/lars/lars.pl b/src/methods/lars/lars.pl index aef6aeb4f4ef0ee04cf8078f59115471a6a17e54..2ecb176cdbed7a4638875eb85521390558195b85 100644 --- a/src/methods/lars/lars.pl +++ b/src/methods/lars/lars.pl @@ -1,4 +1,4 @@ -:- module(lars, [function/4, function/1, function/2, function/6]). +:- module(lars, [initModelNoDataNoGram/4, initModelNoDataWithGram/7, initModelWithDataNoGram/10, initModelWithDataWithGram/13, activeSet/2,beta/2, betaPath/3, computeError/7, lambdaPath/2, matUtriCholFactor/3, predict/6, train/9, trainNoBetaReturn/7]). :- load_files(library(str_decl), [when(compile_time), if(changed)]). @@ -14,92 +14,73 @@ %% definitions for the connected function and what there inputs and output arguments are -%% Funktion const bool useCholesky, const double lambda1, const double lambda2, const double tolerance +%% Funktion +%% input const bool useCholesky, const double lambda1, const double lambda2, const double tolerance +%% output foreign(initModelNoDataNoGram, c, initModelNoDataNoGram(+integer, +float32, +float32, +float32)). -%% Funktion const bool useCholesky, const arma::mat & gramMatrix, const double lambda1, const double lambda2, const double tolerance +%% Funktion +%% input const bool useCholesky, const arma::mat & gramMatrix, const double lambda1, const double lambda2, const double tolerance +%% output foreign(initModelNoDataWithGram, c, initModelNoDataWithGram(+integer, +pointer(float_array), +integer, +integer, +float32, +float32, +float32)). -%% Funktion const arma::mat & dataMatrix, const arma::rowvec & responses, const bool transposeData, const bool useCholesky, const double lambda1, const double lambda2, const double tolerance -foreign(initModelWithDataNoGram, c, initModelWithDataNoGram(+pointer(float_array), +integer, +pointer(float_array), +integer, +integer, +integer, +float32, +float32, +float32)). +%% Funktion +%% input const arma::mat & dataMatrix, const arma::rowvec & responses, const bool transposeData, const bool useCholesky, const double lambda1, const double lambda2, const double tolerance +%% output +foreign(initModelWithDataNoGram, c, initModelWithDataNoGram(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, +integer, +float32, +float32, +float32)). -%% Funktion const arma::mat & dataMatrix, const arma::rowvec & responses, const bool transposeData, const bool useCholesky, const arma::mat & gramMatrix, const double lambda1, const double lambda2, const double tolerance -foreign(initModelWithDataWithGram, c, initModelWithDataWithGram(+pointer(float_array), +integer, +pointer(float_array), +integer, +integer, +integer, +pointer(float_array), +integer, +integer, +float32, +float32, +float32)). +%% Funktion +%% input const arma::mat & dataMatrix, const arma::rowvec & responses, const bool transposeData, const bool useCholesky, const arma::mat & gramMatrix, const double lambda1, const double lambda2, const double tolerance +%% output +foreign(initModelWithDataWithGram, c, initModelWithDataWithGram(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, +integer, +pointer(float_array), +integer, +integer, +float32, +float32, +float32)). -%% TODO: -%% Funktion that takes data from Prolog +%% Funktion %% input -%% output const std::vector<size_t>& -foreign(activeSet, c, activeSet(+integer, +integer, +integer, +float32)). +%% output const std::vector<size_t>& +foreign(activeSet, c, activeSet(-pointer(float_array), -integer)). -%% Funktion that takes data from Prolog +%% Funktion %% input %% output arma::vec& -foreign(beta, c, beta(+integer, +integer, +integer, +float32)). +foreign(beta, c, beta(-pointer(float_array), -integer)). -%% TODO: -%% Funktion that takes data from Prolog +%% Funktion %% input %% output std::vector<arma::vec>& -foreign(betaPath, c, betaPath(+integer, +integer, +integer, +float32)). +foreign(betaPath, c, betaPath(-pointer(float_array), -integer, -integer)). -%% Funktion that takes data from Prolog +%% Funktion %% input: const arma::mat &data, const arma::rowvec &responses, const bool rowMajor %% output: double minimum cost error -foreign(computeError, c, computeError(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, [-float32])). +foreign(computeError, c, computeError(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, [-integer])). -%% TODO: -%% Funktion that takes data from Prolog +%% Funktion %% input %% output std::vector<double>& -foreign(lambdaPath, c, lambdaPath(+integer, +integer, +integer, +float32)). +foreign(lambdaPath, c, lambdaPath(-pointer(float_array), -integer)). -%% TODO: -%% Funktion that takes data from Prolog +%% Funktion %% input %% output arma::mat& upper triangular cholesky factor -foreign(matUtriCholFactor, c, matUtriCholFactor(+integer)). +foreign(matUtriCholFactor, c, matUtriCholFactor(-pointer(float_array), -integer, -integer)). -%% Funktion that takes data from Prolog +%% Funktion %% input const arma::mat &points, arma::rowvec &predictions, const bool rowMajor %% output foreign(predict, c, predict(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer, +integer)). -%% Funktion that takes data from Prolog +%% Funktion %% input const arma::mat &data, const arma::rowvec &responses, arma::vec& beta, const bool transposeData %% output double minimum cost error foreign(train, c, train(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, -pointer(float_array), -integer, +integer, [-integer])). -%% Funktion that takes data from Prolog +%% Funktion %% input const arma::mat &data, const arma::rowvec &responses, const bool transposeData %% output double minimum cost error foreign(trainNoBetaReturn, c, trainNoBetaReturn(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, [-integer])). -%% Funktion that takes data from Prolog -%% input -%% output -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(lars, [ - initModelNoDataNoGram, - initModelNoDataWithGram, - initModelWithDataNoGram, - initModelWithDataWithGram, - activeSet, - beta, - betaPath, - computeError, - lambdaPath, - matUtriCholFactor, - predict, - train, - trainNoBetaReturn]). - -:- load_foreign_resource(lars). \ No newline at end of file +foreign_resource(lars, [initModelNoDataNoGram, initModelNoDataWithGram, initModelWithDataNoGram, initModelWithDataWithGram, activeSet, beta, betaPath, computeError, lambdaPath, matUtriCholFactor, predict, train, trainNoBetaReturn]). + +:- load_foreign_resource(lars). diff --git a/src/methods/lars/lars_test.pl b/src/methods/lars/lars_test.pl new file mode 100644 index 0000000000000000000000000000000000000000..20dc240d42cfe8e29f9939b61d9674e00671ec5d --- /dev/null +++ b/src/methods/lars/lars_test.pl @@ -0,0 +1,47 @@ +:- use_module(library(plunit)). +:- use_module(library(structs)). + +:- use_module(lars). +:- use_module('../../helper_files/helper.pl'). + +reset_Model :- + initModelNoDataNoGram(1, 0.1, 0.3, 0.001), + 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)), + trainNoBetaReturn(X,Xsize, Xrownum,Y, Ysize, 1, _). + +:- begin_tests(lists). + + +%% train tests +test(train, [true(A =:= 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)), + trainNoBetaReturn(X,Xsize, Xrownum,Y, Ysize, 1, A), + predict(X, Xsize,Xrownum, Predic, PredicSize,0), + convert_float_array_to_list(Predic, PredicSize, Result), + print(Result). + +test(activeSet) :- + reset_Model, + activeSet(ActSet, ActSetSize), + convert_float_array_to_list(ActSet, ActSetSize, Result), + print(Result). + +test(matUtriCholFactor) :- + reset_Model, + matUtriCholFactor(Matrix, MatrixColNum, MatrixRowNum), + print(MatrixColNum), + convert_float_array_to_2d_list(Matrix, MatrixColNum, MatrixRowNum, Results), + print(Results). + +test(betaPath) :- + reset_Model, + betaPath(Matrix, MatrixColNum, MatrixRowNum), + print(MatrixColNum), + convert_float_array_to_2d_list(Matrix, MatrixColNum, MatrixRowNum, Results), + print(Results). + + +:- end_tests(lists). \ No newline at end of file diff --git a/src/methods/lars/test.pl b/src/methods/lars/test.pl deleted file mode 100644 index 533981b96bd761d4bf07a5ed061a96a87db12f6f..0000000000000000000000000000000000000000 --- a/src/methods/lars/test.pl +++ /dev/null @@ -1,56 +0,0 @@ -:- 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