diff --git a/Makefile b/Makefile index 7be3f52f04333a13dd3997d4c5684d3c2cb1b9ce..4cc8bfa0dc4ff0af31c328211b34836a0d205f22 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,11 @@ SPLFR_PATH=/usr/local/sicstus4.7.1/bin/splfr all: + @echo "Start compiling!" make -C src/methods/ada_boost splfr=$(SPLFR_PATH) + @echo "AdaBoost!" make -C src/methods/bayesian_linear_regression splfr=$(SPLFR_PATH) - make -C src/methods/cf splfr=$(SPLFR_PATH) + #make -C src/methods/cf splfr=$(SPLFR_PATH) make -C src/methods/dbscan splfr=$(SPLFR_PATH) make -C src/methods/emst splfr=$(SPLFR_PATH) make -C src/methods/fastmks splfr=$(SPLFR_PATH) @@ -17,15 +19,16 @@ all: make -C src/methods/lsh splfr=$(SPLFR_PATH) make -C src/methods/mean_shift splfr=$(SPLFR_PATH) make -C src/methods/naive_bayes_classifier splfr=$(SPLFR_PATH) + make -C src/methods/nmf splfr=$(SPLFR_PATH) make -C src/methods/perceptron splfr=$(SPLFR_PATH) make -C src/methods/random_forest splfr=$(SPLFR_PATH) - make -C src/methods/softmac_regression splfr=$(SPLFR_PATH) + make -C src/methods/softmax_regression splfr=$(SPLFR_PATH) make -C src/methods/approx_kfn splfr=$(SPLFR_PATH) clean: make -C src/methods/ada_boost clean make -C src/methods/bayesian_linear_regression clean - make -C src/methods/cf clean + #make -C src/methods/cf clean make -C src/methods/dbscan clean make -C src/methods/emst clean make -C src/methods/fastmks clean @@ -38,9 +41,10 @@ clean: make -C src/methods/lsh clean make -C src/methods/mean_shift clean make -C src/methods/naive_bayes_classifier clean + make -C src/methods/nmf clean make -C src/methods/perceptron clean make -C src/methods/random_forest clean - make -C src/methods/softmac_regression clean + make -C src/methods/softmax_regression clean make -C src/methods/approx_kfn clean - \ No newline at end of file + diff --git a/src/methods/nmf/Makefile b/src/methods/nmf/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..387b1e095d43b830cd142d27f9d7fd7721d2aa02 --- /dev/null +++ b/src/methods/nmf/Makefile @@ -0,0 +1,8 @@ +splfr=/usr/local/sicstus4.7.1/bin/splfr + +METHOD_NAME=nmf + +$(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/nmf/nmf.cpp b/src/methods/nmf/nmf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2bd5e933c9a7049b8496349000e7e7295521929 --- /dev/null +++ b/src/methods/nmf/nmf.cpp @@ -0,0 +1,74 @@ +#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 "nmf_glue.h" +#include <mlpack/methods/amf/amf.hpp> +#include <mlpack/core.hpp> + +#include <mlpack/methods/amf/update_rules/nmf_mult_div.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::amf; + + +// TODO: +// input: const TerminationPolicyType & terminationPolicy = TerminationPolicyType(), +// const InitializationRuleType & initializeRule = InitializationRuleType(), +// const UpdateRuleType & update = UpdateRuleType() +// const MatType & V, +// const size_t r, +// arma::mat & W, +// arma::mat & H +// +// output: double +// +// description: +void nmf(char const *updateRule, SP_integer maxIterations, double minResidue, + float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, + SP_integer rank, + float **WMatArr, SP_integer *WMatColNum, SP_integer *WMatRowNum, + float **HMatArr, SP_integer *HMatColNum, SP_integer *HMatRowNum) +{ + // convert the Prolog arrays to arma::mat + mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); + + // create the ReturnMat + mat WReturnMat; + + // create the ReturnMat + mat HReturnMat; + + // decide which update rule to use + if (strcmp(updateRule, "multdist") == 0) + { + AMF<SimpleResidueTermination, RandomAcolInitialization<>,NMFMultiplicativeDistanceUpdate>(SimpleResidueTermination(minResidue, maxIterations)) + .Apply(data, rank, WReturnMat, HReturnMat); + } + else if (strcmp(updateRule, "multdiv") == 0) + { + AMF<SimpleResidueTermination, RandomAcolInitialization<>,NMFMultiplicativeDivergenceUpdate>(SimpleResidueTermination(minResidue, maxIterations)) + .Apply(data, rank, WReturnMat, HReturnMat); + } + else if (strcmp(updateRule, "als") == 0) + { + AMF<SimpleResidueTermination, RandomAcolInitialization<>,NMFALSUpdate>(SimpleResidueTermination(minResidue, maxIterations)) + .Apply(data, rank, WReturnMat, HReturnMat); + } + else + { + cout << "wrong updateRule input" << endl; + } + + // return the Matrix + returnMatrixInformation(WReturnMat, WMatArr, WMatColNum, WMatRowNum); + + // return the Matrix + returnMatrixInformation(HReturnMat, HMatArr, HMatColNum, HMatRowNum); +} \ No newline at end of file diff --git a/src/methods/nmf/nmf.pl b/src/methods/nmf/nmf.pl new file mode 100644 index 0000000000000000000000000000000000000000..98b6ac3b5aa84278c1a80fe49e4b4d00fd2e73ee --- /dev/null +++ b/src/methods/nmf/nmf.pl @@ -0,0 +1,41 @@ +:- module(nmf, [nmf/13]). + +%% 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-- +%% bool updateRuel => (1)true / (0)false, +%% int maxIterations => 10000, +%% float32 minResidue => 1e-05, +%% mat data, +%% int rank +%% +%% --Output-- +%% mat W, +%% mat H +%% +%% --Description-- +foreign(nmf, c, nmf(+string, +integer, +float32, + +pointer(float_array), +integer, +integer, + +integer, + -pointer(float_array), -integer, -integer, + -pointer(float_array), -integer, -integer)). + + +%% Defines the functions that get connected from main.cpp +foreign_resource(nmf, [nmf]). + +:- load_foreign_resource(nmf). \ No newline at end of file diff --git a/src/methods/nmf/nmf_test.pl b/src/methods/nmf/nmf_test.pl new file mode 100644 index 0000000000000000000000000000000000000000..3132d0d859bd5228b4fb5f523f073d4b9dec55d0 --- /dev/null +++ b/src/methods/nmf/nmf_test.pl @@ -0,0 +1,56 @@ +:- use_module(library(plunit)). + +:- use_module(nmf). +:- 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