Skip to content
Snippets Groups Projects
Commit e3e57026 authored by Jakhes's avatar Jakhes
Browse files

Adding a template for new methods

parent 33230a01
No related branches found
No related tags found
No related merge requests found
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
clean:
rm $(METHOD_NAME).so
#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>
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;
// Extra functions to reduce some code for the conversion between arma and float *array
float *convertArmaToArray(colvec vec)
{
vector<float> vectorData = conv_to<vector<float>>::from(vec);
int vectorSize = vectorData.size();
// using malloc so the memory is still valid outside of the function
float *arr = (float *)malloc (sizeof(float) * vectorSize);
// save the data in a normal array so it can be send to prolog
for(int i = 0; i < vectorSize; i++)
{
arr[i] = vectorData[i];
}
return arr;
}
float *convertArmaToArray(rowvec vec)
{
colvec newVec = conv_to<colvec>::from(vec);
return convertArmaToArray(newVec);
}
rowvec convertArrayToRowvec(float *arr, SP_integer vecSize)
{
rowvec rVector(vecSize);
for(int i = 0; i < vecSize; i++)
{
rVector[i] = arr[i];
}
return rVector;
}
mat convertArrayToMat(float *arr, SP_integer vecSize, SP_integer rowCount)
{
mat matrix(rowCount,(vecSize/rowCount));
for(int i = 0; i < vecSize; i++)
{
matrix[i] = arr[i];
}
return matrix;
}
// 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;
}
*/
:- module(new_method, [initModel/4, alpha/1, beta/1, dataOffset/2, dataScale/2, omega/2, predict/5, predictWithStd/7, rmse/6, train/5, variance/1]).
:- 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('/home/afkjakhes/git/prolog-mlpack-libary/src/helper_files/helper').
%% 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
foreign(initModel, c, initModel(+integer, +integer, +integer, +float32)).
foreign(alpha, c, alpha([-integer])).
foreign(beta, c, beta([-integer])).
foreign(dataOffset, c, dataOffset(-integer, [-pointer(float_array)])).
foreign(dataScale, c, dataScale(-integer, [-pointer(float_array)])).
foreign(omega, c, omega(-integer, [-pointer(float_array)])).
foreign(predict, c, predict(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer)).
foreign(predictWithStd, c, predictWithStd(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer, -pointer(float_array), -integer)).
foreign(rmse, c, rmse(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, [-integer])).
foreign(train, c, train(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer)).
foreign(variance, c, variance([-integer])).
%% Defines what functions should be connected from main.cpp
foreign_resource(new_method, [initModel, alpha, beta, dataOffset, dataScale, omega, predict, predictWithStd, rmse, train, variance]).
:- load_foreign_resource(new_method).
%% Some funktions that use the new Method
%% First trains the model and then tries to predict the targets and the std for the given data
predict(PredictList, StdList) :-
train,
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)),
predictWithStd(X, Xsize,Xrownum, Predic, PredicSize, Std, StdSize),
convert_float_array_to_list(Predic, PredicSize, PredictList),
convert_float_array_to_list(Std, StdSize, StdList).
%% Trains the model with the given data and targets
train :-
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).
:- use_module(library(plunit)).
:- use_module(new_method).
:- use_module('/home/afkjakhes/git/prolog-mlpack-libary/src/helper_files/helper').
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment