diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1b6e12fbab6213f0133e489c10aab61be9d6c7fd..81b27944f279a77c1d2a0a4508259a4b2a9c40d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,14 @@ cmake_minimum_required(VERSION 3.20)
 
 project(ehigeneratorsa)
 
-set(SRC_FILES  main.cpp cap.cpp resistor.cpp model.cpp tokenize.cpp)
+set(SRC_FILES
+	main.cpp
+	cap.cpp
+	resistor.cpp
+	constantphase.cpp
+	model.cpp
+	tokenize.cpp
+)
 
 find_package(PkgConfig REQUIRED)
 pkg_check_modules(SPICE REQUIRED ngspice)
@@ -10,6 +17,6 @@ pkg_check_modules(SPICE REQUIRED ngspice)
 add_executable(${PROJECT_NAME} ${SRC_FILES})
 target_link_libraries(${PROJECT_NAME} ${SPICE_LIBRARIES})
 target_include_directories(${PROJECT_NAME} PUBLIC ${SPICE_CFLAGS} .)
-set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-std=c++20 -Wall -O0 -march=native -g" LINK_FLAGS "-flto")
+set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-std=c++20 -Wall -O3 -march=native -g" LINK_FLAGS "-flto")
 
 install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
diff --git a/cap.cpp b/cap.cpp
index 447d5641fcb25ba4efbd34172dfda5ca135f82e5..0bed2004a2a9a707be626f2ba0d5facb04af49cf 100644
--- a/cap.cpp
+++ b/cap.cpp
@@ -51,3 +51,8 @@ void Cap::setParam(const std::vector<double>& param)
 
 	_C = param[0];
 }
+
+size_t Cap::paramCount()
+{
+	return 1;
+}
diff --git a/cap.h b/cap.h
index 95c7bb2e6a1797df9525be61eed1817a2cb94326..ad7cd7335c259ca858b5c59785d43d7c956d0cde 100644
--- a/cap.h
+++ b/cap.h
@@ -14,4 +14,5 @@ public:
 	virtual std::complex<double> execute(double omega) override;
 	virtual std::vector<double> getParam() override;
 	virtual void setParam(const std::vector<double>& param) override;
+	virtual size_t paramCount() override;
 };
diff --git a/componant.h b/componant.h
index c5f3a53b929643d8dea456d3cf10ee7408a6a1ca..b93967f1938095346e219835cf606a2be9303d2b 100644
--- a/componant.h
+++ b/componant.h
@@ -17,4 +17,5 @@ class Componant
 			return std::vector<double>();
 		};
 		virtual void setParam(const std::vector<double>& param){};
+		virtual size_t paramCount(){return 0;}
 };
diff --git a/constantphase.cpp b/constantphase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa86aa0b129f4e24fdf3c13bc916c63c87054b47
--- /dev/null
+++ b/constantphase.cpp
@@ -0,0 +1,63 @@
+#include "constantphase.h"
+#include "tokenize.h"
+#include <cstdlib>
+#include <math.h>
+
+Cpe::Cpe(double q, double alpha): _Q(q), _alpha(alpha)
+{
+
+}
+
+Cpe::Cpe(std::string paramStr)
+{
+	std::vector<std::string> tokens = tokenize(paramStr, ',');
+	if(tokens.size() < 2)
+	{
+		std::cout<<"Warning: to few parameters in "<<__func__<<" parameter string: "<<paramStr<<'\n';
+		_Q = 1e-7;
+		_alpha = 0.9;
+		return;
+	}
+	else
+	{
+		try
+		{
+			_Q = std::stod(tokens[0]);
+			_alpha = std::stod(tokens[1]);
+		}
+		catch(const std::invalid_argument& ia)
+		{
+			std::cout<<"Warning: cant parse parameter in "<<__func__<<" parameter: "<<tokens[0]<<'\n';
+			_Q = 1e-7;
+			_alpha = 0.9;
+		}
+	}
+}
+
+std::complex<double> Cpe::execute(double omega)
+{
+	return std::complex<double>((1.0/(_Q*pow(omega, _alpha)))*cos((M_PI/2)*_alpha),
+	                           0-(1.0/(_Q*pow(omega, _alpha)))*sin((M_PI/2)*_alpha));
+}
+
+std::vector<double> Cpe::getParam()
+{
+	return std::vector<double>({_Q, _alpha});
+}
+
+void Cpe::setParam(const std::vector<double>& param)
+{
+	if(param.size() < 2)
+	{
+		std::cout<<"Warning: invalid parameter list sent to "<<__func__<<'\n';
+		return;
+	}
+
+	_Q = param[0];
+	_alpha = param[1];
+}
+
+size_t Cpe::paramCount()
+{
+	return 2;
+}
diff --git a/constantphase.h b/constantphase.h
new file mode 100644
index 0000000000000000000000000000000000000000..81804ec9373664304ae3dd61f3efc2ee3af514a3
--- /dev/null
+++ b/constantphase.h
@@ -0,0 +1,19 @@
+#pragma once
+#include <complex>
+#include <string>
+#include <vector>
+#include "componant.h"
+
+class Cpe: public Componant
+{
+private:
+	double _Q;
+	double _alpha;
+public:
+	Cpe(std::string paramStr);
+	Cpe(double q = 1e-7, double alpha = 0.9);
+	virtual std::complex<double> execute(double omega) override;
+	virtual std::vector<double> getParam() override;
+	virtual void setParam(const std::vector<double>& param) override;
+	virtual size_t paramCount() override;
+};
diff --git a/main.cpp b/main.cpp
index 7f83be72605ad92c890f6242f0887e36a0b301c9..65d0be49c9a62f91a96ed55fa279570dbb9861e8 100644
--- a/main.cpp
+++ b/main.cpp
@@ -6,18 +6,31 @@
 
 double omegafn(size_t i)
 {
-	return i*10;
+	return i*10000;
 }
 
 int main(int argc, char** argv)
 {
-	std::string modelStr("r{1e3}-(c{1e-6}r{1e3})");
+	std::string modelStr("r{20e3}p{1e-7, 0.9}");
 
 	std::vector<Model::DataPoint> results;
 
 	Model model(modelStr);
+	std::cout<<"Compnants: \n";
+	for(Componant* componant : model.getFlatComponants())
+	{
+		std::cout<<Model::getComponantChar(componant)<<"{";
+		for(size_t i = 0; i < componant->paramCount(); ++i)
+		{
+			std::cout<<componant->getParam()[i];
+			if(i != componant->paramCount()-1)
+				std::cout<<", ";
+		}
+		std::cout<<"}\n";
+	}
+
 	auto start = std::chrono::high_resolution_clock::now();
-	for(size_t i = 0; i < 50; ++i)
+	for(size_t i = 0; i < 101; ++i)
 		results.push_back(model.execute(omegafn(i)));
 	auto end = std::chrono::high_resolution_clock::now();
 	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
diff --git a/model.cpp b/model.cpp
index 375ce2741e37366d16f894e18b911d99c93b2145..c7b80d1bf17c637575a93362793d5e91cca000af 100644
--- a/model.cpp
+++ b/model.cpp
@@ -3,6 +3,7 @@
 #include "tokenize.h"
 #include "cap.h"
 #include "resistor.h"
+#include "constantphase.h"
 
 Model::Paralell::Paralell(std::vector<Componant*> componantsIn): componants(componantsIn)
 {
@@ -139,6 +140,11 @@ Componant *Model::processBracket(std::string& str)
 					componants.push_back(new Resistor(getParamStr(nodeStr, i)));
 					i = opposingBraket(nodeStr, i, '}');
 					break;
+				case 'p':
+				case 'P':
+					componants.push_back(new Cpe(getParamStr(nodeStr, i)));
+					i = opposingBraket(nodeStr, i, '}');
+					break;
 				case '{':
 					i = opposingBraket(nodeStr, i, '}');
 				case '}':
@@ -193,3 +199,47 @@ Model::DataPoint Model::execute(double omega)
 	}
 	return DataPoint({std::complex<double>(0,0), 0});
 }
+
+void Model::addComponantToFlat(Componant* componant)
+{
+	Paralell* paralell = dynamic_cast<Paralell*>(componant);
+	if(paralell)
+	{
+		for(Componant* element : paralell->componants)
+			addComponantToFlat(element);
+		return;
+	}
+
+	Serial* serial = dynamic_cast<Serial*>(componant);
+	if(serial)
+	{
+		for(Componant* element : serial->componants)
+			addComponantToFlat(element);
+		return;
+	}
+
+	_flatComponants.push_back(componant);
+}
+
+std::vector<Componant*> Model::getFlatComponants()
+{
+	if(!_flatComponants.empty())
+		return _flatComponants;
+
+	addComponantToFlat(_model);
+	return getFlatComponants();
+}
+
+char Model::getComponantChar(Componant* componant)
+{
+	if(dynamic_cast<Resistor*>(componant))
+		return 'r';
+
+	if(dynamic_cast<Cap*>(componant))
+		return 'c';
+
+	if(dynamic_cast<Cpe*>(componant))
+		return 'p';
+
+	return 'x';
+}
diff --git a/model.h b/model.h
index bee488ed2c6a227542ea518f0d7052b86cdc7931..18b3e3a99abac0a58447ff57c75450d83ba2ed76 100644
--- a/model.h
+++ b/model.h
@@ -38,6 +38,7 @@ private:
 	Componant *processBrackets(std::string& str, size_t& bracketCounter);
 	Componant *processBracket(std::string& str);
 	std::string getParamStr(const std::string& str, size_t index);
+	void addComponantToFlat(Componant* componant);
 
 private:
 	Componant *_model = nullptr;
@@ -50,4 +51,5 @@ public:
 	DataPoint execute(double omaga);
 	std::string getModelStr();
 	std::vector<Componant*> getFlatComponants();
+	static char getComponantChar(Componant* componant);
 };
diff --git a/resistor.cpp b/resistor.cpp
index d9b33b32a3235ff3b2f21487b42020b0097bed39..d81c17f5cdd45d1f82373e4e40d5caf5d1dca19f 100644
--- a/resistor.cpp
+++ b/resistor.cpp
@@ -50,3 +50,8 @@ void Resistor::setParam(const std::vector<double>& param)
 
 	_R = param[0];
 }
+
+size_t Resistor::paramCount()
+{
+	return 1;
+}
diff --git a/resistor.h b/resistor.h
index 0f9d2cd2c73e723ddd5274264d3090127fb991fd..aa894cbfd98195042ebb50cbd95d70137c44b02d 100644
--- a/resistor.h
+++ b/resistor.h
@@ -13,4 +13,5 @@ public:
 	virtual std::complex<double> execute(double omega)  override;
 	virtual std::vector<double> getParam() override;
 	virtual void setParam(const std::vector<double>& param) override;
+	virtual size_t paramCount() override;
 };