Cypress  1.0
C++ Spiking Neural Network Simulation Framework
connector.hpp
Go to the documentation of this file.
1 /*
2  * Cypress -- C++ Spiking Neural Network Simulation Framework
3  * Copyright (C) 2016 Andreas Stöckel
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #ifndef CYPRESS_CORE_CONNECTOR_HPP
22 #define CYPRESS_CORE_CONNECTOR_HPP
23 
24 #include <algorithm>
25 #include <memory>
26 #include <random>
27 #include <string>
28 #include <vector>
29 
31 #include <cypress/core/types.hpp>
33 
34 namespace cypress {
42 struct Synapse {
50 
55 
63  explicit Synapse(Real weight = 0.0, Real delay = 0.0)
64  : weight(weight), delay(delay)
65  {
66  }
67 
71  bool excitatory() const { return weight > 0.0; }
72 
76  bool inhibitory() const { return weight < 0.0; }
77 
82  bool valid() const { return (weight != 0.0) && (delay >= 0.0); }
83 };
84 
95 
100 
104  std::vector<Real> SynapseParameters;
105 
110  LocalConnection(uint32_t src = 0, uint32_t tar = 0, Real weight = 0.0,
111  Real delay = 0.0)
112  : src(src), tar(tar), SynapseParameters({weight, delay})
113  {
114  }
115  LocalConnection(uint32_t src, uint32_t tar, SynapseBase &synapse)
116  : src(src), tar(tar), SynapseParameters(synapse.parameters())
117  {
118  }
119 
123  bool valid() const
124  {
125  return (SynapseParameters[0] != 0.0) && (SynapseParameters[1] >= 0.0);
126  }
127 
131  bool excitatory() const { return SynapseParameters[0] > 0; }
132 
136  bool inhibitory() const { return SynapseParameters[0] < 0; }
137 
142  {
143  LocalConnection temp = *this;
144  temp.SynapseParameters[0] = std::abs(SynapseParameters[0]);
145  return temp;
146  }
147 
151  bool operator==(const LocalConnection &s) const
152  {
154  1 - uint32_t(valid()), 1 - uint32_t(s.valid()))(src, s.src)(
155  tar, s.tar)() &&
156  SynapseParameters == s.SynapseParameters;
157  }
158 
165  bool operator<(const LocalConnection &s) const
166  {
168  1 - uint32_t(valid()), 1 - uint32_t(s.valid()))(src, s.src)(
169  tar, s.tar)();
170  }
171 };
172 
173 /*
174  * Forward declarations.
175  */
177 class AllToAllConnector;
178 class OneToOneConnector;
179 class FromListConnector;
180 
181 template <typename Callback>
183 
184 template <typename Callback>
186 
187 template <typename RandomEngine>
189 
190 template <typename RandomEngine>
192 
193 template <typename RandomEngine>
195 
196 template <typename RandomEngine>
198 
212 class Connector {
213 protected:
217  std::shared_ptr<SynapseBase> m_synapse;
218 
222  std::vector<LocalConnection> m_weights;
223 
227  Real m_additional_parameter = 0.0;
228 
233  bool m_self_connections = true;
234 
240  bool m_seed_given = false;
241 
245  explicit Connector(SynapseBase &synapse, bool self_connections)
246  {
247  m_synapse = SynapseBase::make_shared(synapse);
248  m_self_connections = self_connections;
249  }
250  explicit Connector(std::shared_ptr<SynapseBase> synapse,
251  bool self_connections)
252  {
253  m_synapse = std::move(synapse);
254  m_self_connections = self_connections;
255  }
256  Connector(Real weight, Real delay, bool self_connections)
257  {
258  m_synapse =
259  std::make_shared<StaticSynapse>(StaticSynapse({weight, delay}));
260  m_self_connections = self_connections;
261  }
262 
263 public:
267  virtual ~Connector() = default;
268 
277  virtual void connect(const ConnectionDescriptor &descr,
278  std::vector<LocalConnection> &tar) const = 0;
279 
285  virtual bool valid(const ConnectionDescriptor &descr) const = 0;
286 
291  bool allow_self_connections() const { return m_self_connections; }
292 
293  Real additional_parameter() const { return m_additional_parameter; }
294 
303  virtual std::string name() const = 0;
304 
312  virtual size_t size(size_t size_src_pop, size_t size_target_pop) const = 0;
313 
318  const std::shared_ptr<SynapseBase> synapse() const { return m_synapse; }
319 
324  const std::string synapse_name() const { return m_synapse->name(); }
325 
330  const std::vector<LocalConnection> &learned_weights() const
331  {
332  if (!m_synapse->learning()) {
333  throw CypressException(
334  "Requested learned weights, although Synapse is static");
335  }
336  return m_weights;
337  }
338 
344  void _store_learned_weights(std::vector<LocalConnection> &&weights)
345  {
346  m_weights = std::move(weights);
347  }
348 
360  static std::unique_ptr<AllToAllConnector> all_to_all(
361  Real weight = 1.0, Real delay = 0.0,
362  bool allow_self_connections = true);
371  static std::unique_ptr<AllToAllConnector> all_to_all(
372  SynapseBase &synapse, bool allow_self_connections = true);
373 
383  static std::unique_ptr<OneToOneConnector> one_to_one(Real weight = 1.0,
384  Real delay = 0.0);
385 
392  static std::unique_ptr<OneToOneConnector> one_to_one(SynapseBase &synapse);
393 
401  static std::unique_ptr<FromListConnector> from_list(
402  const std::vector<LocalConnection> &connections);
403 
411  static std::unique_ptr<FromListConnector> from_list(
412  std::initializer_list<LocalConnection> connections);
413 
422  static std::unique_ptr<FromListConnector> from_list(
423  const std::vector<LocalConnection> &connections, SynapseBase &synapse);
424 
433  static std::unique_ptr<FromListConnector> from_list(
434  std::initializer_list<LocalConnection> connections,
435  SynapseBase &synapse);
436 
446  template <typename F>
447  static std::unique_ptr<FunctorConnector<F>> functor(const F &cback);
448 
462  template <typename F>
463  static std::unique_ptr<UniformFunctorConnector<F>> functor(
464  const F &cback, Real weight, Real delay = 0.0);
465 
475  static std::unique_ptr<
477  fixed_probability(std::unique_ptr<Connector> connector, Real p,
478  bool allow_self_connections = true);
479 
493  static std::unique_ptr<
495  fixed_probability(std::unique_ptr<Connector> connector, Real p, size_t seed,
496  bool allow_self_connections = true);
497 
511  static std::unique_ptr<RandomConnector<std::default_random_engine>> random(
512  Real weight = 1, Real delay = 0, Real probability = 1,
513  bool allow_self_connections = true);
514 
525  static std::unique_ptr<RandomConnector<std::default_random_engine>> random(
526  SynapseBase &synapse, Real probability = 1,
527  bool allow_self_connections = true);
528 
544  static std::unique_ptr<RandomConnector<std::default_random_engine>> random(
545  Real weight, Real delay, Real probability, size_t seed,
546  bool allow_self_connections = true);
547 
560  static std::unique_ptr<RandomConnector<std::default_random_engine>> random(
561  SynapseBase &synapse, Real probability, size_t seed,
562  bool allow_self_connections = true);
563 
576  static std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
577  fixed_fan_in(size_t n_fan_in, Real weight, Real delay = 0.0,
578  bool allow_self_connections = true);
579 
591  static std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
592  fixed_fan_in(size_t n_fan_in, SynapseBase &synapse,
593  bool allow_self_connections = true);
594 
610  static std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
611  fixed_fan_in(size_t n_fan_in, Real weight, Real delay, size_t seed,
612  bool allow_self_connections = true);
613 
628  static std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
629  fixed_fan_in(size_t n_fan_in, SynapseBase &synapse, size_t seed,
630  bool allow_self_connections = true);
631 
644  static std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
645  fixed_fan_out(size_t n_fan_out, Real weight, Real delay = 0.0,
646  bool allow_self_connections = true);
647 
659  static std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
660  fixed_fan_out(size_t n_fan_out, SynapseBase &synapse,
661  bool allow_self_connections = true);
662 
678  static std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
679  fixed_fan_out(size_t n_fan_out, Real weight, Real delay, size_t seed,
680  bool allow_self_connections = true);
681 
696  static std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
697  fixed_fan_out(size_t n_fan_out, SynapseBase &synapse, size_t seed,
698  bool allow_self_connections = true);
699 };
700 
706 private:
707  PopulationIndex m_pid_src;
708  NeuronIndex m_nid_src0;
709  NeuronIndex m_nid_src1;
710  PopulationIndex m_pid_tar;
711  NeuronIndex m_nid_tar0;
712  NeuronIndex m_nid_tar1;
713  std::shared_ptr<Connector> m_connector;
714  std::string m_label;
715 
716 public:
720  ConnectionDescriptor(uint32_t pid_src, uint32_t nid_src0, uint32_t nid_src1,
721  uint32_t pid_tar, uint32_t nid_tar0, uint32_t nid_tar1,
722  std::shared_ptr<Connector> connector = nullptr,
723  const char *label = "")
724  : m_pid_src(pid_src),
725  m_nid_src0(nid_src0),
726  m_nid_src1(nid_src1),
727  m_pid_tar(pid_tar),
728  m_nid_tar0(nid_tar0),
729  m_nid_tar1(nid_tar1),
730  m_connector(std::move(connector)),
731  m_label(std::string(label))
732  {
733  }
734 
738  PopulationIndex pid_src() const { return m_pid_src; }
739 
744  NeuronIndex nid_src0() const { return m_nid_src0; }
745 
750  NeuronIndex nid_src1() const { return m_nid_src1; }
751 
755  PopulationIndex pid_tar() const { return m_pid_tar; }
756 
761  NeuronIndex nid_tar0() const { return m_nid_tar0; }
762 
767  NeuronIndex nid_tar1() const { return m_nid_tar1; }
768 
773  Connector &connector() const { return *m_connector; }
774 
778  void update_connector(std::shared_ptr<Connector> connector)
779  {
780  m_connector = std::move(connector);
781  }
782 
790  void connect(std::vector<LocalConnection> &tar) const
791  {
792  connector().connect(*this, tar);
793  }
794 
798  bool valid() const { return m_connector && connector().valid(*this); }
799 
803  NeuronIndex nsrc() const { return m_nid_src1 - m_nid_src0; }
804 
808  NeuronIndex ntar() const { return m_nid_tar1 - m_nid_tar0; }
809 
814  bool operator==(const ConnectionDescriptor &s) const
815  {
816  return Comperator<uint32_t>::equals(m_pid_src, s.m_pid_src)(
817  m_pid_tar, s.m_pid_tar)(m_nid_src0, s.m_nid_src0)(
818  m_nid_src1, s.m_nid_src1)(m_nid_tar0, s.m_nid_tar0)(m_nid_tar1,
819  s.m_nid_tar1)();
820  }
821 
825  bool operator<(const ConnectionDescriptor &s) const
826  {
827  return Comperator<uint32_t>::smaller(m_pid_src, s.m_pid_src)(
828  m_pid_tar, s.m_pid_tar)(m_nid_src0, s.m_nid_src0)(
829  m_nid_src1, s.m_nid_src1)(m_nid_tar0, s.m_nid_tar0)(m_nid_tar1,
830  s.m_nid_tar1)();
831  }
832 
833  size_t size()
834  {
835  return connector().size(m_nid_src1 - m_nid_src0,
836  m_nid_tar1 - m_nid_tar0);
837  }
838 
844  const std::string &label() const { return m_label; }
845 };
846 
856 std::vector<std::vector<LocalConnection>> instantiate_connections(
857  const std::vector<ConnectionDescriptor> &descrs);
858 
860  std::string filename, const std::vector<ConnectionDescriptor> &descrs);
861 
865 class UniformConnector : public Connector {
866 public:
867  explicit UniformConnector(Real weight = 0.0, Real delay = 0.0,
868  bool self_connections = true)
869  : Connector(weight, delay, self_connections)
870  {
871  }
872  explicit UniformConnector(SynapseBase &synapse,
873  bool self_connections = true)
874  : Connector(synapse, self_connections)
875  {
876  }
877 };
878 
885 public:
887 
888  ~AllToAllConnector() override = default;
889 
890  void connect(const ConnectionDescriptor &descr,
891  std::vector<LocalConnection> &tar) const override;
892 
893  bool valid(const ConnectionDescriptor &) const override { return true; }
894 
895  size_t size(size_t size_src_pop, size_t size_target_pop) const override
896  {
897  return size_src_pop * size_target_pop;
898  }
899 
900  std::string name() const override { return "AllToAllConnector"; }
901 };
902 
908 public:
910 
911  ~OneToOneConnector() override = default;
912 
913  void connect(const ConnectionDescriptor &descr,
914  std::vector<LocalConnection> &tar) const override;
915 
916  bool valid(const ConnectionDescriptor &descr) const override
917  {
918  return descr.nsrc() == descr.ntar();
919  }
920 
921  size_t size(size_t size_src_pop, size_t) const override
922  {
923  return size_src_pop;
924  }
925 
926  std::string name() const override { return "OneToOneConnector"; }
927 };
928 
934 class FromListConnector : public Connector {
935 private:
936  std::vector<LocalConnection> m_connections;
937  void check_synapse()
938  {
939  if (m_connections.size() > 0 &&
940  m_synapse->parameter_names().size() !=
941  m_connections[0].SynapseParameters.size()) {
942  throw CypressException(
943  "Please provide an instance of the synapse type in the from "
944  "list connector!");
945  }
946  }
947 
948 public:
949  explicit FromListConnector(std::vector<LocalConnection> connections,
950  SynapseBase &synapse)
951  : Connector(synapse, true), m_connections(std::move(connections))
952  {
953  check_synapse();
954  }
955 
956  FromListConnector(std::initializer_list<LocalConnection> connections,
957  SynapseBase &synapse)
958  : Connector(synapse, true), m_connections(connections)
959  {
960  check_synapse();
961  }
962 
963  explicit FromListConnector(std::vector<LocalConnection> connections)
964  : Connector(0.0, 0.0, true), m_connections(std::move(connections))
965  {
966  check_synapse();
967  }
968 
969  FromListConnector(std::initializer_list<LocalConnection> connections)
970  : Connector(0.0, 0.0, true), m_connections(connections)
971  {
972  check_synapse();
973  }
974 
975  ~FromListConnector() override = default;
976 
977  void connect(const ConnectionDescriptor &descr,
978  std::vector<LocalConnection> &tar) const override;
979 
980  bool valid(const ConnectionDescriptor &) const override { return true; }
981 
982  size_t size(size_t, size_t) const override { return m_connections.size(); }
983 
984  std::string name() const override { return "FromListConnector"; }
985 
991  void update_learned_weights();
992 
993  std::vector<LocalConnection> &get_connections() { return m_connections; }
994 };
995 
997 protected:
998  FunctorConnectorBase() : Connector(0, 0, true) {}
999 
1000 public:
1001  std::string name() const override { return "FunctorConnector"; }
1002 };
1003 
1004 template <typename Callback>
1005 class FunctorConnector : public FunctorConnectorBase {
1006 private:
1007  Callback m_cback;
1008 
1009 public:
1010  explicit FunctorConnector(const Callback &cback) : m_cback(cback) {}
1011 
1012  ~FunctorConnector() override = default;
1013 
1014  void connect(const ConnectionDescriptor &descr,
1015  std::vector<LocalConnection> &tar) const override
1016  {
1017  for (NeuronIndex n_src = descr.nid_src0(); n_src < descr.nid_src1();
1018  n_src++) {
1019  for (NeuronIndex n_tar = descr.nid_tar0(); n_tar < descr.nid_tar1();
1020  n_tar++) {
1021  Synapse synapse = m_cback(n_src, n_tar);
1022  if (synapse.valid()) {
1023  tar.emplace_back(n_src, n_tar, synapse.weight,
1024  synapse.delay);
1025  }
1026  }
1027  }
1028  }
1029 
1030  bool valid(const ConnectionDescriptor &) const override { return true; }
1031 
1032  size_t size(size_t size_src_pop, size_t size_target_pop) const override
1033  {
1034  return size_src_pop * size_target_pop;
1035  }
1036 };
1037 
1039 public:
1041 
1042  std::string name() const override { return "UniformFunctorConnector"; }
1043 
1044  size_t size(size_t size_src_pop, size_t size_target_pop) const override
1045  {
1046  return size_src_pop * size_target_pop;
1047  }
1048 };
1049 
1050 template <typename Callback>
1052 private:
1053  Callback m_cback;
1054 
1055 public:
1056  explicit UniformFunctorConnector(const Callback &cback, Real weight = 0.0,
1057  Real delay = 0.0)
1058  : UniformFunctorConnectorBase(weight, delay, true), m_cback(cback)
1059  {
1060  }
1061  UniformFunctorConnector(const Callback &cback, SynapseBase &synapse)
1062  : UniformFunctorConnectorBase(synapse, true), m_cback(cback)
1063  {
1064  }
1065 
1066  ~UniformFunctorConnector() override = default;
1067 
1068  void connect(const ConnectionDescriptor &descr,
1069  std::vector<LocalConnection> &tar) const override
1070  {
1071  for (NeuronIndex n_src = descr.nid_src0(); n_src < descr.nid_src1();
1072  n_src++) {
1073  for (NeuronIndex n_tar = descr.nid_tar0(); n_tar < descr.nid_tar1();
1074  n_tar++) {
1075  if (m_cback(n_src, n_tar)) {
1076  tar.emplace_back(n_src, n_tar, *m_synapse);
1077  }
1078  }
1079  }
1080  }
1081 
1082  bool valid(const ConnectionDescriptor &) const override { return true; }
1083 };
1084 
1086 protected:
1087  std::string name_string = "FixedProbabilityConnector";
1088  FixedProbabilityConnectorBase(std::shared_ptr<SynapseBase> synapse,
1089  bool self_connections)
1090  : Connector(std::move(synapse), self_connections)
1091  {
1092  }
1093 
1094 public:
1095  std::string name() const override { return name_string; }
1096 
1101  void seed_given() { m_seed_given = true; }
1102 };
1103 
1104 template <typename RandomEngine>
1106 protected:
1107  std::unique_ptr<Connector> m_connector;
1108  std::shared_ptr<RandomEngine> m_engine;
1109 
1110 public:
1111  FixedProbabilityConnector(std::unique_ptr<Connector> connector, Real p,
1112  std::shared_ptr<RandomEngine> engine,
1113  bool self_connections)
1114  : FixedProbabilityConnectorBase(connector->synapse(), self_connections),
1115  m_connector(std::move(connector)),
1116  m_engine(std::move(engine))
1117  {
1118  m_additional_parameter = p;
1119  }
1120 
1121  ~FixedProbabilityConnector() override = default;
1122 
1123  void connect(const ConnectionDescriptor &descr,
1124  std::vector<LocalConnection> &tar) const override
1125  {
1126  const size_t first = tar.size(); // Old number of connections
1127  m_connector->connect(descr, tar); // Instantiate the connections
1128  std::uniform_real_distribution<Real> distr(0.0, 1.0);
1129  for (size_t i = first; i < tar.size(); i++) {
1130  if (distr(*m_engine) >= m_additional_parameter) {
1131  tar[i].SynapseParameters[0] = 0.0; // Invalidate the connection
1132  }
1133  }
1134 
1135  if ((!descr.connector().allow_self_connections()) &&
1136  descr.pid_src() == descr.pid_tar()) {
1137  for (size_t i = first; i < tar.size(); i++) {
1138  if (tar[i].src == tar[i].tar) {
1139  tar[i].SynapseParameters[0] =
1140  0.0; // Invalidate the connection
1141  }
1142  }
1143  }
1144  }
1145 
1146  bool valid(const ConnectionDescriptor &descr) const override
1147  {
1148  return m_connector->valid(descr);
1149  }
1150 
1151  size_t size(size_t size_src_pop, size_t size_target_pop) const override
1152  {
1153  return size_t(Real(size_src_pop * size_target_pop) *
1154  m_additional_parameter);
1155  }
1156 };
1157 
1162 template <typename RandomEngine>
1163 class RandomConnector : public FixedProbabilityConnector<RandomEngine> {
1164 private:
1166 
1167 public:
1169  std::shared_ptr<RandomEngine> engine, bool self_connections)
1170  : FixedProbabilityConnector<RandomEngine>(
1171  Connector::all_to_all(weight, delay), probability, engine,
1172  self_connections)
1173  {
1174  FixedProbabilityConnectorBase::name_string = "RandomConnector";
1175  }
1176  RandomConnector(SynapseBase &synapse, Real probability,
1177  std::shared_ptr<RandomEngine> engine, bool self_connections)
1178  : FixedProbabilityConnector<RandomEngine>(
1179  Connector::all_to_all(synapse), probability, engine,
1180  self_connections)
1181  {
1182  FixedProbabilityConnectorBase::name_string = "RandomConnector";
1183  }
1184 
1185  std::string name() const override { return "RandomConnector"; }
1186 };
1187 
1193 template <typename RandomEngine>
1195 private:
1196  std::shared_ptr<RandomEngine> m_engine;
1197 
1198 protected:
1199  template <typename F>
1200  void generate_connections(size_t offs, size_t len, size_t subset_len,
1201  size_t i0, size_t i1, const F &f, bool self) const
1202  {
1203  // Initialize a vector with the identity permutation
1204  std::vector<size_t> perm(len);
1205  for (size_t i = 0; i < len; i++) {
1206  perm[i] = offs + i;
1207  }
1208 
1209  // Iterate over each target neuron, create a new permutation containing
1210  // the source neuron indices and instantiate the connection
1211  std::uniform_int_distribution<size_t> distr(0, perm.size() - 1);
1212  for (size_t i = i0; i < i1; i++) {
1213  // Generate a new permutation for the first subset_len elements
1214  for (size_t j = 0; j < subset_len; j++) {
1215  std::swap(perm[j], perm[distr(*m_engine)]);
1216  }
1217  // Create the connections
1218  if (self) {
1219  for (size_t j = 0; j < subset_len; j++) {
1220  f(i, perm[j]);
1221  }
1222  }
1223  else {
1224  size_t sub_len = subset_len;
1225  for (size_t j = 0; j < sub_len; j++) {
1226  if (i != perm[j]) {
1227  f(i, perm[j]);
1228  }
1229  else {
1230  sub_len = std::min(sub_len + 1, perm.size());
1231  }
1232  }
1233  }
1234  }
1235  }
1236 
1237 public:
1239  std::shared_ptr<RandomEngine> engine,
1240  bool self_connections)
1241  : UniformConnector(weight, delay, self_connections),
1242  m_engine(std::move(engine))
1243  {
1244  }
1246  std::shared_ptr<RandomEngine> engine,
1247  bool self_connections)
1248  : UniformConnector(synapse, self_connections),
1249  m_engine(std::move(engine))
1250  {
1251  }
1252 
1257  void seed_given() { m_seed_given = true; }
1258 };
1259 
1264 template <typename RandomEngine>
1265 class FixedFanInConnector : public FixedFanConnectorBase<RandomEngine> {
1266 private:
1268 
1269 public:
1271  std::shared_ptr<RandomEngine> engine,
1272  bool self_connections)
1273  : FixedFanConnectorBase<RandomEngine>(weight, delay, std::move(engine),
1274  self_connections)
1275  {
1276  Base::m_additional_parameter = n_fan_in;
1277  }
1278  FixedFanInConnector(size_t n_fan_in, SynapseBase &synapse,
1279  std::shared_ptr<RandomEngine> engine,
1280  bool self_connections)
1281  : FixedFanConnectorBase<RandomEngine>(synapse, std::move(engine),
1282  self_connections)
1283  {
1284  Base::m_additional_parameter = n_fan_in;
1285  }
1286 
1287  ~FixedFanInConnector() override = default;
1288 
1289  void connect(const ConnectionDescriptor &descr,
1290  std::vector<LocalConnection> &tar) const override
1291  {
1292  if (descr.pid_src() == descr.pid_tar()) {
1293  Base::generate_connections(
1294  descr.nid_src0(), descr.nsrc(), Base::m_additional_parameter,
1295  descr.nid_tar0(), descr.nid_tar1(),
1296  [&](size_t i, size_t r) {
1297  tar.emplace_back(r, i, *this->m_synapse);
1298  },
1299  descr.connector().allow_self_connections());
1300  }
1301  else {
1302  Base::generate_connections(
1303  descr.nid_src0(), descr.nsrc(), Base::m_additional_parameter,
1304  descr.nid_tar0(), descr.nid_tar1(),
1305  [&](size_t i, size_t r) {
1306  tar.emplace_back(r, i, *this->m_synapse);
1307  },
1308  true);
1309  }
1310  }
1311 
1317  bool valid(const ConnectionDescriptor &descr) const override
1318  {
1319  return descr.nsrc() >= NeuronIndex(Base::m_additional_parameter);
1320  }
1321 
1322  std::string name() const override { return "FixedFanInConnector"; }
1323 
1324  size_t size(size_t, size_t size_target_pop) const override
1325  {
1326  return Base::m_additional_parameter * size_target_pop;
1327  }
1328 };
1329 
1334 template <typename RandomEngine>
1335 class FixedFanOutConnector : public FixedFanConnectorBase<RandomEngine> {
1336 private:
1338 
1339 public:
1341  std::shared_ptr<RandomEngine> engine,
1342  bool self_connections)
1343  : Base(weight, delay, std::move(engine), self_connections)
1344  {
1345  Base::m_additional_parameter = n_fan_out;
1346  }
1347 
1348  FixedFanOutConnector(size_t n_fan_out, SynapseBase &synapse,
1349  std::shared_ptr<RandomEngine> engine,
1350  bool self_connections)
1351  : Base(synapse, std::move(engine), self_connections)
1352  {
1353  Base::m_additional_parameter = n_fan_out;
1354  }
1355 
1356  ~FixedFanOutConnector() override = default;
1357 
1358  void connect(const ConnectionDescriptor &descr,
1359  std::vector<LocalConnection> &tar) const override
1360  {
1361  if (descr.pid_src() == descr.pid_tar()) {
1362  Base::generate_connections(
1363  descr.nid_tar0(), descr.ntar(), Base::m_additional_parameter,
1364  descr.nid_src0(), descr.nid_src1(),
1365  [&](size_t i, size_t r) {
1366  tar.emplace_back(i, r, *this->m_synapse);
1367  },
1368  descr.connector().allow_self_connections());
1369  }
1370  else {
1371  Base::generate_connections(
1372  descr.nid_tar0(), descr.ntar(), Base::m_additional_parameter,
1373  descr.nid_src0(), descr.nid_src1(),
1374  [&](size_t i, size_t r) {
1375  tar.emplace_back(i, r, *this->m_synapse);
1376  },
1377  true);
1378  }
1379  }
1380 
1386  bool valid(const ConnectionDescriptor &descr) const override
1387  {
1388  return descr.ntar() >= NeuronIndex(Base::m_additional_parameter);
1389  }
1390 
1391  std::string name() const override { return "FixedFanOutConnector"; }
1392 
1393  size_t size(size_t size_src_pop, size_t) const override
1394  {
1395  return size_src_pop * Base::m_additional_parameter;
1396  }
1397 };
1398 
1403 inline std::unique_ptr<AllToAllConnector> Connector::all_to_all(
1404  Real weight, Real delay, bool self_connections)
1405 {
1406  return std::make_unique<AllToAllConnector>(weight, delay, self_connections);
1407 }
1408 inline std::unique_ptr<AllToAllConnector> Connector::all_to_all(
1409  SynapseBase &synapse, bool self_connections)
1410 {
1411  return std::make_unique<AllToAllConnector>(synapse, self_connections);
1412 }
1413 
1414 inline std::unique_ptr<OneToOneConnector> Connector::one_to_one(Real weight,
1415  Real delay)
1416 {
1417  return std::make_unique<OneToOneConnector>(weight, delay);
1418 }
1419 inline std::unique_ptr<OneToOneConnector> Connector::one_to_one(
1420  SynapseBase &synapse)
1421 {
1422  return std::make_unique<OneToOneConnector>(synapse);
1423 }
1424 
1425 inline std::unique_ptr<FromListConnector> Connector::from_list(
1426  const std::vector<LocalConnection> &connections, SynapseBase &synapse)
1427 {
1428  return std::make_unique<FromListConnector>(connections, synapse);
1429 }
1430 
1431 inline std::unique_ptr<FromListConnector> Connector::from_list(
1432  std::initializer_list<LocalConnection> connections, SynapseBase &synapse)
1433 {
1434  return std::make_unique<FromListConnector>(connections, synapse);
1435 }
1436 
1437 inline std::unique_ptr<FromListConnector> Connector::from_list(
1438  const std::vector<LocalConnection> &connections)
1439 {
1440  return std::make_unique<FromListConnector>(connections);
1441 }
1442 
1443 inline std::unique_ptr<FromListConnector> Connector::from_list(
1444  std::initializer_list<LocalConnection> connections)
1445 {
1446  return std::make_unique<FromListConnector>(connections);
1447 }
1448 
1449 template <typename F>
1450 inline std::unique_ptr<FunctorConnector<F>> Connector::functor(const F &cback)
1451 {
1452  return std::make_unique<FunctorConnector<F>>(cback);
1453 }
1454 
1455 template <typename F>
1456 inline std::unique_ptr<UniformFunctorConnector<F>> Connector::functor(
1457  const F &cback, Real weight, Real delay)
1458 {
1459  return std::make_unique<UniformFunctorConnector<F>>(cback, weight, delay);
1460 }
1461 /*template <typename F>
1462 inline std::unique_ptr<UniformFunctorConnector<F>> Connector::functor(
1463  const F &cback, SynapseBase& synapse)
1464 {
1465  return std::make_unique<UniformFunctorConnector<F>>(cback, synapse);
1466 }*/
1467 
1468 inline std::unique_ptr<FixedProbabilityConnector<std::default_random_engine>>
1469 Connector::fixed_probability(std::unique_ptr<Connector> connector, Real p,
1470  bool self_connections)
1471 {
1472  return fixed_probability(std::move(connector), p, std::random_device()(),
1473  self_connections);
1474 }
1475 
1476 inline std::unique_ptr<FixedProbabilityConnector<std::default_random_engine>>
1477 Connector::fixed_probability(std::unique_ptr<Connector> connector, Real p,
1478  size_t seed, bool self_connections)
1479 {
1480  auto tmp =
1481  std::make_unique<FixedProbabilityConnector<std::default_random_engine>>(
1482  std::move(connector), p,
1483  std::make_shared<std::default_random_engine>(seed),
1484  self_connections);
1485  tmp->seed_given();
1486  return tmp;
1487 }
1488 
1489 inline std::unique_ptr<RandomConnector<std::default_random_engine>>
1491  bool self_connections)
1492 {
1493  return std::make_unique<RandomConnector<std::default_random_engine>>(
1494  weight, delay, probability,
1495  std::make_shared<std::default_random_engine>(std::random_device()()),
1496  self_connections);
1497 }
1498 
1499 inline std::unique_ptr<RandomConnector<std::default_random_engine>>
1500 Connector::random(SynapseBase &synapse, Real probability, bool self_connections)
1501 {
1502  return std::make_unique<RandomConnector<std::default_random_engine>>(
1503  synapse, probability,
1504  std::make_shared<std::default_random_engine>(std::random_device()()),
1505  self_connections);
1506 }
1507 
1508 inline std::unique_ptr<RandomConnector<std::default_random_engine>>
1509 Connector::random(Real weight, Real delay, Real probability, size_t seed,
1510  bool self_connections)
1511 {
1512  auto tmp = std::make_unique<RandomConnector<std::default_random_engine>>(
1513  weight, delay, probability,
1514  std::make_shared<std::default_random_engine>(seed), self_connections);
1515  tmp->seed_given();
1516  return tmp;
1517 }
1518 inline std::unique_ptr<RandomConnector<std::default_random_engine>>
1519 Connector::random(SynapseBase &synapse, Real probability, size_t seed,
1520  bool self_connections)
1521 {
1522  auto tmp = std::make_unique<RandomConnector<std::default_random_engine>>(
1523  synapse, probability,
1524  std::make_shared<std::default_random_engine>(seed), self_connections);
1525  tmp->seed_given();
1526  return tmp;
1527 }
1528 
1529 inline std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
1531  bool self_connections)
1532 {
1533 
1534  return std::make_unique<FixedFanInConnector<std::default_random_engine>>(
1535  n_fan_in, weight, delay,
1536  std::make_shared<std::default_random_engine>(std::random_device()()),
1537  self_connections);
1538 }
1539 inline std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
1540 Connector::fixed_fan_in(size_t n_fan_in, SynapseBase &synapse,
1541  bool self_connections)
1542 {
1543  return std::make_unique<FixedFanInConnector<std::default_random_engine>>(
1544  n_fan_in, synapse,
1545  std::make_shared<std::default_random_engine>(std::random_device()()),
1546  self_connections);
1547 }
1548 
1549 inline std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
1550 Connector::fixed_fan_in(size_t n_fan_in, Real weight, Real delay, size_t seed,
1551  bool self_connections)
1552 {
1553  auto tmp =
1554  std::make_unique<FixedFanInConnector<std::default_random_engine>>(
1555  n_fan_in, weight, delay,
1556  std::make_shared<std::default_random_engine>(seed),
1557  self_connections);
1558  tmp->seed_given();
1559  return tmp;
1560 }
1561 inline std::unique_ptr<FixedFanInConnector<std::default_random_engine>>
1562 Connector::fixed_fan_in(size_t n_fan_in, SynapseBase &synapse, size_t seed,
1563  bool self_connections)
1564 {
1565  auto tmp =
1566  std::make_unique<FixedFanInConnector<std::default_random_engine>>(
1567  n_fan_in, synapse,
1568  std::make_shared<std::default_random_engine>(seed),
1569  self_connections);
1570  tmp->seed_given();
1571  return tmp;
1572 }
1573 
1574 inline std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
1576  bool self_connections)
1577 {
1578  return std::make_unique<FixedFanOutConnector<std::default_random_engine>>(
1579  n_fan_out, weight, delay,
1580  std::make_shared<std::default_random_engine>(std::random_device()()),
1581  self_connections);
1582 }
1583 inline std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
1584 Connector::fixed_fan_out(size_t n_fan_out, SynapseBase &synapse,
1585  bool self_connections)
1586 {
1587  return std::make_unique<FixedFanOutConnector<std::default_random_engine>>(
1588  n_fan_out, synapse,
1589  std::make_shared<std::default_random_engine>(std::random_device()()),
1590  self_connections);
1591 }
1592 
1593 inline std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
1594 Connector::fixed_fan_out(size_t n_fan_out, Real weight, Real delay, size_t seed,
1595  bool self_connections)
1596 {
1597  auto tmp =
1598  std::make_unique<FixedFanOutConnector<std::default_random_engine>>(
1599  n_fan_out, weight, delay,
1600  std::make_shared<std::default_random_engine>(seed),
1601  self_connections);
1602  tmp->seed_given();
1603  return tmp;
1604 }
1605 inline std::unique_ptr<FixedFanOutConnector<std::default_random_engine>>
1606 Connector::fixed_fan_out(size_t n_fan_out, SynapseBase &synapse, size_t seed,
1607  bool self_connections)
1608 {
1609  auto tmp =
1610  std::make_unique<FixedFanOutConnector<std::default_random_engine>>(
1611  n_fan_out, synapse,
1612  std::make_shared<std::default_random_engine>(seed),
1613  self_connections);
1614  tmp->seed_given();
1615  return tmp;
1616 }
1617 } // namespace cypress
1618 
1619 #endif /* CYPRESS_CORE_CONNECTOR_HPP */
bool valid(const ConnectionDescriptor &) const override
Definition: connector.hpp:980
NeuronIndex nid_src0() const
Definition: connector.hpp:744
FixedProbabilityConnectorBase(std::shared_ptr< SynapseBase > synapse, bool self_connections)
Definition: connector.hpp:1088
void connect(const ConnectionDescriptor &descr, std::vector< LocalConnection > &tar) const override
Definition: connector.hpp:1358
bool valid(const ConnectionDescriptor &) const override
Definition: connector.hpp:1030
Definition: connector.hpp:212
std::string name() const override
Definition: connector.hpp:1095
Definition: connector.hpp:996
Connector(Real weight, Real delay, bool self_connections)
Definition: connector.hpp:256
Real weight
Definition: connector.hpp:49
Connector & connector() const
Definition: connector.hpp:773
bool operator<(const LocalConnection &s) const
Definition: connector.hpp:165
std::string name() const override
Definition: connector.hpp:1001
UniformFunctorConnector(const Callback &cback, Real weight=0.0, Real delay=0.0)
Definition: connector.hpp:1056
bool valid() const
Definition: connector.hpp:123
FixedFanConnectorBase(SynapseBase &synapse, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1245
static std::unique_ptr< FixedProbabilityConnector< std::default_random_engine > > fixed_probability(std::unique_ptr< Connector > connector, Real p, bool allow_self_connections=true)
Definition: connector.hpp:1469
Definition: connector.hpp:191
Definition: connector.hpp:1194
void update_connector(std::shared_ptr< Connector > connector)
Definition: connector.hpp:778
size_t size(size_t size_src_pop, size_t size_target_pop) const override
Definition: connector.hpp:895
std::string name() const override
Definition: connector.hpp:1322
int32_t NeuronIndex
Definition: types.hpp:74
const std::shared_ptr< SynapseBase > synapse() const
Definition: connector.hpp:318
void connect(const ConnectionDescriptor &descr, std::vector< LocalConnection > &tar) const override
Definition: connector.hpp:1123
Definition: connector.hpp:1038
static std::unique_ptr< FromListConnector > from_list(const std::vector< LocalConnection > &connections)
Definition: connector.hpp:1437
static std::unique_ptr< AllToAllConnector > all_to_all(Real weight=1.0, Real delay=0.0, bool allow_self_connections=true)
Definition: connector.hpp:1403
Synapse(Real weight=0.0, Real delay=0.0)
Definition: connector.hpp:63
bool instantiate_connections_to_file(std::string filename, const std::vector< ConnectionDescriptor > &descrs)
static std::unique_ptr< FixedFanOutConnector< std::default_random_engine > > fixed_fan_out(size_t n_fan_out, Real weight, Real delay=0.0, bool allow_self_connections=true)
Definition: connector.hpp:1575
const std::string synapse_name() const
Definition: connector.hpp:324
void seed_given()
Definition: connector.hpp:1101
bool valid(const ConnectionDescriptor &) const override
Definition: connector.hpp:893
bool operator==(const ConnectionDescriptor &s) const
Definition: connector.hpp:814
std::string name() const override
Definition: connector.hpp:900
bool valid(const ConnectionDescriptor &) const override
Definition: connector.hpp:1082
FunctorConnectorBase()
Definition: connector.hpp:998
FromListConnector(std::initializer_list< LocalConnection > connections)
Definition: connector.hpp:969
FromListConnector(std::vector< LocalConnection > connections)
Definition: connector.hpp:963
PopulationIndex pid_tar() const
Definition: connector.hpp:755
static std::unique_ptr< FixedFanInConnector< std::default_random_engine > > fixed_fan_in(size_t n_fan_in, Real weight, Real delay=0.0, bool allow_self_connections=true)
Definition: connector.hpp:1530
double Real
Definition: types.hpp:56
static std::unique_ptr< OneToOneConnector > one_to_one(Real weight=1.0, Real delay=0.0)
Definition: connector.hpp:1414
STL namespace.
Definition: synapses.hpp:71
PopulationIndex pid_src() const
Definition: connector.hpp:738
bool valid(const ConnectionDescriptor &descr) const override
Definition: connector.hpp:1386
void generate_connections(size_t offs, size_t len, size_t subset_len, size_t i0, size_t i1, const F &f, bool self) const
Definition: connector.hpp:1200
static auto equals(const T &t1, const T &t2)
Definition: comperator.hpp:116
std::vector< LocalConnection > & get_connections()
Definition: connector.hpp:993
void connect(const ConnectionDescriptor &descr, std::vector< LocalConnection > &tar) const override
Definition: connector.hpp:1068
FixedFanOutConnector(size_t n_fan_out, Real weight, Real delay, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1340
FromListConnector(std::initializer_list< LocalConnection > connections, SynapseBase &synapse)
Definition: connector.hpp:956
size_t size(size_t size_src_pop, size_t size_target_pop) const override
Definition: connector.hpp:1151
bool operator<(const ConnectionDescriptor &s) const
Definition: connector.hpp:825
size_t size(size_t size_src_pop, size_t) const override
Definition: connector.hpp:1393
Definition: connector.hpp:90
NeuronIndex src
Definition: connector.hpp:94
bool valid(const ConnectionDescriptor &descr) const override
Definition: connector.hpp:916
Connector(std::shared_ptr< SynapseBase > synapse, bool self_connections)
Definition: connector.hpp:250
ConnectionDescriptor(uint32_t pid_src, uint32_t nid_src0, uint32_t nid_src1, uint32_t pid_tar, uint32_t nid_tar0, uint32_t nid_tar1, std::shared_ptr< Connector > connector=nullptr, const char *label="")
Definition: connector.hpp:720
size_t size(size_t size_src_pop, size_t size_target_pop) const override
Definition: connector.hpp:1044
NeuronIndex ntar() const
Definition: connector.hpp:808
bool excitatory() const
Definition: connector.hpp:71
size_t size(size_t, size_t) const override
Definition: connector.hpp:982
size_t size(size_t size_src_pop, size_t) const override
Definition: connector.hpp:921
FixedFanInConnector(size_t n_fan_in, SynapseBase &synapse, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1278
UniformFunctorConnector(const Callback &cback, SynapseBase &synapse)
Definition: connector.hpp:1061
Real additional_parameter() const
Definition: connector.hpp:293
std::string name() const override
Definition: connector.hpp:926
void connect(const ConnectionDescriptor &descr, std::vector< LocalConnection > &tar) const override
Definition: connector.hpp:1014
RandomConnector(Real weight, Real delay, Real probability, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1168
bool allow_self_connections() const
Definition: connector.hpp:291
static auto smaller(const T &t1, const T &t2)
Definition: comperator.hpp:88
FixedFanOutConnector(size_t n_fan_out, SynapseBase &synapse, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1348
size_t size(size_t size_src_pop, size_t size_target_pop) const override
Definition: connector.hpp:1032
FunctorConnector(const Callback &cback)
Definition: connector.hpp:1010
std::string name() const override
Definition: connector.hpp:1185
static std::unique_ptr< RandomConnector< std::default_random_engine > > random(Real weight=1, Real delay=0, Real probability=1, bool allow_self_connections=true)
Definition: connector.hpp:1490
FromListConnector(std::vector< LocalConnection > connections, SynapseBase &synapse)
Definition: connector.hpp:949
size_t size()
Definition: connector.hpp:833
bool inhibitory() const
Definition: connector.hpp:136
bool valid(const ConnectionDescriptor &descr) const override
Definition: connector.hpp:1146
static std::unique_ptr< FunctorConnector< F > > functor(const F &cback)
Definition: connector.hpp:1450
LocalConnection(uint32_t src, uint32_t tar, SynapseBase &synapse)
Definition: connector.hpp:115
RandomConnector(SynapseBase &synapse, Real probability, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1176
Connector(SynapseBase &synapse, bool self_connections)
Definition: connector.hpp:245
Definition: connector.hpp:197
UniformConnector(SynapseBase &synapse, bool self_connections=true)
Definition: connector.hpp:872
NeuronIndex tar
Definition: connector.hpp:99
Real delay
Definition: connector.hpp:54
LocalConnection absolute_connection()
Definition: connector.hpp:141
NeuronIndex nsrc() const
Definition: connector.hpp:803
Definition: brainscales_lib.hpp:39
void connect(std::vector< LocalConnection > &tar) const
Definition: connector.hpp:790
Definition: connector.hpp:185
Definition: connector.hpp:188
std::string name() const override
Definition: connector.hpp:984
NeuronIndex nid_tar1() const
Definition: connector.hpp:767
bool operator==(const LocalConnection &s) const
Definition: connector.hpp:151
bool valid() const
Definition: connector.hpp:798
std::string name() const override
Definition: connector.hpp:1391
Definition: connector.hpp:907
std::string name() const override
Definition: connector.hpp:1042
static std::shared_ptr< SynapseBase > make_shared(SynapseBase &synapse)
LocalConnection(uint32_t src=0, uint32_t tar=0, Real weight=0.0, Real delay=0.0)
Definition: connector.hpp:110
const std::string & label() const
Definition: connector.hpp:844
bool inhibitory() const
Definition: connector.hpp:76
bool excitatory() const
Definition: connector.hpp:131
NeuronIndex nid_tar0() const
Definition: connector.hpp:761
std::string name_string
Definition: connector.hpp:1087
Definition: synapses.hpp:217
void connect(const ConnectionDescriptor &descr, std::vector< LocalConnection > &tar) const override
Definition: connector.hpp:1289
Definition: connector.hpp:182
void seed_given()
Definition: connector.hpp:1257
Definition: connector.hpp:705
int32_t PopulationIndex
Definition: types.hpp:75
std::unique_ptr< Connector > m_connector
Definition: connector.hpp:1107
Definition: exceptions.hpp:38
bool valid(const ConnectionDescriptor &descr) const override
Definition: connector.hpp:1317
NeuronIndex nid_src1() const
Definition: connector.hpp:750
std::shared_ptr< RandomEngine > m_engine
Definition: connector.hpp:1108
Definition: connector.hpp:194
FixedFanInConnector(size_t n_fan_in, Real weight, Real delay, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1270
Definition: connector.hpp:865
FixedProbabilityConnector(std::unique_ptr< Connector > connector, Real p, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1111
bool valid() const
Definition: connector.hpp:82
std::vector< std::vector< LocalConnection > > instantiate_connections(const std::vector< ConnectionDescriptor > &descrs)
UniformConnector(Real weight=0.0, Real delay=0.0, bool self_connections=true)
Definition: connector.hpp:867
const std::vector< LocalConnection > & learned_weights() const
Definition: connector.hpp:330
std::shared_ptr< SynapseBase > m_synapse
Definition: connector.hpp:217
FixedFanConnectorBase(Real weight, Real delay, std::shared_ptr< RandomEngine > engine, bool self_connections)
Definition: connector.hpp:1238
size_t size(size_t, size_t size_target_pop) const override
Definition: connector.hpp:1324
Definition: connector.hpp:934
Definition: connector.hpp:884
void _store_learned_weights(std::vector< LocalConnection > &&weights)
Definition: connector.hpp:344
Definition: connector.hpp:42
std::vector< LocalConnection > m_weights
Definition: connector.hpp:222
std::vector< Real > SynapseParameters
Definition: connector.hpp:104
Definition: connector.hpp:1085