Ver código fonte

c++ version->filesystem?

willi 4 anos atrás
pai
commit
834efea6bf
100 arquivos alterados com 45298 adições e 967 exclusões
  1. 752 157
      .idea/workspace.xml
  2. 20 7
      CMakeLists.txt
  3. 38 0
      cmake/configure_msvc.cmake
  4. 0 0
      cmake/mdd-config.cmake
  5. 42 9
      lib/CMakeLists.txt
  6. 42 0
      lib/include/Connector.h
  7. 38 0
      lib/include/Generator.h
  8. 18 0
      lib/include/IConnection.h
  9. 16 0
      lib/include/IGenerator.h
  10. 25 6
      lib/include/IInput.h
  11. 16 4
      lib/include/IModule.h
  12. 18 0
      lib/include/IOptimizable.h
  13. 18 0
      lib/include/IOptimizer.h
  14. 12 5
      lib/include/IOutput.h
  15. 5 1
      lib/include/IProcessor.h
  16. 55 0
      lib/include/IProperty.h
  17. 14 0
      lib/include/IState.h
  18. 2 3
      lib/include/IUnique.h
  19. 30 13
      lib/include/Input.h
  20. 22 12
      lib/include/ModuleBase.h
  21. 0 32
      lib/include/ModuleHTTP.h
  22. 0 41
      lib/include/ModuleMath.h
  23. 18 0
      lib/include/ModuleMerge.h
  24. 16 0
      lib/include/ModuleParameter.h
  25. 28 0
      lib/include/ModuleSQL.h
  26. 0 0
      lib/include/ModuleSplitt.h
  27. 1 1
      lib/include/ModuleSwitch.h
  28. 32 0
      lib/include/OptimizerBase.h
  29. 49 0
      lib/include/OptimizerEvolutionary.h
  30. 21 9
      lib/include/Output.h
  31. 39 19
      lib/include/ProcessorBase.h
  32. 0 0
      lib/include/ProcessorEvolution.h
  33. 0 14
      lib/include/ProcessorManual.h
  34. 39 0
      lib/include/ProcessorStandard.h
  35. 61 0
      lib/include/Property.h
  36. 11 0
      lib/include/UpdateState.h
  37. 11 0
      lib/include/state.h
  38. 18 0
      lib/src/Connector.cpp
  39. 24 0
      lib/src/Generator.cpp
  40. 60 13
      lib/src/Input.cpp
  41. 77 8
      lib/src/ModuleBase.cpp
  42. 85 33
      lib/src/ModuleHTTP.cpp
  43. 214 297
      lib/src/ModuleMath.cpp
  44. 44 0
      lib/src/ModuleMerge.cpp
  45. 14 0
      lib/src/ModuleParameter.cpp
  46. 168 0
      lib/src/ModuleSQL.cpp
  47. 0 0
      lib/src/ModuleSplitt.cpp
  48. 20 17
      lib/src/ModuleSwitch.cpp
  49. 58 0
      lib/src/OptimizerBase.cpp
  50. 282 0
      lib/src/OptimizerEvolutionary.cpp
  51. 52 9
      lib/src/Output.cpp
  52. 116 8
      lib/src/ProcessorBase.cpp
  53. 0 0
      lib/src/ProcessorEvolution.cpp
  54. 0 30
      lib/src/ProcessorManual.cpp
  55. 154 0
      lib/src/ProcessorStandard.cpp
  56. 16 10
      lib/test/CMakeLists.txt
  57. BIN
      lib/test/db/materials.db
  58. 2 0
      lib/test/server/.gitignore
  59. BIN
      lib/test/server/__pycache__/ini_logger.cpython-36.pyc
  60. 15 0
      lib/test/server/ansys/00_Model.inp
  61. 21 0
      lib/test/server/ansys/01_Parameter.inp
  62. 61 0
      lib/test/server/ansys/02_Laminate.inp
  63. 53 0
      lib/test/server/ansys/03_Modell.inp
  64. 39 0
      lib/test/server/ansys/04_Plot.inp
  65. 179 0
      lib/test/server/gfk_plate.py
  66. 0 2
      lib/test/server/links.txt
  67. 16 0
      lib/test/server/monitor.json
  68. 135 0
      lib/test/server/server-ansys.py
  69. 9 9
      lib/test/server/server.py
  70. 140 0
      lib/test/test_Ansys.cpp
  71. 69 0
      lib/test/test_Connector.cpp
  72. 30 28
      lib/test/test_ModuleHTTP.cpp
  73. 50 38
      lib/test/test_ModuleMath.cpp
  74. 236 0
      lib/test/test_ModuleSQL.cpp
  75. 26 26
      lib/test/test_ModuleSwitch.cpp
  76. 80 0
      lib/test/test_OptimizerEvolutionary.cpp
  77. 0 106
      lib/test/test_ProcessorManual.cpp
  78. 183 0
      lib/test/test_ProcessorStandard.cpp
  79. 54 0
      thirdparty/exprtk/Makefile
  80. BIN
      thirdparty/exprtk/exprtk - Verknüpfung.lnk
  81. 39050 0
      thirdparty/exprtk/exprtk.hpp
  82. 564 0
      thirdparty/exprtk/exprtk_benchmark.cpp
  83. 58 0
      thirdparty/exprtk/exprtk_simple_example_01.cpp
  84. 73 0
      thirdparty/exprtk/exprtk_simple_example_02.cpp
  85. 60 0
      thirdparty/exprtk/exprtk_simple_example_03.cpp
  86. 88 0
      thirdparty/exprtk/exprtk_simple_example_04.cpp
  87. 81 0
      thirdparty/exprtk/exprtk_simple_example_05.cpp
  88. 60 0
      thirdparty/exprtk/exprtk_simple_example_06.cpp
  89. 71 0
      thirdparty/exprtk/exprtk_simple_example_07.cpp
  90. 90 0
      thirdparty/exprtk/exprtk_simple_example_08.cpp
  91. 152 0
      thirdparty/exprtk/exprtk_simple_example_09.cpp
  92. 92 0
      thirdparty/exprtk/exprtk_simple_example_10.cpp
  93. 71 0
      thirdparty/exprtk/exprtk_simple_example_11.cpp
  94. 69 0
      thirdparty/exprtk/exprtk_simple_example_12.cpp
  95. 100 0
      thirdparty/exprtk/exprtk_simple_example_13.cpp
  96. 56 0
      thirdparty/exprtk/exprtk_simple_example_14.cpp
  97. 94 0
      thirdparty/exprtk/exprtk_simple_example_15.cpp
  98. 82 0
      thirdparty/exprtk/exprtk_simple_example_16.cpp
  99. 78 0
      thirdparty/exprtk/exprtk_simple_example_17.cpp
  100. 0 0
      thirdparty/exprtk/exprtk_simple_example_18.cpp

Diferenças do arquivo suprimidas por serem muito extensas
+ 752 - 157
.idea/workspace.xml


+ 20 - 7
CMakeLists.txt

@@ -1,18 +1,31 @@
-
-
 cmake_minimum_required(VERSION 3.8.0)
 project(mdd)
 option(TESTS_ENABLED "enable unit tests" ON)
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
 
-install(FILES cmake/auslegung-config.cmake DESTINATION .)
+include(cmake/configure_msvc.cmake)
+configure_msvc_runtime()
+install(FILES cmake/mdd-config.cmake DESTINATION .)
 
 if(${TESTS_ENABLED})
     enable_testing()
-    include_directories(/usr/src/gtest/include)
-    add_subdirectory(/usr/src/gtest ${CMAKE_CURRENT_BINARY_DIR}/gtest)
+    add_definitions(-D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING )
+
+    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/googletest/googlemock/include)
+    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/googletest)
 endif()
 
+FIND_PACKAGE( Boost REQUIRED  COMPONENTS program_options system)
+INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} )
+LINK_DIRECTORIES( ${Boost_LIBRARY_DIRS} )
+
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/json/single_include)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/cpp-httplib)
-add_subdirectory(lib)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/exprtk)
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/sqlite3)
+
+add_subdirectory(lib)
+
+install(FILES thirdparty/json/single_include/json.hpp DESTINATION include)
+
+install(FILES thirdparty/json/single_include/nlohmann/json.hpp DESTINATION include/nlohmann)

+ 38 - 0
cmake/configure_msvc.cmake

@@ -0,0 +1,38 @@
+macro(configure_msvc_runtime)
+  if(MSVC)
+    # Default to statically-linked runtime.
+    if("${MSVC_RUNTIME}" STREQUAL "")
+      set(MSVC_RUNTIME "static")
+    endif()
+    # Set compiler options.
+    set(variables
+      CMAKE_C_FLAGS_DEBUG
+      CMAKE_C_FLAGS_MINSIZEREL
+      CMAKE_C_FLAGS_RELEASE
+      CMAKE_C_FLAGS_RELWITHDEBINFO
+      CMAKE_CXX_FLAGS_DEBUG
+      CMAKE_CXX_FLAGS_MINSIZEREL
+      CMAKE_CXX_FLAGS_RELEASE
+      CMAKE_CXX_FLAGS_RELWITHDEBINFO
+    )
+    if(${MSVC_RUNTIME} STREQUAL "static")
+      message(STATUS
+        "MSVC -> forcing use of statically-linked runtime."
+      )
+      foreach(variable ${variables})
+        if(${variable} MATCHES "/MD")
+          string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}")
+        endif()
+      endforeach()
+    else()
+      message(STATUS
+        "MSVC -> forcing use of dynamically-linked runtime."
+      )
+      foreach(variable ${variables})
+        if(${variable} MATCHES "/MT")
+          string(REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}")
+        endif()
+      endforeach()
+    endif()
+  endif()
+endmacro()

cmake/auslegung-config.cmake → cmake/mdd-config.cmake


+ 42 - 9
lib/CMakeLists.txt

@@ -1,44 +1,77 @@
-
-
 cmake_minimum_required(VERSION 3.8.0)
 project(mdd_lib)
 
-add_library(${PROJECT_NAME} STATIC
+add_library(${PROJECT_NAME} SHARED
+	include/Connector.h
+	include/Generator.h
         include/HandlerModule
-        include/Input.h
-        include/IListener.h
+	include/IConnection.h
+	include/IGenerator.h
+        include/IInput.h
         include/IModule.h
         include/Input.h
+	include/IOptimizable.h
+	include/IOptimizer.h
         include/IOutput.h
         include/IProcessor.h
+	include/IProperty.h
+	include/IState.h
         include/IUnique.h
         include/ModuleBase.h
-        include/ModuleHTTP.h
-        include/ModuleMath.h
+	include/ModuleMerge.h
+	include/ModuleParameter.h
+	include/ModuleSplitt.h
+        include/ModuleSQL.h
         include/ModuleSwitch.h
+	include/OptimizerBase.h
+	include/OptimizerEvolutionary.h
         include/Output.h
         include/ProcessorBase.h
-        include/ProcessorManual.h
+        include/ProcessorEvolution.h
+	include/ProcessorStandard.h
+	include/Property.h
+	include/state.h
 
+	src/Connector.cpp
+	src/Generator.cpp
         src/Input.cpp
         src/ModuleBase.cpp
         src/ModuleHTTP.cpp
         src/ModuleMath.cpp
+	src/ModuleMerge.cpp
+	src/ModuleParameter.cpp
+	src/ModuleSplitt.cpp
+        src/ModuleSQL.cpp
         src/ModuleSwitch.cpp
+	src/OptimizerBase.cpp
+	src/OptimizerEvolutionary.cpp
         src/Output.cpp
         src/ProcessorBase.cpp
-        src/ProcessorManual.cpp
+	src/ProcessorEvolution.cpp
+        src/ProcessorStandard.cpp
         )
 
 target_include_directories(${PROJECT_NAME} PUBLIC
         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
         $<INSTALL_INTERFACE:include>)
 
+target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} sqlite3)
+
+set_target_properties( ${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
+if(WIN32)
+	target_compile_options(${PROJECT_NAME} PRIVATE /bigobj)
+endif(WIN32)
+
 install(DIRECTORY include DESTINATION .)
 
 install(TARGETS ${PROJECT_NAME} DESTINATION lib/$<CONFIG> EXPORT targets)
 install(EXPORT targets DESTINATION cmake)
 
+add_custom_command(TARGET mdd_lib POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy
+	"$<TARGET_FILE:mdd_lib>"
+	"${CMAKE_BINARY_DIR}/lib/test/$<CONFIGURATION>")
+
 
 if(${TESTS_ENABLED})
     add_subdirectory(test)

+ 42 - 0
lib/include/Connector.h

@@ -0,0 +1,42 @@
+#ifndef CONNECTOR_H
+#define CONNECTOR_H
+#include "memory"
+#include "json.hpp"
+
+#include "Input.h"
+#include "Output.h"
+
+#include "ModuleMerge.h"
+#include "ModuleSplitt.h"
+#include "ModuleSQL.h"
+#include "ModuleSwitch.h"
+
+#include "ProcessorStandard.h"
+
+namespace mdd {
+	class Connector {
+
+	public:
+		/*
+		json{
+		"type": "StandardProcessor",
+		("params": [param1, param2,...])
+		("subs":[
+		{
+		"type": "Math",
+		"params":[param1,param2,...]
+		},
+		{
+		"type": "Math",
+		"params":[param1,param2,...]
+		}
+		],
+		"connections":[[in1,out1],[in2,out2],...]
+		})
+		*/
+		static std::shared_ptr<IModule> decode(const json& structure);
+		static const json& encode(const std::shared_ptr<IModule>& structure);
+	};
+}
+
+#endif

+ 38 - 0
lib/include/Generator.h

@@ -0,0 +1,38 @@
+
+
+#pragma once
+
+#include <map>
+#include <string>
+#include "IGenerator.h"
+
+namespace mdd
+{
+	template <class MODULE_CLASS>
+	class Generator
+		: public IGenerator
+	{
+
+		virtual std::shared_ptr<IModule> Generate()
+		{
+			return std::make_shared<MODULE_CLASS>();
+		}
+	};
+
+	std::map<std::string, std::shared_ptr<IGenerator>>&
+		GetGenerators(
+			const std::string& name = "", 
+			const std::shared_ptr<IGenerator>& generator = nullptr);
+
+	template<class MODULE_CLASS>
+	class GeneratorRegistration
+	{
+	public:
+		GeneratorRegistration(const std::string& name)
+		{
+			GetGenerators(name.substr(6), std::make_shared<Generator<MODULE_CLASS>>());
+		}
+	};
+}
+
+#define ADD_GENERATOR(CLASS) namespace{mdd::GeneratorRegistration<CLASS> reg_sdewfdsf(typeid(CLASS).name());}

+ 18 - 0
lib/include/IConnection.h

@@ -0,0 +1,18 @@
+#ifndef ICONNECTION_H
+#define ICONNECTION_H
+
+#include <vector>
+#include <memory>
+
+namespace mdd {
+	template <class T>
+	class IConnection {
+	public:
+		virtual int addConnection(std::shared_ptr<T> conector) = 0;
+		virtual int removeConnection(std::shared_ptr<T> conector) = 0;
+		virtual bool connect(std::shared_ptr<T> conector) = 0;
+		virtual ~IConnection() {};
+	};
+}
+
+#endif

+ 16 - 0
lib/include/IGenerator.h

@@ -0,0 +1,16 @@
+
+#pragma once
+
+#include <memory>
+#include "IModule.h"
+
+namespace mdd
+{
+	class IGenerator
+	{
+	public:
+		virtual ~IGenerator() {}
+
+		virtual std::shared_ptr<IModule> Generate() = 0;
+	};
+}

+ 25 - 6
lib/include/IInput.h

@@ -1,15 +1,34 @@
 #ifndef MDD_IINPUT_H
 #define MDD_IINPUT_H
 
-#include "IUnique.h"
+//#include "json.hpp"
+#include <memory>
 #include "IOutput.h"
+#include "IUnique.h"
+#include "IState.h"
+#include "IConnection.h"
+#include "IOptimizable.h"
+#include <vector>
+
 namespace mdd{
-    class IInput : public IUnique{
+    struct limits {
+        std::vector<double> min;
+        std::vector<double> max;
+        std::vector<double> step;
+        std::string rule;
+        std::vector<std::vector<double>> elements;
+    };
+
+    class IInput 
+        : public IUnique
+        , public IState
+        , public IConnection<IOutput>
+        , public IOptimizable
+    {
     public:
-        virtual const json& getValue() = 0;
-        virtual json& setDefaultValue() = 0;
-        virtual bool verify(const json & data) = 0;
-        virtual bool connect(std::shared_ptr<IOutput> output) = 0;
+        virtual const limits& getLimits() = 0;
+        virtual limits& setLimits() = 0;
+        virtual std::shared_ptr<IOutput> getConnection() = 0;
         virtual ~IInput() = default;
     };
 }

+ 16 - 4
lib/include/IModule.h

@@ -3,6 +3,8 @@
 
 #include "IOutput.h"
 #include "IInput.h"
+#include "IProperty.h"
+#include "state.h"
 #include <string>
 #include <vector>
 #include <memory>
@@ -10,17 +12,27 @@
 namespace mdd {
     class IOutput;
 
-    class IModule : public IUnique{
+    class IModule : public IUnique, public IProperty{
     public:
+        typedef std::shared_ptr<IModule> Ptr;
+
         virtual void updateID() = 0;
         virtual std::vector<std::string> getInputs() = 0;
         virtual std::vector<std::string> getOutputs() = 0;
         virtual std::vector<std::string> getInputIDs() = 0;
         virtual std::vector<std::string> getOutputIDs() = 0;
-        virtual std::shared_ptr<IOutput> getOutput(std::string output_id) = 0;
-        virtual std::shared_ptr<IInput> getInput(std::string input_id) = 0;
-        virtual bool update() = 0;
+        virtual std::vector<state> getInputStates() = 0;
+        virtual std::vector<state> getOutputStates() = 0;
+        virtual std::shared_ptr<IOutput> getOutput(const std::string& output_id) = 0;
+        virtual std::shared_ptr<IInput> getInput(const std::string& input_id) = 0;
+        virtual std::vector <std::shared_ptr<IOutput>> getInputConnections() = 0;
+        virtual std::vector <std::vector <std::shared_ptr<IInput>>> getOutputConnections() = 0;
+        virtual std::vector <std::shared_ptr<IInput>> getOptimizableInputs() = 0;
+        virtual std::vector <std::shared_ptr<IOutput>> getOptimizableOutputs() = 0;
+        virtual state update() = 0;
         virtual ~IModule() = default;
+
+        virtual void configure() = 0;
     };
 }
 #endif //MDD_IMODULE_H

+ 18 - 0
lib/include/IOptimizable.h

@@ -0,0 +1,18 @@
+#ifndef IOPTIMIZABLE_H
+#define IOPTIMIZABLE_H
+
+#include <vector>
+
+namespace mdd {
+	class IOptimizable {
+	public:
+		virtual const std::vector<double>& getValue() = 0;
+		virtual std::vector<double>& setValue() = 0;
+		virtual state setValue(const std::vector<double>& val) = 0;
+		virtual bool isOptimizable() = 0;
+		virtual void setOptimizability(bool state) = 0;
+		virtual ~IOptimizable() = default;
+	};
+}
+
+#endif // !IOPTIMIZABLE_H

+ 18 - 0
lib/include/IOptimizer.h

@@ -0,0 +1,18 @@
+#ifndef IOPTIMIZER_H
+#define IOPTIMIZER_H
+#include "json.hpp"
+#include <IModule.h>
+
+namespace mdd {
+	class IOptimizer {
+		public:
+			//virtual bool connect(std::shared_ptr<IModule> module) = 0;
+			/*
+			
+			*/
+			
+			virtual bool setEvaluation(std::string func) = 0;
+			virtual std::vector<std::vector<double>> update() = 0;
+	};
+}
+#endif // !IOPTIMIZER_H

+ 12 - 5
lib/include/IOutput.h

@@ -3,17 +3,24 @@
 #include "json.hpp"
 #include <memory>
 #include "IUnique.h"
+#include "IState.h"
+//#include "IInput.h"
+#include "IOptimizable.h"
+#include "IConnection.h"
 
 namespace mdd
 {
+    class IInput;
     class IModule;
 
-    class IOutput : public IUnique{
+    class IOutput 
+        : public IUnique
+        , public IState
+        , public IConnection<IInput>
+        , public IOptimizable
+    {
     public:
-        virtual const json& getValue() = 0;
-        virtual json& getValueInternal() = 0;
-        virtual bool hasChanged() = 0;
-        virtual void resetChange() = 0;
+        virtual std::vector<std::shared_ptr<IInput>> getConnections() = 0;
         virtual ~IOutput() = default;
     };
 }

+ 5 - 1
lib/include/IProcessor.h

@@ -6,10 +6,14 @@
 
 namespace mdd
 {
-
     class IProcessor: public  IModule{
     public:
         virtual std::string  addModule(std::shared_ptr<IModule> module) = 0;
+        virtual std::string addModuleInput(std::string module_ID, std::string input_ID) = 0;
+        virtual std::string addModuleInput(std::shared_ptr<IModule> module, std::shared_ptr<IInput> input) = 0;
+        virtual std::string addModuleOutput(std::string module_ID, std::string output_ID) = 0;
+        virtual std::string addModuleOutput(std::shared_ptr<IModule> module, std::shared_ptr<IOutput> output) = 0;
+        virtual void  removeModule(std::shared_ptr<IModule> module) = 0;
         virtual std::vector<std::string> getModules() = 0;
         virtual std::vector<std::string> getModuleIDs() = 0;
         virtual std::shared_ptr<IModule> getModule(std::string module_id) = 0;

+ 55 - 0
lib/include/IProperty.h

@@ -0,0 +1,55 @@
+
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+namespace mdd
+{
+	class IPropertyValue
+	{
+	public:
+		virtual ~IPropertyValue(){}
+		virtual std::string GetPropertyType() = 0;
+	};
+
+	template<typename TYPE>
+	class PropertyValue : public IPropertyValue
+	{
+	public:
+		std::string GetPropertyType()
+		{
+			return typeid(TYPE).name();
+		}
+
+		std::shared_ptr<TYPE> value = std::make_shared<TYPE>();
+	};
+
+	class IProperty
+	{
+	protected:
+		virtual IPropertyValue* GetPropertyValue() = 0;
+
+	public:
+
+		virtual ~IProperty(){}
+
+		virtual std::shared_ptr<IProperty> GetSubProp(const std::string& name) = 0;
+
+
+		template<typename EXPECTED_TYPE>
+		std::shared_ptr<EXPECTED_TYPE> Value()
+		{
+			if (GetPropertyValue()->GetPropertyType() != typeid(EXPECTED_TYPE).name())
+			{
+				return std::make_shared<EXPECTED_TYPE>();
+			}
+			else
+			{
+				return dynamic_cast<PropertyValue<EXPECTED_TYPE>>(GetPropertyValue())->value;
+			}
+		}
+	};
+
+}

+ 14 - 0
lib/include/IState.h

@@ -0,0 +1,14 @@
+#ifndef MDD_ISTATE_H
+#define MDD_ISTATE_H
+#include "state.h"
+
+namespace mdd
+{
+    class IState{
+    public:
+        virtual state getState() = 0;
+        virtual void resetState() = 0;
+    };
+}
+
+#endif //MDD_IOUTPUT_H

+ 2 - 3
lib/include/IUnique.h

@@ -5,12 +5,11 @@
 namespace mdd{
     class IUnique{
     public:
-        virtual std::string setType(std::string type) = 0;
+        virtual std::string setType(const std::string& type) = 0;
         virtual std::string getType() = 0;
         virtual std::string getID() = 0;
-        virtual std::string setPrefix(std::string prefix) = 0;
+        virtual std::string setPrefix(const std::string& prefix) = 0;
         virtual std::string setAppendix(int appendix) = 0;
     };
 }
-
 #endif

+ 30 - 13
lib/include/Input.h

@@ -3,8 +3,9 @@
 
 #include <string>
 #include <functional>
-#include "Output.h"
-#include <bits/shared_ptr.h>
+#include "IInput.h"
+#include "IOutput.h"
+#include <memory>
 #include "IUnique.h"
 
 namespace mdd {
@@ -14,25 +15,41 @@ namespace mdd {
         std::string _type;
         int _appendix;
 
-        json _value;
-        std::function<bool(const json &)> _verification;
+        std::vector<double> _value;
+        //std::function<bool(const json &)> _verification;
         std::shared_ptr <IOutput> _output;
+        bool _optimizable;
+        limits _limit;
+    protected:
+       
 
     public:
-        Input(const std::string &type, int appendix, const json &default_value,
-              const std::function<bool(const json &)> &verification = [](
-                      const json &) { return true; });
-        std::string setType(std::string type) override;
+        Input(const std::string &type, int appendix, const std::vector<double>& default_value);
+        //const std::function<bool(const json &)> &verification = [](const json&) { return true; }
+        std::string setType(const std::string& type) override;
         std::string getType() override;
         std::string getID() override;
-        std::string setPrefix(std::string prefix) override;
+        std::string setPrefix(const std::string& prefix) override;
         std::string setAppendix(int appendix) override;
 
-        const json& getValue() override;
-        json& setDefaultValue() override;
-        bool verify(const json & data) override;
-        bool connect(std::shared_ptr<IOutput> output) override;
+        state getState() override;
+        void resetState() override;
+
+        const std::vector<double>& getValue() override;
+        std::vector<double>& setValue() override;
+        state setValue(const std::vector<double>& val) override;
+        bool isOptimizable() override;
+        void setOptimizability(bool state) override;
 
+        const limits& getLimits() override;
+        limits& setLimits() override;
+
+        std::shared_ptr<IOutput> getConnection() override;
+        
+        //bool verify(const json & data) override;
+        int addConnection(std::shared_ptr<IOutput> output) override;
+        int removeConnection(std::shared_ptr<IOutput> output) override;
+        bool connect(std::shared_ptr<IOutput> output) override;
     };
 }
 

+ 22 - 12
lib/include/ModuleBase.h

@@ -2,25 +2,27 @@
 #define MDD_ModuleBase_H
 
 #include "Input.h"
+#include "Output.h"
 #include "IModule.h"
+#include "Property.h"
+#include "Generator.h"
 
 namespace mdd {
 
-class ModuleBase : public  IModule{
+class ModuleBase : public  IModule, protected Property<bool>{
     private:
-        std::string _prefix;
-        std::string _type;
-        int _appendix;
+        std::string _prefix = "";
+        std::string _type = "";
+        int _appendix = 0;
         std::vector<std::shared_ptr<Input>> _inputs;
         std::vector<std::shared_ptr<Output>> _outputs;
 
     protected:
+        virtual void configure() {};
         std::shared_ptr<IOutput> getOutput(int handle);
         std::shared_ptr<IInput> getInput(int handle);
-        int addInput(const std::string& type, const json& value,
-                         const std::function<bool(const json&)>& verification = [](
-                                 const json&) { return true; });
-        int addOutput(const std::string& type, const json& initial);
+        int addInput(const std::string& type, const std::vector<double>& value);
+        int addOutput(const std::string& type, const std::vector<double>& initial);
 
         int pop_backInput();
         int pop_backOutput();
@@ -31,17 +33,25 @@ class ModuleBase : public  IModule{
         int eraseInput(int index);
         int eraseOutput(int index);
 
+        IPropertyValue* GetPropertyValue();
+        std::shared_ptr<IProperty> GetSubProp(const std::string& name);
     public:
         std::vector<std::string> getInputs() override;
         std::vector<std::string> getInputIDs() override;
         std::vector<std::string> getOutputs() override;
         std::vector<std::string> getOutputIDs() override;
-        std::shared_ptr<IOutput> getOutput(std::string output_id) override;
-        std::shared_ptr<IInput> getInput(std::string input_id) override;
-        std::string setType(std::string type) override;
+        std::vector<state> getInputStates() override;
+        std::vector<state> getOutputStates() override;
+        std::vector<std::shared_ptr<IOutput>> getInputConnections() override;
+        std::vector <std::vector <std::shared_ptr<IInput>>> getOutputConnections() override;
+        std::vector <std::shared_ptr<IInput>> getOptimizableInputs() override;
+        std::vector <std::shared_ptr<IOutput>> getOptimizableOutputs() override;
+        std::shared_ptr<IOutput> getOutput(const std::string& output_id) override;
+        std::shared_ptr<IInput> getInput(const std::string& input_id) override;
+        std::string setType(const std::string& type) override;
         std::string getType() override;
         std::string getID() override;
-        std::string setPrefix(std::string prefix) override;
+        std::string setPrefix(const std::string& prefix) override;
         std::string setAppendix(int appendix) override;
         void updateID() override ;
     };

+ 0 - 32
lib/include/ModuleHTTP.h

@@ -1,32 +0,0 @@
-#ifndef MDD_MODULEHTTP_H
-#define MDD_MODULEHTTP_H
-
-#include "ModuleBase.h"
-#include <httplib.h>
-#include <unistd.h>
-
-
-using namespace httplib;
-
-namespace mdd{
-    class ModuleHTTP : public ModuleBase{
-    private:
-        std::string _fname;
-        std::string _id;
-        int _port;
-        pid_t _child_pid = 0;
-    protected:
-        bool connect();
-        std::string str_to_json(const std::string& input);
-        bool updateInputs();
-        bool updateOutputs();
-        void updateLayout();
-
-    public:
-        ModuleHTTP(std::string fname, std::string id, int port);
-        ~ModuleHTTP();
-        bool update() override;
-    };
-}
-
-#endif //MDD_MODULEHTTP_H

+ 0 - 41
lib/include/ModuleMath.h

@@ -1,41 +0,0 @@
-#ifndef MDD_MODULEMATH_H
-#define MDD_MODULEMATH_H
-#include "ModuleBase.h"
-
-namespace mdd {
-    enum MathOperation {
-        ADD = 1,
-        SUBTRACT = 2,
-        MULTIPLY = 3,
-        DIVIDE = 4,
-        POWER = 5,
-        LOGARITHM = 6,
-        MINIMUM = 7,
-        MAXIMUM = 8,
-        LESS_THAN = 9,
-        GREATER_THAN = 10
-    };
-
-    class ModuleMath : public ModuleBase {
-    private:
-        MathOperation _operation;
-
-        static json add(const json &val1, const json &val2);
-        static json subtract(const json &val1, const json &val2);
-        static json multiply(const json &val1, const json &val2);
-        static json divide(const json &val1, const json &val2);
-        static json power(const json &val1, const json &val2);
-        static json logarithm(const json &val1, const json &val2);
-        static json minimum(const json &val1, const json &val2);
-        static json maximum(const json &val1, const json &val2);
-        static json less(const json &val1, const json &val2);
-        static json greater(const json &val1, const json &val2);
-
-    public:
-        explicit ModuleMath(MathOperation operation = ADD);
-        bool update() override;
-        void setMathOperation(MathOperation operation);
-        MathOperation getMathOperation();
-    };
-}
-#endif

+ 18 - 0
lib/include/ModuleMerge.h

@@ -0,0 +1,18 @@
+#ifndef MODULEMERGE_H
+#define MODULEMERGE_H
+#include "ModuleBase.h"
+
+namespace mdd {
+	class ModuleMerge : public ModuleBase {
+	private:
+
+	public:
+		ModuleMerge();
+		int addModuleInput();
+		int removeModuleInput();
+		std::string setInputType(const std::string& input_id, const std::string& new_type);
+		state update() override;
+	};
+}
+
+#endif 

+ 16 - 0
lib/include/ModuleParameter.h

@@ -0,0 +1,16 @@
+#ifndef MODULEPARAMETER_H
+#define MODULEPARAMETER_H
+#include "ModuleBase.h"
+
+namespace mdd {
+
+    class ModuleParameter : public ModuleBase {
+    private:
+       
+    public:
+        ModuleParameter();
+        state update() override;
+    };
+}
+
+#endif

+ 28 - 0
lib/include/ModuleSQL.h

@@ -0,0 +1,28 @@
+#ifndef MDD_MODULESQL_H
+#define MDD_MODULESQL_H
+#include "ModuleBase.h"
+#include <iostream>
+#include <string>
+#include <sqlite3.h>
+
+namespace mdd {
+	class ModuleSQL : public ModuleBase {
+	private:
+		sqlite3* _db;
+		std::string _tbname;
+		void erase_keyword(std::string& str, std::string key);
+		struct _entity {
+			std::string key;
+			std::string type;
+		};
+		std::vector<_entity> _content;
+
+	public:
+		ModuleSQL(std::string dbname);
+		~ModuleSQL();
+		state update() override;
+	};
+}
+
+
+#endif

+ 0 - 0
lib/include/ModuleSplitt.h


+ 1 - 1
lib/include/ModuleSwitch.h

@@ -7,7 +7,7 @@ namespace mdd{
     class ModuleSwitch : public ModuleBase{
     public:
         ModuleSwitch();
-        bool update() override;
+        state update() override;
     };
 }
 #endif //MDD_MODULESWITCH_H

+ 32 - 0
lib/include/OptimizerBase.h

@@ -0,0 +1,32 @@
+#ifndef OPTIMIZERBASE_H
+#define OPTIMIZERBASE_H
+#include "IOptimizer.h"
+#include "exprtk.hpp"
+
+namespace mdd {
+	////////////////////////////////////////////////////////////
+	//
+	//Optimization is always minimization!
+	//
+	////////////////////////////////////////////////////////////
+	class OptimizerBase : public IOptimizer {
+	protected:
+		std::shared_ptr<IModule> _module;
+		std::vector<std::shared_ptr<IInput>> _inputs;
+		std::vector<std::shared_ptr<IOutput>> _outputs;
+		std::vector<double> _output_vals;
+		exprtk::expression<double> _func_expr;
+
+		struct opt_state {
+			state module_state = state::STATE_ERROR;
+			double opt_value = 0;
+		};
+		opt_state updateOutputs();
+		
+	public:
+		void updateLayout();
+		bool setEvaluation(std::string func) override;
+		//state update() override;
+	};
+}
+#endif

+ 49 - 0
lib/include/OptimizerEvolutionary.h

@@ -0,0 +1,49 @@
+#ifndef OPTIMIZEREVOLUTIONARY_H
+#define OPTIMIZEREVOLUTIONARY_H
+#include "OptimizerBase.h"
+
+namespace mdd {
+	class OptimizerEvolutionary : public OptimizerBase {
+	public:
+		struct Individual {
+		public:
+			std::vector<std::vector<double>> dna;
+			double fitness = 0;
+			bool operator== (const Individual& ind) {
+				return (dna == ind.dna) && (fitness == ind.fitness);
+			};
+		};
+	protected:
+		static int random_num(double min, double max, double inc = 1.0)
+		{
+			int range = (max - min)/inc + 1;
+			return min + inc*(std::rand() % range);
+		}
+
+		Individual generateIndividual();
+		Individual combine(Individual par1, Individual par2);
+
+		std::vector<Individual> _children;
+		Individual _best;
+		int _min_generations;
+		double _max_fitness;
+		size_t _grow_generation;
+		size_t _converges;
+
+		void evolve(std::vector<Individual> parents);
+		void evaluate(size_t ignore_len = 0);
+		std::vector<double> mutateGene(std::shared_ptr<IInput> input, std::vector<double> seed = std::vector<double>());
+		
+
+	public:
+		OptimizerEvolutionary(std::shared_ptr<IModule> module,
+			size_t converges = 0,
+			size_t grow_generation = 20,
+			double max_fitness = 0.0,
+			int min_generations = -1);
+		std::vector<std::vector<double>> update() override;
+		Individual getBest();
+		double evaluateFitness(const Individual& ind);
+	};
+}
+#endif

+ 21 - 9
lib/include/Output.h

@@ -1,28 +1,40 @@
 #ifndef MDD_OUTPUT_H
 #define MDD_OUTPUT_H
 #include "IOutput.h"
+#include "IInput.h"
 #include "IModule.h"
 
 namespace mdd {
     class Output : public IOutput{
     private:
-        bool _changed;
-        json _value;
+        state _state;
+        std::vector<double> _value;
         std::string _prefix;
         std::string _type;
         int _appendix;
+        std::vector<std::shared_ptr<IInput>> _connections;
+        bool _optimizable;
+
+    protected:
 
     public:
-        Output(const std::string& type, int appendix, const json& initial);
-        const json& getValue() override;
-        json& getValueInternal() override;
-        bool hasChanged() override;
-        void resetChange() override;
-        std::string setType(std::string type) override;
+        Output(const std::string& type, int appendix, const std::vector<double>& initial);
+        const std::vector<double>& getValue() override;
+        std::vector<double>& setValue() override;
+        state setValue(const std::vector<double>& val) override;
+        bool isOptimizable();
+        void setOptimizability(bool state);
+        state getState() override;
+        void resetState() override;
+        std::string setType(const std::string& type) override;
         std::string getType() override;
         std::string getID() override;
-        std::string setPrefix(std::string prefix) override;
+        std::string setPrefix(const std::string& prefix) override;
         std::string setAppendix(int appendix) override;
+        int addConnection(std::shared_ptr<IInput> input) override;
+        int removeConnection(std::shared_ptr<IInput> input) override;
+        bool connect(std::shared_ptr<IInput> input) override;
+        std::vector<std::shared_ptr<IInput>> getConnections() override;
     };
 }
 #endif

+ 39 - 19
lib/include/ProcessorBase.h

@@ -3,15 +3,27 @@
 
 #include <list>
 #include "Input.h"
+#include "Output.h"
 #include "IProcessor.h"
-#include "HandlerModule.h"
 
 namespace mdd {
     class ProcessorBase : public IProcessor{
     private:
-        std::string _prefix;
-        std::string _type;
-        int _appendix;
+
+        template<class T>
+        class HandlerModule {
+        public:
+            std::shared_ptr<IModule> moduleHandler;
+            std::shared_ptr<T> accessHandler;
+            HandlerModule(std::shared_ptr<IModule> module, std::shared_ptr<T> access) {
+                moduleHandler = module;
+                accessHandler = access;
+            }
+        };
+
+        std::string _prefix = "";
+        std::string _type = "";
+        int _appendix = 0;
 
         std::vector<std::shared_ptr<Input>> _processor_inputs;
         std::vector<std::shared_ptr<Output>> _processor_outputs;
@@ -21,38 +33,46 @@ namespace mdd {
         std::vector<std::shared_ptr<IModule>> _modules;
 
     protected:
-        int addProcesorInput(const std::string& type, const json& value,
-        const std::function<bool(const json&)>& verification = [](
-                const json&) { return true; });
-        int addProcessorOutput(const std::string& type, const json& initial);
+        int addProcesorInput(const std::string& type, const std::vector<double>& value);
+        int addProcessorOutput(const std::string& type, const std::vector<double>& initial);
         std::shared_ptr<IOutput> getProcessorOutput(int handle);
         std::shared_ptr<IInput> getProcessorInput(int handle);
         std::shared_ptr<IModule> getModule(int handle);
 
     public:
         std::string getID() override ;
-        std::string setType(std:: string type) override;
+        std::string setType(const std::string& type) override;
         std::string getType() override;
-        std::string setPrefix(std::string prefix) override;
+        std::string setPrefix(const std::string& prefix) override;
         std::string setAppendix(int appendix) override;
         void updateID() override ;
 
         std::string addModule(std::shared_ptr<IModule> module) override ;
-        std::string addModuleInput(std::string module_ID, std::string input_ID);
-        std::string addModuleInput(std::shared_ptr<IModule> module, std::shared_ptr<IInput> input);
-        std::string addModuleOutput(std::string module_ID, std::string output_ID);
-        std::string addModuleOutput(std::shared_ptr<IModule> module, std::shared_ptr<IOutput> output);
+        void removeModule(std::shared_ptr<IModule> module) override;
+        std::string addModuleInput(std::string module_ID, std::string input_ID) override;
+        std::string addModuleInput(std::shared_ptr<IModule> module, std::shared_ptr<IInput> input) override;
+        std::string addModuleOutput(std::string module_ID, std::string output_ID) override;
+        std::string addModuleOutput(std::shared_ptr<IModule> module, std::shared_ptr<IOutput> output) override;
 
         std::vector<std::string> getInputs() override;
         std::vector<std::string> getOutputs() override;
         std::vector<std::string> getModules() override;
 
-        std::vector<std::string> getInputIDs();
-        std::vector<std::string> getOutputIDs();
-        std::vector<std::string> getModuleIDs();
+        std::vector<std::string> getInputIDs() override;
+        std::vector<std::string> getOutputIDs() override;
+        std::vector<std::string> getModuleIDs() override;
+
+        std::vector<state> getInputStates() override;
+        std::vector<state> getOutputStates() override;
+
+        std::vector<std::shared_ptr<IOutput>> getInputConnections() override;
+        std::vector <std::vector <std::shared_ptr<IInput>>> getOutputConnections() override;
+
+        std::vector <std::shared_ptr<IInput>> getOptimizableInputs() override;
+        std::vector <std::shared_ptr<IOutput>> getOptimizableOutputs() override;
 
-        std::shared_ptr<IOutput> getOutput(std::string output_id) override;
-        std::shared_ptr<IInput> getInput(std::string input_id) override;
+        std::shared_ptr<IOutput> getOutput(const std::string& output_id) override;
+        std::shared_ptr<IInput> getInput(const std::string& input_id) override;
         std::shared_ptr<IModule> getModule(std::string module_id) override;
     };
 }

+ 0 - 0
lib/include/ProcessorEvolution.h


+ 0 - 14
lib/include/ProcessorManual.h

@@ -1,14 +0,0 @@
-#ifndef MDD_PROCESSORMANUAL_H
-#define MDD_PROCESSORMANUAL_H
-#include "ProcessorBase.h"
-#include "Output.h"
-namespace mdd {
-    class ProcessorManual : public ProcessorBase {
-    public:
-        ProcessorManual();
-        bool update() override;
-        std::shared_ptr<IOutput> getIteration();
-    };
-}
-
-#endif //MDD_PROCESSORMANUAL_H

+ 39 - 0
lib/include/ProcessorStandard.h

@@ -0,0 +1,39 @@
+#ifndef MDD_PROCESSORSTANDARD_H
+#define MDD_PROCESSORSTANDARD_H
+#include "ProcessorBase.h"
+#include "Output.h"
+#include <chrono>
+namespace mdd {
+    enum priority {
+        MANUAL,
+        STATIC,
+        DYNAMIC,
+        TIME
+    };
+
+    class ProcessorStandard : public ProcessorBase {
+    private:
+        struct module_priority{
+            std::shared_ptr<IModule> module_ptr;
+            size_t inputCounter;
+            size_t changeCounter;
+            size_t outputCounter;
+            int time_priority;
+            module_priority(std::shared_ptr<IModule> module, size_t inputs = 0, size_t outputs = 0, size_t change = 0);
+        };
+        std::vector<module_priority> _priority_list;
+
+    public:
+        int maxIterations;
+        priority priorityEvaluation;
+
+        ProcessorStandard(priority priorityEvaluation = MANUAL, int maxIterations = -1);
+        std::string addModule(std::shared_ptr<IModule> module) override;
+        void removeModule(std::shared_ptr<IModule> module) override;
+        std::vector<std::shared_ptr<IModule>> getModulePriority();
+        state update() override;
+        std::shared_ptr<IOutput> getIteration();
+    };
+}
+
+#endif //MDD_PROCESSORMANUAL_H

+ 61 - 0
lib/include/Property.h

@@ -0,0 +1,61 @@
+
+
+#pragma once
+
+#include <map>
+#include "IProperty.h"
+
+namespace mdd
+{
+
+	template<typename TYPE>
+	class Property : public IProperty
+	{
+		PropertyValue<TYPE> val;
+		std::map<std::string, std::shared_ptr<IProperty>> _subprops;
+	protected:
+		virtual IPropertyValue* GetPropertyValue()
+		{
+			return &val;
+		}
+
+	public:
+		typedef std::shared_ptr<Property<TYPE>> Ptr;
+
+		virtual std::shared_ptr<IProperty> GetSubProp(const std::string& name)
+		{
+			auto sub = _subprops.find(name);
+			if (sub == _subprops.end())
+			{
+				return std::make_shared<Property<bool>>();
+			}
+			else
+			{
+				return sub->second;
+			}
+		}
+
+		template<typename T>
+		std::shared_ptr<Property<T>> addSubProperty(const std::string& name)
+		{
+			auto newprop = std::make_shared<Property<T>>();
+			_subprops[name] = newprop;
+			return newprop;
+		}
+
+		template<typename T>
+		std::shared_ptr<Property<T>> addSubProperty(const std::string& name, const T& default_val)
+		{
+			auto newprop = std::make_shared<Property<T>>();
+			newprop->Value() = default_val;
+			_subprops[name] = newprop;
+			return newprop;
+		}
+
+		TYPE& Value()
+		{
+			return *val.value;
+		}
+	};
+
+}

+ 11 - 0
lib/include/UpdateState.h

@@ -0,0 +1,11 @@
+#ifndef STATE_H
+#define STATE_H
+
+namespace mdd {
+    enum class state : char {
+        ERROR = -1,
+        CHANGED = 0,
+        UNCHANGED = 1,
+    };
+}
+#endif

+ 11 - 0
lib/include/state.h

@@ -0,0 +1,11 @@
+#ifndef STATE_H
+#define STATE_H
+
+namespace mdd {
+    enum class state : char {
+        STATE_ERROR = -1,
+        CHANGED = 0,
+        UNCHANGED = 1
+    };
+}
+#endif

+ 18 - 0
lib/src/Connector.cpp

@@ -0,0 +1,18 @@
+#include "Connector.h"
+namespace mdd {
+	std::shared_ptr<IModule> Connector::decode(const json& structure)
+	{
+		std::shared_ptr<IModule> ret;
+
+		return ret;
+	}
+	const json&  Connector::encode(const std::shared_ptr<IModule>& module)
+	{
+		json ret;
+		ret["test"]= "";
+
+		return ret;
+	}
+
+}
+

+ 24 - 0
lib/src/Generator.cpp

@@ -0,0 +1,24 @@
+
+
+#include <Generator.h>
+#include <mutex>
+namespace mdd
+{
+
+	std::map<std::string, std::shared_ptr<IGenerator>>&
+		GetGenerators(
+			const std::string& name,
+			const std::shared_ptr<IGenerator>& generator)
+	{
+		static std::map<std::string, std::shared_ptr<IGenerator>> gens;
+		static std::mutex mutex;
+
+		if (generator != nullptr)
+		{
+			mutex.lock();
+			gens[name] = generator;
+			mutex.unlock();
+		}
+		return gens;
+	}
+}

+ 60 - 13
lib/src/Input.cpp

@@ -1,16 +1,26 @@
 #include "Input.h"
 
 namespace mdd{
-    Input::Input(const std::string& type, int appendix, const json& default_value,
-                 const std::function<bool(const json&)>& verification) {
+    int Input::addConnection(std::shared_ptr<IOutput> output)
+    {
+        _output = output;
+        return 1;
+    }
+    int Input::removeConnection(std::shared_ptr<IOutput> output)
+    {
+        _output = nullptr;
+        return 0;
+    }
+    Input::Input(const std::string& type, int appendix, const std::vector<double>& default_value) {
         _type = type;
         _value = default_value;
-        _verification = std::move(verification);
         _prefix = "";
         _appendix = appendix;
+        _optimizable = false;
+
     }
 
-    std::string Input::setType(std::string type){
+    std::string Input::setType(const std::string& type){
         _type = type;
         return getID();
     }
@@ -21,7 +31,7 @@ namespace mdd{
         return _prefix + "/" + _type + std::to_string(_appendix);
     }
 
-    std::string Input::setPrefix(std::string prefix){
+    std::string Input::setPrefix(const std::string& prefix){
         _prefix = prefix;
         return getID();
     }
@@ -31,7 +41,20 @@ namespace mdd{
         return  getID();
     }
 
-    const json& Input::getValue() {
+    state Input::getState() {
+        if (_output == nullptr) {
+            return state::UNCHANGED;
+        }
+        else {
+            return _output->getState();
+        }
+    }
+
+    void Input::resetState() {
+
+    }
+
+    const std::vector<double>& Input::getValue() {
         if(_output == nullptr){
             return _value;
         } else{
@@ -39,18 +62,42 @@ namespace mdd{
         }
     }
 
-    json& Input::setDefaultValue(){
+    std::shared_ptr<IOutput> Input::getConnection() { return _output; }
+
+    std::vector<double>& Input::setValue(){
         return _value;
     }
 
-    bool Input::verify(const json & data){
-        return _verification(data);
+    state Input::setValue(const std::vector<double>& val) {
+        if (val != _value)
+        {
+            _value = val;
+            return state::CHANGED;
+        }
+        else {
+            return state::UNCHANGED;
+        }
     }
 
     bool Input::connect(std::shared_ptr<IOutput> output){
-        if (verify(output->getValue())) {
-            _output = output;
-            return true;
-        }
+        _output = output;
+        _output->addConnection(std::make_shared<Input>((*this)));
+        return true;
+    }
+
+    bool Input::isOptimizable() {
+        return _optimizable;
+    }
+
+    void Input::setOptimizability(bool state) {
+        _optimizable = state;
+    }
+    const limits& Input::getLimits()
+    {
+        return _limit;
+    }
+    limits& Input::setLimits()
+    {
+        return _limit;
     }
 }

+ 77 - 8
lib/src/ModuleBase.cpp

@@ -3,7 +3,7 @@
 
 namespace mdd {
 
-    std::string ModuleBase::setType(std:: string type){
+    std::string ModuleBase::setType(const std::string& type){
         _type=type;
         updateID();
         return getID();
@@ -44,15 +44,74 @@ namespace mdd {
         return ret;
     }
 
-    int ModuleBase::addInput(const std::string& type , const json& value,
-                             const std::function<bool(const json&)>& verification) {
-        _inputs.emplace_back(std::make_shared<Input>(type, _inputs.size(), value, verification));
+    std::vector<state> ModuleBase::getInputStates() {
+        std::vector<state> ret;
+        for (auto& input : _inputs) {
+            ret.push_back(input->getState());
+        }
+        return ret;
+    }
+
+    std::vector<state> ModuleBase::getOutputStates() {
+        std::vector<state> ret;
+        for (auto& output : _outputs) {
+            ret.push_back(output->getState());
+        }
+        return ret;
+    }
+
+    std::vector<std::shared_ptr<IOutput>> ModuleBase::getInputConnections()
+    {
+        std::vector<std::shared_ptr<IOutput>> ret;
+        for (auto& input : _inputs) {
+            ret.push_back(input->getConnection());
+        }
+        return ret;
+    }
+
+    int ModuleBase::addInput(const std::string& type , const std::vector<double>& value) {
+        _inputs.emplace_back(std::make_shared<Input>(type, _inputs.size(), value));
         _inputs.back()->setPrefix(getID());
         return _inputs.size() - 1;
     }
 
 
-    std::shared_ptr<IOutput> ModuleBase::getOutput(std::string output_id) {
+    std::vector<std::vector<std::shared_ptr<IInput>>> ModuleBase::getOutputConnections()
+    {
+        std::vector<std::vector<std::shared_ptr<IInput>>> ret;
+        for (auto& output : _outputs) {
+            ret.push_back(output->getConnections());
+        }
+        return ret;
+    }
+
+    std::vector<std::shared_ptr<IInput>> ModuleBase::getOptimizableInputs()
+    {
+        std::vector<std::shared_ptr<IInput>> ret;
+        for (auto it = _inputs.begin(); it != _inputs.end();  ++it)
+        {
+            if ((*it)->isOptimizable())
+            {
+                ret.push_back((*it));
+            }
+        }
+        return ret;
+    }
+
+    std::vector<std::shared_ptr<IOutput>> ModuleBase::getOptimizableOutputs()
+    {
+        std::vector<std::shared_ptr<IOutput>> ret;
+        for (auto it = _outputs.begin(); it != _outputs.end(); ++it)
+        {
+            if ((*it)->isOptimizable())
+            {
+                ret.push_back((*it));
+            }
+        }
+        return ret;
+    }
+
+    std::shared_ptr<IOutput> ModuleBase::getOutput(const std::string& output_id) {
         for(auto& output : _outputs){
                 if (output->getID() == output_id) {
                     return output;
@@ -61,7 +120,7 @@ namespace mdd {
         return nullptr;
     }
 
-    std::shared_ptr<IInput> ModuleBase::getInput(std::string input_id){
+    std::shared_ptr<IInput> ModuleBase::getInput(const std::string& input_id){
         for(auto& input : _inputs){
             if (input->getID() == input_id) {
                 return input;
@@ -78,7 +137,7 @@ namespace mdd {
         return _inputs[handle];
     }
 
-    int ModuleBase::addOutput(const std::string& type, const json& initial) {
+    int ModuleBase::addOutput(const std::string& type, const std::vector<double>& initial) {
         _outputs.push_back(std::make_shared<Output>( type, _outputs.size(), initial));
         _outputs.back()->setPrefix(getID());
         return  _outputs.size()-1;
@@ -115,7 +174,17 @@ namespace mdd {
         return _prefix + "/" + _type + std::to_string(_appendix);
     }
 
-    std::string ModuleBase::setPrefix(std::string prefix){
+    IPropertyValue* ModuleBase::GetPropertyValue()
+    {
+        return Property<bool>::GetPropertyValue();
+    }
+
+    std::shared_ptr<IProperty> ModuleBase::GetSubProp(const std::string& name)
+    {
+        return Property<bool>::GetSubProp(name);
+    }
+
+    std::string ModuleBase::setPrefix(const std::string& prefix){
         _prefix = prefix;
         updateID();
         return getID();

+ 85 - 33
lib/src/ModuleHTTP.cpp

@@ -1,13 +1,41 @@
-#include "ModuleHTTP.h"
 #include <httplib.h>
 #include <iostream>
 #include <thread>
-#include <wait.h>
+#include <Generator.h>
+#include <boost/process.hpp>
+#include <filesystem>
+
+//#include <wait.h>
+
+#include "ModuleBase.h"
+#include <httplib.h>
+#include <memory>
 #include <chrono>
 
 using namespace httplib;
 namespace mdd{
 
+    using namespace boost::process;
+    class ModuleHTTP : public ModuleBase {
+    private:
+        std::string _fname;
+        std::string _id;
+        int _port;
+        std::unique_ptr<child> _child;
+
+    protected:
+        bool connect();
+        std::string str_to_json(const std::string& input);
+        state updateInputs();
+        state updateOutputs();
+        void updateLayout();
+
+    public:
+        ModuleHTTP();// std::string fname, std::string id, int port);
+        ~ModuleHTTP();
+        state update() override;
+    };
+
     bool ModuleHTTP::connect(){
         Client cli(_id, _port);
         std::string body;
@@ -47,7 +75,7 @@ namespace mdd{
         return str;
     }
 
-    bool ModuleHTTP::updateInputs() {
+    state ModuleHTTP::updateInputs() {
         Client cli(_id, _port);
 
         std::string body;
@@ -66,16 +94,22 @@ namespace mdd{
         for(size_t i=0; i < getInputs().size(); i++){
             getInput(i)->setType(inputs[i]["type"].get<std::string>());
             getInput(i)->setAppendix(i);
-            getInput(i)->setDefaultValue() = inputs[i];
+            getInput(i)->setValue() = inputs[i]["value"].get<std::vector<double>>();
         }
         for(int index = getInputs().size(); index < inputs.size(); ++index){
-            json val;
-            val["value"] = inputs[index]["value"];
-            addInput(inputs[index]["type"].get<std::string>(),val);
+            if (inputs[index]["value"].is_array())
+            {
+                addInput(inputs[index]["type"].get<std::string>(), inputs[index]["value"].get<std::vector<double>>());
+            }
+            else {
+                addInput(inputs[index]["type"].get<std::string>(), { inputs[index]["value"].get<double>() });
+                std::cout << "Warning: Server expects single values, but mdd work with arrays!" << std::endl;
+            }
         }
+        return state::UNCHANGED;
     }
 
-    bool ModuleHTTP::updateOutputs() {
+    state ModuleHTTP::updateOutputs() {
         Client cli(_id, _port);
 
         std::string body;
@@ -88,20 +122,28 @@ namespace mdd{
         assert(res->body.empty());
         body =  std::string(R"()") + body;
         json outputs = json::parse(body);
-
+        state output_state = state::UNCHANGED;
         for(int j = 0; j < (int)getOutputs().size()-(int)outputs.size(); ++j){
             pop_backOutput();
+            output_state = state::CHANGED;
         }
         for(size_t i=0; i < getOutputs().size(); i++){
-            getOutput(i)->setType(outputs[i]["type"].get<std::string>());
-            getOutput(i)->setAppendix(i);
-            getOutput(i)->getValueInternal() = outputs[i];
+            //getOutput(i)->setType(outputs[i]["type"].get<std::string>());
+            //getOutput(i)->setAppendix(i);
+            getOutput(i)->setValue(outputs[i]["value"].get<std::vector<double>>());
         }
         for(int index = getOutputs().size(); index < outputs.size(); ++index){
-            json val;
-            val["value"] = outputs[index]["value"];
-            addOutput(outputs[index]["type"].get<std::string>(),val);
+            if (outputs[index]["value"].is_array()) {
+                addOutput(outputs[index]["type"].get<std::string>(), outputs[index]["value"].get<std::vector<double>>());
+            }
+            else
+            {
+                addOutput(outputs[index]["type"].get<std::string>(), { outputs[index]["value"].get<double>() });
+                std::cout << "Warning: Server delivers single values, but mdd work with arrays!" << std::endl;
+            }
+            output_state = state::CHANGED;
         }
+        return output_state;
     }
 
     void ModuleHTTP::updateLayout(){
@@ -109,44 +151,51 @@ namespace mdd{
         updateOutputs();
     }
 
-    ModuleHTTP::ModuleHTTP(std::string fname, std::string id, int port):
-        _fname(fname),
-        _id(id),
-        _port(port)
+    ModuleHTTP::ModuleHTTP()// std::string fname, std::string id, int port):
+      //  _fname(fname),
+       // _id(id),
+       // _port(port)
     {
-        setType("HTTP");
+       /* setType("HTTP");
 
         if(!fname.empty()){
-            _child_pid = fork();
-            if(_child_pid == 0)
+            if (std::filesystem::exists(fname))
             {
-                char*const arghs[] = {"python3", (char*const)fname.c_str(), NULL};
-                execvp("python3", arghs);
+                _child = std::make_unique<child>("python3 " + fname + " " + std::to_string(port));
+            }
+            else {
+                std::cout << "ERROR Couldnt find: " << fname << std::endl;
             }
         }
         while(!connect()){
             std::this_thread::sleep_for(std::chrono::microseconds(500));
         }
-        updateLayout();
+        updateLayout();*/
     }
 
     ModuleHTTP::~ModuleHTTP()
     {
-        if(_child_pid != 0)
+        if (_child != nullptr)
         {
-            kill(_child_pid, SIGINT);
-            int status;
-            waitpid(_child_pid, &status, 0);
+            _child->terminate();
+            _child->join();
         }
     }
 
-    bool ModuleHTTP::update() {
+    state ModuleHTTP::update() {
         Client cli(_id, _port);
         json new_inputs;
         for (int i = 0; i < getInputs().size(); ++i) {
-            new_inputs.push_back(getInput(i)->getValue());
+            json input;
+            input["value"] = getInput(i)->getValue();
+            //std::cout << "ModuleHTTP::update: last: " << getInput(i)->getValue().back() << std::endl;
+            new_inputs.push_back(input);
         }
         std::string content = new_inputs.dump();
+        while (!connect()) {
+            std::this_thread::sleep_for(std::chrono::microseconds(500));
+        }
+        //std::cout << "ModuleHTTP::update: " << content << std::endl;
         auto res = cli.Post("/update",content.size(),
                             [&](size_t offset, size_t length, DataSink &sink) {
                                 sink.write(content.data() + offset, length);
@@ -155,6 +204,9 @@ namespace mdd{
         while(!connect()){
             std::this_thread::sleep_for(std::chrono::microseconds(500));
         }
-        updateOutputs();
+        return updateOutputs();
     }
-}
+
+}
+
+ADD_GENERATOR(mdd::ModuleHTTP);

+ 214 - 297
lib/src/ModuleMath.cpp

@@ -1,375 +1,290 @@
-#include "ModuleMath.h"
+#include "ModuleBase.h"
+
 #include <iostream>
+#include <cmath>
 
 namespace mdd {
-    ModuleMath::ModuleMath(MathOperation operation) {
-        _operation = operation;
-        json default_val;
-        default_val["value"] = 1;
+
+    class ModuleMath : public ModuleBase {
+        enum class MathOperation : char {
+            ADD = 1,
+            SUBTRACT = 2,
+            MULTIPLY = 3,
+            DIVIDE = 4,
+            POWER = 5,
+            LOGARITHM = 6,
+            MINIMUM = 7,
+            MAXIMUM = 8,
+            LESS_THAN = 9,
+            GREATER_THAN = 10
+        };
+        const std::map<std::string, std::function<double(double, double)>> _ops = {
+            {"mutiply", [](double a, double b) {return a * b; }}
+        };
+        std::function<double(double, double)> operation;
+    private:
+        MathOperation _operation;
+        Property<std::string>::Ptr _operation_prop;
+
+        static std::vector<double> add(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> subtract(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> multiply(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> divide(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> power(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> logarithm(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> minimum(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> maximum(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> less(const std::vector<double>& val1, const std::vector<double>& val2);
+        static std::vector<double> greater(const std::vector<double>& val1, const std::vector<double>& val2);
+
+    public:
+        explicit ModuleMath();
+        void configure();
+        state update() override;
+        void setMathOperation(MathOperation operation);
+        MathOperation getMathOperation();
+    };
+
+    ModuleMath::ModuleMath() {
+        std::vector<double> default_val = {1};
         addInput("Value", default_val);
         addInput("Value", default_val);
         addOutput("Value", default_val);
         setType("Math");
+        _operation_prop = addSubProperty<std::string>("operation");
     }
 
-    json ModuleMath::add(const json &val1, const json &val2) {
-        json ret = json::array();
-        if (val1.is_array()) {
-            for (int i = 0; i < val1.size(); i++) {
-                if (val2.is_array()) {
-                    if (val1.size() == val2.size()) {
-                        ret.push_back(add(val1[i],val2[i]));
-                    }
-                } else {
-                    ret.push_back(add(val1[i],val2));
-                }
-            }
-
-        } else {
-            if (val2.is_array()) {
-                for (int i = 0; i < val2.size(); i++) {
-                    ret.push_back(add(val1,val2[i]));
-                }
-            } else {
-                if (val1.is_number() && val2.is_number()) {
-                    if (val1.is_number_float()) {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<double>() + val2.get<double>();
-                        } else {
-                            ret = val1.get<float>() + val2.get<int>();
-                        }
-                    } else {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<int>() + val2.get<double>();
-                        } else {
-                            ret = val1.get<int>() + val2.get<int>();
-                        }
-                    }
-
-                } else {
-
-                }
+    void ModuleMath::configure()
+    {
+        _operation = ModuleMath::MathOperation::ADD;
+        /*if (_operation_prop->Value() == "multiply")
+        {
+            _operation = ModuleMath::MathOperation::MULTIPLY;
+        }
+        else if (_operation_prop->Value() == "add")
+        {
+            _operation = ModuleMath::MathOperation::ADD;
+        }
+        */
+    }
 
+    std::vector<double> ModuleMath::add(const std::vector<double>&val1, const std::vector<double>&val2) {
+        std::vector<double> ret; //= json::array();
+        size_t length= std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(val1[i] + val2[i]);
+            }
+            else if (1 == val1.size()) {
+                ret.push_back(val1[0] + val2[i]);
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(val1[i] + val2[0]);
             }
         }
         return ret;
     }
 
-    json ModuleMath::subtract(const json &val1, const json &val2){
-        json ret = json::array();
-        if (val1.is_array()) {
-            for (int i = 0; i < val1.size(); i++) {
-                if (val2.is_array()) {
-                    if (val1.size() == val2.size()) {
-                        ret.push_back(subtract(val1[i],val2[i]));
-                    }
-                } else {
-                    ret.push_back(subtract(val1[i],val2));
-                }
+    std::vector<double> ModuleMath::subtract(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(val1[i] - val2[i]);
             }
-
-        } else {
-            if (val2.is_array()) {
-                for (int i = 0; i < val2.size(); i++) {
-                    ret.push_back(subtract(val1,val2[i]));
-                }
-            } else {
-                if (val1.is_number() && val2.is_number()) {
-                    if (val1.is_number_float()) {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<double>() - val2.get<double>();
-                        } else {
-                            ret = val1.get<double>() - val2.get<int>();
-                        }
-                    } else {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<int>() - val2.get<double>();
-                        } else {
-                            ret = val1.get<int>() - val2.get<int>();
-                        }
-                    }
-
-                } else {
-
-                }
-
+            else if (1 == val1.size()) {
+                ret.push_back(val1[0] - val2[i]);
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(val1[i] - val2[0]);
             }
         }
         return ret;
     }
 
-    json ModuleMath::multiply(const json &val1, const json &val2){
-        json ret = json::array();
-        if (val1.is_array()) {
-            for (int i = 0; i < val1.size(); i++) {
-                if (val2.is_array()) {
-                    if (val1.size() == val2.size()) {
-                        ret.push_back(multiply(val1[i],val2[i]));
-                    }
-                } else {
-                    ret.push_back(multiply(val1[i],val2));
-                }
+    std::vector<double> ModuleMath::multiply(const std::vector<double>&val1, const std::vector<double> &val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(val1[i] * val2[i]);
             }
-
-        } else {
-            if (val2.is_array()) {
-                for (int i = 0; i < val2.size(); i++) {
-                    ret.push_back(multiply(val1,val2[i]));
-                }
-            } else {
-                if (val1.is_number() && val2.is_number()) {
-                    if (val1.is_number_float()) {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<double>() * val2.get<double>();
-                        } else {
-                            ret = val1.get<double>() * val2.get<int>();
-                        }
-                    } else {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<int>() * val2.get<float>();
-                        } else {
-                            ret = val1.get<int>() * val2.get<int>();
-                        }
-                    }
-
-                } else {
-
-                }
-
+            else if (1 == val1.size()) {
+                ret.push_back(val1[0] * val2[i]);
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(val1[i] * val2[0]);
             }
         }
         return ret;
     }
 
-    json ModuleMath::divide(const json &val1, const json &val2){
-        json ret = json::array();
-        if (val1.is_array()) {
-            for (int i = 0; i < val1.size(); i++) {
-                if (val2.is_array()) {
-                    if (val1.size() == val2.size()) {
-                        ret.push_back(divide(val1[i],val2[i]));
-                    }
-                } else {
-                    ret.push_back(divide(val1[i],val2));
-                }
+    std::vector<double> ModuleMath::divide(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(val1[i] / val2[i]);
             }
-
-        } else {
-            if (val2.is_array()) {
-                for (int i = 0; i < val2.size(); i++) {
-                    ret.push_back(divide(val1,val2[i]));
-                }
-            } else {
-                if (val1.is_number() && val2.is_number()) {
-                    if (val1.is_number_float()) {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<double>() / val2.get<double>();
-                        } else {
-                            ret = val1.get<double>() / val2.get<int>();
-                        }
-                    } else {
-                        if (val2.is_number_float()) {
-                            ret = val1.get<int>() / val2.get<double>();
-                        } else {
-                            ret = val1.get<int>()*1.0 / val2.get<int>();
-                        }
-                    }
-
-                } else {
-
-                }
-
+            else if (1 == val1.size()) {
+                ret.push_back(val1[0] / val2[i]);
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(val1[i] / val2[0]);
             }
         }
         return ret;
     }
 
-    json ModuleMath::power(const json &val1, const json &val2){
-
-    }
-
-    json ModuleMath::logarithm(const json &val1, const json &val2){
-
+    std::vector<double> ModuleMath::power(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(pow(val1[i] , val2[i]));
+            }
+            else if (1 == val1.size()) {
+                ret.push_back(pow(val1[0] , val2[i]));
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(pow(val1[i] , val2[0]));
+            }
+        }
+        return ret;
     }
 
-    json ModuleMath::minimum(const json &val1, const json &val2){
-        json ret = json::array();
-        if (val1.is_array()) {
-            for (int i = 0; i < val1.size(); i++) {
-                if (val2.is_array()) {
-                    if (val1.size() == val2.size()) {
-                        ret.push_back(minimum(val1[i],val2[i]));
-                    }
-                } else {
-                    ret.push_back(minimum(val1[i],val2));
-                }
+    std::vector<double> ModuleMath::logarithm(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                
+                ret.push_back(log(val2[i]) / log(val1[i]));
             }
-
-        } else {
-            if (val2.is_array()) {
-                for (int i = 0; i < val2.size(); i++) {
-                    ret.push_back(minimum(val1,val2[i]));
-                }
-            } else {
-                if (val1.is_number() && val2.is_number()) {
-                    if (val1.is_number_float()) {
-                        if (val2.is_number_float()) {
-                            if(val1.get<double>()<= val2.get<double>()){
-                                ret = val1.get<double>();
-                            } else{
-                                ret = val2.get<double>();
-                            }
-                        } else {
-                            if(val1.get<double>()<= val2.get<int>()*1.0){
-                                ret = val1.get<double>();
-                            } else{
-                                ret = val2.get<int>();
-                            }
-                        }
-                    } else {
-                        if (val2.is_number_float()) {
-                            if(val1.get<int>()*1.0 <= val2.get<double>()){
-                                ret = val1.get<int>();
-                            } else{
-                                ret = val2.get<double>();
-                            }
-                        } else {
-                            if(val1.get<int>()<= val2.get<int>()){
-                                ret = val1.get<int>();
-                            } else{
-                                ret = val2.get<int>();
-                            }
-                        }
-                    }
-
-                } else {
-
-                }
-
+            else if (1 == val1.size()) {
+                ret.push_back(log(val2[i]) / log(val1[0]));
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(log(val2[0]) / log(val1[i]));
             }
         }
         return ret;
     }
 
-    json ModuleMath::maximum(const json &val1, const json &val2){
-        json ret = json::array();
-        if (val1.is_array()) {
-            for (int i = 0; i < val1.size(); i++) {
-                if (val2.is_array()) {
-                    if (val1.size() == val2.size()) {
-                        ret.push_back(minimum(val1[i],val2[i]));
-                    }
-                } else {
-                    ret.push_back(minimum(val1[i],val2));
+    std::vector<double> ModuleMath::minimum(const std::vector<double>&val1, const std::vector<double>&val2){
+            std::vector<double> ret; //= json::array();
+            size_t length = std::max(val1.size(), val2.size());
+            for (int i = 0; i < length; i++) {
+                if (val1.size() == val2.size()) {
+                    ret.push_back(std::min(val1[i], val2[i]));
                 }
-            }
-
-        } else {
-            if (val2.is_array()) {
-                for (int i = 0; i < val2.size(); i++) {
-                    ret.push_back(minimum(val1,val2[i]));
+                else if (1 == val1.size()) {
+                    ret.push_back(std::min(val1[0], val2[i]));
                 }
-            } else {
-                if (val1.is_number() && val2.is_number()) {
-                    if (val1.is_number_float()) {
-                        if (val2.is_number_float()) {
-                            if(val1.get<double>()>= val2.get<double>()){
-                                ret = val1.get<double>();
-                            } else{
-                                ret = val2.get<double>();
-                            }
-                        } else {
-                            if(val1.get<float>()>= val2.get<int>()*1.0){
-                                ret = val1.get<double>();
-                            } else{
-                                ret = val2.get<int>();
-                            }
-                        }
-                    } else {
-                        if (val2.is_number_float()) {
-                            if(val1.get<int>()*1.0 >= val2.get<double>()){
-                                ret = val1.get<int>();
-                            } else{
-                                ret = val2.get<double>();
-                            }
-                        } else {
-                            if(val1.get<int>()>= val2.get<int>()){
-                                ret = val1.get<int>();
-                            } else{
-                                ret = val2.get<int>();
-                            }
-                        }
-                    }
-
-                } else {
-
+                else if (1 == val2.size()) {
+                    ret.push_back(std::min(val1[i], val2[0]));
                 }
+            }
+            return ret;
+    }
 
+    std::vector<double> ModuleMath::maximum(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(std::max(val1[i], val2[i]));
+            }
+            else if (1 == val1.size()) {
+                ret.push_back(std::max(val1[0], val2[i]));
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(std::max(val1[i], val2[0]));
             }
         }
         return ret;
     }
 
-    json ModuleMath::less(const json &val1, const json &val2){
-
+    std::vector<double> ModuleMath::less(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(val1[i] > val2[i]);
+            }
+            else if (1 == val1.size()) {
+                ret.push_back(val1[0] > val2[i]);
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(val1[i] > val2[0]);
+            }
+        }
+        return ret;
     }
 
-    json ModuleMath::greater(const json &val1, const json &val2){
-
+    std::vector<double> ModuleMath::greater(const std::vector<double>&val1, const std::vector<double>&val2){
+        std::vector<double> ret; //= json::array();
+        size_t length = std::max(val1.size(), val2.size());
+        for (int i = 0; i < length; i++) {
+            if (val1.size() == val2.size()) {
+                ret.push_back(val1[i] < val2[i]);
+            }
+            else if (1 == val1.size()) {
+                ret.push_back(val1[0] < val2[i]);
+            }
+            else if (1 == val2.size()) {
+                ret.push_back(val1[i] < val2[0]);
+            }
+        }
+        return ret;
     }
 
-    bool ModuleMath::update() {
-        json ret = getOutput(0)->getValue()["value"];
+    state ModuleMath::update() {
+        std::vector<double> ret = getOutput(0)->getValue();
 
         switch (_operation) {
-            case ADD:
-                ret = add(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+        case MathOperation::ADD:
+                ret = add(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case SUBTRACT:
-                ret = subtract(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::SUBTRACT:
+                ret = subtract(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case MULTIPLY:
-                ret = multiply(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::MULTIPLY:
+                ret = multiply(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case DIVIDE:
-                ret = divide(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::DIVIDE:
+                ret = divide(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case POWER:
-                ret = power(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::POWER:
+                ret = power(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case LOGARITHM:
-                ret = logarithm(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::LOGARITHM:
+                ret = logarithm(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case MINIMUM:
-                ret = minimum(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::MINIMUM:
+                ret = minimum(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case MAXIMUM:
-                ret = maximum(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::MAXIMUM:
+                ret = maximum(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case LESS_THAN:
-                ret = less(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::LESS_THAN:
+                ret = less(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
 
-            case GREATER_THAN:
-                ret = greater(getInput(0)->getValue()["value"], getInput(1)->getValue()["value"]);
+            case MathOperation::GREATER_THAN:
+                ret = greater(getInput(0)->getValue(), getInput(1)->getValue());
                 break;
         }
-
-        if (ret.dump() != getOutput(0)->getValue()["value"].dump()) {
-            getOutput(0)->getValueInternal()["value"] = ret ;
-            return true;
-        }
-        else{
-            return false;
-        }
+        
+        return getOutput(0)->setValue(ret);
     }
 
 
@@ -377,10 +292,12 @@ namespace mdd {
         _operation = operation;
     }
 
-    MathOperation ModuleMath::getMathOperation(){
+    ModuleMath::MathOperation ModuleMath::getMathOperation(){
         return _operation;
     }
+
 }
+ADD_GENERATOR(mdd::ModuleMath);
 
 //gdb
 //catch throw

+ 44 - 0
lib/src/ModuleMerge.cpp

@@ -0,0 +1,44 @@
+#include "ModuleMerge.h"
+#include <boost/algorithm/string.hpp>
+
+namespace mdd {
+	ModuleMerge::ModuleMerge() {
+		std::vector<double> default_val = { 1 };
+		addInput("Value", default_val);
+		addInput("Value", default_val);
+		addOutput("Value", default_val);
+		setType("Merge");
+	}
+
+	int ModuleMerge::addModuleInput() {
+		std::vector<double> default_val = { 1 };
+		return addInput("Value", default_val);
+	}
+
+	int ModuleMerge::removeModuleInput() {
+		return pop_backInput();
+	}
+
+	std::string ModuleMerge::setInputType(const std::string& input_id, const std::string& new_type) {
+		for (int id = 0; id < getInputs().size(); ++id) {
+			if (getInput(id)->getID() == input_id) {
+				getInput(id)->setType(new_type);
+				return getInput(id)->getID();
+			}
+		}
+		return "";
+	}
+	state ModuleMerge::update() {
+		std::vector<double>  ret;
+		for (size_t i = 0; i < getInputs().size(); i++)
+		{
+			std::string key = getInput(i)->getType();
+			boost::algorithm::to_lower(key);
+			for (size_t j = 0; j < getInput(i)->getValue().size(); j++)
+			{
+				ret.push_back(getInput(i)->getValue()[j]);
+			}
+		}
+		return getOutput(0)->setValue(ret);
+	}
+}

+ 14 - 0
lib/src/ModuleParameter.cpp

@@ -0,0 +1,14 @@
+#include "ModuleParameter.h"
+
+namespace mdd {
+    ModuleParameter::ModuleParameter() {
+        std::vector<double> default_val = { 1 };
+        addInput("Value", default_val);
+        addOutput("Value", default_val);
+        setType("Parameter");
+    }
+
+    state ModuleParameter::update() {
+        return getOutput(0)->setValue(getInput(0)->getValue());
+    }
+}

+ 168 - 0
lib/src/ModuleSQL.cpp

@@ -0,0 +1,168 @@
+#include "ModuleSQL.h"
+#include <boost/algorithm/string.hpp>
+
+namespace mdd {
+	void ModuleSQL::erase_keyword(std::string& str, std::string key) {
+		while (true) {
+			int start = (int)str.find(key);
+			if (start != -1) {
+				str.erase(start, key.length());
+			}
+			else {
+				return;
+			}
+		}
+	}
+
+	ModuleSQL::ModuleSQL(std::string dbname) {
+		int rc = sqlite3_open(dbname.c_str(), &_db);
+		if (rc) {
+			fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(_db));
+			return;
+		}
+		else {
+			fprintf(stderr, "Opened database successfully\n");
+		}
+		std::string sql;
+		sqlite3_stmt* res;
+		int step;
+
+
+		// Create SQL statement
+		sql = "SELECT tbl_name  "\
+			"FROM   sqlite_master "\
+			"WHERE type = 'table' ";
+
+		// Execute SQL statement
+		rc = sqlite3_prepare_v2(_db, sql.c_str(), -1, &res, 0);
+
+		if (rc != SQLITE_OK) {
+			fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(_db));
+			sqlite3_close(_db);
+		}
+		else {
+			fprintf(stdout, "Operation done successfully\n");
+		}
+
+		step = sqlite3_step(res);
+
+		if (step == SQLITE_ROW) {
+			int nCol = sqlite3_column_count(res);
+			for (size_t i = 0; i < nCol; i++)
+			{
+				_tbname = (char*)sqlite3_column_text(res, i);
+			}
+
+		}
+		sqlite3_finalize(res);
+
+
+		// Create SQL statement
+		sql = "SELECT sql "\
+			"FROM   sqlite_master "\
+			"WHERE type = 'table' AND tbl_name = '" + _tbname + "'";
+		//std::cout << sql << std::endl;
+		// Execute SQL statement
+		rc = sqlite3_prepare_v2(_db, sql.c_str(), -1, &res, 0);
+
+		if (rc != SQLITE_OK) {
+			fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(_db));
+			sqlite3_close(_db);
+		}
+		else {
+			fprintf(stdout, "Operation done successfully\n");
+		}
+
+		step = sqlite3_step(res);
+
+		if (step == SQLITE_ROW) {
+			std::string sql_res = (char*)sqlite3_column_text(res, 0);
+			int start = sql_res.find("(");
+			int end = sql_res.find(")");
+			sql_res = sql_res.substr(++start, (size_t)(--end) - start);
+
+			erase_keyword(sql_res, "KEY");
+			erase_keyword(sql_res, "PRIMARY");
+			erase_keyword(sql_res, "AUTOINCREMENT");
+			erase_keyword(sql_res, "NOT NULL");
+
+			std::string::iterator new_end = std::unique(sql_res.begin(), sql_res.end(), [](char lhs, char rhs)->bool { return (lhs == rhs) && (lhs == ' '); });
+			sql_res.erase(new_end, sql_res.end());
+
+			_content.clear();
+			while(true){
+				end = sql_res.find(" ,");
+				if (end == -1)
+				{
+					end = sql_res.length();
+				}
+				std::string sub_str = sql_res.substr(0, end);
+				int mid = sub_str.find(" ");
+				_entity enti;
+				enti.key = sub_str.substr(0, mid);
+				enti.type = sub_str.substr(mid + 1, sub_str.length() - (mid + 1));
+				_content.push_back(enti);
+				//std::cout << "'" << enti.key << "':  '" << enti.type << "'\n";
+				if (end != sql_res.length())
+				{
+					sql_res.erase(0, end + 2);
+				}
+				else {
+					break;
+				}
+			}
+
+		}
+		sqlite3_finalize(res);
+
+		addInput(_content[0].key, {0});
+		for (auto& cont :_content)
+		{
+			addOutput(cont.key, {1});
+		}
+		setType("SQL");
+	}
+
+	state ModuleSQL::update() {
+		int rc;
+		std::string sql;
+		sqlite3_stmt* res;
+		int step;
+		// Create SQL statement
+		sql = "SELECT * "\
+			"FROM " + _tbname + " "\
+			"WHERE " + _content[0].key + " = " + std::to_string(getInput(0)->getValue()[0]);
+
+		std::cout << sql << std::endl;
+
+		// Execute SQL statement
+		rc = sqlite3_prepare_v2(_db, sql.c_str(), -1, &res, 0);
+
+		if (rc != SQLITE_OK) {
+			fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(_db));
+			sqlite3_close(_db);
+		}
+		else {
+			fprintf(stdout, "Operation done successfully\n");
+		}
+
+		step = sqlite3_step(res);
+		state state = state::UNCHANGED;
+		if (step == SQLITE_ROW) {
+			int nCol = sqlite3_column_count(res);
+			std::string parse_str = "{\"" + _tbname + "\" : {";
+			for (size_t i = 0; i < nCol; i++)
+			{
+				//json val = (char*)sqlite3_column_text(res, i);
+				getOutput(i)->setValue({ std::atof((char*)sqlite3_column_text(res, i)) });
+			}
+		}
+		sqlite3_finalize(res);
+
+		return state;
+	}
+
+	ModuleSQL::~ModuleSQL() {
+		sqlite3_close(_db);
+	}
+}

+ 0 - 0
lib/src/ModuleSplitt.cpp


+ 20 - 17
lib/src/ModuleSwitch.cpp

@@ -3,31 +3,34 @@
 
 namespace mdd{
     ModuleSwitch::ModuleSwitch(){
-        json default_val;
-        default_val["value"] = 42;
+        std::vector<double> default_val = { 42 };
         addInput("Switch", default_val);
         addInput("Value", default_val);
         addInput("Default", default_val);
         addOutput("Value", default_val);
         setType("Switch");
     }
-    bool ModuleSwitch::update(){
-        int index = getInput(0)->getValue()["value"].get<int>();
-        if(index == 0){
-            index = 1;
-        }
+    state ModuleSwitch::update(){
+        std::vector<double> ret;
+        size_t length = getInput(0)->getValue().size();
+        for (size_t i = 0; i < length; i++)
+        {
+            int index = (int)getInput(0)->getValue()[i];
+           
+            if (index == 0) {
+                index = 1;
+            }
 
-        if(index > getInputs().size() - 1){
-            index = getInputs().size() - 1;
+            if (index > getInputs().size() - 1) {
+                index = getInputs().size() - 1;
+            }
+            for (size_t j = 0; j < getInput(index)->getValue().size(); j++)
+            {
+                ret.push_back(getInput(index)->getValue()[j]);
+            }
+            
         }
+        return getOutput(0)->setValue(ret);
 
-        json ret = getInput(index)->getValue()["value"];
-        if (ret.dump() != getOutput(0)->getValue()["value"].dump()) {
-            getOutput(0)->getValueInternal()["value"] = ret ;
-            return true;
-        }
-        else{
-            return false;
-        }
     }
 }

+ 58 - 0
lib/src/OptimizerBase.cpp

@@ -0,0 +1,58 @@
+#include "OptimizerBase.h"
+#include <iostream>
+
+namespace mdd{
+	OptimizerBase::opt_state OptimizerBase::updateOutputs()
+	{
+		opt_state ret;
+		ret.module_state = _module->update();
+		if (ret.module_state != state::STATE_ERROR)
+		{
+			for (size_t i = 0; i < _output_vals.size(); ++i)
+			{
+				_output_vals[i] = _outputs[i]->getValue()[0];
+				//std::cout << "get: " << i << ": " << _output_vals[i] << std::endl;
+			}
+			ret.opt_value = _func_expr.value();
+			//std::cout << "get: " << "opt" << ": " << ret.opt_value << std::endl;
+		}
+		
+		return ret;
+	}
+
+	void OptimizerBase::updateLayout()
+	{
+		_inputs = _module->getOptimizableInputs();
+		_outputs = _module->getOptimizableOutputs();
+		_output_vals.clear();
+		if (_inputs.empty())
+		{
+			std::cout << "ERROR: No optimizable inputs detected!" << std::endl;
+		}
+		if (_outputs.empty())
+		{
+			std::cout << "ERROR: No optimizable outputs detected!" << std::endl;
+		}
+		for (auto& out : _outputs)
+		{
+			_output_vals.push_back(out->getValue()[0]);
+		}
+	}
+	
+	bool OptimizerBase::setEvaluation(std::string func)
+	{
+		updateLayout();
+		exprtk::symbol_table<double> symbol_table;
+		for (size_t i = 0; i < _output_vals.size(); ++i)
+		{
+			symbol_table.add_variable("out" + std::to_string(i), _output_vals[i]);
+		}
+		symbol_table.add_constants();
+	
+		_func_expr.register_symbol_table(symbol_table);
+	
+		exprtk::parser<double> parser;
+		return parser.compile(func, _func_expr);
+	}
+	
+}

+ 282 - 0
lib/src/OptimizerEvolutionary.cpp

@@ -0,0 +1,282 @@
+#include "OptimizerEvolutionary.h"
+#include <iostream>
+
+namespace mdd {
+	void OptimizerEvolutionary::evaluate(size_t ignore_len)
+	{
+		//calculate fitness
+		for (auto& it = _children.begin() + ignore_len; it != _children.end(); ++it)
+		{
+			for (size_t j = 0; j < _inputs.size(); j++)
+			{
+				//std::cout << "set: " << j << ": " << it->dna[j] << std::endl;
+				_inputs[j]->setValue() = it->dna[j];
+			}
+			auto opt = updateOutputs();
+			if (opt.module_state == state::STATE_ERROR) {
+				_children.erase(it);
+			}
+			else {
+				it->fitness = opt.opt_value;
+			}
+		}
+		//find fitest
+		double min = _children[0].fitness;
+		for (size_t i = 1; i < _children.size(); i++)
+		{
+			if (min > _children[i].fitness) {
+				min = _children[i].fitness;
+				_best = _children[i];
+			}
+		}
+	}
+	OptimizerEvolutionary::OptimizerEvolutionary(std::shared_ptr<IModule> module, size_t converges, size_t grow_generation, double max_fitness, int min_generations)
+	{
+		_module = module;
+		_grow_generation = grow_generation;
+		_min_generations = min_generations;
+		_max_fitness = max_fitness;
+		_converges = converges;
+	}
+	std::vector<std::vector<double>> OptimizerEvolutionary::update()
+	{
+		int gen = -1;
+		bool check;
+		Individual old_best;
+		size_t same_counter = 0;
+		if (_inputs.size() == 0)
+		{
+			std::cout << "ERROR: No optimizable inputs detected!" << std::endl;
+			return std::vector<std::vector<double>>();
+		}
+		do
+		{
+			std::cout << _children.size() << " | " << gen << std::endl;
+			if (_children.empty())
+			{
+				for (size_t i = 0; i < _grow_generation*2; i++)
+				{
+					_children.push_back(generateIndividual());
+				}
+				evaluate();
+			}
+			else {
+				if (gen != -1)
+				{
+					evolve(_children);
+				}
+				else {
+					evaluate();
+				}
+			}
+			
+			++gen;
+			check = gen < _min_generations || _best.fitness > _max_fitness;
+			if (!check && _converges > 0)
+			{
+				if (_best == old_best)
+				{
+					++same_counter;
+				}
+				else
+				{
+					old_best = _best;
+					same_counter = 0;
+				}
+				if (same_counter < _converges)
+				{
+					check = true;
+				}
+			}
+		} while (check);
+		
+		return _best.dna;
+	}
+	std::vector<double> OptimizerEvolutionary::mutateGene(std::shared_ptr<IInput> input, std::vector<double> seed)
+	{
+	
+		limits limit = input->getLimits();
+		auto ret = seed;
+		
+		if (!limit.elements.empty())
+		{
+			int i = (int)random_num(0, limit.elements.size() - 1);
+			ret = limit.elements[i];
+			return ret;
+		}
+		if (!limit.min.empty() && !limit.max.empty()) {
+
+			bool check = true;
+			do {
+				if (!ret.empty())
+				{
+					int i = (int)random_num(0, limit.min.size() - 1);
+					if (!limit.step.empty()) {
+						//randomly generate step dx in [min, max]
+						/*std::cout << limit["min"][i].get<double>() << " | ";
+						std::cout << limit["max"][i].dump() << " | ";
+						std::cout << limit["step"][i].dump() << " | ";*/
+						ret[i] = random_num(limit.min[i], limit.max[i], limit.step[i]);
+					}
+					else {
+						int m = (int)random_num(0, 1);
+						if (m == 0)
+						{
+							ret[i] = limit.min[i];
+						}
+						else {
+							ret[i] = limit.max[i];
+						}
+					}
+				}
+				else
+				{
+					for (size_t i = 0; i < limit.min.size(); i++)
+					{
+						if (!limit.step.empty()) {
+							//randomly generate step dx in [min, max]
+							ret.push_back(random_num(limit.min[i], limit.max[i], limit.step[i]));
+						}
+						else {
+							int m = (int)random_num(0, 1);
+							if (m == 0)
+							{
+								ret.push_back(limit.min[i]);
+							}
+							else {
+								ret.push_back(limit.max[i]);
+							}
+						}
+					}
+				}
+				
+				if (!limit.rule.empty()) {
+					//use rule to check
+					exprtk::symbol_table<double> symbol_table;
+					
+					symbol_table.add_vector("val", ret);
+					symbol_table.add_constants();
+					exprtk::expression<double> func_expr;
+					func_expr.register_symbol_table(symbol_table);
+
+					exprtk::parser<double> parser;
+					parser.compile(limit.rule, func_expr);
+					check = (bool)func_expr.value();
+				}
+			} while (!check);
+			return ret; 
+			
+		}
+		std::cout << "ERROR in GENE elements! (END)" << std::endl;
+		return input->getValue();//ERROR
+	}
+
+	void OptimizerEvolutionary::evolve(std::vector<Individual> parents)
+	{
+		////fittest should breed more
+		//detect lower border
+		double max = parents[0].fitness;
+		for (size_t i = 1; i < parents.size(); i++)
+		{
+			if (max < parents[i].fitness) {
+				max = parents[i].fitness;
+			}
+		}
+		//detect lower border
+		double sum = 0;
+		for (size_t i = 0; i < parents.size(); i++)
+		{
+			sum += max - parents[i].fitness;
+		}
+		if (sum == 0)
+		{
+			sum = 1.0;
+		}
+		//multiply fitter parents
+		std::vector<Individual> gen_pool = parents;
+		for (size_t i = 0; i < parents.size(); i++)
+		{
+			int additional = std::round((max - parents[i].fitness) / sum * 20);
+			//std::cout << additional << std::endl;
+			for (size_t j = 1; j < additional; j++)
+			{
+				gen_pool.push_back(parents[i]);
+			}
+		}
+		//fittest parents will also be new childrens
+		_children.clear();
+		double min = parents[0].fitness;
+		for (size_t i = 1; i < parents.size(); i++)
+		{
+			if (max > parents[i].fitness) {
+				min = parents[i].fitness;
+			}
+		}
+		for (size_t i = 0; i < parents.size(); i++)
+		{
+			if (max == parents[i].fitness) {
+				bool exist = false;
+				for (size_t j = 0; j < _children.size(); j++)
+				{
+					if (_children[j].dna == parents[i].dna) {
+						exist = true;
+						break;
+					}
+				}
+				if (!exist) {
+					_children.push_back(parents[i]);
+				}
+			}
+		}
+		//breed
+		size_t init_len = _children.size();
+		for (size_t i = 0; i < _grow_generation; i++)
+		{
+			int p1 = (int)random_num(0, gen_pool.size() - 1);
+			int p2 = (int)random_num(0, gen_pool.size() - 1);
+			_children.push_back(combine(gen_pool[p1], gen_pool[p2]));
+		}
+		evaluate(init_len);
+	}
+	OptimizerEvolutionary::Individual OptimizerEvolutionary::combine(Individual par1, Individual par2)
+	{
+		size_t len = par1.dna.size();
+		Individual child;
+		for (size_t i = 0; i < len; i++)
+		{
+			double p = random_num(0.0, 100.0, 1.0);
+			if (p<45.0)
+			{
+				child.dna.push_back(par1.dna[i]);
+			}
+			else if(p<90.0){
+				child.dna.push_back(par2.dna[i]);
+			}
+			else
+			{
+				child.dna.push_back(mutateGene(_inputs[i]));
+			}
+		}
+		return child;
+	}
+	OptimizerEvolutionary::Individual OptimizerEvolutionary::generateIndividual()
+	{
+		Individual ret;
+		for (size_t i = 0; i < _inputs.size(); i++)
+		{
+			ret.dna.push_back(mutateGene(_inputs[i]));
+		}
+		return ret;
+	}
+	OptimizerEvolutionary::Individual OptimizerEvolutionary::getBest() {
+		return _best;
+	}
+	double OptimizerEvolutionary::evaluateFitness(const Individual& ind) {
+		for (size_t j = 0; j < _inputs.size(); j++)
+		{
+			_inputs[j]->setValue() = ind.dna[j];
+		}
+		auto opt = updateOutputs();
+		return opt.opt_value;
+	}
+}

+ 52 - 9
lib/src/Output.cpp

@@ -1,28 +1,61 @@
 #include "Output.h"
 namespace mdd {
-    Output::Output( const std::string& type, int appendix, const json& initial) :
-            _changed(false)
+    int Output::addConnection(std::shared_ptr<IInput> input)
+    {
+        _connections.push_back(input);
+        return _connections.size();
+    }
+    int Output::removeConnection(std::shared_ptr<IInput> input)
+    {
+        for (auto it = _connections.begin(); it != _connections.end(); ++it) {
+            if ((*it) == input)
+            {
+                _connections.erase(it);
+            }
+        }
+        return _connections.size();
+    }
+    Output::Output( const std::string& type, int appendix, const std::vector<double>& initial) :
+            _state(state::UNCHANGED)
     {
         _appendix = appendix;
         _prefix = "";
         _type = type;
         _value = initial;
+        _optimizable = false;
     }
 
-    const json& Output::getValue() { return _value; }
+    const std::vector<double>& Output::getValue() { return _value; }
 
-    json& Output::getValueInternal() {
-        _changed = true;
+    std::vector<double>& Output::setValue() {
+        _state = state::CHANGED;
         return _value;
     }
+    state Output::setValue(const std::vector<double>& val) {
+        if (val != _value)
+        {
+            _value = val;
+            _state = state::CHANGED;
+        }
+        else {
+            _state = state::UNCHANGED;
+        }
+        return _state;
+    }
+    bool Output::isOptimizable() {
+        return _optimizable;
+    }
 
+    void Output::setOptimizability(bool state) {
+        _optimizable = state;
+    }
     std::string Output::getType() { return _type; }
 
-    bool Output::hasChanged() { return _changed; }
+    state Output::getState() { return _state; } 
 
-    void Output::resetChange() { _changed = false; }
+    void Output::resetState() { _state = state::UNCHANGED; }
 
-    std::string Output::setType(std::string type){
+    std::string Output::setType(const std::string& type){
         _type = type;
         return getID();
     }
@@ -31,7 +64,7 @@ namespace mdd {
         return _prefix + "/" + _type + std::to_string(_appendix);
     }
 
-    std::string Output::setPrefix(std::string prefix){
+    std::string Output::setPrefix(const std::string& prefix){
         _prefix = prefix;
         return getID();
     }
@@ -40,4 +73,14 @@ namespace mdd {
         _appendix = appendix;
         return getID();
     }
+    bool Output::connect(std::shared_ptr<IInput> input)
+    {
+        addConnection(input);
+        input->addConnection(std::make_shared<Output>((*this)));
+        return true;
+    }
+    std::vector<std::shared_ptr<IInput>> Output::getConnections()
+    {
+        return _connections;
+    }
 }

+ 116 - 8
lib/src/ProcessorBase.cpp

@@ -4,14 +4,13 @@
 
 namespace mdd{
 
-    int ProcessorBase::addProcesorInput(const std::string &type, const json &value,
-                                        const std::function<bool(const json &)> &verification){
-        _processor_inputs.push_back(std::make_shared<Input>( type, _processor_inputs.size(), value, verification));
+    int ProcessorBase::addProcesorInput(const std::string &type, const std::vector<double>&value){
+        _processor_inputs.push_back(std::make_shared<Input>( type, _processor_inputs.size(), value));
         _processor_inputs[_processor_inputs.size() - 1]->setPrefix(getID());
         return  _processor_inputs.size()-1;
     }
 
-    int ProcessorBase::addProcessorOutput(const std::string& type, const json& initial){
+    int ProcessorBase::addProcessorOutput(const std::string& type, const std::vector<double>& initial){
         _processor_outputs.push_back(std::make_shared<Output>( type, _processor_outputs.size(), initial));
         _processor_outputs[_processor_outputs.size() - 1]->setPrefix(getID());
         return  _processor_outputs.size()-1;
@@ -48,7 +47,7 @@ namespace mdd{
         return _prefix + "/" + _type + std::to_string(_appendix);
     }
 
-    std::string ProcessorBase::setType(std:: string type){
+    std::string ProcessorBase::setType(const std::string& type){
         _type=type;
         updateID();
         return getID();
@@ -57,7 +56,7 @@ namespace mdd{
         return _type;
     }
 
-    std::string ProcessorBase::setPrefix(std::string prefix){
+    std::string ProcessorBase::setPrefix(const std::string& prefix){
         _prefix = prefix;
         updateID();
         return getID();
@@ -77,6 +76,30 @@ namespace mdd{
         return _modules.back()->getID();
     }
 
+    void ProcessorBase::removeModule(std::shared_ptr<IModule> module)
+    {
+        for (auto it = _module_inputs.begin(); it != _module_inputs.end(); ++it) {
+            if (it->moduleHandler == module)
+            {
+                _module_inputs.erase(it);
+            }
+        }
+
+        for (auto it = _module_outputs.begin(); it != _module_outputs.end(); ++it) {
+            if (it->moduleHandler == module)
+            {
+                _module_outputs.erase(it);
+            }
+        }
+
+        for (auto it = _modules.begin(); it != _modules.end(); ++it) {
+            if ((*it) == module)
+            {
+                _modules.erase(it);
+            }
+        }
+    }
+
     std::string ProcessorBase::addModuleInput(std::string module_ID, std::string input_ID){
         int ret = _processor_inputs.size();
         for (auto& module : _modules) {
@@ -166,7 +189,92 @@ namespace mdd{
         return ret;
     }
 
-    std::shared_ptr<IOutput> ProcessorBase::getOutput(std::string output_id){
+    std::vector<state> ProcessorBase::getInputStates() {
+        std::vector<state> ret;
+        for (auto& input : _processor_inputs) {
+            ret.push_back(input->getState());
+        }
+        for (auto& input : _module_inputs) {
+            ret.push_back(input.accessHandler->getState());
+        }
+        return ret;
+    }
+    
+    std::vector<state> ProcessorBase::getOutputStates() {
+        std::vector<state> ret;
+        for (auto& output : _processor_outputs) {
+            ret.push_back(output->getState());
+        }
+        for (auto& output : _module_outputs) {
+            ret.push_back(output.accessHandler->getState());
+        }
+        return ret;
+    }
+
+    std::vector<std::shared_ptr<IOutput>> ProcessorBase::getInputConnections()
+    {
+        std::vector<std::shared_ptr<IOutput>> ret;
+        for (auto& input : _processor_inputs) {
+            ret.push_back(input->getConnection());
+        }
+        for (auto& input : _module_inputs) {
+            ret.push_back(input.accessHandler->getConnection());
+        }
+        return ret;
+    }
+
+    std::vector<std::vector<std::shared_ptr<IInput>>> ProcessorBase::getOutputConnections()
+    {
+        std::vector<std::vector<std::shared_ptr<IInput>>> ret;
+        for (auto& output : _processor_outputs) {
+            ret.push_back(output->getConnections());
+        }
+        for (auto& output : _module_outputs) {
+            ret.push_back(output.accessHandler->getConnections());
+        }
+        return ret;
+    }
+
+    std::vector <std::shared_ptr<IInput>> ProcessorBase::getOptimizableInputs() 
+    {
+        std::vector<std::shared_ptr<IInput>> ret;
+        for (auto& input : _processor_inputs) {
+            if (input->isOptimizable())
+            {
+                ret.push_back(input);
+            }
+        }
+        for (auto& mod : _modules) {
+            auto in = mod->getOptimizableInputs();
+            for (size_t i = 0; i < in.size(); i++)
+            {
+                ret.push_back(in[i]);
+            }
+        }
+        return ret;
+    }
+
+    std::vector <std::shared_ptr<IOutput>> ProcessorBase::getOptimizableOutputs()
+    {
+        std::vector<std::shared_ptr<IOutput>> ret;
+        for (auto& output : _processor_outputs) {
+            if (output->isOptimizable())
+            {
+                ret.push_back(output);
+            }
+        }
+        for (auto& mod : _modules) {
+            auto out = mod->getOptimizableOutputs();
+            for (size_t i = 0; i < out.size(); i++)
+            {
+                ret.push_back(out[i]);
+            }
+        }
+        
+        return ret;
+    }
+
+    std::shared_ptr<IOutput> ProcessorBase::getOutput(const std::string& output_id){
         for (auto& output : _processor_outputs) {
             if(output->getID() == output_id){
                 return output;
@@ -180,7 +288,7 @@ namespace mdd{
         return nullptr;
     }
 
-    std::shared_ptr<IInput> ProcessorBase::getInput(std::string input_id){
+    std::shared_ptr<IInput> ProcessorBase::getInput(const std::string& input_id){
         for (auto& input : _processor_inputs) {
             if(input->getID() == input_id){
                 return input;

+ 0 - 0
lib/src/ProcessorEvolution.cpp


+ 0 - 30
lib/src/ProcessorManual.cpp

@@ -1,30 +0,0 @@
-#include "ProcessorManual.h"
-#include <iostream>
-
-namespace mdd {
-    ProcessorManual::ProcessorManual()
-    {
-        addProcessorOutput("Iterator", "{ \"value\": 0 }"_json);
-    }
-
-    bool ProcessorManual::update() {
-        bool ret = false;
-        bool group_state = true;
-        while(group_state){
-            getProcessorOutput(0)->getValueInternal()["value"]= getProcessorOutput(0)->getValue()["value"].get<int>()+1;
-            group_state = false;
-            for (int i = 0; i < getModules().size(); ++i) {
-                bool module_state = getModule(i)->update();
-                if(module_state){
-                    group_state=true;
-                    ret = true;
-                }
-            }
-        }
-        return ret;
-    }
-
-    std::shared_ptr<IOutput> ProcessorManual::getIteration(){
-        return getProcessorOutput(0);
-    }
-}

+ 154 - 0
lib/src/ProcessorStandard.cpp

@@ -0,0 +1,154 @@
+#include "ProcessorStandard.h"
+#include <iostream>
+
+namespace mdd {
+    ProcessorStandard::ProcessorStandard(priority priorityEvaluation , int maxIterations):
+        priorityEvaluation(priorityEvaluation),
+        maxIterations(maxIterations)
+    {
+        setType("StandardProcessor");
+        addProcessorOutput("Iterator", {0});
+    }
+
+    std::string ProcessorStandard::addModule(std::shared_ptr<IModule> module)
+    {
+        std::string id = ProcessorBase::addModule(module);
+        _priority_list.emplace_back(module_priority(module));
+        return id;
+    }
+
+    void ProcessorStandard::removeModule(std::shared_ptr<IModule> module)
+    {
+        ProcessorBase::removeModule(module);
+        for (auto it = _priority_list.begin(); it != _priority_list.end(); ++it) {
+            if (it->module_ptr == module)
+            {
+                _priority_list.erase(it);
+                return;
+            }
+        }
+    }
+
+    std::vector<std::shared_ptr<IModule>> ProcessorStandard::getModulePriority()
+    {
+        std::vector <std::shared_ptr<IModule>> ret;
+        for (auto& p : _priority_list) {
+            ret.push_back(p.module_ptr);
+        }
+        return ret;
+    }
+
+    state ProcessorStandard::update() {
+        if (priorityEvaluation != MANUAL)
+        {
+            //update priorities
+            for (auto it = _priority_list.begin(); it != _priority_list.end(); ++it) {
+                //collect connected inputs
+                auto input_connections = it->module_ptr->getInputConnections();
+                it->inputCounter = 0;
+                for (auto it_c = input_connections.begin(); it_c != input_connections.end(); ++it_c) {
+                    if ((*it_c) != nullptr)
+                    {
+                        ++(it->inputCounter);
+                    }
+                }
+                //collect connected outputs
+                auto output_connections = it->module_ptr->getOutputConnections();
+                it->outputCounter = 0;
+                for (auto it_c = output_connections.begin(); it_c != output_connections.end(); ++it_c) {
+                    if (!(*it_c).empty())
+                    {
+                        ++(it->outputCounter);
+                    }
+                }
+            }
+            //sort by connections
+            std::sort(_priority_list.begin(), _priority_list.end(), [](module_priority a, module_priority b) {
+                if (a.inputCounter == b.inputCounter)
+                {
+                    return a.outputCounter > b.outputCounter;
+                }
+                return a.inputCounter < b.inputCounter;
+            });
+        }
+        
+        typedef std::chrono::high_resolution_clock Time;
+        //update
+        state ret = state::UNCHANGED;
+        state group_state = state::CHANGED;
+        size_t restart = 0;
+        while (group_state == state::CHANGED) {
+            getProcessorOutput(0)->setValue()[0] += 1;
+            getProcessorOutput(0)->resetState();
+            group_state = state::UNCHANGED;
+            for (int i = restart; i < _priority_list.size(); ++i) {
+                auto t_start = Time::now();
+                state module_state = _priority_list[i].module_ptr->update();
+                auto t_end = Time::now();
+                if (priorityEvaluation == TIME)
+                {
+                    _priority_list[i].time_priority = std::round(std::log10(std::chrono::duration_cast<std::chrono::milliseconds>(t_end - t_start).count()));
+                }
+                if (module_state == state::CHANGED) {
+                    group_state = state::CHANGED;
+                    ret = state::CHANGED;
+                }
+                // ignore modules which have to initilize once in the future
+                if (_priority_list[i].inputCounter == 0 && priorityEvaluation != MANUAL) {
+                    restart = i;
+                }
+                if ((priorityEvaluation == DYNAMIC || priorityEvaluation == TIME) && _priority_list.size() < i+1) {
+                    if (_priority_list[i + 1].inputCounter == _priority_list[i].inputCounter && _priority_list[i + 1].inputCounter != 0)
+                    {
+                        //collect changes
+                        for (auto it = _priority_list.begin() + i + 1; it != _priority_list.end(); ++it) {
+                            auto input_states = it->module_ptr->getInputStates();
+                            it->changeCounter = 0;
+                            for (auto it_c = input_states.begin(); it_c != input_states.end(); ++it_c) {
+                                if ((*it_c) == state::CHANGED)
+                                {
+                                    ++(it->changeCounter);
+                                }
+                            }
+                        }
+                        std::sort(_priority_list.begin() + i + 1, _priority_list.end(), [](module_priority a, module_priority b) {
+                            if (a.inputCounter == b.inputCounter)
+                            {
+                                if (a.time_priority == b.time_priority)
+                                {
+                                    if ((a.inputCounter - a.changeCounter) == (b.inputCounter - b.changeCounter)) {
+                                        if (a.changeCounter == b.changeCounter) {
+                                            return a.outputCounter > b.outputCounter;
+                                        }
+                                        return a.changeCounter > b.changeCounter;
+                                    }
+                                    return (a.inputCounter - a.changeCounter) < (b.inputCounter - b.changeCounter);
+                                }
+                                return a.time_priority < b.time_priority;
+                            }
+                            return a.inputCounter < b.inputCounter;
+                            
+                        });
+                    }
+                }
+            }
+            if (maxIterations != -1 && getProcessorOutput(0)->getValue()[0] >= maxIterations)
+            {
+                return state::STATE_ERROR;
+            }
+        }
+        return ret;
+    }
+
+    std::shared_ptr<IOutput> ProcessorStandard::getIteration(){
+        return getProcessorOutput(0);
+    }
+    ProcessorStandard::module_priority::module_priority(std::shared_ptr<IModule> module, size_t inputs, size_t outputs, size_t change)
+    {
+        module_ptr = module;
+        inputCounter = inputs;
+        outputCounter = outputs;
+        changeCounter = change;
+        time_priority = 0;
+    }
+}

+ 16 - 10
lib/test/CMakeLists.txt

@@ -1,11 +1,17 @@
-if(EXISTS /usr/src/gtest)
-    add_executable(auslegung_test
-            test_ModuleHTTP
-            test_ModuleMath.cpp
-            test_ModuleSwitch.cpp
-            test_ProcessorManual.cpp
-            )
-    target_link_libraries(auslegung_test gtest gtest_main ${PROJECT_NAME})
-    add_test(auslegung_test auslegung_test)
+add_executable(mdd_lib_test
+	test_Ansys.cpp
+	test_Connector
+        test_ModuleHTTP.cpp
+        test_ModuleMath.cpp
+        test_ModuleSQL.cpp
+        test_ModuleSwitch.cpp
+	test_OptimizerEvolutionary.cpp
+        test_ProcessorStandard.cpp
+        )
+target_link_libraries(mdd_lib_test gtest gtest_main ${PROJECT_NAME})
 
-endif()
+if(WIN32)
+	target_compile_options(mdd_lib_test PRIVATE /bigobj)
+endif(WIN32)
+
+add_test(mdd_lib_test mdd_lib_test)

BIN
lib/test/db/materials.db


+ 2 - 0
lib/test/server/.gitignore

@@ -1,2 +1,4 @@
 .idea
 __pycache__
+venv
+ws

BIN
lib/test/server/__pycache__/ini_logger.cpython-36.pyc


+ 15 - 0
lib/test/server/ansys/00_Model.inp

@@ -0,0 +1,15 @@
+! /INPUT, C:/Users/Willi/Documents/projects/gfk-plate/script/00_Modell.inp
+finish
+/clear
+
+/CONTOUR
+/RGB,INDEX,100,100,100, 0   
+/RGB,INDEX, 80, 80, 80,13   
+/RGB,INDEX, 60, 60, 60,14   
+/RGB,INDEX, 0, 0, 0,15  
+/COLOR,CURVE,4
+/REPLOT 
+
+/filename,GFK_Rotor
+/title,GFK Rotor
+/PLOTPTS,INFO,AUTO

+ 21 - 0
lib/test/server/ansys/01_Parameter.inp

@@ -0,0 +1,21 @@
+! /INPUT, C:/Users/Willi/Documents/projects/gfk-plate/script/00_Modell.inp
+
+
+!**********************************
+!	Variables
+!**********************************
+t_r		=	0.7			![mm]		Schichtdicke
+theta_r	=	0			![°]		Faserorientierung
+
+t_t		=	0.7			![mm]		Schichtdicke
+theta_t	=	90			![°]		Faserorientierung
+
+TH		=	200			![°C]		Herstellungstemperatur
+TN		=	20			![°C]		Nutzungstemperatur
+
+R_out	=	125			![mm]		Aussenradius
+r_in	=	25			![mm]		Innenradius
+D_plate	=	5			![mm]		Plattenhöhe
+d_layer	=	1			![mm]		Schichtdicke
+
+omega_z	=	0.1			![rad/s]	Winkelgeschwindigkeit(+: gegen Uhrzeigersinn)

+ 61 - 0
lib/test/server/ansys/02_Laminate.inp

@@ -0,0 +1,61 @@
+/PREP7
+!**********************************
+!	Materials
+!********************************** 
+!X:	radiale Richtung
+!Y: tangentiale Richtung
+!Z: normale Richtung
+
+!MPTEMP,,,,,,,,  
+!GFK EP-E Glas radial
+MPTEMP,1,TH  
+MPDATA,EX,1,,42.5 			![N/mm^2] 	E-Module in Faserrichtung
+MPDATA,EY,1,,11 			![N/mm^2] 	E-Modul quer zur Faserrichtung
+MPDATA,EZ,1,,11  			![N/mm^2] 	E-Modul quer zur Faserrichtung
+MPDATA,PRXY,1,,0.28
+MPDATA,PRYZ,1,,0.28
+MPDATA,PRXZ,1,,0.28
+MPDATA,GXY,1,,4.2
+MPDATA,GYZ,1,,11/(2*(1+0.28))!
+MPDATA,GXZ,1,,4.2
+MPDATA,DENS,1,,1950E-6		![kg/mm^3]	Dichte
+MPDATA,ALPX,1,,5.7E-6		![1/K]		Waermeausdenungsk
+MPDATA,ALPY,1,,45E-6		![1/K]		Waermeausdenungsk
+MPDATA,ALPZ,1,,45E-6		![1/K]		Waermeausdenungsk
+
+MPDATA,KXX,1,,0.72E3 		![W/K]		Waermeleitfaehigk.
+MPDATA,KYY,1,,0.5E3  		![W/K]		Waermeleitfaehigk.
+MPDATA,KZZ,1,,0.5E3 		![W/K]		Waermeleitfaehigk.
+
+MPDATA,BETX,1,,0E-3			![1/%M]		Quellkoeffizient
+MPDATA,BETY,1,,4E-3			![1/%M]		Quellkoeffizient
+MPDATA,BETZ,1,,4E-3			![1/%M]		Quellkoeffizient
+
+MPDATA,DXX,1,,4.4E3			![mm^2/s]	Diffusionskoeffizient
+MPDATA,DYY,1,,3.1E3			![mm^2/s]	Diffusionskoeffizient
+MPDATA,DZZ,1,,3.1E3			![mm^2/s]	Diffusionskoeffizient
+
+!MPDATA,CTEX,1,,5.7E-6		![]			Schrumpfen
+!MPDATA,CTEY,1,,45E-6		![]			Schrumpfen
+!MPDATA,CTEZ,1,,45E-6		![]			Schrumpfen
+
+!/EOf
+!**********************************
+!	Elements
+!**********************************
+ET,1,SHELL181   
+KEYOPT,1,8,1 ! Enable Laminate
+
+!**********************************
+!	Laminate
+!**********************************
+sect,1,shell,,  
+!secdata, Thickness ,MatId,theta,Number of integration points in layer
+secdata, t_t,1,theta_t,3   
+secdata, t_r,1,theta_r,3
+secdata, t_r,1,theta_r,3
+secdata, t_r,1,theta_r,3
+secdata, t_r,1,theta_r,3
+secdata, t_r,1,thet,0a_r,3
+secoffset,MID   !Shell node will be offset to midplane of the section
+seccontrol,,,, , , ,

+ 53 - 0
lib/test/server/ansys/03_Modell.inp

@@ -0,0 +1,53 @@
+! /INPUT, C:/Users/Willi/Documents/projects/gfk-plate/script/00_Modell.inp
+ 
+!**********************************
+!	Geometry
+!**********************************
+CSYS,1  
+CYL4,0,0,r_in,0,R_out,180
+CYL4,0,0,r_in,180,R_out,360
+
+NSEL,S,LOC,Y,0
+NUMMRG,ALL
+
+NSEL,S,LOC,Y,180
+NUMMRG,ALL
+
+LSEL,S,,,1,7,2
+LESIZE,ALL,,,20
+
+LSEL,S,,,2,4,2
+LESIZE,ALL,,,20
+
+LSEL,ALL
+APLOT,All
+
+MSHAPE,0,2D !quadratic 2D Shapes
+Mshkey,1	!0-free meshing
+AMESH,ALL
+
+EPLOT,ALL
+!**********************************
+!	Load
+!**********************************
+/SOLU
+OMEGA,,,omega_z
+NSEL,S,LOC,X,r_in
+D,ALL,UX,0
+D,ALL,UY,0
+D,ALL,UZ,0
+D,ALL,ROTX,0
+D,ALL,ROTY,0
+D,ALL,ROTZ,0
+ALLS
+
+!Nichtliniearitäten
+!NLGEOM,ON
+	!NSUBST,20
+	!AUTOTS,ON
+outres,ALL,ALL
+!time,1
+solve
+
+finish
+

+ 39 - 0
lib/test/server/ansys/04_Plot.inp

@@ -0,0 +1,39 @@
+!**********************************
+!	Plot
+!**********************************
+/Post1
+ALLS
+
+/erase
+/win,1,ltop $/win,2,rtop
+/win,3,lbot $/win,4,rbot
+
+/win,1,off
+/win,2,off
+/win,3,off
+/win,4,off
+
+/win,1,on
+PLNSOL,S,X !Stress in Radialrichtung
+/noerase
+/win,1,off
+
+/win,2,on
+/view,2,0,0,-1
+PLNSOL,S,X !Stress in Radialrichtung, Sicht von hinten
+/noerase
+/win,2,off
+
+/win,3,on
+PLNSOL,S,Y !Stress in Tangentialrichtung
+/noerase
+/win,3,off
+
+/win,4,on
+!/DSCALE,,1	!Verformung
+!/PLDISP,0
+PLNSOL,U,SUM
+/noerase
+/win,4,off
+
+/EOF

+ 179 - 0
lib/test/server/gfk_plate.py

@@ -0,0 +1,179 @@
+# https://akaszynski.github.io/pyansys/ansys_control.html#initial-setup-and-example
+# pip install pyansys --upgrade
+import pyansys
+import numpy as np
+import os
+import time
+
+
+def sim_rotor(materials, angles, outer_diameter=250, inner_diameter=50, thickness=5, omega=1):
+    layers = len(angles)
+    layer_thickness = thickness / layers
+
+    path = os.getcwd() + "\\ws"
+    mapdl = pyansys.launch_mapdl(run_location=path, interactive_plotting=True, loglevel='ERROR', override=True)
+
+    # clear existing geometry
+    mapdl.finish()
+    mapdl.clear()
+
+    th = 200  # [°C]        Herstellungstemperatur
+    tn = 20  # [°C]         Nutzungstemperatur
+
+    mapdl.prep7()
+    # define Material
+    for i in range(0, len(materials)):
+        mapdl.mptemp(i + 1, th)
+
+        mapdl.mpdata("EX", i + 1, "", materials[i]["e11"])
+        mapdl.mpdata("EY", i + 1, "", materials[i]["e22"])
+        mapdl.mpdata("EZ", i + 1, "", materials[i]["e33"])
+
+        mapdl.mpdata("PRXY", i + 1, "", materials[i]["pr12"])
+        mapdl.mpdata("PRXZ", i + 1, "", materials[i]["pr13"])
+        mapdl.mpdata("PRYZ", i + 1, "", materials[i]["pr23"])
+
+        mapdl.mpdata("DENS", i + 1, "", materials[i]["dens"])
+
+        mapdl.mpdata("GXY", i + 1, "", materials[i]["g12"])
+        mapdl.mpdata("GXZ", i + 1, "", materials[i]["g13"])
+        mapdl.mpdata("GYZ", i + 1, "", materials[i]["g23"])
+
+        # Waermeausdenungsk
+        mapdl.mpdata("ALPX", i + 1, "", materials[i]["alp11"])
+        mapdl.mpdata("ALPY", i + 1, "", materials[i]["alp22"])
+        mapdl.mpdata("ALPZ", i + 1, "", materials[i]["alp33"])
+
+        # Waermeleitfaehigk
+        mapdl.mpdata("KXX", i + 1, "", materials[i]["k11"])
+        mapdl.mpdata("KYY", i + 1, "", materials[i]["k22"])
+        mapdl.mpdata("KZZ", i + 1, "", materials[i]["k33"])
+
+        # Quellkoeffizient
+        mapdl.mpdata("BETX", i + 1, "", materials[i]["bet11"])
+        mapdl.mpdata("BETY", i + 1, "", materials[i]["bet22"])
+        mapdl.mpdata("BETZ", i + 1, "", materials[i]["bet33"])
+
+        # Diffusionskoeffizient
+        mapdl.mpdata("DXX", i + 1, "", materials[i]["d11"])
+        mapdl.mpdata("DYY", i + 1, "", materials[i]["d22"])
+        mapdl.mpdata("DZZ", i + 1, "", materials[i]["d33"])
+
+    # define Element
+    mapdl.et(1, "SHELL181")
+    # enable Laminate
+    mapdl.run("KEYOPT,1,8,1")
+
+    # define Laminate
+    mapdl.run("SECT, 1, SHELL")
+
+    # secdata, Thickness ,MatId,theta,Number of integration points in layer
+    if len(angles) != len(materials):
+        for i in range(0, len(angles)):
+            mapdl.secdata(layer_thickness, 1, angles[i], 3)
+            print(str(angles[i]))
+    else:
+        for i in range(0, len(angles)):
+            mapdl.secdata(layer_thickness, i + 1, angles[i], 3)
+
+    # Shell node will be offset to midplane of the section
+    mapdl.secoffset("MID")
+    mapdl.run("seccontrol,,,,,,,")
+
+    mapdl.run("/ESHAPE,1.0")
+    # define Geometry
+    # change global coordinate system to cylindric system
+    mapdl.csys(1)
+    mapdl.cyl4(0, 0, inner_diameter / 2, 0, outer_diameter / 2, 180)
+    mapdl.cyl4(0, 0, inner_diameter / 2, 180, outer_diameter / 2, 360)
+    mapdl.nsel("S", "LOC", "Y", 0)
+    mapdl.nummrg("ALL")
+    mapdl.nsel("S", "LOC", "Y", 180)
+    mapdl.nummrg("ALL")
+    mapdl.lsel("S", "", "", 1, 7, 2)
+    mapdl.lesize("ALL", "", "", 20)
+    mapdl.lsel("S", "", "", 2, 4, 2)
+    mapdl.lesize("ALL", "", "", 20)
+    mapdl.lsel("ALL")
+    mapdl.mshape(0, "2D")  # quadratic 2D Shapes
+    mapdl.mshkey(1)  # 0-free meshing
+    mapdl.amesh("ALL")
+
+    mapdl.run("/SOLU")
+    mapdl.omega("", "", omega)  # [rad/s]	Winkelgeschwindigkeit(+: gegen Uhrzeigersinn))
+    mapdl.nsel("S", "LOC", "X", inner_diameter / 2)
+    mapdl.d("ALL", "UX", 0)
+    mapdl.d("ALL", "UY", 0)
+    mapdl.d("ALL", "UZ", 0)
+    mapdl.d("ALL", "ROTX", 0)
+    mapdl.d("ALL", "ROTY", 0)
+    mapdl.d("ALL", "ROTZ", 0)
+    mapdl.run("ALLS")
+
+    mapdl.outres("ALL", "ALL")
+    # mapdl.open_gui()
+    mapdl.solve()
+
+    mapdl.finish()
+    #mapdl.post1()
+    #mapdl.open_gui()
+
+
+    # plot_rotor(mapdl)
+
+    # access results using ANSYS object
+    resultfile = os.getcwd() + '\\ws\\file.rst'
+
+    result = pyansys.read_binary(resultfile)
+    # result = mapdl.result
+    #result.plot_nodal_solution(0, 'x')
+
+# plot_nodal_solution doesnt work
+    nodenump, stress = result.principal_nodal_stress(0)
+
+    # von first principle stress is the first column
+    # must be nanmax as the shell element stress is not recorded
+    s1max = np.nanmax(stress[:, -5])
+
+    # von second principle stress is the first column
+    # must be nanmax as the shell element stress is not recorded
+    s2max = np.nanmax(stress[:, -4])
+
+    nodenum, stress = result.nodal_stress(0)
+    # von Mises stress is the last column
+    # must be nanmax as the shell element stress is not recorded
+    srmax = np.nanmax(stress[:, -6])
+    stmax = np.nanmax(stress[:, -5])
+
+    mapdl.exit()
+    time.sleep(0.5)
+
+    return s1max, s2max, srmax, stmax
+
+"""
+print(sim_rotor(
+    [{
+        "e11": 42.5,
+        "e22": 11,
+        "e33": 11,
+        "pr12": 0.28,
+        "pr13": 0.28,
+        "pr23": 0.28,
+        "dens": 1950E-6,
+        "g12": 4.2,
+        "g13": 4.2,
+        "g23": 2.56,
+        "alp11": 5.7E-6,
+        "alp22": 45E-6,
+        "alp33": 45E-6,
+        "k11": 0.72E3,
+        "k22": 0.5E3,
+        "k33": 0.5E3,
+        "bet11": 0E-3,
+        "bet22": 4E-3,
+        "bet33": 4E-3,
+        "d11": 4.4E3,
+        "d22": 3.1E3,
+        "d33": 3.1E3
+    }], [90, 0, 0, 0, 0, 0]))
+"""

+ 0 - 2
lib/test/server/links.txt

@@ -1,2 +0,0 @@
-https://www.w3schools.com/python/python_mysql_insert.asp
-https://www.sqlitetutorial.net/sqlite-python/insert/

+ 16 - 0
lib/test/server/monitor.json

@@ -0,0 +1,16 @@
+{
+"aaS.list_monitors_with_persisted_data mntr":
+[
+{
+	"Error": "Opening file 'file.mntr'"
+}
+],
+"aaS.list_monitors_with_persisted_data gst":
+[
+],
+"aaS.list_monitors_with_persisted_data cnd":
+[
+],
+"aaS.list_monitors_with_persisted_data nlh":
+[
+]}

+ 135 - 0
lib/test/server/server-ansys.py

@@ -0,0 +1,135 @@
+from abc import ABC
+
+import tornado.ioloop
+import tornado.web
+import tornado.escape
+import collections
+import json
+import pyansys
+import os
+import sqlite3 as lite
+import sys
+
+import gfk_plate
+import time
+
+import logging
+
+from ini_logger import *
+
+# log_dir = r'/var/log/server'
+# ini_logger(log_dir)
+
+inputs = [
+    {'type': "e11", 'value': [42.5]},
+    {'type': "e22", 'value': [11]},
+    {'type': "e33", 'value': [11]},
+    {'type': "pr12", 'value': [0.28]},
+    {'type': "pr13", 'value': [0.28]},
+    {'type': "pr23", 'value': [0.28]},
+    {'type': "g12", 'value': [4.2]},
+    {'type': "g13", 'value': [4.2]},
+    {'type': "g23", 'value': [2.56]},
+    {'type': "dens", 'value': [1950E-6]},
+    {'type': "alp11", 'value': [5.7E-6]},
+    {'type': "alp22", 'value': [45E-6]},
+    {'type': "alp33", 'value': [45E-6]},
+    {'type': "k11", 'value': [0.72E3]},
+    {'type': "k22", 'value': [0.5E3]},
+    {'type': "k33", 'value': [0.5E3]},
+    {'type': "bet11", 'value': [0E-3]},
+    {'type': "bet22", 'value': [4E-3]},
+    {'type': "bet33", 'value': [4E-3]},
+    {'type': "d11", 'value': [4.4E3]},
+    {'type': "d22", 'value': [3.1E3]},
+    {'type': "d33", 'value': [3.1E3]},
+    {'type': "angles", 'value': [90, 0, 0, 0, 0, 0]}
+]
+
+outputs = [
+    {'type': "Srmax", 'value': [0]},
+    {'type': "Stmax", 'value': [2]},
+    {'type': "S1max", 'value': [4]},
+    {'type': "S2max", 'value': [4]}
+]
+
+status = {
+    "status": "ready"
+}
+
+
+def update():
+    materials = []
+    for i in range(0, len(inputs[0]['value'])):
+        material = {}
+        for j in range(0, len(inputs) - 1):
+            material[inputs[j]['type']] = inputs[j]['value'][i]
+        materials.append(material)
+    success = False
+    while not success:
+        try:
+            outputs[0]['value'][0], outputs[1]['value'][0], outputs[2]['value'][0], outputs[3]['value'][
+                0] = gfk_plate.sim_rotor(materials, inputs[len(inputs) - 1]['value'])
+            success = True
+        except PermissionError:
+            print("Catch Error")
+            # time.sleep(3)
+            success = False
+
+
+class MainHandler(tornado.web.RequestHandler, ABC):
+    def prepare(self):
+        self.set_header("Content-Type", "application/json")
+        if self.request.headers.get('Content-Type') == 'application/json':
+            print(self.request.body)
+            self.json_args = json.loads(self.request.body.decode('utf-8'))
+        else:
+            self.json_args = None
+
+    def get(self, param):
+        print("INFO: GET /" + param)
+        if param == "inputs":
+            self.write(json.dumps(inputs))
+        elif param == "outputs":
+            self.write(json.dumps(outputs))
+        elif param == "status":
+            self.write(json.dumps(status))
+        elif param == "stop":
+            instance = tornado.ioloop.IOLoop.instance()
+            instance.add_callback(instance.stop)
+        else:
+            self.write("Error: GET /" + param)
+            print("Error: GET /" + param)
+
+    def post(self, param):
+        if param == "update":
+            status["status"] = "updating"
+            if self.json_args is not None:
+                # print("INFO: GET /" + param + "with body: " + self.json_args.dump())
+                counter = 0
+                for entity in self.json_args:
+                    inputs[counter]['value'] = entity['value']
+                    # print("INFO: update " + str(entity['value'][0]))
+                    counter = counter + 1
+            update()
+            self.write(json.dumps(outputs))
+            status["status"] = "ready"
+        else:
+            self.write("Error: POST /" + param)
+            print("Error: POST /" + param)
+
+
+def make_app():
+    return tornado.web.Application([
+        (r"/(.*)", MainHandler),
+    ])
+
+
+if __name__ == "__main__":
+    app = make_app()
+    if len(sys.argv) == 1:
+        app.listen(int(8888))
+    else:
+        app.listen(int(sys.argv[1]))
+
+    tornado.ioloop.IOLoop.current().start()

+ 9 - 9
lib/test/server/server.py

@@ -17,17 +17,17 @@ from ini_logger import *
 #ini_logger(log_dir)
 
 inputs = [
-    {'type': "INPUT", 'value': 0},
-    {'type': "INPUT", 'value': 1},
-    {'type': "INPUT", 'value': 2},
-    {'type': "INPUT", 'value': 3},
-    {'type': "INPUT", 'value': 4}
+    {'type': "INPUT", 'value': [0]},
+    {'type': "INPUT", 'value': [1]},
+    {'type': "INPUT", 'value': [2]},
+    {'type': "INPUT", 'value': [3]},
+    {'type': "INPUT", 'value': [4]}
 ]
 
 outputs = [
-    {'type': "OUTPUT", 'value': 0},
-    {'type': "OUTPUT", 'value': 2},
-    {'type': "OUTPUT", 'value': 4}
+    {'type': "OUTPUT", 'value': [0]},
+    {'type': "OUTPUT", 'value': [2]},
+    {'type': "OUTPUT", 'value': [4]}
 ]
 
 def update():
@@ -81,5 +81,5 @@ def make_app():
 
 if __name__ == "__main__":
     app = make_app()
-    app.listen(8888)
+    app.listen(int(sys.argv[1]))
     tornado.ioloop.IOLoop.current().start()

+ 140 - 0
lib/test/test_Ansys.cpp

@@ -0,0 +1,140 @@
+#include <gtest/gtest.h>
+#include <json.hpp>
+#include <httplib.h>
+//#define private public
+#include "OptimizerEvolutionary.h"
+#include <ProcessorStandard.h>
+#include <ModuleSQL.h>
+#include <ModuleSwitch.h>
+#include <math.h>
+#include <thread>
+/*
+using namespace mdd;
+TEST(ModuleHTTP, test_ansys_sql_server) {
+    std::shared_ptr<ModuleSQL> sql = std::make_shared<ModuleSQL>("../../../lib/test/db/materials.db");
+    std::shared_ptr<ModuleHTTP> http = std::make_shared<ModuleHTTP>("", "localhost", 8888);//../../../lib/test/server/server-ansys.py
+
+    auto sql_inputs = sql->getInputIDs();
+    auto sql_outputs = sql->getOutputIDs();
+    auto http_inputs = http->getInputIDs();
+    auto http_outputs = http->getOutputIDs();
+    sql->getInput(sql_inputs[0])->setValue() = { 1 };
+
+    //test http
+    std::cout << "http-TEST" << std::endl;
+    for (size_t i = 0; i < http_inputs.size(); i++)
+    {
+        std::cout << http->getInput(http_inputs[i])->getValue()[0] << std::endl;
+    }
+    for (size_t i = 2; i < sql_outputs.size(); i++)//0: ID 1: Name
+    {
+        http->getInput(http_inputs[i - 2])->connect(sql->getOutput(sql_outputs[i]));
+    }
+    http->getInput(http_inputs.back())->setOptimizability(true);
+    limits limit;
+    limit.min = { 0, 0, 0, 0, 0, 0 };
+    limit.max = { 90, 90, 90, 90, 90, 90 };
+    limit.rule = "val[0] != val[5] || val[1] != val[4] || val[2] != val[3]";
+    http->getInput(http_inputs.back())->setLimits() = limit;
+    //http->getInput(http_inputs.back())->setValue().clear();
+    http->getInput(http_inputs.back())->setValue() = { 90,90,0,90,0,90 };
+
+    http->getOutput(http_outputs[3])->setOptimizability(true);
+
+    sql->update();
+    //test SQL
+    std::cout << "SQL-TEST" << std::endl;
+    for (size_t i = 2; i < sql_outputs.size(); i++)
+    {
+        std::cout<< sql->getOutput(sql_outputs[i])->getValue()[0] <<std::endl;
+    }
+
+    http->update();
+    EXPECT_FLOAT_EQ(http->getOutput(http_outputs[3])->getValue()[0], 0.31204228291286723);
+}
+
+TEST(ModuleHTTP, test_configurations) {
+    std::shared_ptr<ModuleSQL> sql = std::make_shared<ModuleSQL>("../../../lib/test/db/materials.db");
+    std::shared_ptr<ModuleHTTP> http = std::make_shared<ModuleHTTP>("", "localhost", 8888);//../../../lib/test/server/server-ansys.py
+
+    auto sql_inputs = sql->getInputIDs();
+    auto sql_outputs = sql->getOutputIDs();
+    auto http_inputs = http->getInputIDs();
+    auto http_outputs = http->getOutputIDs();
+    sql->getInput(sql_inputs[0])->setValue() = { 1 };
+    for (size_t i = 2; i < sql_outputs.size(); i++)//0: ID 1: Name
+    {
+        http->getInput(http_inputs[i - 2])->connect(sql->getOutput(sql_outputs[i]));
+    }
+    http->getInput(http_inputs.back())->setOptimizability(true);
+    limits limit;
+    limit.min = { 0, 0, 0, 0, 0, 0 };
+    limit.max = { 90, 90, 90, 90, 90, 90 };
+    limit.rule = "val[0] != val[5] or val[1] != val[4] or val[2] != val[3]";
+    http->getInput(http_inputs.back())->setLimits() = limit;
+
+    http->getOutput(http_outputs[3])->setOptimizability(true);
+
+    std::shared_ptr<ProcessorStandard> processor = std::make_shared<ProcessorStandard>();;
+    processor->addModule(sql);
+    processor->addModule(http);
+    auto mods = processor->getModuleIDs();
+
+    OptimizerEvolutionary optimizer(processor, 3, 20, 0.13, 5);
+    optimizer.setEvaluation("out0");
+
+    //auto res = optimizer.update();
+    OptimizerEvolutionary::Individual ind;
+    ind.dna = { { 0,90,90,90,90,90 } };
+    std::cout << "{ 0,90,90,90,90,90 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    ind.dna = { { 90,90,90,90,90,0 } };
+    std::cout << "{ 90,90,90,90,90,0 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    ind.dna = { { 90,0,0,0,0,0 } };
+    std::cout << "{ 90,0,0,0,0,0 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    ind.dna = { { 0,0,0,0,0,90 } };
+    std::cout << "{ 0,0,0,0,0,90 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    ind.dna = { { 0,0,0,0,0,0 } };
+    std::cout << "{ 0,0,0,0,0,0 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    ind.dna = { { 90,90,90,90,90,90 } };
+    std::cout << "{ 90,90,90,90,90,90 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    ind.dna = { { 0,0,90,90,90,90 } };
+    std::cout << "{ 0,0,90,90,90,90 }: " << optimizer.evaluateFitness(ind) << std::endl;
+    EXPECT_TRUE(ind.fitness <= 100.0);
+}
+
+TEST(ModuleHTTP, test_ansys_server) {
+    std::shared_ptr<ModuleSQL> sql = std::make_shared<ModuleSQL>("../../../lib/test/db/materials.db");
+    std::shared_ptr<ModuleHTTP> http = std::make_shared<ModuleHTTP>("", "localhost", 8888);//../../../lib/test/server/server-ansys.py
+
+    auto sql_inputs = sql->getInputIDs();
+    auto sql_outputs = sql->getOutputIDs();
+    auto http_inputs = http->getInputIDs();
+    auto http_outputs = http->getOutputIDs();
+    sql->getInput(sql_inputs[0])->setValue() = { 1 };
+    for (size_t i = 2; i < sql_outputs.size(); i++)//0: ID 1: Name
+    {
+        http->getInput(http_inputs[i - 2])->connect(sql->getOutput(sql_outputs[i]));
+    }
+    http->getInput(http_inputs.back())->setOptimizability(true);
+    limits limit;
+    limit.min = { 0, 0, 0, 0, 0, 0 };
+    limit.max = { 90, 90, 90, 90, 90, 90 };
+    limit.rule = "val[0] != val[5] or val[1] != val[4] or val[2] != val[3]";
+    http->getInput(http_inputs.back())->setLimits() = limit;
+
+    http->getOutput(http_outputs[3])->setOptimizability(true);
+   
+    std::shared_ptr<ProcessorStandard> processor = std::make_shared<ProcessorStandard>();;
+    processor->addModule(sql);
+    processor->addModule(http);
+    auto mods = processor->getModuleIDs();
+
+    OptimizerEvolutionary optimizer(processor, 3, 20, 0.13, 5);
+    optimizer.setEvaluation("out0");
+
+    auto res = optimizer.update();
+    std::cout << optimizer.getBest().fitness << std::endl;
+    std::cout << optimizer.evaluateFitness(optimizer.getBest()) << std::endl;
+    EXPECT_TRUE(optimizer.getBest().fitness <= 100.0);
+}
+//*/

+ 69 - 0
lib/test/test_Connector.cpp

@@ -0,0 +1,69 @@
+#include <gtest/gtest.h>
+#include <json.hpp>
+#include "Connector.h"
+
+using namespace mdd;
+/*
+TEST(Connector, encode) {
+    //decode (3+4)*2
+    std::vector<std::string> inputs;
+    std::shared_ptr<IModule> f1 = GetGenerators()["mdd::ModuleMath"]->Generate();
+    inputs = f1->getInputIDs();
+    f1->getInput(inputs[0])->setValue() = { 3 };
+    f1->getInput(inputs[1])->setValue() = { 4 };
+
+    std::shared_ptr<IModule> f2 = GetGenerators()["mdd::ModuleMath"]->Generate();
+    f2->GetSubProp("operation")->Set("multiply");
+    //= std::make_shared<ModuleMath>(MathOperation::ADD);
+    inputs = f2->getInputIDs();
+    f2->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
+    f2->getInput(inputs[1])->setValue() = { 2 };
+
+    std::shared_ptr<ProcessorStandard> processor = std::make_shared<ProcessorStandard>();
+    processor->addModule(f1);
+    processor->addModule(f2);
+
+    processor->addModuleOutput(f2, f2->getOutput(f2->getOutputIDs()[0]));
+    processor->update();
+
+    EXPECT_EQ((int)f1->getOutput(f1->getOutputIDs()[0])->getValue()[0], 7);
+    EXPECT_EQ((int)f2->getOutput(f2->getOutputIDs()[0])->getValue()[0], 14);
+    EXPECT_EQ((int)processor->getOutput(processor->getOutputIDs()[1])->getValue()[0], 14);
+
+    json code = Connector::encode(processor);
+    code = "test";
+    std::cout << code.dump() << std::endl;
+    json m1;
+    m1["type"] = "Math";
+    m1["params"] = { "param1", "param2","..." };
+    json m2;
+    m2["type"] = "Math";
+    m2["params"] = { "param1", "param2","..." };
+
+    json p;
+    p["type"] = "StandardProcessor";
+    p["subs"] = { m1, m2 };
+    p["connections"] = { {"in1", "out1"}, {"in2", "out2"} };
+
+   
+    EXPECT_EQ(code.dump(), p.dump());
+}
+
+TEST(Connector, decode) {
+    //parse (3+4)*2
+    json m1;
+    m1["type"] = "Math";
+    m1["params"] = { "param1", "param2","..." };
+    json m2;
+    m2["type"] = "Math";
+    m2["params"] = { "param1", "param2","..." };
+
+    json p;
+    p["type"] = "StandardProcessor";
+    p["subs"] = {m1, m2};
+    p["connections"] = { {"in1", "out1"}, {"in2", "out2"} };
+
+    auto module = Connector::decode(p);
+    //auto ids_out = module->getOutputIDs();
+    //EXPECT_EQ((int)module->getOutput(ids_out[0])->getValue()[0], 14);
+}*/

+ 30 - 28
lib/test/test_ModuleHTTP.cpp

@@ -2,16 +2,15 @@
 #include <json.hpp>
 #include <httplib.h>
 //#define private public
-#include <ProcessorManual.h>
-#include <ModuleHTTP.h>
-#include <ModuleMath.h>
+#include <ProcessorStandard.h>
 #include <ModuleSwitch.h>
+#include <Generator.h>
 #include <math.h>
 #include <thread>
 
 using namespace mdd;
 using namespace httplib;
-
+/*
 void serverThread()
 {
     Server svr;
@@ -22,14 +21,14 @@ void serverThread()
     for (int i = 0; i < 5; ++i) {
         json entity;
         entity["type"] = "INPUT";
-        entity["value"] = i;
+        entity["value"] = { i };
         input.push_back(entity);
     }
 
     for (int i = 0; i < 3; ++i) {
         json entity;
         entity["type"] = "OUTPUT";
-        entity["value"] = i*2;
+        entity["value"] = { i * 2 };
         output.push_back(entity);
     }
 
@@ -66,12 +65,12 @@ void serverThread()
                 for (int i = 0; i < inputs.size(); ++i) {
                     input[i]["value"] = inputs[i]["value"];
                 }
-                output[0]["value"] = input[0]["value"].get<int>() + input[1]["value"].get<int>();
-                output[1]["value"] = input[2]["value"].get<int>() * input[2]["value"].get<int>();
-                output[2]["value"] = input[3]["value"].get<int>() - input[4]["value"].get<int>();
-                std::cout << output[0].dump() << std::endl;
-                std::cout << output[1].dump() << std::endl;
-                std::cout << output[2].dump() << std::endl;
+                output[0]["value"][0] = input[0]["value"][0].get<int>() + input[1]["value"][0].get<int>();
+                output[1]["value"][0] = input[2]["value"][0].get<int>() * input[2]["value"][0].get<int>();
+                output[2]["value"][0] = input[3]["value"][0].get<int>() - input[4]["value"][0].get<int>();
+                //std::cout << output[0].dump() << std::endl;
+                //std::cout << output[1].dump() << std::endl;
+                //std::cout << output[2].dump() << std::endl;
                 res.set_content(output.dump(), "application/json");
                 status = "ready";
              }
@@ -87,7 +86,7 @@ void serverThread()
 
 TEST(ModuleHTTP, updateLayout_intern){
     std::thread server (serverThread);
-    ModuleHTTP module("", "localhost", 8888);
+    auto module = GetGenerators()["mdd::ModuleHTTP"]->Generate();// ("", "localhost", 8888);
 
     Client cli("localhost",8888);
     cli.Get("/stop");
@@ -97,48 +96,49 @@ TEST(ModuleHTTP, updateLayout_intern){
     auto inputs_ids = module.getInputIDs();
     for (int i = 0; i < 5; ++i) {
         EXPECT_EQ(inputs_types[i], "INPUT");
-        EXPECT_EQ(module.getInput(inputs_ids[i])->getValue()["value"].get<int>(), i);
+        EXPECT_EQ((int)module.getInput(inputs_ids[i])->getValue()[0], i);
     }
 
     auto outputs_types = module.getOutputs();
     auto outputs_ids = module.getOutputIDs();
     for (int i = 0; i < 3; ++i) {
         EXPECT_EQ(outputs_types[i], "OUTPUT");
-        EXPECT_EQ(module.getOutput(outputs_ids[i])->getValue()["value"].get<int>(), i * 2);
+        EXPECT_EQ((int)module.getOutput(outputs_ids[i])->getValue()[0], i * 2);
     }
 }
 
 TEST(ModuleHTTP, updateLayout_extern){
-    ModuleHTTP module("../../../lib/test/server/server.py","localhost",8888);
-
+    ModuleHTTP module("../../../lib/test/server/server.py","localhost",8889);
+   
     auto inputs_types = module.getInputs();
     auto inputs_ids = module.getInputIDs();
     for(int i = 0; i < 5; ++i){
         EXPECT_EQ(inputs_types[i], "INPUT");
-        EXPECT_EQ(module.getInput(inputs_ids[i])->getValue()["value"].get<int>(), i);
+        EXPECT_EQ((int)module.getInput(inputs_ids[i])->getValue()[0], i);
     }
 
     auto outputs_types = module.getOutputs();
     auto outputs_ids = module.getOutputIDs();
     for(int i = 0; i < 3; ++i){
         EXPECT_EQ(outputs_types[i], "OUTPUT");
-        EXPECT_EQ(module.getOutput(outputs_ids[i])->getValue()["value"].get<int>(), i*2);
+        EXPECT_EQ((int)module.getOutput(outputs_ids[i])->getValue()[0], i*2);
     }
-    Client cli("localhost",8888);
+    Client cli("localhost",8889);
     cli.Get("/stop");
 }
 
 TEST(ModuleHTTP, update_intern){
     std::thread server (serverThread);
     ModuleHTTP module("", "localhost", 8888);
+    //std::cout << "WORKED" << std::endl;
     auto inputs_types = module.getInputs();
     auto inputs_ids = module.getInputIDs();
     for (int i = 0; i < 5; ++i) {
-        module.getInput(inputs_ids[i])->setDefaultValue()["value"] = 10-i;
+        module.getInput(inputs_ids[i])->setValue() = { (double)(10 - i) };
     }
     module.update();
 
-    Client cli("localhost",8888);
+    Client cli("localhost", 8888);
     cli.Get("/stop");
     server.join();
 
@@ -146,12 +146,14 @@ TEST(ModuleHTTP, update_intern){
     inputs_ids = module.getInputIDs();
     for (int i = 0; i < 5; ++i) {
         EXPECT_EQ(inputs_types[i], "INPUT");
-        EXPECT_EQ(module.getInput(inputs_ids[i])->getValue()["value"].get<int>(), 10-i);
+        EXPECT_EQ(module.getInput(inputs_ids[i])->getValue()[0], 10-i);
     }
-
+    //std::cout << "WORKED" << std::endl;
     auto outputs_types = module.getOutputs();
     auto outputs_ids = module.getOutputIDs();
-    EXPECT_EQ(module.getOutput(outputs_ids[0])->getValue()["value"].get<int>(), 19);
-    EXPECT_EQ(module.getOutput(outputs_ids[1])->getValue()["value"].get<int>(), 64);
-    EXPECT_EQ(module.getOutput(outputs_ids[2])->getValue()["value"].get<int>(), 1);
-}
+    //std::cout << module.getOutput(outputs_ids[0])->getValue() << std::endl;
+    EXPECT_EQ((int)module.getOutput(outputs_ids[1])->getValue()[0], 64);
+    EXPECT_EQ((int)module.getOutput(outputs_ids[2])->getValue()[0], 1);
+    EXPECT_EQ((int)module.getOutput(outputs_ids[0])->getValue()[0], 19);
+}
+//*/

+ 50 - 38
lib/test/test_ModuleMath.cpp

@@ -1,7 +1,7 @@
 #include <gtest/gtest.h>
 #include <json.hpp>
+#include <Generator.h>
 //#define private public
-#include <ModuleMath.h>
 
 //cd cmake-build-debug/lib/test
 //gtb auslegung_test
@@ -11,80 +11,92 @@
 
 using namespace mdd;
 TEST(ModuleMath, INT_PLUS_INT){
-    ModuleMath test = ModuleMath();
-    test.update();
-
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].get<int>(), 2);
+    
+    auto generators = GetGenerators();
+    IModule::Ptr mod = generators["mdd::ModuleMath"]->Generate();
+    //mod->configure();
+    mod->update();
+    auto ids = mod->getOutputIDs();
+    auto id = ids[0];
+    auto output = mod->getOutput(id);
+    auto res = output->getValue();
+    EXPECT_FLOAT_EQ(res[0], 2.0);
 }
 
+/*
 TEST(ModuleMath, FLOAT_PLUS_FLOAT){
-    ModuleMath test = ModuleMath();
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = 1.25;
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = 3.125;
-    test.update();
+    IModule::Ptr test = GetGenerators()["class mdd::ModuleMath"]->Generate();
+    test->configure();
+    test->getInput(test->getInputIDs()[0])->setValue() = { 1.25 };
+    test->getInput(test->getInputIDs()[1])->setValue() = { 3.125 };
+    test->update();
 
-    EXPECT_FLOAT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"], 4.375);
+    EXPECT_FLOAT_EQ(test->getOutput(test->getOutputIDs()[0])->getValue()[0], 4.375);
 }
-
 TEST(ModuleMath, FLOAT_PLUS_FLOAT_HARDER){
     ModuleMath test = ModuleMath();
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = 2.2;
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = -3.4;
+    test.getInput(test.getInputIDs()[0])->setValue() = { 2.2 };
+    test.getInput(test.getInputIDs()[1])->setValue() = { -3.4 };
     test.update();
 
-    EXPECT_FLOAT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"], -1.2);
+    EXPECT_FLOAT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()[0], -1.2);
 }
 
-TEST(ModuleMath, ARRAY_PLUS_ARRAY){
+TEST(ModuleMath, ARRAY_PLUS_ARRAY) {
     ModuleMath test = ModuleMath();
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = {1,2.5,3.75,45};
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = {10,31,23,23};
+    test.getInput(test.getInputIDs()[0])->setValue() = { 1,2.5,3.75,45 };
+    test.getInput(test.getInputIDs()[1])->setValue() = { 10,31,23,23 };
+    std::vector<double> expect = { 11, 33.5, 26.75, 68 };
     test.update();
-
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].dump(), "[11,33.5,26.75,68]");
+    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue(), expect);
 }
 
 TEST(ModuleMath, INT_PLUS_ARRAY){
     ModuleMath test = ModuleMath();
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = 2.5;
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = {10,31,23,23};
+    test.getInput(test.getInputIDs()[0])->setValue() = { 2.5 };
+    test.getInput(test.getInputIDs()[1])->setValue() = {10,31,23,23};
+    std::vector<double> expect = { 12.5,33.5,25.5,25.5 };
     test.update();
 
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].dump(), "[12.5,33.5,25.5,25.5]");
+    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue(), expect);
 }
 
 TEST(ModuleMath, ARRAY_PLUS_INT){
     ModuleMath test = ModuleMath();
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = {10,31,23,23};
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = 2.5;
+    test.getInput(test.getInputIDs()[0])->setValue() = {10,31,23,23};
+    test.getInput(test.getInputIDs()[1])->setValue() = { 2.5 };
+    std::vector<double> expect = { 12.5,33.5,25.5,25.5 };
     test.update();
 
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].dump(), "[12.5,33.5,25.5,25.5]");
+    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue(), expect);
 }
 
 TEST(ModuleMath, ARRAY_MINUS_ARRAY){
-    ModuleMath test = ModuleMath(SUBTRACT);
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = {10,31,3,45};
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = {1,2.5,23,23};
+    ModuleMath test = ModuleMath(MathOperation::SUBTRACT);
+    test.getInput(test.getInputIDs()[0])->setValue() = {10,31,3,45};
+    test.getInput(test.getInputIDs()[1])->setValue() = {1,2.5,23,23};
+    std::vector<double> expect = { 9,28.5,-20,22 };
     test.update();
 
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].dump(), "[9,28.5,-20,22]");
+    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue(), expect);
 }
 
 TEST(ModuleMath, ARRAY_MAL_ARRAY){
-    ModuleMath test = ModuleMath(MULTIPLY);
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = {10,30,-3.5,45};
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = {1,2.5,2.25,20};
+    ModuleMath test = ModuleMath(MathOperation::MULTIPLY);
+    test.getInput(test.getInputIDs()[0])->setValue() = {10,30,-3.5,45};
+    test.getInput(test.getInputIDs()[1])->setValue() = {1,2.5,2.25,20};
+    std::vector<double> expect = { 10,75.0,-7.875,900 };
     test.update();
 
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].dump(), "[10,75.0,-7.875,900]");
+    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue(), expect);
 }
 
 TEST(ModuleMath, ARRAY_DURCH_ARRAY){
-    ModuleMath test = ModuleMath(DIVIDE);
-    test.getInput(test.getInputIDs()[0])->setDefaultValue()["value"] = {10,30,-3.5,45};
-    test.getInput(test.getInputIDs()[1])->setDefaultValue()["value"] = {4,2.5,2,20};
+    ModuleMath test = ModuleMath(MathOperation::DIVIDE);
+    test.getInput(test.getInputIDs()[0])->setValue() = {10,30,-3.5,45};
+    test.getInput(test.getInputIDs()[1])->setValue() = {4,2.5,2,20};
+    std::vector<double> expect = { 2.5,12.0,-1.75,2.25 };
     test.update();
 
-    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue()["value"].dump(), "[2.5,12.0,-1.75,2.25]");
-}
+    EXPECT_EQ(test.getOutput(test.getOutputIDs()[0])->getValue(), expect);
+}*/

+ 236 - 0
lib/test/test_ModuleSQL.cpp

@@ -0,0 +1,236 @@
+#include <gtest/gtest.h>
+#include <json.hpp>
+#include <filesystem>
+//#define private public
+#include <ModuleSQL.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sqlite3.h> 
+
+
+using namespace mdd;
+/*
+static int callback(void* data, int argc, char** argv, char** azColName) {
+    int i;
+    fprintf(stderr, "%s: ", (const char*)data);
+    for (i = 0; i < argc; i++) {
+        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
+    }
+    printf("\n");
+    return 0;
+}
+
+void sqlite3_exec_debug(sqlite3* db, char* sql) {
+    char* zErrMsg = 0;
+    int rc;
+
+    // Execute SQL statement 
+    rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
+
+    if (rc != SQLITE_OK) {
+        fprintf(stderr, "SQL error: %s\n", zErrMsg);
+        sqlite3_free(zErrMsg);
+    }
+    else {
+        fprintf(stdout, "Table created successfully\n");
+    }
+}
+
+void create_test_db() {
+        sqlite3* db;
+        int rc;
+        char* sql;
+
+        // Open database
+        rc = sqlite3_open("../../../lib/test/db/materials.db", &db);
+
+        if (rc) {
+            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
+            return;
+        }
+        else {
+            fprintf(stdout, "Opened database successfully\n");
+        }
+
+        // Create SQL statement
+        sql = "CREATE TABLE MATERIAL("  \
+            "ID INTEGER PRIMARY KEY     AUTOINCREMENT," \
+            "NAME           TEXT    NOT NULL," \
+
+            "E11            FLOAT   NOT NULL," \
+            "E22            FLOAT   NOT NULL," \
+            "E33            FLOAT   NOT NULL," \
+
+            "PR12           FLOAT   NOT NULL," \
+            "PR13           FLOAT   NOT NULL," \
+            "PR23           FLOAT   NOT NULL," \
+
+            "G12            FLOAT   NOT NULL," \
+            "G13            FLOAT   NOT NULL," \
+            "G23            FLOAT   NOT NULL," \
+
+            "DENS           FLOAT           ," \
+
+            "ALP11          FLOAT           ," \
+            "ALP22          FLOAT           ," \
+            "ALP33          FLOAT           ," \
+
+            "K11            FLOAT           ," \
+            "K22            FLOAT           ," \
+            "K33            FLOAT           ," \
+
+            "BET11          FLOAT           ," \
+            "BET22          FLOAT           ," \
+            "BET33          FLOAT           ," \
+
+            "D11            FLOAT           ," \
+            "D22            FLOAT           ," \
+            "D33            FLOAT           );";
+
+        sqlite3_exec_debug(db, sql);
+        
+       // Create SQL statement
+        sql = "INSERT INTO MATERIAL (   NAME,           E11,    E22,    E33,    PR12,   PR13,   PR23,   G12,    G13,    G23,    DENS,       ALP11,  ALP22, ALP33, K11,      K22,    K33,    BET11,  BET22,  BET33,  D11,    D22,    D33) "  \
+            "VALUES (                   'EP-E Glas',    42.5,   11,     11,     0.28,   0.28,   0.28,   4.2,    4.2,    2.56,   1950E-6,    5.7E-6, 45E-6, 45E-6, 0.72E3,   0.5E3,  0.5E3,  0E-3,   4E-3,   4E-3,   4.4E3,  3.1E3,  3.1E3); ";
+
+        sqlite3_exec_debug(db, sql);
+
+        sqlite3_close(db);
+}
+
+
+TEST(ModuleSQL, TestSQL) {
+    if (!std::filesystem::exists("../../../lib/test/db/materials.db")) {
+        create_test_db();
+    }
+    
+    sqlite3* db;
+    char* zErrMsg = 0;
+    int rc;
+    char* sql;
+    const char* data = "Callback function called";
+
+    // Open database 
+    rc = sqlite3_open("../../../lib/test/db/materials.db", &db);
+
+    if (rc) {
+        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
+        return;
+    }
+    else {
+        fprintf(stderr, "Opened database successfully\n");
+    }
+
+    // Create SQL statement 
+    sql = "SELECT * from MATERIAL";
+
+    // Execute SQL statement 
+    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
+
+    if (rc != SQLITE_OK) {
+        fprintf(stderr, "SQL error: %s\n", zErrMsg);
+        sqlite3_free(zErrMsg);
+    }
+    else {
+        fprintf(stdout, "Operation done successfully\n");
+    }
+    sqlite3_close(db);
+
+    EXPECT_TRUE(std::filesystem::exists("../../../lib/test/db/materials.db"));
+}
+
+TEST(ModuleSQL, TestGetSQLTableStructure) {
+    if (!std::filesystem::exists("../../../lib/test/db/materials.db")) {
+        create_test_db();
+    }
+
+    sqlite3* db;
+    char* zErrMsg = 0;
+    int rc;
+    char* sql;
+    const char* data = "Callback function called";
+
+    // Open database 
+    rc = sqlite3_open("../../../lib/test/db/materials.db", &db);
+
+    if (rc) {
+        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
+        return;
+    }
+    else {
+        fprintf(stderr, "Opened database successfully\n");
+    }
+
+    // Create SQL statement 
+    sql =   "SELECT * "\
+            "FROM   sqlite_master "\
+            "WHERE type = 'table' ";
+
+    // Execute SQL statement 
+    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
+
+    if (rc != SQLITE_OK) {
+        fprintf(stderr, "SQL error: %s\n", zErrMsg);
+        sqlite3_free(zErrMsg);
+    }
+    else {
+        fprintf(stdout, "Operation done successfully\n");
+    }
+    sqlite3_close(db);
+
+    EXPECT_TRUE(std::filesystem::exists("../../../lib/test/db/materials.db"));
+}
+
+
+
+TEST(ModuleSQL, OpenDB) {
+    if (!std::filesystem::exists("../../../lib/test/db/materials.db")) {
+        create_test_db();
+    }
+	ModuleSQL module = ModuleSQL("../../../lib/test/db/materials.db");
+    module.update();
+
+
+	EXPECT_TRUE(std::filesystem::exists("../../../lib/test/db/materials.db"));
+}
+
+TEST(ModuleSQL, TestDataExists) {
+    if (!std::filesystem::exists("../../../lib/test/db/materials.db")) {
+        create_test_db();
+    }
+
+    sqlite3* db;
+    char* zErrMsg = 0;
+    int rc;
+    char* sql;
+    const char* data = "Callback function called";
+
+    // Open database 
+    rc = sqlite3_open("../../../lib/test/db/materials.db", &db);
+
+    if (rc) {
+        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
+        return;
+    }
+    else {
+        fprintf(stderr, "Opened database successfully\n");
+    }
+
+    // Create SQL statement 
+    sql = "SELECT * from MATERIAL";
+
+    // Execute SQL statement 
+    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
+
+    if (rc != SQLITE_OK) {
+        fprintf(stderr, "SQL error: %s\n", zErrMsg);
+        sqlite3_free(zErrMsg);
+    }
+    else {
+        fprintf(stdout, "Operation done successfully\n");
+    }
+    sqlite3_close(db);
+
+    EXPECT_TRUE(std::filesystem::exists("../../../lib/test/db/materials.db"));
+}
+//*/

+ 26 - 26
lib/test/test_ModuleSwitch.cpp

@@ -1,57 +1,57 @@
 #include <gtest/gtest.h>
 #include <json.hpp>
 //#define private public
-#include <ProcessorManual.h>
-#include <ModuleMath.h>
+#include <ProcessorStandard.h>
 #include <ModuleSwitch.h>
 
 
 using namespace mdd;
+/*
 TEST(ModuleSwitch, EasySwitch){
     ModuleSwitch sModule = ModuleSwitch();
     auto inputs = sModule.getInputIDs();
     auto outputs = sModule.getOutputIDs();
 
-    sModule.getInput(inputs[0])->setDefaultValue()["value"] = 0;
-    sModule.getInput(inputs[1])->setDefaultValue()["value"] = 1;
-    sModule.getInput(inputs[2])->setDefaultValue()["value"] = 2;
+    sModule.getInput(inputs[0])->setValue() = { 0 };
+    sModule.getInput(inputs[1])->setValue() = { 1 };
+    sModule.getInput(inputs[2])->setValue() = { 2 };
 
     sModule.update();
 
-    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()["value"].get<int>(), 1);
+    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()[0], 1);
 
-    sModule.getInput(inputs[0])->setDefaultValue()["value"] = 1;
+    sModule.getInput(inputs[0])->setValue() = { 1 };
     sModule.update();
-    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()["value"].get<int>(), 1);
+    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()[0], 1);
 
-    sModule.getInput(inputs[0])->setDefaultValue()["value"] = 2;
+    sModule.getInput(inputs[0])->setValue() = { 2 };
     sModule.update();
-    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()["value"].get<int>(), 2);
+    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()[0], 2);
 
-    sModule.getInput(inputs[0])->setDefaultValue()["value"] = 3;
+    sModule.getInput(inputs[0])->setValue() = { 3 };
     sModule.update();
-    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()["value"].get<int>(), 2);
-    sModule.getInput(inputs[0])->setDefaultValue()["value"] = 33;
+    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()[0], 2);
+    sModule.getInput(inputs[0])->setValue() = { 33 };
     sModule.update();
-    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()["value"].get<int>(), 2);
+    EXPECT_EQ(sModule.getOutput(outputs[0])->getValue()[0], 2);
 }
 
 TEST(ModuleSwitch, ConnectTest){
 
-    ModuleMath f0 = ModuleMath(MULTIPLY);
+    ModuleMath f0 = ModuleMath(MathOperation::MULTIPLY);
     auto inputs = f0.getInputIDs();
-    f0.getInput(inputs[0])->setDefaultValue()["value"] = 1;
-    f0.getInput(inputs[1])->setDefaultValue()["value"] = 1;
+    f0.getInput(inputs[0])->setValue() = { 1 };
+    f0.getInput(inputs[1])->setValue() = { 1 };
 
-    ModuleMath f1 = ModuleMath(MULTIPLY);
+    ModuleMath f1 = ModuleMath(MathOperation::MULTIPLY);
     inputs = f1.getInputIDs();
-    f1.getInput(inputs[0])->setDefaultValue()["value"] = 2;
-    f1.getInput(inputs[1])->setDefaultValue()["value"] = 3;
+    f1.getInput(inputs[0])->setValue() = { 2 };
+    f1.getInput(inputs[1])->setValue() = { 3 };
 
-    ModuleMath f2 = ModuleMath(MULTIPLY);
+    ModuleMath f2 = ModuleMath(MathOperation::MULTIPLY);
     inputs = f2.getInputIDs();
-    f2.getInput(inputs[0])->setDefaultValue()["value"] = 5;
-    f2.getInput(inputs[1])->setDefaultValue()["value"] = 7;
+    f2.getInput(inputs[0])->setValue() = { 5 };
+    f2.getInput(inputs[1])->setValue() = { 7 };
 
     ModuleSwitch sModule = ModuleSwitch();
     inputs = sModule.getInputIDs();
@@ -64,6 +64,6 @@ TEST(ModuleSwitch, ConnectTest){
     f2.update();
     sModule.update();
 
-
-    EXPECT_EQ(sModule.getOutput(sModule.getOutputIDs()[0])->getValue()["value"].get<int>(), 6);
-}
+    //std::cout << sModule.getOutput(sModule.getOutputIDs()[0])->getValue()["value"].dump() << std::endl;
+    EXPECT_EQ(sModule.getOutput(sModule.getOutputIDs()[0])->getValue()[0], 6);
+}*/

+ 80 - 0
lib/test/test_OptimizerEvolutionary.cpp

@@ -0,0 +1,80 @@
+#include <gtest/gtest.h>
+#include <json.hpp>
+//#define private public
+#include "OptimizerEvolutionary.h"
+#include <ModuleSwitch.h>
+
+/*
+using namespace mdd;
+TEST(OptimizerEvolutionary, OptimizeSimpleFormula) {
+    //optimize f(x)=a*b
+    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MathOperation::MULTIPLY);
+    auto inputs = f1->getInputIDs();
+    auto outputs = f1->getOutputIDs();
+    limits limit;
+    limit.min = { -10 };
+    limit.max = { 10 };
+    limit.step = { 1 };
+
+    f1->getInput(inputs[0])->setLimits() = limit;
+    f1->getInput(inputs[1])->setLimits() = limit;
+
+    f1->getInput(inputs[0])->setOptimizability(true);
+    f1->getInput(inputs[1])->setOptimizability(true);
+    f1->getOutput(outputs[0])->setOptimizability(true);
+
+    OptimizerEvolutionary optimizer(f1, 5);
+    optimizer.setEvaluation("out0");
+
+    auto res = optimizer.update();
+    //std::cout << res.dump() << std::endl;
+    EXPECT_EQ(res[0][0]* res[1][0],-100);
+}
+
+TEST(OptimizerEvolutionary, OptimizeSimpleFormulaWithSimpleRestriction) {
+    //optimize f(x)=a*b
+    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MathOperation::MULTIPLY);
+    auto inputs = f1->getInputIDs();
+    auto outputs = f1->getOutputIDs();
+    limits limit;
+    limit.min = { -10 };
+    limit.max = { 10 };
+    limit.step = { 1 };
+    limit.rule = "val[0] != -10";
+
+    f1->getInput(inputs[0])->setLimits() = limit;
+    f1->getInput(inputs[1])->setLimits() = limit;
+
+    f1->getInput(inputs[0])->setOptimizability(true);
+    f1->getInput(inputs[1])->setOptimizability(true);
+    f1->getOutput(outputs[0])->setOptimizability(true);
+    OptimizerEvolutionary optimizer(f1, 3);
+    optimizer.setEvaluation("out0");
+
+    auto res = optimizer.update();
+    //std::cout << res.dump() << std::endl;
+    EXPECT_EQ(res[0][0] * res[1][0], -90);
+}
+
+TEST(OptimizerEvolutionary, exprtk) {
+    json a;
+    a["value"] = { 1,2,3 };
+    exprtk::symbol_table<double> symbol_table;
+    auto v = a["value"].get<std::vector<double>>();
+    //std::cout << v[0] << "|" << v[1] << "|" << v[2] << std::endl;
+    symbol_table.add_vector("in" + std::to_string(0), v);
+    symbol_table.add_constants();
+    exprtk::expression<double> _func_expr;
+    _func_expr.register_symbol_table(symbol_table);
+
+    exprtk::parser<double> parser;
+    //"in0[1]==in0[1]"=>1
+    //"in0[1]!=in0[1]"=>0
+    
+    //std::cout << _func_expr.value() << std::endl;
+    //std::cout << res.dump() << std::endl;
+    parser.compile("in0[1]==in0[1]", _func_expr);
+    EXPECT_EQ(_func_expr.value(), 1);
+    parser.compile("in0[1]!=in0[1]", _func_expr);
+    EXPECT_EQ(_func_expr.value(), 0);
+}*/

+ 0 - 106
lib/test/test_ProcessorManual.cpp

@@ -1,106 +0,0 @@
-#include <gtest/gtest.h>
-#include <json.hpp>
-//#define private public
-#include <ProcessorManual.h>
-#include <ModuleMath.h>
-#include <ModuleSwitch.h>
-
-
-using namespace mdd;
-TEST(ProcessorManual, CalculateSimpleFormula){
-    //f4:(f3:(f1:(5*3)-f2:(4+5))/2)==(15-9)/2==6/2==3
-    std::vector<std::string> inputs;
-    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MULTIPLY);
-    inputs = f1->getInputIDs();
-    f1->getInput(inputs[0])->setDefaultValue()["value"] = 5;
-    f1->getInput(inputs[1])->setDefaultValue()["value"] = 3;
-
-    std::shared_ptr<ModuleMath> f2 = std::make_shared<ModuleMath>(ADD);
-    inputs = f2->getInputIDs();
-    f2->getInput(inputs[0])->setDefaultValue()["value"] = 4;
-    f2->getInput(inputs[1])->setDefaultValue()["value"] = 5;
-
-    std::shared_ptr<ModuleMath> f3 = std::make_shared<ModuleMath>(SUBTRACT);
-    inputs = f3->getInputIDs();
-    f3->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
-    f3->getInput(inputs[1])->connect(f2->getOutput(f2->getOutputIDs()[0]));
-
-    std::shared_ptr<ModuleMath> f4 = std::make_shared<ModuleMath>(DIVIDE);
-    inputs = f4->getInputIDs();
-    f4->getInput(inputs[0])->connect(f3->getOutput(f3->getOutputIDs()[0]));
-    f4->getInput(inputs[1])->setDefaultValue()["value"] = 2;
-
-    std::shared_ptr<ProcessorManual> test = std::make_shared<ProcessorManual>();
-    test->addModule(f1);
-    test->addModule(f2);
-    test->addModule(f3);
-    test->addModule(f4);
-    test->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
-    test->update();
-
-    EXPECT_EQ(f1->getOutput(f1->getOutputIDs()[0])->getValue()["value"].get<int>(), 15);
-
-    EXPECT_EQ(f2->getOutput(f2->getOutputIDs()[0])->getValue()["value"].get<int>(), 9);
-
-    EXPECT_EQ(f3->getOutput(f3->getOutputIDs()[0])->getValue()["value"].get<int>(), 6);
-
-    EXPECT_EQ(f4->getOutput(f4->getOutputIDs()[0])->getValue()["value"].get<int>(), 3);
-
-    EXPECT_EQ(test->getOutput(test->getOutputIDs()[1])->getValue()["value"].get<int>(), 3);
-}
-
-TEST(ProcessorManual, CalculateAdvancedFormula){
-    //f4:(f3:(f1:(5*3)-f2:(4+5))/2)==(15-9)/2==6/2==3
-    std::vector<std::string> inputs;
-    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MULTIPLY);
-    inputs = f1->getInputIDs();
-    f1->getInput(inputs[0])->setDefaultValue()["value"] = 5;
-    f1->getInput(inputs[1])->setDefaultValue()["value"] = 3;
-
-    std::shared_ptr<ModuleMath> f2 = std::make_shared<ModuleMath>(ADD);
-    inputs = f2->getInputIDs();
-    f2->getInput(inputs[0])->setDefaultValue()["value"] = 4;
-    f2->getInput(inputs[1])->setDefaultValue()["value"] = 5;
-
-    std::shared_ptr<ModuleMath> f3 = std::make_shared<ModuleMath>(SUBTRACT);
-    inputs = f3->getInputIDs();
-    f3->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
-    f3->getInput(inputs[1])->connect(f2->getOutput(f2->getOutputIDs()[0]));
-
-    std::shared_ptr<ModuleMath> f4 = std::make_shared<ModuleMath>(DIVIDE);
-    inputs = f4->getInputIDs();
-    f4->getInput(inputs[0])->connect(f3->getOutput(f3->getOutputIDs()[0]));
-    f4->getInput(inputs[1])->setDefaultValue()["value"] = 2;
-
-    std::shared_ptr<ProcessorManual> test = std::make_shared<ProcessorManual>();
-    test->addModule(f4);
-    test->addModule(f3);
-    test->addModule(f2);
-    test->addModule(f1);
-    test->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
-    test->update();
-
-    EXPECT_EQ(test->getOutput(test->getOutputIDs()[1])->getValue()["value"].get<int>(), 3);
-}
-
-TEST(ProcessorManual, CalculateExtremeFormula){
-    //x_0=8, x_i=x_{i-1}/2
-    std::shared_ptr<ModuleSwitch> switchModule =  std::make_shared<ModuleSwitch>();
-    std::shared_ptr<ModuleMath> calcModule = std::make_shared<ModuleMath>(DIVIDE);
-    std::shared_ptr<ProcessorManual> processor = std::make_shared<ProcessorManual>();
-    processor->addModule(switchModule);
-    processor->addModule(calcModule);
-
-    bool connect;
-    connect =switchModule->getInput(switchModule->getInputIDs()[0])->connect(processor->getIteration());
-    switchModule->getInput(switchModule->getInputIDs()[1])->setDefaultValue()["value"] = 8.0;
-    connect = switchModule->getInput(switchModule->getInputIDs()[2])->connect(calcModule->getOutput(calcModule->getOutputIDs()[0]));
-
-    calcModule->getInput(calcModule->getInputIDs()[0])->connect(switchModule->getOutput(switchModule->getOutputIDs()[0]));
-    calcModule->getInput(calcModule->getInputIDs()[1])->setDefaultValue()["value"] = 2.0;
-
-    processor->addModuleOutput(calcModule,calcModule->getOutput(calcModule->getOutputIDs()[0]));
-    processor->update();
-
-    EXPECT_FLOAT_EQ(processor->getOutput(processor->getOutputIDs()[1])->getValue()["value"].get<double>(), 0.0);
-}

+ 183 - 0
lib/test/test_ProcessorStandard.cpp

@@ -0,0 +1,183 @@
+#include <gtest/gtest.h>
+#include <json.hpp>
+//#define private public
+#include "ProcessorStandard.h"
+#include <ModuleSwitch.h>
+/*
+
+using namespace mdd;
+TEST(ProcessorStandard, CalculateSimpleFormula){
+    //f4:(f3:(f1:(5*3)-f2:(4+5))/2)==(15-9)/2==6/2==3
+    std::vector<std::string> inputs;
+    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MathOperation::MULTIPLY);
+    inputs = f1->getInputIDs();
+    f1->getInput(inputs[0])->setValue() = { 5 };
+    f1->getInput(inputs[1])->setValue() = { 3 };
+
+    std::shared_ptr<ModuleMath> f2 = std::make_shared<ModuleMath>(MathOperation::ADD);
+    inputs = f2->getInputIDs();
+    f2->getInput(inputs[0])->setValue() = { 4 };
+    f2->getInput(inputs[1])->setValue() = { 5 };
+
+    std::shared_ptr<ModuleMath> f3 = std::make_shared<ModuleMath>(MathOperation::SUBTRACT);
+    inputs = f3->getInputIDs();
+    f3->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
+    f3->getInput(inputs[1])->connect(f2->getOutput(f2->getOutputIDs()[0]));
+
+    std::shared_ptr<ModuleMath> f4 = std::make_shared<ModuleMath>(MathOperation::DIVIDE);
+    inputs = f4->getInputIDs();
+    f4->getInput(inputs[0])->connect(f3->getOutput(f3->getOutputIDs()[0]));
+    f4->getInput(inputs[1])->setValue() = { 2 };
+
+    std::shared_ptr<ProcessorStandard> processor = std::make_shared<ProcessorStandard>();
+    processor->addModule(f1);
+    processor->addModule(f2);
+    processor->addModule(f3);
+    processor->addModule(f4);
+    processor->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
+    processor->update();
+
+    EXPECT_EQ(f1->getOutput(f1->getOutputIDs()[0])->getValue()[0], 15);
+
+    EXPECT_EQ(f2->getOutput(f2->getOutputIDs()[0])->getValue()[0], 9);
+
+    EXPECT_EQ(f3->getOutput(f3->getOutputIDs()[0])->getValue()[0], 6);
+
+    EXPECT_EQ(f4->getOutput(f4->getOutputIDs()[0])->getValue()[0], 3);
+
+    EXPECT_EQ(processor->getOutput(processor->getOutputIDs()[1])->getValue()[0], 3);
+}
+
+
+TEST(ProcessorStandard, CalculateAdvancedFormula){
+    //f4:(f3:(f1:(5*3)-f2:(4+5))/2)==(15-9)/2==6/2==3
+    std::vector<std::string> inputs;
+    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MathOperation::MULTIPLY);
+    inputs = f1->getInputIDs();
+    f1->getInput(inputs[0])->setValue() = { 5 };
+    f1->getInput(inputs[1])->setValue() = { 3 };
+
+    std::shared_ptr<ModuleMath> f2 = std::make_shared<ModuleMath>(MathOperation::ADD);
+    inputs = f2->getInputIDs();
+    f2->getInput(inputs[0])->setValue() = { 4 };
+    f2->getInput(inputs[1])->setValue() = { 5 };
+
+    std::shared_ptr<ModuleMath> f3 = std::make_shared<ModuleMath>(MathOperation::SUBTRACT);
+    inputs = f3->getInputIDs();
+    f3->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
+    f3->getInput(inputs[1])->connect(f2->getOutput(f2->getOutputIDs()[0]));
+
+    std::shared_ptr<ModuleMath> f4 = std::make_shared<ModuleMath>(MathOperation::DIVIDE);
+    inputs = f4->getInputIDs();
+    f4->getInput(inputs[0])->connect(f3->getOutput(f3->getOutputIDs()[0]));
+    f4->getInput(inputs[1])->setValue() = { 2 };
+
+    std::shared_ptr<ProcessorStandard> test = std::make_shared<ProcessorStandard>();
+    test->addModule(f4);
+    test->addModule(f3);
+    test->addModule(f2);
+    test->addModule(f1);
+    test->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
+    test->update();
+    //std::cout << test->getOutput(test->getOutputIDs()[1])->getValue()["value"].dump() << std::endl;
+    EXPECT_EQ(test->getOutput(test->getOutputIDs()[1])->getValue()[0], 3);
+}
+
+TEST(ProcessorStandard, CalculateExtremeFormula){
+    //x_0=8, x_i=x_{i-1}/2
+    std::shared_ptr<ModuleSwitch> switchModule =  std::make_shared<ModuleSwitch>();
+    std::shared_ptr<ModuleMath> calcModule = std::make_shared<ModuleMath>(MathOperation::DIVIDE);
+    std::shared_ptr<ProcessorStandard> processor = std::make_shared<ProcessorStandard>();
+    processor->addModule(switchModule);
+    processor->addModule(calcModule);
+
+    bool connect;
+    connect =switchModule->getInput(switchModule->getInputIDs()[0])->connect(processor->getIteration());
+    switchModule->getInput(switchModule->getInputIDs()[1])->setValue() = { 8.0 };
+    connect = switchModule->getInput(switchModule->getInputIDs()[2])->connect(calcModule->getOutput(calcModule->getOutputIDs()[0]));
+
+    calcModule->getInput(calcModule->getInputIDs()[0])->connect(switchModule->getOutput(switchModule->getOutputIDs()[0]));
+    calcModule->getInput(calcModule->getInputIDs()[1])->setValue() = { 2.0 };
+
+    processor->addModuleOutput(calcModule,calcModule->getOutput(calcModule->getOutputIDs()[0]));
+    processor->update();
+
+    EXPECT_FLOAT_EQ(processor->getOutput(processor->getOutputIDs()[1])->getValue()[0], 0.0);
+}
+
+TEST(ProcessorStandard, CalculateAdvancedFormulaWithSTATIC) {
+    //f4:(f3:(f1:(5*3)-f2:(4+5))/2)==(15-9)/2==6/2==3
+    std::vector<std::string> inputs;
+    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MathOperation::MULTIPLY);
+    inputs = f1->getInputIDs();
+    f1->getInput(inputs[0])->setValue() = { 5 };
+    f1->getInput(inputs[1])->setValue() = { 3 };
+
+    std::shared_ptr<ModuleMath> f2 = std::make_shared<ModuleMath>(MathOperation::ADD);
+    inputs = f2->getInputIDs();
+    f2->getInput(inputs[0])->setValue() = { 4 };
+    f2->getInput(inputs[1])->setValue() = { 5 };
+
+    std::shared_ptr<ModuleMath> f3 = std::make_shared<ModuleMath>(MathOperation::SUBTRACT);
+    inputs = f3->getInputIDs();
+    f3->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
+    f3->getInput(inputs[1])->connect(f2->getOutput(f2->getOutputIDs()[0]));
+
+    std::shared_ptr<ModuleMath> f4 = std::make_shared<ModuleMath>(MathOperation::DIVIDE);
+    inputs = f4->getInputIDs();
+    f4->getInput(inputs[0])->connect(f3->getOutput(f3->getOutputIDs()[0]));
+    f4->getInput(inputs[1])->setValue() = { 2 };
+
+    std::shared_ptr<ProcessorStandard> process_static = std::make_shared<ProcessorStandard>(STATIC);
+    process_static->addModule(f4);
+    process_static->addModule(f3);
+    process_static->addModule(f2);
+    process_static->addModule(f1);
+    process_static->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
+    process_static->update();
+    //std::cout << test->getOutput(test->getOutputIDs()[1])->getValue()["value"].dump() << std::endl;
+    EXPECT_EQ(process_static->getOutput(process_static->getOutputIDs()[1])->getValue()[0], 3);
+}
+
+TEST(ProcessorStandard, PrioritySTATIC) {
+    //f4:(f3:(f1:(5*3)-f2:(4+5))/2)==(15-9)/2==6/2==3
+    std::vector<std::string> inputs;
+    std::shared_ptr<ModuleMath> f1 = std::make_shared<ModuleMath>(MathOperation::MULTIPLY);
+    inputs = f1->getInputIDs();
+    f1->getInput(inputs[0])->setValue() = { 5 };
+    f1->getInput(inputs[1])->setValue() = { 3 };
+
+    std::shared_ptr<ModuleMath> f2 = std::make_shared<ModuleMath>(MathOperation::ADD);
+    inputs = f2->getInputIDs();
+    f2->getInput(inputs[0])->setValue() = { 4 };
+    f2->getInput(inputs[1])->setValue() = { 5 };
+
+    std::shared_ptr<ModuleMath> f3 = std::make_shared<ModuleMath>(MathOperation::SUBTRACT);
+    inputs = f3->getInputIDs();
+    f3->getInput(inputs[0])->connect(f1->getOutput(f1->getOutputIDs()[0]));
+    f3->getInput(inputs[1])->connect(f2->getOutput(f2->getOutputIDs()[0]));
+
+    std::shared_ptr<ModuleMath> f4 = std::make_shared<ModuleMath>(MathOperation::DIVIDE);
+    inputs = f4->getInputIDs();
+    f4->getInput(inputs[0])->connect(f3->getOutput(f3->getOutputIDs()[0]));
+    f4->getInput(inputs[1])->setValue() = { 2 };
+
+    std::shared_ptr<ProcessorStandard> process_manual = std::make_shared<ProcessorStandard>();
+    process_manual->addModule(f1);
+    process_manual->addModule(f2);
+    process_manual->addModule(f3);
+    process_manual->addModule(f4);
+    process_manual->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
+    process_manual->update();
+
+    std::shared_ptr<ProcessorStandard> process_static = std::make_shared<ProcessorStandard>(STATIC);
+    process_static->addModule(f4);
+    process_static->addModule(f3);
+    process_static->addModule(f2);
+    process_static->addModule(f1);
+    process_static->addModuleOutput(f4, f4->getOutput(f4->getOutputIDs()[0]));
+    process_static->update();
+    //std::cout << process_static->getOutput(process_static->getOutputIDs()[1])->getValue()["value"].dump() << std::endl;
+    EXPECT_TRUE(process_static->getIteration()->getValue()[0] <= process_manual->getIteration()->getValue()[0]);
+}
+//*/

+ 54 - 0
thirdparty/exprtk/Makefile

@@ -0,0 +1,54 @@
+#
+# **************************************************************
+# *         C++ Mathematical Expression Toolkit Library        *
+# *                                                            *
+# * Author: Arash Partow (1999-2020)                           *
+# * URL: http://www.partow.net/programming/exprtk/index.html   *
+# *                                                            *
+# * Copyright notice:                                          *
+# * Free use of the Mathematical Expression Toolkit Library is *
+# * permitted under the guidelines and in accordance with the  *
+# * most current version of the MIT License.                   *
+# * http://www.opensource.org/licenses/MIT                     *
+# *                                                            *
+# **************************************************************
+#
+
+
+COMPILER         := -c++
+#COMPILER        := -clang++
+OPTIMIZATION_OPT := -O1
+BASE_OPTIONS     := -pedantic-errors -Wall -Wextra -Werror -Wno-long-long
+OPTIONS          := $(BASE_OPTIONS) $(OPTIMIZATION_OPT)
+LINKER_OPT       := -L/usr/lib -lstdc++ -lm
+ASAN_OPT         := -g -fsanitize=address   -fno-omit-frame-pointer
+MSAN_OPT         := -g -fsanitize=memory    -fno-omit-frame-pointer
+LSAN_OPT         := -g -fsanitize=leak      -fno-omit-frame-pointer
+USAN_OPT         := -g -fsanitize=undefined -fno-omit-frame-pointer
+BUILD_SRC        := $(sort $(wildcard exprtk_*.cpp))
+BUILD_LIST       := $(BUILD_SRC:%.cpp=%)
+
+
+all: $(BUILD_LIST)
+
+$(BUILD_LIST) : %: %.cpp exprtk.hpp
+	$(COMPILER) $(OPTIONS) -o $@ $@.cpp $(LINKER_OPT)
+
+strip_bin :
+	@for f in $(BUILD_LIST); do if [ -f $$f ]; then strip -s $$f; echo $$f; fi done;
+
+valgrind :
+	@for f in $(BUILD_LIST); do \
+		if [ -f $$f ]; then \
+			cmd="valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=$$f.log -v ./$$f"; \
+			echo $$cmd; \
+			$$cmd; \
+		fi done;
+
+pgo: exprtk_benchmark.cpp exprtk.hpp
+	$(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-generate -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT)
+	./exprtk_benchmark
+	$(COMPILER) $(BASE_OPTIONS) -O3 -march=native -fprofile-use -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT)
+
+clean:
+	rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch

BIN
thirdparty/exprtk/exprtk - Verknüpfung.lnk


Diferenças do arquivo suprimidas por serem muito extensas
+ 39050 - 0
thirdparty/exprtk/exprtk.hpp


+ 564 - 0
thirdparty/exprtk/exprtk_benchmark.cpp

@@ -0,0 +1,564 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * ExprTk vs Native Benchmarks                                *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <cmath>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <deque>
+
+#include "exprtk.hpp"
+
+
+const std::string global_expression_list[]
+                     = {
+                          "(y + x)",
+                          "2 * (y + x)",
+                          "(2 * y + 2 * x)",
+                          "((1.23 * x^2) / y) - 123.123",
+                          "(y + x / y) * (x - y / x)",
+                          "x / ((x + y) + (x - y)) / y",
+                          "1 - ((x * y) + (y / x)) - 3",
+                          "(5.5 + x) + (2 * x - 2 / 3 * y) * (x / 3 + y / 4) + (y + 7.7)",
+                          "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^15 - 5.5x^23 + 6.6y^55",
+                          "sin(2 * x) + cos(pi / y)",
+                          "1 - sin(2 * x) + cos(pi / y)",
+                          "sqrt(111.111 - sin(2 * x) + cos(pi / y) / 333.333)",
+                          "(x^2 / sin(2 * pi / y)) - x / 2",
+                          "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y",
+                          "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)",
+                          "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))",
+                          "if((y + (x * 2.2)) <= (x + y + 1.1), x - y, x * y) + 2 * pi / x"
+                       };
+
+const std::size_t global_expression_list_size = sizeof(global_expression_list) / sizeof(std::string);
+
+static const double global_lower_bound_x = -100.0;
+static const double global_lower_bound_y = -100.0;
+static const double global_upper_bound_x = +100.0;
+static const double global_upper_bound_y = +100.0;
+static const double global_delta         = 0.0111;
+
+
+template <typename T,
+          typename Allocator,
+          template <typename,typename> class Sequence>
+bool load_expression(exprtk::symbol_table<T>& symbol_table,
+                     Sequence<exprtk::expression<T>,Allocator>& expr_seq)
+{
+   exprtk::parser<double> parser;
+
+   for (std::size_t i = 0; i < global_expression_list_size; ++i)
+   {
+      exprtk::expression<double> expression;
+      expression.register_symbol_table(symbol_table);
+
+      if (!parser.compile(global_expression_list[i],expression))
+      {
+         printf("[load_expression] - Parser Error: %s\tExpression: %s\n",
+                parser.error().c_str(),
+                global_expression_list[i].c_str());
+
+         return false;
+      }
+
+      expr_seq.push_back(expression);
+   }
+
+   return true;
+}
+
+template <typename T>
+void run_exprtk_benchmark(T& x, T& y,
+                          exprtk::expression<T>& expression,
+                          const std::string& expr_string)
+{
+   T total = T(0);
+   unsigned int count = 0;
+
+   exprtk::timer timer;
+   timer.start();
+
+   for (x = global_lower_bound_x; x <= global_upper_bound_x; x += global_delta)
+   {
+      for (y = global_lower_bound_y; y <= global_upper_bound_y; y += global_delta)
+      {
+         total += expression.value();
+         ++count;
+      }
+   }
+
+   timer.stop();
+
+   if (T(0) != total)
+      printf("[exprtk] Total Time:%12.8f  Rate:%14.3fevals/sec Expression: %s\n",
+             timer.time(),
+             count / timer.time(),
+             expr_string.c_str());
+   else
+      printf("run_exprtk_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str());
+}
+
+template <typename T> struct native;
+
+template <typename T, typename NativeFunction>
+void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_string)
+{
+   T total = T(0);
+   unsigned int count = 0;
+
+   exprtk::timer timer;
+   timer.start();
+
+   for (x = global_lower_bound_x; x <= global_upper_bound_x; x += global_delta)
+   {
+      for (y = global_lower_bound_y; y <= global_upper_bound_y; y += global_delta)
+      {
+         total += f(x,y);
+         ++count;
+      }
+   }
+
+   timer.stop();
+
+   if (T(0) != total)
+      printf("[native] Total Time:%12.8f  Rate:%14.3fevals/sec Expression: %s\n",
+             timer.time(),
+             count / timer.time(),
+             expr_string.c_str());
+   else
+      printf("run_native_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str());
+}
+
+template <typename T>
+bool run_parse_benchmark(exprtk::symbol_table<T>& symbol_table)
+{
+   static const std::size_t rounds = 100000;
+   exprtk::parser<double> parser;
+   exprtk::expression<double> expression;
+
+   expression.register_symbol_table(symbol_table);
+
+   for (std::size_t i = 0; i < global_expression_list_size; ++i)
+   {
+      exprtk::timer timer;
+      timer.start();
+
+      for (std::size_t r = 0; r < rounds; ++r)
+      {
+         if (!parser.compile(global_expression_list[i],expression))
+         {
+            printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n",
+                   parser.error().c_str(),
+                   global_expression_list[i].c_str());
+
+            return false;
+         }
+      }
+
+      timer.stop();
+
+      printf("[parse] Total Time:%12.8f  Rate:%14.3fparse/sec Expression: %s\n",
+             timer.time(),
+             rounds / timer.time(),
+             global_expression_list[i].c_str());
+   }
+
+   return true;
+}
+
+const double pi = 3.141592653589793238462643383279502;
+
+template <typename T>
+struct native
+{
+   typedef typename exprtk::details::functor_t<T> functor_t;
+   typedef typename functor_t::Type Type;
+
+   static inline T avg(Type x, Type y)
+   {
+      return (x + y) / T(2);
+   }
+
+   static inline T clamp(const Type l, const Type v, const Type u)
+   {
+      return ((v < l) ? l : ((v > u) ? u : v));
+   }
+
+   static inline T func00(Type x, Type y)
+   {
+      return (y + x);
+   }
+
+   static inline T func01(Type x, Type y)
+   {
+      return T(2) * (y + x);
+   }
+
+   static inline T func02(Type x, Type y)
+   {
+      return (T(2) * y + T(2) * x);
+   }
+
+   static inline T func03(Type x, Type y)
+   {
+      return ((T(1.23) * (x * x)) / y) - T(123.123);
+   }
+
+   static inline T func04(Type x, Type y)
+   {
+      return (y + x / y) * (x - y / x);
+   }
+
+   static inline T func05(Type x, Type y)
+   {
+      return x / ((x + y) + (x - y)) / y;
+   }
+
+   static inline T func06(Type x, Type y)
+   {
+      return T(1) - ((x * y) + (y / x)) - T(3);
+   }
+
+   static inline T func07(Type x, Type y)
+   {
+      return (T(5.5) + x) + (T(2) * x - T(2) / T(3) * y) * (x / T(3) + y / T(4)) + (y + T(7.7));
+   }
+
+   static inline T func08(Type x, Type y)
+   {
+      using namespace std;
+      return (T(1.1)*pow(x,T(1))+T(2.2)*pow(y,T(2))-T(3.3)*pow(x,T(3))+T(4.4)*pow(y,T(15))-T(5.5)*pow(x,T(23))+T(6.6)*pow(y,T(55)));
+   }
+
+   static inline T func09(Type x, Type y)
+   {
+      return std::sin(T(2) * x) + std::cos(pi / y);
+   }
+
+   static inline T func10(Type x, Type y)
+   {
+      return T(1) - std::sin(T(2) * x) + std::cos(pi / y);
+   }
+
+   static inline T func11(Type x, Type y)
+   {
+      return std::sqrt(T(111.111) - std::sin(T(2) * x) + std::cos(pi / y) / T(333.333));
+   }
+
+   static inline T func12(Type x, Type y)
+   {
+      return ((x * x) / std::sin(T(2) * pi / y)) - x / T(2);
+   }
+
+   static inline T func13(Type x, Type y)
+   {
+      return (x + (std::cos(y - std::sin(T(2) / x * pi)) - std::sin(x - std::cos(T(2) * y / pi))) - y);
+   }
+
+   static inline T func14(Type x, Type y)
+   {
+      return clamp(T(-1), std::sin(T(2) * pi * x) + std::cos(y / T(2) * pi), + T(1));
+   }
+
+   static inline T func15(Type x, Type y)
+   {
+      return std::max(T(3.33), std::min(sqrt(T(1) - std::sin(T(2) * x) + std::cos(pi / y) / T(3)), T(1.11)));
+   }
+
+   static inline T func16(Type x, Type y)
+   {
+      return (((y + (x * T(2.2))) <= (x + y + T(1.1))) ? x - y : x * y) + T(2) * pi / x;
+   }
+};
+
+void pgo_primer();
+void perform_file_based_benchmark(const std::string& file_name, const std::size_t& rounds = 100000);
+
+int main(int argc, char* argv[])
+{
+   if (argc >= 2)
+   {
+      const std::string file_name = argv[1];
+
+      if (argc == 2)
+         perform_file_based_benchmark(file_name);
+      else
+         perform_file_based_benchmark(file_name,atoi(argv[2]));
+
+      return 0;
+   }
+
+   pgo_primer();
+
+   double x = 0;
+   double y = 0;
+
+   exprtk::symbol_table<double> symbol_table;
+   symbol_table.add_constants();
+   symbol_table.add_variable("x",x);
+   symbol_table.add_variable("y",y);
+
+   std::deque<exprtk::expression<double> > compiled_expr_list;
+
+   if (!load_expression(symbol_table,compiled_expr_list))
+   {
+      return 1;
+   }
+
+   {
+      std::cout << "--- EXPRTK ---" << std::endl;
+      for (std::size_t i = 0; i < compiled_expr_list.size(); ++i)
+      {
+         run_exprtk_benchmark(x,y,compiled_expr_list[i],global_expression_list[i]);
+      }
+   }
+
+   {
+      std::cout << "--- NATIVE ---" << std::endl;
+      run_native_benchmark(x,y,native<double>::func00,global_expression_list[ 0]);
+      run_native_benchmark(x,y,native<double>::func01,global_expression_list[ 1]);
+      run_native_benchmark(x,y,native<double>::func02,global_expression_list[ 2]);
+      run_native_benchmark(x,y,native<double>::func03,global_expression_list[ 3]);
+      run_native_benchmark(x,y,native<double>::func04,global_expression_list[ 4]);
+      run_native_benchmark(x,y,native<double>::func05,global_expression_list[ 5]);
+      run_native_benchmark(x,y,native<double>::func06,global_expression_list[ 6]);
+      run_native_benchmark(x,y,native<double>::func07,global_expression_list[ 7]);
+      run_native_benchmark(x,y,native<double>::func08,global_expression_list[ 8]);
+      run_native_benchmark(x,y,native<double>::func09,global_expression_list[ 9]);
+      run_native_benchmark(x,y,native<double>::func10,global_expression_list[10]);
+      run_native_benchmark(x,y,native<double>::func11,global_expression_list[11]);
+      run_native_benchmark(x,y,native<double>::func12,global_expression_list[12]);
+      run_native_benchmark(x,y,native<double>::func13,global_expression_list[13]);
+      run_native_benchmark(x,y,native<double>::func14,global_expression_list[14]);
+      run_native_benchmark(x,y,native<double>::func15,global_expression_list[15]);
+      run_native_benchmark(x,y,native<double>::func16,global_expression_list[16]);
+   }
+
+   {
+      std::cout << "--- PARSE ----" << std::endl;
+      run_parse_benchmark(symbol_table);
+   }
+
+   return 0;
+}
+
+void pgo_primer()
+{
+   exprtk::pgo_primer<double>();
+
+   static const double lower_bound_x = -50.0;
+   static const double lower_bound_y = -50.0;
+   static const double upper_bound_x = +50.0;
+   static const double upper_bound_y = +50.0;
+   static const double delta = 0.07;
+
+   double total = 0.0;
+
+   for (double x = lower_bound_x; x <= upper_bound_x; x += delta)
+   {
+      for (double y = lower_bound_y; y <= upper_bound_y; y += delta)
+      {
+         total += native<double>::func00(x,y);
+         total += native<double>::func01(x,y);
+         total += native<double>::func02(x,y);
+         total += native<double>::func03(x,y);
+         total += native<double>::func04(x,y);
+         total += native<double>::func05(x,y);
+         total += native<double>::func06(x,y);
+         total += native<double>::func07(x,y);
+         total += native<double>::func08(x,y);
+         total += native<double>::func09(x,y);
+         total += native<double>::func10(x,y);
+         total += native<double>::func11(x,y);
+         total += native<double>::func12(x,y);
+         total += native<double>::func13(x,y);
+         total += native<double>::func14(x,y);
+         total += native<double>::func15(x,y);
+         total += native<double>::func16(x,y);
+      }
+   }
+}
+
+std::size_t load_expression_file(const std::string& file_name, std::deque<std::string>& expression_list)
+{
+   std::ifstream stream(file_name.c_str());
+
+   if (!stream) return 0;
+
+   std::string buffer;
+   buffer.reserve(1024);
+   std::size_t line_count = 0;
+
+   while (std::getline(stream,buffer))
+   {
+      if (buffer.empty())
+         continue;
+      else if ('#' == buffer[0])
+         continue;
+
+      ++line_count;
+      expression_list.push_back(buffer);
+   }
+
+   return line_count;
+}
+
+void perform_file_based_benchmark(const std::string& file_name, const std::size_t& rounds)
+{
+   std::deque<std::string> expr_str_list;
+
+   if (0 == load_expression_file(file_name,expr_str_list))
+   {
+      std::cout << "Failed to load any expressions from: " << file_name << "\n";
+      return;
+   }
+
+   typedef exprtk::symbol_table<double> symbol_table_t;
+   typedef exprtk::expression<double>     expression_t;
+   typedef exprtk::parser<double>             parser_t;
+
+   std::deque<expression_t> expression_list;
+
+   symbol_table_t symbol_table;
+
+   double a = 1.1;
+   double b = 2.2;
+   double c = 3.3;
+   double x = 2.123456;
+   double y = 3.123456;
+   double z = 4.123456;
+   double w = 5.123456;
+
+   symbol_table.add_variable("a", a);
+   symbol_table.add_variable("b", b);
+   symbol_table.add_variable("c", c);
+
+   symbol_table.add_variable("x", x);
+   symbol_table.add_variable("y", y);
+   symbol_table.add_variable("z", z);
+   symbol_table.add_variable("w", w);
+
+   exprtk::polynomial<double, 1> poly01;
+   exprtk::polynomial<double, 2> poly02;
+   exprtk::polynomial<double, 3> poly03;
+   exprtk::polynomial<double, 4> poly04;
+   exprtk::polynomial<double, 5> poly05;
+   exprtk::polynomial<double, 6> poly06;
+   exprtk::polynomial<double, 7> poly07;
+   exprtk::polynomial<double, 8> poly08;
+   exprtk::polynomial<double, 9> poly09;
+   exprtk::polynomial<double,10> poly10;
+   exprtk::polynomial<double,11> poly11;
+   exprtk::polynomial<double,12> poly12;
+
+   symbol_table.add_function("poly01", poly01);
+   symbol_table.add_function("poly02", poly02);
+   symbol_table.add_function("poly03", poly03);
+   symbol_table.add_function("poly04", poly04);
+   symbol_table.add_function("poly05", poly05);
+   symbol_table.add_function("poly06", poly06);
+   symbol_table.add_function("poly07", poly07);
+   symbol_table.add_function("poly08", poly08);
+   symbol_table.add_function("poly09", poly09);
+   symbol_table.add_function("poly10", poly10);
+   symbol_table.add_function("poly11", poly11);
+   symbol_table.add_function("poly12", poly12);
+
+   static double e = exprtk::details::numeric::constant::e;
+   symbol_table.add_variable("e", e, true);
+
+   symbol_table.add_constants();
+
+   {
+      parser_t parser;
+
+      for (std::size_t i = 0; i < expr_str_list.size(); ++i)
+      {
+         expression_t expression;
+         expression.register_symbol_table(symbol_table);
+
+         if (!parser.compile(expr_str_list[i],expression))
+         {
+            printf("[perform_file_based_benchmark] - Parser Error: %s\tExpression: %s\n",
+                   parser.error().c_str(),
+                   expr_str_list[i].c_str());
+
+            return;
+         }
+
+         expression_list.push_back(expression);
+      }
+   }
+
+   exprtk::timer total_timer;
+   exprtk::timer timer;
+
+   double single_eval_total_time = 0.0;
+
+   total_timer.start();
+
+   for (std::size_t i = 0; i < expression_list.size(); ++i)
+   {
+      expression_t& expression = expression_list[i];
+
+      a = 1.1;
+      b = 2.2;
+      c = 3.3;
+      x = 2.123456;
+      y = 3.123456;
+      z = 4.123456;
+      w = 5.123456;
+
+      timer.start();
+      double sum = 0.0;
+
+      for (std::size_t r = 0; r < rounds; ++r)
+      {
+         sum += expression.value();
+         std::swap(a,b);
+         std::swap(x,y);
+      }
+
+      timer.stop();
+
+      printf("Expression %3d of %3d %9.3f ns\t%10d ns\t(%30.10f)  '%s'\n",
+             static_cast<int>(i + 1),
+             static_cast<int>(expression_list.size()),
+             (timer.time() * 1000000000.0) / (1.0 * rounds),
+             static_cast<int>(timer.time() * 1000000000.0),
+             sum,
+             expr_str_list[i].c_str());
+
+      fflush(stdout);
+
+      single_eval_total_time += (timer.time() * 1000000000.0) / (1.0 * rounds);
+   }
+
+   total_timer.stop();
+
+   printf("[*] Number Of Evals:        %15.0f\n",
+          rounds * (expression_list.size() * 1.0));
+
+   printf("[*] Total Time:             %9.3fsec\n",
+          total_timer.time());
+
+   printf("[*] Total Single Eval Time: %9.3fms\n",
+          single_eval_total_time / 1000000.0);
+}

+ 58 - 0
thirdparty/exprtk/exprtk_simple_example_01.cpp

@@ -0,0 +1,58 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 1                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void trig_function()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string expression_string =
+                     "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
+
+   T x;
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("x",x);
+   symbol_table.add_constants();
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_string,expression);
+
+   for (x = T(-5); x <= T(+5); x += T(0.001))
+   {
+      const T y = expression.value();
+      printf("%19.15f\t%19.15f\n", x, y);
+   }
+}
+
+int main()
+{
+   trig_function<double>();
+   return 0;
+}

+ 73 - 0
thirdparty/exprtk/exprtk_simple_example_02.cpp

@@ -0,0 +1,73 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 2                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void square_wave()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string expr_string =
+                  "a*(4/pi)*"
+                  "((1 /1)*sin( 2*pi*f*t)+(1 /3)*sin( 6*pi*f*t)+"
+                  " (1 /5)*sin(10*pi*f*t)+(1 /7)*sin(14*pi*f*t)+"
+                  " (1 /9)*sin(18*pi*f*t)+(1/11)*sin(22*pi*f*t)+"
+                  " (1/13)*sin(26*pi*f*t)+(1/15)*sin(30*pi*f*t)+"
+                  " (1/17)*sin(34*pi*f*t)+(1/19)*sin(38*pi*f*t)+"
+                  " (1/21)*sin(42*pi*f*t)+(1/23)*sin(46*pi*f*t)+"
+                  " (1/25)*sin(50*pi*f*t)+(1/27)*sin(54*pi*f*t))";
+
+   static const T pi = T(3.141592653589793238462643383279502);
+
+   const T f = pi / T(10);
+   const T a = T(10);
+         T t = T(0);
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("t",t);
+   symbol_table.add_constant("f",f);
+   symbol_table.add_constant("a",a);
+   symbol_table.add_constants();
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expr_string,expression);
+
+   const T delta = (T(4) * pi) / T(1000);
+
+   for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta)
+   {
+      const T result = expression.value();
+      printf("%19.15f\t%19.15f\n", t, result);
+   }
+}
+
+int main()
+{
+   square_wave<double>();
+   return 0;
+}

+ 60 - 0
thirdparty/exprtk/exprtk_simple_example_03.cpp

@@ -0,0 +1,60 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 3                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void polynomial()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string expression_string =
+                  "25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1";
+
+   const T r0 = T(0);
+   const T r1 = T(1);
+         T  x = T(0);
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("x",x);
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_string,expression);
+
+   const T delta = T(1.0 / 100.0);
+
+   for (x = r0; x <= r1; x += delta)
+   {
+      printf("%19.15f\t%19.15f\n", x, expression.value());
+   }
+}
+
+int main()
+{
+   polynomial<double>();
+   return 0;
+}

+ 88 - 0
thirdparty/exprtk/exprtk_simple_example_04.cpp

@@ -0,0 +1,88 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 4                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void fibonacci()
+{
+   typedef exprtk::symbol_table<T>      symbol_table_t;
+   typedef exprtk::expression<T>          expression_t;
+   typedef exprtk::parser<T>                  parser_t;
+   typedef exprtk::function_compositor<T> compositor_t;
+   typedef typename compositor_t::function  function_t;
+
+   compositor_t compositor;
+
+   compositor
+      .add(
+      function_t( // define function: fibonacci(x)
+           "fibonacci",
+           " var w := 0;             "
+           " var y := 0;             "
+           " var z := 1;             "
+           " switch                  "
+           " {                       "
+           "   case x == 0 : 0;      "
+           "   case x == 1 : 1;      "
+           "   default     :         "
+           "    while ((x -= 1) > 0) "
+           "    {                    "
+           "      w := z;            "
+           "      z := z + y;        "
+           "      y := w;            "
+           "      z                  "
+           "    };                   "
+           " }                       ",
+           "x"));
+
+   T x = T(0);
+
+   symbol_table_t& symbol_table = compositor.symbol_table();
+   symbol_table.add_constants();
+   symbol_table.add_variable("x",x);
+
+   std::string expression_str = "fibonacci(x)";
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_str,expression);
+
+   for (std::size_t i = 0; i < 40; ++i)
+   {
+      x = static_cast<T>(i);
+
+      const T result = expression.value();
+
+      printf("fibonacci(%3d) = %10.0f\n",
+             static_cast<int>(i),
+             result);
+   }
+}
+
+int main()
+{
+   fibonacci<double>();
+   return 0;
+}

+ 81 - 0
thirdparty/exprtk/exprtk_simple_example_05.cpp

@@ -0,0 +1,81 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 5                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+struct myfunc : public exprtk::ifunction<T>
+{
+   using exprtk::ifunction<T>::operator();
+
+   myfunc()
+   : exprtk::ifunction<T>(2)
+   { exprtk::disable_has_side_effects(*this); }
+
+   inline T operator()(const T& v1, const T& v2)
+   {
+      return T(1) + (v1 * v2) / T(3);
+   }
+};
+
+template <typename T>
+inline T myotherfunc(T v0, T v1, T v2)
+{
+   return std::abs(v0 - v1) * v2;
+}
+
+template <typename T>
+void custom_function()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string expression_string =
+                  "myfunc(sin(x / pi), otherfunc(3 * y, x / 2, x * y))";
+
+   T x = T(1);
+   T y = T(2);
+   myfunc<T> mf;
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("x",x);
+   symbol_table.add_variable("y",y);
+   symbol_table.add_function("myfunc",mf);
+   symbol_table.add_function("otherfunc",myotherfunc);
+   symbol_table.add_constants();
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_string,expression);
+
+   const T result = expression.value();
+   printf("Result: %10.5f\n",result);
+}
+
+int main()
+{
+   custom_function<double>();
+   return 0;
+}

+ 60 - 0
thirdparty/exprtk/exprtk_simple_example_06.cpp

@@ -0,0 +1,60 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 6                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void vector_function()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string expression_string =
+                  " for (var i := 0; i < min(x[],y[],z[]); i += 1) "
+                  " {                                              "
+                  "   z[i] := 3sin(x[i]) + 2log(y[i]);             "
+                  " }                                              ";
+
+   T x[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
+   T y[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) };
+   T z[] = { T(0.0), T(0.0), T(0.0), T(0.0), T(0.0) };
+
+   symbol_table_t symbol_table;
+   symbol_table.add_vector("x",x);
+   symbol_table.add_vector("y",y);
+   symbol_table.add_vector("z",z);
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_string,expression);
+
+   expression.value();
+}
+
+int main()
+{
+   vector_function<double>();
+   return 0;
+}

+ 71 - 0
thirdparty/exprtk/exprtk_simple_example_07.cpp

@@ -0,0 +1,71 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 7                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void logic()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string expression_string = "not(A and B) or C";
+
+   symbol_table_t symbol_table;
+   symbol_table.create_variable("A");
+   symbol_table.create_variable("B");
+   symbol_table.create_variable("C");
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_string,expression);
+
+   printf(" # | A | B | C | %s\n"
+          "---+---+---+---+-%s\n",
+          expression_string.c_str(),
+          std::string(expression_string.size(),'-').c_str());
+
+   for (int i = 0; i < 8; ++i)
+   {
+      symbol_table.get_variable("A")->ref() = T((i & 0x01) ? 1 : 0);
+      symbol_table.get_variable("B")->ref() = T((i & 0x02) ? 1 : 0);
+      symbol_table.get_variable("C")->ref() = T((i & 0x04) ? 1 : 0);
+
+      const int result = static_cast<int>(expression.value());
+
+      printf(" %d | %d | %d | %d | %d \n",
+             i,
+             static_cast<int>(symbol_table.get_variable("A")->value()),
+             static_cast<int>(symbol_table.get_variable("B")->value()),
+             static_cast<int>(symbol_table.get_variable("C")->value()),
+             result);
+   }
+}
+
+int main()
+{
+   logic<double>();
+   return 0;
+}

+ 90 - 0
thirdparty/exprtk/exprtk_simple_example_08.cpp

@@ -0,0 +1,90 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 8                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void composite()
+{
+   typedef exprtk::symbol_table<T>      symbol_table_t;
+   typedef exprtk::expression<T>          expression_t;
+   typedef exprtk::parser<T>                  parser_t;
+   typedef exprtk::parser_error::type            err_t;
+   typedef exprtk::function_compositor<T> compositor_t;
+   typedef typename compositor_t::function  function_t;
+
+   compositor_t compositor;
+
+   T x = T(1);
+   T y = T(2);
+
+   symbol_table_t& symbol_table = compositor.symbol_table();
+   symbol_table.add_constants();
+   symbol_table.add_variable("x",x);
+   symbol_table.add_variable("y",y);
+
+   compositor
+      .add(
+      function_t("f","sin(x / pi)","x"));          // f(x) = sin(x / pi)
+
+   compositor
+      .add(
+      function_t("g","3*[f(x) + f(y)]","x","y"));  // g(x,y) = 3[f(x) + f(y)]
+
+   std::string expression_string = "g(1 + f(x), f(y) / 2)";
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+
+   if (!parser.compile(expression_string,expression))
+   {
+      printf("Error: %s\tExpression: %s\n",
+             parser.error().c_str(),
+             expression_string.c_str());
+
+      for (std::size_t i = 0; i < parser.error_count(); ++i)
+      {
+         const err_t error = parser.get_error(i);
+
+         printf("Error: %02d  Position: %02d Type: [%14s] Msg: %s\tExpression: %s\n",
+                static_cast<unsigned int>(i),
+                static_cast<unsigned int>(error.token.position),
+                exprtk::parser_error::to_str(error.mode).c_str(),
+                error.diagnostic.c_str(),
+                expression_string.c_str());
+      }
+
+      return;
+   }
+
+   const T result = expression.value();
+
+   printf("%s = %e\n", expression_string.c_str(), result);
+}
+
+int main()
+{
+   composite<double>();
+   return 0;
+}

+ 152 - 0
thirdparty/exprtk/exprtk_simple_example_09.cpp

@@ -0,0 +1,152 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 9                                           *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void primes()
+{
+   typedef exprtk::symbol_table<T>      symbol_table_t;
+   typedef exprtk::expression<T>          expression_t;
+   typedef exprtk::parser<T>                  parser_t;
+   typedef exprtk::function_compositor<T> compositor_t;
+   typedef typename compositor_t::function  function_t;
+
+   T x = T(0);
+
+   symbol_table_t symbol_table;
+
+   symbol_table.add_constants();
+   symbol_table.add_variable("x",x);
+
+   compositor_t compositor(symbol_table);
+
+   //Mode 1 - if statement based
+   compositor
+      .add(
+      function_t( // define function: is_prime_impl1(x,y)
+           "is_prime_impl1",
+           " if (y == 1,true,                "
+           "    if (0 == (x % y),false,      "
+           "       is_prime_impl1(x,y - 1))) ",
+           "x","y"));
+
+   compositor
+      .add(
+      function_t( // define function: is_prime1(x)
+           "is_prime1",
+           " if (frac(x) != 0, false,                                "
+           "    if (x <= 0, false,                                   "
+           "       is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1)))) ",
+           "x"));
+
+   //Mode 2 - switch statement based
+   compositor
+      .add(
+      function_t( // define function: is_prime_impl2(x,y)
+           "is_prime_impl2",
+           " switch                                         "
+           " {                                              "
+           "   case y == 1       : true;                    "
+           "   case (x % y) == 0 : false;                   "
+           "   default           : is_prime_impl2(x,y - 1); "
+           " }                                              ",
+           "x","y"));
+
+   compositor
+      .add(
+      function_t( // define function: is_prime2(x)
+           "is_prime2",
+           " switch                                                                 "
+           " {                                                                      "
+           "   case x <= 0       : false;                                           "
+           "   case frac(x) != 0 : false;                                           "
+           "   default           : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1)); "
+           " }                                                                      ",
+           "x"));
+
+   //Mode 3 - switch statement and while-loop based
+   compositor
+      .add(
+      function_t( // define function: is_prime_impl3(x,y)
+           "is_prime_impl3",
+           " while (y > 0)                            "
+           " {                                        "
+           "   switch                                 "
+           "   {                                      "
+           "     case y == 1       : ~(y := 0,true);  "
+           "     case (x % y) == 0 : ~(y := 0,false); "
+           "     default           : y := y - 1;      "
+           "   }                                      "
+           " }                                        ",
+           "x","y"));
+
+   compositor
+      .add(
+      function_t( // define function: is_prime3(x)
+           "is_prime3",
+           " switch                                                                 "
+           " {                                                                      "
+           "   case x <= 0       : false;                                           "
+           "   case frac(x) != 0 : false;                                           "
+           "   default           : is_prime_impl3(x,min(x - 1,trunc(sqrt(x)) + 1)); "
+           " }                                                                      ",
+           "x"));
+
+   std::string expression_str1 = "is_prime1(x)";
+   std::string expression_str2 = "is_prime2(x)";
+   std::string expression_str3 = "is_prime3(x)";
+
+   expression_t expression1;
+   expression_t expression2;
+   expression_t expression3;
+   expression1.register_symbol_table(symbol_table);
+   expression2.register_symbol_table(symbol_table);
+   expression3.register_symbol_table(symbol_table);
+
+   parser_t parser;
+
+   parser.compile(expression_str1,expression1);
+   parser.compile(expression_str2,expression2);
+   parser.compile(expression_str3,expression3);
+
+   for (std::size_t i = 0; i < 100; ++i)
+   {
+      x = static_cast<T>(i);
+
+      const T result1 = expression1.value();
+      const T result2 = expression2.value();
+      const T result3 = expression3.value();
+
+      printf("%03d  Result1: %c  Result2: %c  Result3: %c\n",
+             static_cast<unsigned int>(i),
+             (result1 == T(1)) ? 'T' : 'F',
+             (result2 == T(1)) ? 'T' : 'F',
+             (result3 == T(1)) ? 'T' : 'F');
+   }
+}
+
+int main()
+{
+   primes<double>();
+   return 0;
+}

+ 92 - 0
thirdparty/exprtk/exprtk_simple_example_10.cpp

@@ -0,0 +1,92 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 10                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cmath>
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void newton_sqrt()
+{
+   typedef exprtk::symbol_table<T>      symbol_table_t;
+   typedef exprtk::expression<T>          expression_t;
+   typedef exprtk::parser<T>                  parser_t;
+   typedef exprtk::function_compositor<T> compositor_t;
+   typedef typename compositor_t::function  function_t;
+
+   T x = T(0);
+
+   symbol_table_t symbol_table;
+
+   symbol_table.add_constants();
+   symbol_table.add_variable("x",x);
+
+   compositor_t compositor(symbol_table);
+
+   compositor
+      .add(
+      function_t( // define function: newton_sqrt(x)
+           "newton_sqrt",
+           " switch                                                "
+           " {                                                     "
+           "   case x < 0  : null;                                 "
+           "   case x == 0 : 0;                                    "
+           "   case x == 1 : 1;                                    "
+           "   default:                                            "
+           "   ~{                                                  "
+           "      var z := 100;                                    "
+           "      var sqrt_x := x / 2;                             "
+           "      repeat                                           "
+           "        if (equal(sqrt_x^2, x))                        "
+           "          break[sqrt_x];                               "
+           "        else                                           "
+           "          sqrt_x := (1 / 2) * (sqrt_x + (x / sqrt_x)); "
+           "      until ((z -= 1) <= 0);                           "
+           "    };                                                 "
+           " }                                                     ",
+           "x"));
+
+   const std::string expression_str = "newton_sqrt(x)";
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(expression_str,expression);
+
+   for (std::size_t i = 0; i < 100; ++i)
+   {
+      x = static_cast<T>(i);
+
+      const T result = expression.value();
+
+      printf("sqrt(%03d) - Result: %15.13f\tReal: %15.13f\n",
+             static_cast<unsigned int>(i),
+             result,
+             std::sqrt(x));
+   }
+}
+
+int main()
+{
+   newton_sqrt<double>();
+   return 0;
+}

+ 71 - 0
thirdparty/exprtk/exprtk_simple_example_11.cpp

@@ -0,0 +1,71 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 11                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void square_wave2()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string wave_program =
+                  " var r := 0;                                         "
+                  " for (var i := 0; i < 1000; i += 1)                  "
+                  " {                                                   "
+                  "   r += (1 / (2i + 1)) * sin((4i + 2) * pi * f * t); "
+                  " };                                                  "
+                  " r *= a * (4 / pi);                                  ";
+
+   static const T pi = T(3.141592653589793238462643383279502);
+
+   T f = pi / T(10);
+   T t = T(0);
+   T a = T(10);
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("f",f);
+   symbol_table.add_variable("t",t);
+   symbol_table.add_variable("a",a);
+   symbol_table.add_constants();
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(wave_program,expression);
+
+   const T delta = (T(4) * pi) / T(1000);
+
+   for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta)
+   {
+      const T result = expression.value();
+      printf("%19.15f\t%19.15f\n", t, result);
+   }
+}
+
+int main()
+{
+   square_wave2<double>();
+   return 0;
+}

+ 69 - 0
thirdparty/exprtk/exprtk_simple_example_12.cpp

@@ -0,0 +1,69 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 12                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void bubble_sort()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string bubblesort_program =
+                  " var upper_bound := v[];                           "
+                  " var swapped := false;                             "
+                  " repeat                                            "
+                  "   swapped := false;                               "
+                  "   for (var i := 0; i < upper_bound; i += 1)       "
+                  "   {                                               "
+                  "     for (var j := i + 1; j < upper_bound; j += 1) "
+                  "     {                                             "
+                  "       if (v[i] > v[j])                            "
+                  "       {                                           "
+                  "         v[i] <=> v[j];                            "
+                  "         swapped := true;                          "
+                  "       };                                          "
+                  "     };                                            "
+                  "   };                                              "
+                  "   upper_bound -= 1;                               "
+                  " until (not(swapped) or (upper_bound == 0));       ";
+
+   T v[] = { T(9.9), T(2.2), T(1.1), T(5.5), T(7.7), T(4.4), T(3.3) };
+
+   symbol_table_t symbol_table;
+   symbol_table.add_vector("v",v);
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(bubblesort_program,expression);
+
+   expression.value();
+}
+
+int main()
+{
+   bubble_sort<double>();
+   return 0;
+}

+ 100 - 0
thirdparty/exprtk/exprtk_simple_example_13.cpp

@@ -0,0 +1,100 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 13                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void savitzky_golay_filter()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string sgfilter_program =
+                  " var weight[9] :=                                          "
+                  "       {                                                   "
+                  "         -21, 14,  39,                                     "
+                  "          54, 59,  54,                                     "
+                  "          39, 14, -21                                      "
+                  "       };                                                  "
+                  "                                                           "
+                  " if (v_in[] >= weight[])                                   "
+                  " {                                                         "
+                  "   var lower_bound := trunc(weight[] / 2);                 "
+                  "   var upper_bound := v_in[] - lower_bound;                "
+                  "                                                           "
+                  "   v_out := 0;                                             "
+                  "                                                           "
+                  "   for (var i := lower_bound; i < upper_bound; i += 1)     "
+                  "   {                                                       "
+                  "     for (var j := -lower_bound; j <= lower_bound; j += 1) "
+                  "     {                                                     "
+                  "       v_out[i] += weight[j + lower_bound] * v_in[i + j];  "
+                  "     };                                                    "
+                  "   };                                                      "
+                  "                                                           "
+                  "   v_out /= sum(weight);                                   "
+                  " }                                                         ";
+
+   const std::size_t n = 1024;
+
+   std::vector<T> v_in;
+   std::vector<T> v_out;
+
+   const T pi = T(3.141592653589793238462643383279502);
+
+   srand(static_cast<unsigned int>(time(0)));
+
+   // Generate a signal with noise.
+   for (T t = T(-5); t <= T(+5); t += T(10.0 / n))
+   {
+      T noise = T(0.5 * (rand() / (RAND_MAX + 1.0) - 0.5));
+      v_in.push_back(sin(2.0 * pi * t) + noise);
+   }
+
+   v_out.resize(v_in.size());
+
+   symbol_table_t symbol_table;
+   symbol_table.add_vector("v_in" , v_in);
+   symbol_table.add_vector("v_out",v_out);
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(sgfilter_program,expression);
+
+   expression.value();
+
+   for (std::size_t i = 0; i < v_out.size(); ++i)
+   {
+      printf("%10.6f\t%10.6f\n",v_in[i],v_out[i]);
+   }
+}
+
+int main()
+{
+   savitzky_golay_filter<double>();
+   return 0;
+}

+ 56 - 0
thirdparty/exprtk/exprtk_simple_example_14.cpp

@@ -0,0 +1,56 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 14                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void stddev_example()
+{
+   typedef exprtk::expression<T> expression_t;
+   typedef exprtk::parser<T>         parser_t;
+
+   const std::string stddev_program =
+                  " var x[25] := {                     "
+                  "                 1,  2,  3,  4,  5, "
+                  "                 6,  7,  8,  9, 10, "
+                  "                11, 12, 13, 14, 15, "
+                  "                16, 17, 18, 19, 20, "
+                  "                21, 22, 23, 24, 25  "
+                  "              };                    "
+                  "                                    "
+                  " sqrt(sum([x - avg(x)]^2) / x[])    ";
+
+   expression_t expression;
+
+   parser_t parser;
+   parser.compile(stddev_program,expression);
+
+   const T stddev = expression.value();
+
+   printf("stddev(1..25) = %10.6f\n",stddev);
+}
+
+int main()
+{
+   stddev_example<double>();
+   return 0;
+}

+ 94 - 0
thirdparty/exprtk/exprtk_simple_example_15.cpp

@@ -0,0 +1,94 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 15                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void black_scholes_merton_model()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string bsm_model_program =
+                  " var d1 := (log(s / x) + (r + v^2 / 2) * t) / (v * sqrt(t)); "
+                  " var d2 := d1 - v * sqrt(t);                                 "
+                  "                                                             "
+                  " if (callput_flag == 'call')                                 "
+                  "   s * ncdf(d1) - x * e^(-r * t) * ncdf(d2);                 "
+                  " else if (callput_flag == 'put')                             "
+                  "   x * e^(-r * t) * ncdf(-d2) - s * ncdf(-d1);               "
+                  "                                                             ";
+
+   T s = T(60.00); // Stock price
+   T x = T(65.00); // Strike price
+   T t = T( 0.25); // Years to maturity
+   T r = T( 0.08); // Risk free rate
+   T v = T( 0.30); // Volatility
+
+   std::string callput_flag;
+
+   static const T e = exprtk::details::numeric::constant::e;
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("s",s);
+   symbol_table.add_variable("x",x);
+   symbol_table.add_variable("t",t);
+   symbol_table.add_variable("r",r);
+   symbol_table.add_variable("v",v);
+   symbol_table.add_constant("e",e);
+   symbol_table.add_stringvar("callput_flag",callput_flag);
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(bsm_model_program,expression);
+
+   {
+      callput_flag = "call";
+
+      T bsm = expression.value();
+
+      printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
+             callput_flag.c_str(),
+             s, x, t, r, v,
+             bsm);
+   }
+
+   {
+      callput_flag = "put";
+
+      T bsm = expression.value();
+
+      printf("BSM(%s,%5.3f,%5.3f,%5.3f,%5.3f,%5.3f) = %10.6f\n",
+             callput_flag.c_str(),
+             s, x, t, r, v,
+             bsm);
+   }
+}
+
+int main()
+{
+   black_scholes_merton_model<double>();
+   return 0;
+}

+ 82 - 0
thirdparty/exprtk/exprtk_simple_example_16.cpp

@@ -0,0 +1,82 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 16                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+void linear_least_squares()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string linear_least_squares_program =
+                  " if (x[] == y[])                                       "
+                  " {                                                     "
+                  "   beta  := (sum(x * y) - sum(x) * sum(y) / x[]) /     "
+                  "            (sum(x^2) -  sum(x)^2 / x[]);              "
+                  "                                                       "
+                  "   alpha := avg(y) - beta * avg(x);                    "
+                  "                                                       "
+                  "   rmse  := sqrt(sum((beta * x + alpha - y)^2) / y[]); "
+                  " }                                                     "
+                  " else                                                  "
+                  " {                                                     "
+                  "   alpha := null;                                      "
+                  "   beta  := null;                                      "
+                  "   rmse  := null;                                      "
+                  " }                                                     ";
+
+   T x[] = {T(  1), T(  2), T(3), T(  4), T(  5), T(6), T(  7), T(  8), T(  9), T(10)};
+   T y[] = {T(8.7), T(6.8), T(6), T(5.6), T(3.8), T(3), T(2.4), T(1.7), T(0.4), T(-1)};
+
+   T alpha = T(0);
+   T beta  = T(0);
+   T rmse  = T(0);
+
+   symbol_table_t symbol_table;
+   symbol_table.add_variable("alpha",alpha);
+   symbol_table.add_variable("beta" ,beta );
+   symbol_table.add_variable("rmse" ,rmse );
+   symbol_table.add_vector  ("x"    ,x    );
+   symbol_table.add_vector  ("y"    ,y    );
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(linear_least_squares_program,expression);
+
+   expression.value();
+
+   printf("alpha: %15.12f\n",alpha);
+   printf("beta:  %15.12f\n",beta );
+   printf("rmse:  %15.12f\n",rmse );
+   printf("y = %15.12fx + %15.12f\n",beta,alpha);
+}
+
+int main()
+{
+   linear_least_squares<double>();
+   return 0;
+}

+ 78 - 0
thirdparty/exprtk/exprtk_simple_example_17.cpp

@@ -0,0 +1,78 @@
+/*
+ **************************************************************
+ *         C++ Mathematical Expression Toolkit Library        *
+ *                                                            *
+ * Simple Example 17                                          *
+ * Author: Arash Partow (1999-2020)                           *
+ * URL: http://www.partow.net/programming/exprtk/index.html   *
+ *                                                            *
+ * Copyright notice:                                          *
+ * Free use of the Mathematical Expression Toolkit Library is *
+ * permitted under the guidelines and in accordance with the  *
+ * most current version of the MIT License.                   *
+ * http://www.opensource.org/licenses/MIT                     *
+ *                                                            *
+ **************************************************************
+*/
+
+
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <string>
+
+#include "exprtk.hpp"
+
+
+template <typename T>
+struct rnd_01 : public exprtk::ifunction<T>
+{
+   using exprtk::ifunction<T>::operator();
+
+   rnd_01() : exprtk::ifunction<T>(0)
+   { ::srand(static_cast<unsigned int>(time(NULL))); }
+
+   inline T operator()()
+   {
+      // Note: Do not use this in production
+      // Result is in the interval [0,1)
+      return T(::rand() / T(RAND_MAX + 1.0));
+   }
+};
+
+template <typename T>
+void monte_carlo_pi()
+{
+   typedef exprtk::symbol_table<T> symbol_table_t;
+   typedef exprtk::expression<T>     expression_t;
+   typedef exprtk::parser<T>             parser_t;
+
+   const std::string monte_carlo_pi_program =
+                  " var experiments[5 * 10^7] := [(rnd_01^2 + rnd_01^2) <= 1]; "
+                  " 4 * sum(experiments) / experiments[];                      ";
+
+   rnd_01<T> rnd01;
+
+   symbol_table_t symbol_table;
+   symbol_table.add_function("rnd_01",rnd01);
+
+   expression_t expression;
+   expression.register_symbol_table(symbol_table);
+
+   parser_t parser;
+   parser.compile(monte_carlo_pi_program,expression);
+
+   const T approximate_pi = expression.value();
+
+   const T real_pi = T(3.141592653589793238462643383279502); // or close enough...
+
+   printf("pi ~ %20.17f\terror: %20.17f\n",
+          approximate_pi,
+          std::abs(real_pi - approximate_pi));
+}
+
+int main()
+{
+   monte_carlo_pi<double>();
+   return 0;
+}

+ 0 - 0
thirdparty/exprtk/exprtk_simple_example_18.cpp


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff