From e7ae668ef46a2d456debbb2623b1e42810ca4f36 Mon Sep 17 00:00:00 2001 From: Jakhes <dean.schmitz@schmitzbauer.de> Date: Fri, 16 Sep 2022 22:48:51 +0200 Subject: [PATCH] Adding Fastmks --- Makefile | 2 + src/methods/fastmks/Makefile | 8 ++ src/methods/fastmks/fastmks.cpp | 151 +++++++++++++++++++++++++++ src/methods/fastmks/fastmks.pl | 67 ++++++++++++ src/methods/fastmks/fastmks_test.pl | 56 ++++++++++ src/methods/new_method/new_method.pl | 2 + 6 files changed, 286 insertions(+) create mode 100644 src/methods/fastmks/Makefile create mode 100644 src/methods/fastmks/fastmks.cpp create mode 100644 src/methods/fastmks/fastmks.pl create mode 100644 src/methods/fastmks/fastmks_test.pl diff --git a/Makefile b/Makefile index 5d58849..c5941fd 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ all: make -C src/methods/random_forest splfr=$(SPLFR_PATH) make -C src/methods/softmac_regression splfr=$(SPLFR_PATH) make -C src/methods/approx_kfn splfr=$(SPLFR_PATH) + make -C src/methods/fastmks splfr=$(SPLFR_PATH) clean: make -C src/methods/ada_boost clean @@ -34,5 +35,6 @@ clean: make -C src/methods/random_forest clean make -C src/methods/softmac_regression clean make -C src/methods/approx_kfn clean + make -C src/methods/fastmks clean \ No newline at end of file diff --git a/src/methods/fastmks/Makefile b/src/methods/fastmks/Makefile new file mode 100644 index 0000000..5295563 --- /dev/null +++ b/src/methods/fastmks/Makefile @@ -0,0 +1,8 @@ +splfr=/usr/local/sicstus4.7.1/bin/splfr + +METHOD_NAME=fastmks + +$(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/fastmks/fastmks.cpp b/src/methods/fastmks/fastmks.cpp new file mode 100644 index 0000000..2641e15 --- /dev/null +++ b/src/methods/fastmks/fastmks.cpp @@ -0,0 +1,151 @@ +#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 "fastmks_glue.h" +#include <mlpack/methods/fastmks/fastmks_model.hpp> +#include <mlpack/core.hpp> + +// including helper functions for converting between arma structures and arrays +#include "../../helper_files/helper.hpp" + +// some of the most used namespaces +using namespace arma; +using namespace mlpack; +using namespace std; +using namespace mlpack::fastmks; +using namespace mlpack::kernel; + +// Global Variable of the FastMKSModel object so it can be accessed from all functions +FastMKSModel fastMKSModel; + +// TODO: +// input: util::Timers & timers, +// arma::mat && referenceData, +// TKernelType & kernel, +// double degree, +// double offset, +// double bandwidth, +// double scale +// const bool singleMode, +// const bool naive, +// const double base +// output: +// description: +void initModel(float *referenceMatArr, SP_integer referenceMatSize, SP_integer referenceMatRowNum, char const *kernel, double degree, double offset, double bandwidth, double scale, SP_integer singleMode, SP_integer naive, double base) +{ + // convert the Prolog arrays to arma::mat + mat reference = convertArrayToMat(referenceMatArr, referenceMatSize, referenceMatRowNum); + + if (strcmp(kernel, "linear") == 0) + { + fastMKSModel = FastMKSModel(0); + LinearKernel lk; + fastMKSModel.BuildModel(move(reference), lk, (singleMode == 1), (naive == 1), base); + } + else if (strcmp(kernel, "polynomial") == 0) + { + PolynomialKernel pk(degree, offset); + fastMKSModel.KernelType() = FastMKSModel::POLYNOMIAL_KERNEL; + fastMKSModel.BuildModel(move(reference), pk, (singleMode == 1), (naive == 1), base); + } + else if (strcmp(kernel, "cosine") == 0) + { + CosineDistance cd; + fastMKSModel.KernelType() = FastMKSModel::COSINE_DISTANCE; + fastMKSModel.BuildModel(move(reference), cd, (singleMode == 1), (naive == 1), base); + } + else if (strcmp(kernel, "gaussian") == 0) + { + GaussianKernel gk(bandwidth); + fastMKSModel.KernelType() = FastMKSModel::GAUSSIAN_KERNEL; + fastMKSModel.BuildModel(move(reference), gk, (singleMode == 1), (naive == 1), base); + } + else if (strcmp(kernel, "epanechnikov") == 0) + { + EpanechnikovKernel ek(bandwidth); + fastMKSModel.KernelType() = FastMKSModel::EPANECHNIKOV_KERNEL; + fastMKSModel.BuildModel(move(reference), ek, (singleMode == 1), (naive == 1), base); + } + else if (strcmp(kernel, "triangular") == 0) + { + TriangularKernel tk(bandwidth); + fastMKSModel.KernelType() = FastMKSModel::TRIANGULAR_KERNEL; + fastMKSModel.BuildModel(move(reference), tk, (singleMode == 1), (naive == 1), base); + } + else if (strcmp(kernel, "hyptan") == 0) + { + HyperbolicTangentKernel htk(scale, offset); + fastMKSModel.KernelType() = FastMKSModel::HYPTAN_KERNEL; + fastMKSModel.BuildModel(move(reference), htk, (singleMode == 1), (naive == 1), base); + } +} + +// TODO: +// input: util::Timers & timers, +// const arma::mat & querySet, +// const size_t k, +// arma::Mat< size_t > & indices <-, +// arma::mat & kernels <-, +// const double base +// output: +// description: +void searchWithQuery(float *querySetMatArr, SP_integer querySetMatSize, SP_integer querySetMatRowNum, SP_integer k, float **indicesMatArr, SP_integer *indicesMatColNum, SP_integer *indicesMatRowNum, float **kernelsMatArr, SP_integer *kernelsMatColNum, SP_integer *kernelsMatRowNum, double base) +{ + // convert the Prolog arrays to arma::mat + mat querySet = convertArrayToMat(querySetMatArr, querySetMatSize, querySetMatRowNum); + + // create the ReturnMat + arma::Mat< size_t > indicesReturnMat; + + // create the ReturnMat + mat kernelsReturnMat; + + fastMKSModel.Search(querySet, k, indicesReturnMat, kernelsReturnMat, base); + + // return the Matrix dimensions + *indicesMatColNum = indicesReturnMat.n_cols; + *indicesMatRowNum = indicesReturnMat.n_rows; + + // return the Matrix as one long Array + *indicesMatArr = convertToArray(indicesReturnMat); + + // return the Matrix dimensions + *kernelsMatColNum = kernelsReturnMat.n_cols; + *kernelsMatRowNum = kernelsReturnMat.n_rows; + + // return the Matrix as one long Array + *kernelsMatArr = convertToArray(kernelsReturnMat); +} + +// TODO: +// input: util::Timers & timers, +// const size_t k, +// arma::Mat< size_t > & indices <-, +// arma::mat & kernels <- +// output: +// description: +void searchNoQuery(SP_integer k, float **indicesMatArr, SP_integer *indicesMatColNum, SP_integer *indicesMatRowNum, float **kernelsMatArr, SP_integer *kernelsMatColNum, SP_integer *kernelsMatRowNum) +{ + // create the ReturnMat + arma::Mat< size_t > indicesReturnMat; + + // create the ReturnMat + mat kernelsReturnMat; + + fastMKSModel.Search(k, indicesReturnMat, kernelsReturnMat); + + // return the Matrix dimensions + *indicesMatColNum = indicesReturnMat.n_cols; + *indicesMatRowNum = indicesReturnMat.n_rows; + + // return the Matrix as one long Array + *indicesMatArr = convertToArray(indicesReturnMat); + + // return the Matrix dimensions + *kernelsMatColNum = kernelsReturnMat.n_cols; + *kernelsMatRowNum = kernelsReturnMat.n_rows; + + // return the Matrix as one long Array + *kernelsMatArr = convertToArray(kernelsReturnMat); +} diff --git a/src/methods/fastmks/fastmks.pl b/src/methods/fastmks/fastmks.pl new file mode 100644 index 0000000..7e95f7a --- /dev/null +++ b/src/methods/fastmks/fastmks.pl @@ -0,0 +1,67 @@ +:- module(fastmks, [ initModel/11, + searchWithQuery/11, + searchNoQuery/7]). + +%% requirements of library(struct) +:- load_files(library(str_decl), + [when(compile_time), if(changed)]). + +%% needed for using the array type +:- 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 + +%% TODO: +%% --Input-- +%% mat referenceData, +%% string kernel "linear", "polynomial", "cosine", "gaussian", "epanechnikov", "triangular", "hyptan" +%% float32 degree, +%% float32 offset, +%% float32 bandwidth, +%% float32 scale, +%% bool singleMode => (1)true / (0)false, +%% bool naive => (1)true / (0)false, +%% double base +%% +%% --Output-- +%% +%% --Description-- +foreign(initModel, c, initModel(+pointer(float_array), +integer, +integer, +string, +float32, +float32, +float32, +float32, +integer, +integer, +float32)). + +%% TODO: +%% --Input-- +%% mat querySet, +%% int k, +%% double base +%% +%% --Output-- +%% mat indices, +%% mat kernels +%% +%% --Description-- +foreign(searchWithQuery, c, searchWithQuery(+pointer(float_array), +integer, +integer, +integer, -pointer(float_array), -integer, -integer, -pointer(float_array), -integer, -integer, +float32)). + +%% TODO: +%% --Input-- +%% int k +%% +%% --Output-- +%% mat indices, +%% mat kernels +%% +%% --Description-- +foreign(searchNoQuery, c, searchNoQuery(+integer, -pointer(float_array), -integer, -integer, -pointer(float_array), -integer, -integer)). + + +%% Defines the functions that get connected from main.cpp +foreign_resource(fastmks, [ initModel, + searchWithQuery, + searchNoQuery]). + +:- load_foreign_resource(fastmks). \ No newline at end of file diff --git a/src/methods/fastmks/fastmks_test.pl b/src/methods/fastmks/fastmks_test.pl new file mode 100644 index 0000000..b33843d --- /dev/null +++ b/src/methods/fastmks/fastmks_test.pl @@ -0,0 +1,56 @@ +:- use_module(library(plunit)). + +:- use_module(fastmks). +:- 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 diff --git a/src/methods/new_method/new_method.pl b/src/methods/new_method/new_method.pl index 69edd4f..43f90c4 100644 --- a/src/methods/new_method/new_method.pl +++ b/src/methods/new_method/new_method.pl @@ -40,6 +40,8 @@ foreign(function, c, function(arguments)). %% array return %% -pointer(float_array), -integer +%% bool name => (1)true / (0)false + %% Defines the functions that get connected from main.cpp foreign_resource(new_method, [function]). -- GitLab