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

Adding kfn

parent 1fe34e94
Branches
No related tags found
No related merge requests found
splfr=/usr/local/sicstus4.7.1/bin/splfr
METHOD_NAME=kfn
$(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
#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 "kfn_glue.h"
#include <mlpack/methods/neighbor_search/ns_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::neighbor;
// Global Variable of the NSModel object so it can be accessed from all functions
NSModel<FurthestNS> nsModelObj;
// TODO:
// input: TreeTypes treeType = TreeTypes::KD_TREE,
// bool randomBasis = false,
// util::Timers & timers,
// arma::mat && referenceSet,
// const NeighborSearchMode searchMode,
// const double epsilon = 0
// output:
// description:
void initAndBuildModel(char const *treeType, char const *algorithm,
SP_integer randomBasis, SP_integer leafSize, double epsilon,
float *referenceMatArr, SP_integer referenceMatSize, SP_integer referenceMatRowNum)
{
// convert the Prolog array to arma::mat
mat reference = convertArrayToMat(referenceMatArr, referenceMatSize, referenceMatRowNum);
// select the treeType
NSModel<FurthestNS>::TreeTypes tree = NSModel<FurthestNS>::KD_TREE;
if (strcmp(treeType, "kd") == 0)
tree = NSModel<FurthestNS>::KD_TREE;
else if (strcmp(treeType, "cover") == 0)
tree = NSModel<FurthestNS>::COVER_TREE;
else if (strcmp(treeType, "r") == 0)
tree = NSModel<FurthestNS>::R_TREE;
else if (strcmp(treeType, "r-star") == 0)
tree = NSModel<FurthestNS>::R_STAR_TREE;
else if (strcmp(treeType, "ball") == 0)
tree = NSModel<FurthestNS>::BALL_TREE;
else if (strcmp(treeType, "x") == 0)
tree = NSModel<FurthestNS>::X_TREE;
else if (strcmp(treeType, "hilbert-r") == 0)
tree = NSModel<FurthestNS>::HILBERT_R_TREE;
else if (strcmp(treeType, "r-plus") == 0)
tree = NSModel<FurthestNS>::R_PLUS_TREE;
else if (strcmp(treeType, "r-plus-plus") == 0)
tree = NSModel<FurthestNS>::R_PLUS_PLUS_TREE;
else if (strcmp(treeType, "vp") == 0)
tree = NSModel<FurthestNS>::VP_TREE;
else if (strcmp(treeType, "rp") == 0)
tree = NSModel<FurthestNS>::RP_TREE;
else if (strcmp(treeType, "max-rp") == 0)
tree = NSModel<FurthestNS>::MAX_RP_TREE;
else if (strcmp(treeType, "ub") == 0)
tree = NSModel<FurthestNS>::UB_TREE;
else if (strcmp(treeType, "oct") == 0)
tree = NSModel<FurthestNS>::OCTREE;
else
cout << "wrong treeType input" << endl;
// select the searchMode
NeighborSearchMode searchMode = DUAL_TREE_MODE;
if (strcmp(algorithm, "naive") == 0)
searchMode = NAIVE_MODE;
else if (strcmp(algorithm, "single_tree") == 0)
searchMode = SINGLE_TREE_MODE;
else if (strcmp(algorithm, "dual_tree") == 0)
searchMode = DUAL_TREE_MODE;
else if (strcmp(algorithm, "greedy") == 0)
searchMode = GREEDY_SINGLE_TREE_MODE;
else
cout << "wrong algorithm input" << endl;
nsModelObj.TreeType() = tree;
nsModelObj.RandomBasis() = (randomBasis == 1);
nsModelObj.BuildModel(std::move(reference), size_t(leafSize), searchMode, epsilon);
}
// TODO:
// input: util::Timers & timers,
// arma::mat && querySet,
// const size_t k,
// arma::Mat< size_t > & neighbors <-,
// arma::mat & distances <-
// output:
// description:
void searchWithQuery( float *queryMatArr, SP_integer queryMatSize, SP_integer queryMatRowNum,
SP_integer k,
float **neighborsMatArr, SP_integer *neighborsMatColNum, SP_integer *neighborsMatRowNum,
float **distancesMatArr, SP_integer *distancesMatColNum, SP_integer *distancesMatRowNum)
{
// convert the Prolog array to arma::mat
mat query = convertArrayToMat(queryMatArr, queryMatSize, queryMatRowNum);
// create the ReturnMat
Mat< size_t > neighborsReturnMat;
// create the ReturnMat
mat distancesReturnMat;
nsModelObj.Search(move(query), (size_t)k, neighborsReturnMat, distancesReturnMat);
// return the Matrix
returnMatrixInformation(neighborsReturnMat, neighborsMatArr, neighborsMatColNum, neighborsMatRowNum);
// return the Matrix
returnMatrixInformation(distancesReturnMat, distancesMatArr, distancesMatColNum, distancesMatRowNum);
}
// TODO:
// input: util::Timers & timers,
// const size_t k,
// arma::Mat< size_t > & neighbors <-,
// arma::mat & distances <-
// output:
// description:
void searchNoQuery( SP_integer k,
float **neighborsMatArr, SP_integer *neighborsMatColNum, SP_integer *neighborsMatRowNum,
float **distancesMatArr, SP_integer *distancesMatColNum, SP_integer *distancesMatRowNum)
{
// create the ReturnMat
Mat< size_t > neighborsReturnMat;
// create the ReturnMat
mat distancesReturnMat;
nsModelObj.Search((size_t)k, neighborsReturnMat, distancesReturnMat);
// return the Matrix
returnMatrixInformation(neighborsReturnMat, neighborsMatArr, neighborsMatColNum, neighborsMatRowNum);
// return the Matrix
returnMatrixInformation(distancesReturnMat, distancesMatArr, distancesMatColNum, distancesMatRowNum);
}
\ No newline at end of file
:- module(kfn, [ initAndBuildModel/8,
searchWithQuery/10,
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--
%% string treeType => "kd", "vp", "rp", "max-rp", "ub", "cover", "r", "r-star", "x", "ball", "hilbert-r", "r-plus", "r-plus-plus", "spill", "oct",
%% string searchMode => "naive", "single_tree", "dual_tree", "greedy",
%% bool randomBasis => (1)true / (0)false,
%% int leafSize => 20,
%% float32 epsilon => 0.0,
%% mat referenceSet
%%
%% --Output--
%%
%% --Description--
foreign(initAndBuildModel, c, initAndBuildModel(+string, +string,
+integer, +integer, +float32,
+pointer(float_array), +integer, +integer)).
%% TODO:
%% --Input--
%% mat querySet,
%% int k
%%
%% --Output--
%% mat neighbors,
%% mat distances
%%
%% --Description--
foreign(searchWithQuery, c, searchWithQuery( +pointer(float_array), +integer, +integer,
+integer,
-pointer(float_array), -integer, -integer,
-pointer(float_array), -integer, -integer)).
%% TODO:
%% --Input--
%% int k
%%
%% --Output--
%% mat neighbors,
%% mat distances
%%
%% --Description--
foreign(searchNoQuery, c, searchNoQuery( +integer,
-pointer(float_array), -integer, -integer,
-pointer(float_array), -integer, -integer)).
%% Defines the functions that get connected from kfn.cpp
foreign_resource(kfn, [ initAndBuildModel,
searchWithQuery,
searchNoQuery]).
:- load_foreign_resource(kfn).
\ No newline at end of file
:- use_module(library(plunit)).
:- use_module(kfn).
:- 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment