diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5932d7129bd2cf4df1370363e047edd0791c5460..c6ea5ebd440df7ff84ff72ebb61a60d63b99c779 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,7 @@ set(SRC_FILES
 	paralellseriel.cpp
 	log.cpp
 	normalize.cpp
+	basicmath.cpp
 )
 
 set(API_HEADERS
@@ -24,6 +25,7 @@ set(API_HEADERS
 	eisgenerator/model.h
 	eisgenerator/log.h
 	eisgenerator/paralellseriel.h
+	eisgenerator/basichmath.h
 )
 
 add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
diff --git a/basicmath.cpp b/basicmath.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..911f98f86e6ea3a2e3605e2a0c490434213fc62e
--- /dev/null
+++ b/basicmath.cpp
@@ -0,0 +1,84 @@
+#include "basicmath.h"
+#include <algorithm>
+
+#include "eistype.h"
+
+std::complex<fvalue> eis::absGrad(const std::vector<eis::DataPoint>& data, size_t index)
+{
+	if(data.size() < 3)
+		return std::complex<fvalue>(1,1);
+
+	if(index == 0)
+		index = 1;
+	else if(index > data.size()-2)
+		index = data.size()-2;
+
+	return std::complex<fvalue>(std::abs((data[index+1].im.real()-data[index-1].im.real())/(data[index+1].omega-data[index-1].omega)),
+								std::abs((data[index+1].im.imag()-data[index-1].im.imag())/(data[index+1].omega-data[index-1].omega)));
+}
+
+std::complex<fvalue> eis::grad(const std::vector<eis::DataPoint>& data, size_t index)
+{
+	if(data.size() < 3)
+		return std::complex<fvalue>(1,1);
+
+	if(index == 0)
+		index = 1;
+	else if(index > data.size()-2)
+		index = data.size()-2;
+
+	return std::complex<fvalue>((data[index+1].im.real()-data[index-1].im.real())/(data[index+1].omega-data[index-1].omega),
+								(data[index+1].im.imag()-data[index-1].im.imag())/(data[index+1].omega-data[index-1].omega));
+}
+
+std::complex<fvalue> mean(const std::vector<eis::DataPoint>& data)
+{
+	fvalue accumRe = 0;
+	fvalue accumIm = 0;
+
+	for(const eis::DataPoint& point : data)
+	{
+		accumRe += point.im.real();
+		accumIm += point.im.imag();
+	}
+
+	accumRe /= data.size();
+	accumIm /= data.size();
+	return std::complex<fvalue>(accumRe, accumIm);
+}
+
+std::complex<fvalue> median(const std::vector<eis::DataPoint>& data)
+{
+	if(data.empty())
+		return std::complex<fvalue>(0,0);
+	else if(data.size() == 1)
+		return data[0].im;
+
+	std::vector<fvalue> imagParts;
+	imagParts.reserve(data.size());
+	std::vector<fvalue> realParts;
+	realParts.reserve(data.size());
+
+	for(const eis::DataPoint& point : data)
+	{
+		imagParts.push_back(point.im.imag());
+		realParts.push_back(point.im.real());
+	}
+
+	std::sort(imagParts.begin(), imagParts.end());
+	std::sort(realParts.begin(), realParts.end());
+
+
+	if(data.size() % 2 == 0)
+	{
+		fvalue real = (realParts[data.size()/2] + realParts[data.size()/2-1])/2;
+		fvalue imag = (imagParts[data.size()/2] + imagParts[data.size()/2-1])/2;
+		return std::complex<fvalue>(real, imag);
+	}
+	else
+	{
+		size_t index = data.size()/2;
+		return std::complex<fvalue>(realParts[index], imagParts[index]);
+	}
+
+}
diff --git a/eisgenerator/basicmath.h b/eisgenerator/basicmath.h
new file mode 100644
index 0000000000000000000000000000000000000000..e53962c983d18914b8728a96143d95844913adb8
--- /dev/null
+++ b/eisgenerator/basicmath.h
@@ -0,0 +1,12 @@
+#pragma once
+#include <vector>
+#include "model.h"
+#include "eistype.h"
+
+namespace eis
+{
+	std::complex<fvalue> absGrad(const std::vector<eis::DataPoint>& data, size_t index);
+	std::complex<fvalue> grad(const std::vector<eis::DataPoint>& data, size_t index);
+	std::complex<fvalue> mean(const std::vector<eis::DataPoint>& data);
+	std::complex<fvalue> median(const std::vector<eis::DataPoint>& data);
+}
diff --git a/eisgenerator/normalize.h b/eisgenerator/normalize.h
index 035b5844a5682db19276d3592f53f7d8598a370c..21409e83a943c369d133b5b1d22f6a71b281f6f7 100644
--- a/eisgenerator/normalize.h
+++ b/eisgenerator/normalize.h
@@ -10,7 +10,6 @@ namespace eis
 
 void normalize(std::vector<eis::DataPoint>& data);
 std::vector<eis::DataPoint> reduceRegion(const std::vector<eis::DataPoint>& data, fvalue gradThreshFactor = 0.01);
-std::complex<fvalue> absGrad(const std::vector<eis::DataPoint>& data, size_t index);
 void eraseSingularites(std::vector<eis::DataPoint>& data);
 
 }
diff --git a/normalize.cpp b/normalize.cpp
index e06fc4ec3bf857c1d8ebb13f22a4f73dc8b5d13f..b70f87a289137b2b6f322eaa13da1e4c8f3ac358 100644
--- a/normalize.cpp
+++ b/normalize.cpp
@@ -4,22 +4,7 @@
 #include <limits>
 #include "eistype.h"
 #include "log.h"
-
-std::complex<fvalue> eis::absGrad(const std::vector<eis::DataPoint>& data, size_t index)
-{
-	if(data.size() < 3)
-		return std::complex<fvalue>(1,1);
-
-	if(index == 0)
-		index = 1;
-	else if(index > data.size()-2)
-		index = data.size()-2;
-
-	return std::complex<fvalue>(std::abs((data[index+1].im.real()-data[index-1].im.real())/(data[index+1].omega-data[index-1].omega)),
-								std::abs((data[index+1].im.imag()-data[index-1].im.imag())/(data[index+1].omega-data[index-1].omega)));
-}
-
-
+#include "basicmath.h"
 
 void eis::eraseSingularites(std::vector<eis::DataPoint>& data)
 {