diff --git a/Makefile b/Makefile
index dc3d0c91dbed63835e729a44f4af7de28088aeb1..628ac7199c7333f9465be8795d851af41c7513f9 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@ all:
 	make -C src/methods/logistic_regression 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/perceptron splfr=$(SPLFR_PATH)
 
 clean:
 	make -C src/methods/ada_boost clean
@@ -24,3 +25,4 @@ clean:
 	make -C src/methods/logistic_regression clean
 	make -C src/methods/mean_shift clean
 	make -C src/methods/naive_bayes_classifier clean
+	make -C src/methods/perceptron clean
diff --git a/src/methods/perceptron/Makefile b/src/methods/perceptron/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3911c137838368723f9035ef9300a5381d3b1d70
--- /dev/null
+++ b/src/methods/perceptron/Makefile
@@ -0,0 +1,8 @@
+splfr=/usr/local/sicstus4.7.1/bin/splfr
+
+METHOD_NAME=perceptron
+
+$(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/perceptron/perceptron.cpp b/src/methods/perceptron/perceptron.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..789cf0a07725c63164a06db460a346eb8ef55875
--- /dev/null
+++ b/src/methods/perceptron/perceptron.cpp
@@ -0,0 +1,125 @@
+#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 "perceptron_glue.h"
+#include <mlpack/methods/perceptron/perceptron.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::perceptron;
+
+// Global Variable of the GlobalMethodObject object so it can be accessed from all functions
+Perceptron perceptronGlobal;
+
+// TODO: 
+// input:   const size_t 	numClasses = 0,
+//          const size_t 	dimensionality = 0,
+//          const size_t 	maxIterations = 1000
+// output: 
+// description: 
+void initModelNoTrain(SP_integer numClasses, SP_integer dimensionality, SP_integer maxIterations)
+{
+   perceptronGlobal = Perceptron(numClasses, dimensionality, maxIterations);
+}
+
+// TODO: 
+// input:   const MatType & 	            data,
+//          const arma::Row< size_t > &     labels,
+//          const size_t 	                numClasses,
+//          const size_t 	                maxIterations = 1000
+// output: 
+// description: 
+void initModelWithTrain(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *labelsArr, SP_integer labelsArrSize, SP_integer numClasses, SP_integer maxIterations)
+{
+    // convert the Prolog arrays to arma::mat
+    mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
+    
+    // convert the Prolog arrays to arma::rowvec
+    Row< size_t > labelsVector = convertArrayToVec(labelsArr, labelsArrSize);
+
+    perceptronGlobal = Perceptron(data, labelsVector, numClasses, maxIterations);
+}
+
+// TODO: 
+// input: 
+// output:  arma::vec&  biases
+// description: 
+void biases(float **biasesArr, SP_integer *biasesArrSize)
+{
+    // create the ReturnVector
+    vec biasesReturnVector = perceptronGlobal.Biases();
+    
+    // return the Vector lenght
+    *biasesArrSize = biasesReturnVector.n_elem;
+    
+    // return the Vector as Array
+    *biasesArr = convertToArray(biasesReturnVector);
+}
+
+// TODO: 
+// input:   const MatType &         test,
+//          arma::Row< size_t > &   predictedLabels <-
+// output: 
+// description: 
+void classify(float *testMatArr, SP_integer testMatSize, SP_integer testMatRowNum, float **predicLabeslsArr, SP_integer *predicLabeslsArrSize)
+{
+    // convert the Prolog arrays to arma::mat
+    mat test = convertArrayToMat(testMatArr, testMatSize, testMatRowNum);
+    
+    // create the ReturnVector
+    Row< size_t > predicLabeslsReturnVector;
+
+    perceptronGlobal.Classify(test, predicLabeslsReturnVector);
+    
+    // return the Vector lenght
+    *predicLabeslsArrSize = predicLabeslsReturnVector.n_elem;
+    
+    // return the Vector as Array
+    *predicLabeslsArr = convertToArray(predicLabeslsReturnVector);
+}
+
+// TODO: 
+// input:   const MatType & 	            data,
+//          const arma::Row< size_t > &     labels,
+//          const size_t 	                numClasses,
+//          const arma::rowvec & 	        instanceWeights = arma::rowvec()
+// output: 
+// description: 
+void train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *labelsArr, SP_integer labelsArrSize, SP_integer numClasses, float *instanceWeightsArr, SP_integer instanceWeightsArrSize)
+{
+    // convert the Prolog arrays to arma::mat
+    mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
+    
+    // convert the Prolog arrays to arma::rowvec
+    Row< size_t > labelsVector = convertArrayToVec(labelsArr, labelsArrSize);
+    
+    // convert the Prolog arrays to arma::rowvec
+    rowvec instanceWeightsVector = convertArrayToRowvec(instanceWeightsArr, instanceWeightsArrSize);
+
+    // use the model function
+    perceptronGlobal.Train(data, labelsVector, numClasses, instanceWeightsVector);
+}
+
+// TODO: 
+// input: 
+// output:  const arma::mat&    weights
+// description: 
+void weights(float **weightsMatArr, SP_integer *weightsMatColNum, SP_integer *weightsMatRowNum)
+{
+    // create the ReturnMat
+    mat weightsReturnMat = perceptronGlobal.Weights();
+    
+    // return the Matrix dimensions
+    *weightsMatColNum = weightsReturnMat.n_cols;
+    *weightsMatRowNum = weightsReturnMat.n_rows;
+    
+    // return the Matrix as one long Array
+    *weightsMatArr = convertToArray(weightsReturnMat);
+}
diff --git a/src/methods/perceptron/perceptron.pl b/src/methods/perceptron/perceptron.pl
new file mode 100644
index 0000000000000000000000000000000000000000..5e119794091bccfda93b4c004c9a1aafad41bc5a
--- /dev/null
+++ b/src/methods/perceptron/perceptron.pl
@@ -0,0 +1,87 @@
+:- module(perceptron, [     initModelNoTrain/3,
+                            initModelWithTrain/7,
+                            biases/2,
+                            classify/5,
+                            train/8,
+                            weights/3]).
+
+%% 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
+
+%% --Input--
+%%              int     numClasses      => 0,
+%%              int     dimensionality  => 0,
+%%              int     maxIterations   => 1000
+%%
+%% --Output--: 
+%% --Description-- 
+foreign(initModelNoTrain, c, initModelNoTrain(+integer, +integer, +integer)).
+
+%% --Input--
+%%              mat     data            => data(float_array), dataSize, dataRowNum,
+%%              vec     labels          => labels(float_array), labelsSize,
+%%              int     numClasses,
+%%              int     maxIterations   => 1000
+%%
+%% --Output--
+%% --Description-- 
+foreign(initModelWithTrain, c, initModelWithTrain(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, +integer)).
+
+%% --Input--    
+%%
+%% --Output--
+%%              vec     biases          => biases(float_array), biasesSize
+%%
+%% --Description-- 
+foreign(biases, c, biases(-pointer(float_array), -integer)).
+
+%% --Input--
+%%              mat     test            => test(float_array), testSize, testRowNum,
+%%
+%% --Output--
+%%              vec     predicLabels    => predicLabels(float_array), predicLabelsSize
+%%
+%% --Description-- 
+foreign(classify, c, classify(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer)).
+
+%% TODO: 
+%% --Input--
+%%              mat     data            => data(float_array), dataSize, dataRowNum,
+%%              vec     labels          => labels(float_array), labelsSize,
+%%              int     numClasses,
+%%              vec     instWeights     => instWeights(float_array), instWeightsSize       = arma::rowvec()
+%%
+%% --Output--
+%% --Description--
+foreign(train, c, train(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, +pointer(float_array), +integer)).
+
+%% --Input--
+%%
+%% --Output--
+%%              mat     weights         => weights(float_array), weightsColNum, weightsRowNum,
+%%
+%% --Description--
+foreign(weights, c, weights(-pointer(float_array), -integer, -integer)).
+
+
+%% Defines the functions that get connected from main.cpp
+foreign_resource(perceptron, [     initModelNoTrain,
+                                   initModelWithTrain,
+                                   biases,
+                                   classify,
+                                   train,
+                                   weights]).
+
+:- load_foreign_resource(perceptron).
\ No newline at end of file
diff --git a/src/methods/perceptron/perceptron_test.pl b/src/methods/perceptron/perceptron_test.pl
new file mode 100644
index 0000000000000000000000000000000000000000..5562eaee7b879bb400701829fcf6a3ee9cea2339
--- /dev/null
+++ b/src/methods/perceptron/perceptron_test.pl
@@ -0,0 +1,56 @@
+:- use_module(library(plunit)).
+
+:- use_module(perceptron).
+:- 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