summaryrefslogtreecommitdiff
path: root/core/convert_topology.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/convert_topology.cpp')
-rw-r--r--core/convert_topology.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/core/convert_topology.cpp b/core/convert_topology.cpp
new file mode 100644
index 0000000..e348c80
--- /dev/null
+++ b/core/convert_topology.cpp
@@ -0,0 +1,161 @@
+/* format
+ "src dst delay weight\n"
+ multiple src dst combinations are possible (?)
+ */
+#include <string.h>
+#include <iostream>
+#include <map>
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/list.hpp>
+
+#include "pla_set.hpp"
+#include "pointers.hpp"
+#include "property_composition.hpp"
+#include "simlimits.hpp"
+#include "time.hpp"
+#include "topology.hpp"
+
+#include "model.hpp"
+
+#include "mempool.hpp"
+
+using namespace std;
+
+typedef Ptr<Neuron>::ptr_t np_t;
+typedef Ptr<Synapse>::ptr_t sp_t;
+typedef Ptr<Synapse>::offset_t op_t;
+
+struct Connection {
+ np_t src, dst;
+ Weight::type weight;
+ Time::type delay;
+};
+
+map<np_t, multimap<Time, Connection>*> cons;
+
+PropertyComposition<boost::mpl::list<
+ boost::mpl::pair<Weight, boost::mpl::bool_<true>>,
+ boost::mpl::pair<TargetSumWeight, boost::mpl::bool_<true>>,
+ boost::mpl::pair<SumWeight, boost::mpl::bool_<true>>
+>> pc;
+
+
+void init() {
+ // check that pc time is 0.0
+ assert(pc.properties.data.data.timeLimit == 0.0);
+ for (np_t i=0; i<maxNeurons; i++)
+ cons[i] = new multimap<Time, Connection>();
+}
+
+void read() {
+ cin >> skipws;
+ while (!cin.eof()) {
+ Connection c;
+
+ // read from stream
+ cin >> c.src >> c.dst >> c.delay >> c.weight;
+ assert(!cin.fail());
+ cin >> ws;
+
+ // first sanity check
+ assert(c.src < maxNeurons);
+ assert(c.dst < maxNeurons);
+ assert(c.delay > 0.0);
+ assert(c.weight != 0.0);
+
+ // store (to sort)
+ cons[c.src]->insert(make_pair(c.delay, c));
+ }
+}
+
+void addPseudo() {
+ const Ptr<Neuron>::ptr_t half = maxNeurons/2;
+ assert(numActualNeurons <= half);
+ for (Ptr<Neuron>::ptr_t i=0; i<half; i++) {
+ Connection c;
+ c.src = i + half;
+ c.dst = i;
+ c.delay = Time::epsilon()();
+ c.weight = ModelConsts::TrainerInput;
+ cons[c.src]->insert(make_pair(c.delay, c));
+ }
+}
+
+void setWeight(const sp_t synapse, Weight::type weight) {
+ PLA_Set<Weight> pla{Time{0}, Ptr<Synapse>{synapse}, weight};
+ pc.call(pla);
+}
+
+void writeTopology() {
+ // fill topology tables
+ Array<Time, maxNeurons * maxSynapsesPerNeuron> &delay
+ = *(new Array<Time, maxNeurons * maxSynapsesPerNeuron>());
+ Array<Ptr<Synapse>::ptr_t, maxNeurons * maxSynapsesPerNeuron> &target
+ = *(new Array<Ptr<Synapse>::ptr_t, maxNeurons * maxSynapsesPerNeuron>());
+
+ op_t currentSynapse[maxNeurons];
+ memset(currentSynapse, 0, sizeof(currentSynapse));
+
+ for (np_t i=0; i<maxNeurons; i++) {
+ op_t j=0;
+ multimap<Time, Connection> &l = *(cons[i]);
+ assert(l.size() < maxSynapsesPerNeuron); // last synapse required for nil
+
+ for (multimap<Time, Connection>::iterator k = l.begin(); k != l.end(); k++) {
+ sp_t t = i * maxSynapsesPerNeuron + j;
+ Connection &c = (*k).second;
+ Time::type dt = c.delay;
+ sp_t s = c.dst * maxSynapsesPerNeuron + currentSynapse[c.dst]++;
+
+ delay.set (t, dt);
+ target.set(t, s);
+ setWeight(s, c.weight);
+ j++;
+ }
+
+ // fill unused synapses
+ for (; j<maxSynapsesPerNeuron; j++) {
+ sp_t t = i * maxSynapsesPerNeuron + j;
+ target.set(t, Topology::nil()());
+ delay.set(t, Time(-666)); // HINT: this should raise an decreasing time error
+ }
+ }
+
+ // write topology via special ctor
+ { Topology(delay, target); }
+
+ // init unused synapse weight to inf to provoke errors
+ for (np_t i=0; i<maxNeurons; i++) {
+ while (currentSynapse[i] < maxSynapsesPerNeuron) {
+ setWeight(i * maxSynapsesPerNeuron + currentSynapse[i],
+ std::numeric_limits<Weight::type>::infinity());
+ currentSynapse[i]++;
+ }
+ }
+}
+
+void writeWeightSums() {
+ Topology t;
+ PropertyInstance<Weight, true> weights;
+ for (auto neuron : Ptr<Global>().childs()) {
+ SumWeight::type weightSum = 0;
+ for (auto synapse : neuron.childs()) {
+ Weight::type weight = weights.data.getValue(Time{0}, synapse());
+ if (weight > 0 and weight < std::numeric_limits<Weight::type>::infinity())
+ weightSum += weight;
+ }
+ PLA_Set<TargetSumWeight> s1{Time{0}, neuron, weightSum};
+ PLA_Set<SumWeight> s2{Time{0}, neuron, weightSum};
+ pc.call(s1); pc.call(s2);
+ }
+}
+
+int main() {
+ init();
+ read();
+ addPseudo();
+ writeTopology();
+ writeWeightSums();
+}
contact: Jan Huwald // Impressum