I am building a system in which mathematical computations are described as a graph. Each node of the graph is either very simple function (e.g. x -> x^2
) which does "double in double out" or it is an arbitrary complex functions with possibly non primitive data types involved. The structure of the graph and all its elements are known at compile time and the structure wont change during execution.
Current program execution order inside main()
is as follows: All nodes are initialized as objects, they are connected with each other via (special) connect()
function, first nodes of the are manually activated and further computation takes place.
The problem I am struggling with is the part of the program where I transfer the result of one node to its children.
Firstly I send void*
of the result of the children and then statically casted it to the right data type inside the child. The thought on this point that there will always be right data type hidden behind void*
, because I previously checked if two nodes are "connectable". It turned out that the program worked (in build mode) but it didn't compile at all in release mode. (Nowadays I think I could use reinterpret_cast
to avoid the problem with release, but still, I wasn't proud about that code.)
My second attempt was using an external function called friend void propagate(...)
which was invoked from inside of a concrete node. I restricted myself of transmitting any data types as in first attempt to only using double
, std::vector<double>
and later maybe a matrix. Inside of propagate()
I am using a simple look-up table together with a switch do decide which of (for the selected data type) specialized transmitting functions to invoke. This attempt works fine and the code is much cleaner but I am restricted to those data types. Even for a simple bool
as a parameter I would need to make it all somehow a template or copy the code.
In further investigation I came over key words as data flow programming, reactive... didn't got far there yet.
Well, I hope I could clarify my struggles. I do not share my code because I think my entire solution does have mangles I am open to hear better approaches which would lead me to implement the system in scalable and elegant way.
EDIT: Just thinking, but maybe if I exactly want this kind of behavior as described, without of usage of inheritance or templates, maybe I need to used some dynamic typed language such as Python
to make the data transfer easily done?