Cypress  1.0
C++ Spiking Neural Network Simulation Framework
network_mixins.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 
28 #pragma once
29 
30 #ifndef CYPRESS_CORE_NETWORK_MIXINS_HPP
31 #define CYPRESS_CORE_NETWORK_MIXINS_HPP
32 
33 #include <algorithm>
34 #include <memory>
35 #include <iterator>
36 
40 #include <cypress/core/neurons.hpp>
41 #include <cypress/core/types.hpp>
43 
44 namespace cypress {
49 template <typename Impl, typename Accessor>
50 class PopulationMixin {
51 private:
52  Impl &impl() { return reinterpret_cast<Impl &>(*this); }
53  const Impl &impl() const { return reinterpret_cast<const Impl &>(*this); }
54 
55  NetworkBase network() const { return Accessor::network(impl()); }
56  PopulationIndex pid() const { return Accessor::pid(impl()); }
57  std::shared_ptr<PopulationData> data() const
58  {
59  return network().population_data(pid());
60  }
61 
62 public:
66  const std::string &name() const { return data()->name(); }
67 
72  Impl &name(const std::string &name)
73  {
74  data()->name() = name;
75  return impl();
76  }
77 
81  size_t size() const { return data()->size(); }
82 
87  {
88  return data()->homogeneous_parameters();
89  }
90 
94  bool homogeneous_record() const { return data()->homogeneous_record(); }
95 
99  bool homogeneous_data() const { return data()->homogeneous_data(); }
100 };
101 
102 template <typename Impl>
103 class NeuronMixin {
104 private:
105  Impl &impl() { return reinterpret_cast<Impl &>(*this); }
106  const Impl &impl() const { return reinterpret_cast<const Impl &>(*this); }
107 
108 public:
109  Impl *operator->() { return &impl(); }
110  const Impl *operator->() const { return &impl(); }
111  Impl &operator*() { return impl(); }
112  const Impl &operator*() const { return impl(); }
113 };
114 
118 template <typename Impl, typename Accessor>
119 class ConnectableMixin {
120 private:
121  Impl &impl() { return reinterpret_cast<Impl &>(*this); }
122  const Impl &impl() const { return reinterpret_cast<const Impl &>(*this); }
123 
124  auto network() const { return Accessor::network(impl()); }
125  PopulationIndex pid() const { return Accessor::pid(impl()); }
126  NeuronIndex i0() const { return Accessor::begin(impl()); }
127  NeuronIndex i1() const { return Accessor::end(impl()); }
128 
129 public:
142  template <typename TargetIterator>
143  Impl &connect_to(TargetIterator tar_begin, TargetIterator tar_end,
144  std::unique_ptr<Connector> connector, const char *name = "")
145  {
146  network().connect(pid(), i0(), i1(), tar_begin->pid(), tar_begin->nid(),
147  tar_end->nid(), std::move(connector), name);
148  return impl();
149  }
150 
160  template <typename Target>
161  Impl &connect_to(const Target &tar, std::unique_ptr<Connector> connector, const char *name = "")
162  {
163  return connect_to(tar.begin(), tar.end(), std::move(connector), name);
164  }
165 };
166 
171 template <typename Impl, typename Accessor, typename Params, typename Signals>
172 class DataMixin {
173 private:
174  Impl &impl() { return reinterpret_cast<Impl &>(*this); }
175  const Impl &impl() const { return reinterpret_cast<const Impl &>(*this); }
176 
177  auto network() const { return Accessor::network(impl()); }
178  PopulationIndex pid() const { return Accessor::pid(impl()); }
179  std::shared_ptr<PopulationData> data() const
180  {
181  return network().population_data(pid());
182  }
183  NeuronIndex i0() const { return Accessor::begin(impl()); }
184  NeuronIndex i1() const { return Accessor::end(impl()); }
185 
186 public:
187  template <typename Other>
188  bool operator==(const Other &o) const
189  {
190  return Comperator<int32_t>::equals(pid(), o.pid())(
191  i0(), o.begin()->nid())(i1(), o.end()->nid())();
192  }
193 
194  template <typename Other>
195  bool operator!=(const Other &o) const
196  {
197  return Comperator<int32_t>::inequal(pid(), o.pid())(
198  i0(), o.begin()->nid())(i1(), o.end()->nid())();
199  }
200 
201  template <typename Other>
202  bool operator<(const Other &o) const
203  {
204  return Comperator<int32_t>::smaller(pid(), o.pid())(
205  i0(), o.begin()->nid())(i1(), o.end()->nid())();
206  }
207 
208  template <typename Other>
209  bool operator<=(const Other &o) const
210  {
211  return Comperator<int32_t>::smaller_equals(pid(), o.pid())(
212  i0(), o.begin()->nid())(i1(), o.end()->nid())();
213  }
214 
215  template <typename Other>
216  bool operator>(const Other &o) const
217  {
218  return Comperator<int32_t>::larger(pid(), o.pid())(
219  i0(), o.begin()->nid())(i1(), o.end()->nid())();
220  }
221 
222  template <typename Other>
223  bool operator>=(const Other &o) const
224  {
225  return Comperator<int32_t>::larger_equals(pid(), o.pid())(
226  i0(), o.begin()->nid())(i1(), o.end()->nid())();
227  }
228 
232  const NeuronType &type() const { return *(data()->type()); }
233 
240  const Params parameters() const { return Params(data(), i0(), i1()); }
241 
247  Params parameters() { return Params(data(), i0(), i1()); }
248 
253  const Signals signals() const { return Signals(data(), i0(), i1()); }
254 
259  Signals signals() { return Signals(data(), i0(), i1()); }
260 };
261 
267 template <typename Impl, typename View, typename Accessor>
269 private:
270  Impl &impl() { return reinterpret_cast<Impl &>(*this); }
271  const Impl &impl() const { return reinterpret_cast<const Impl &>(*this); }
272 
273  auto network() const { return Accessor::network(impl()); }
274  PopulationIndex pid() const { return Accessor::pid(impl()); }
275  NeuronIndex i0() const { return Accessor::begin(impl()); }
276  NeuronIndex i1() const { return Accessor::end(impl()); }
277 
278 #ifndef NDEBUG
279 
282  void check_range(NeuronIndex nid0, NeuronIndex nid1) const
283  {
284  if (nid0 < i0() || nid1 > i1()) {
285  throw std::out_of_range(
286  "Range must be a subset of the source population range.");
287  }
288  }
289 #else
290  void check_range(NeuronIndex, NeuronIndex) const {}
291 #endif
292 
293 public:
304  const View range(NeuronIndex begin, NeuronIndex end) const
305  {
306  check_range(i0() + begin, i0() + end);
307  return View(network(), pid(), i0() + begin, i0() + end);
308  }
309 
320  View range(NeuronIndex begin, NeuronIndex end)
321  {
322  check_range(i0() + begin, i0() + end);
323  return View(network(), pid(), i0() + begin, i0() + end);
324  }
325 
336  const View operator()(NeuronIndex begin, NeuronIndex end) const
337  {
338  return range(begin, end);
339  }
340 
352  {
353  return range(begin, end);
354  }
355 };
356 
362 template <typename Impl, typename Value, typename Accessor>
364 public:
376  template <int Dir, bool Const>
377  class iterator_ : public std::iterator<std::random_access_iterator_tag,
378  Value, NeuronIndex, Value, Value> {
379  private:
383  using Self = iterator_<Dir, Const>;
384 
390  using ImplPtr =
391  typename std::conditional<Const, Impl const *, Impl *>::type;
392 
396  ImplPtr m_impl;
397 
401  NeuronIndex m_idx;
402 
403  public:
411  iterator_(ImplPtr impl, NeuronIndex idx) : m_impl(impl), m_idx(idx) {}
412 
416  operator iterator_<Dir, true>() const
417  {
418  return iterator_<Dir, true>(m_impl, m_idx);
419  }
420 
421  bool operator==(const Self &o) const { return m_idx == o.m_idx; }
422 
423  bool operator!=(const Self &o) const { return m_idx != o.m_idx; }
424 
425  bool operator<(const Self &o) const
426  {
427  return m_idx * Dir < o.m_idx * Dir;
428  }
429 
430  bool operator>(const Self &o) const
431  {
432  return m_idx * Dir > o.m_idx * Dir;
433  }
434 
435  bool operator<=(const Self &o) const
436  {
437  return m_idx * Dir <= o.m_idx * Dir;
438  }
439 
440  bool operator>=(const Self &o) const
441  {
442  return m_idx * Dir >= o.m_idx * Dir;
443  }
444 
445  Self operator+(NeuronIndex b) { return Self(m_impl, m_idx + b * Dir); }
446 
447  Self operator-(NeuronIndex b) { return Self(m_impl, m_idx - b * Dir); }
448 
449  NeuronIndex operator-(const Self &o) const
450  {
451  return (m_idx - o.m_idx) * Dir;
452  }
453 
455  {
456  m_idx += Dir;
457  return *this;
458  }
460  {
461  auto cpy = Self(m_impl, m_idx);
462  m_idx += Dir;
463  return cpy;
464  }
465 
467  {
468  m_idx -= Dir;
469  return *this;
470  }
471 
473  {
474  auto cpy = Self(m_impl, m_idx);
475  m_idx -= Dir;
476  return cpy;
477  }
478 
480  {
481  m_idx += n * Dir;
482  return *this;
483  }
484 
486  {
487  m_idx -= n * Dir;
488  return *this;
489  }
490 
491  template <typename U = Value,
492  typename = typename std::enable_if<!Const, U>::type>
493  Value operator*()
494  {
495  return Value(*m_impl, m_idx);
496  }
497 
498  template <typename U = Value,
499  typename = typename std::enable_if<!Const, U>::type>
500  Value operator->()
501  {
502  return Value(*m_impl, m_idx);
503  }
504 
505  template <typename U = Value,
506  typename = typename std::enable_if<!Const, U>::type>
508  {
509  return Value(*m_impl, m_idx + n * Dir);
510  }
511 
512  Value operator*() const { return Value(*m_impl, m_idx); }
513 
514  Value operator->() const { return Value(*m_impl, m_idx); }
515 
516  Value operator[](NeuronIndex n) const
517  {
518  return Value(*m_impl, m_idx + n * Dir);
519  }
520  };
521 
522 private:
523  Impl *impl() { return reinterpret_cast<Impl *>(this); }
524  const Impl *impl() const { return reinterpret_cast<const Impl *>(this); }
525 
526  NeuronIndex i0() const { return Accessor::begin(*impl()); }
527  NeuronIndex i1() const { return Accessor::end(*impl()); }
528  NeuronIndex ri0() const { return Accessor::end(*impl()) - 1; }
529  NeuronIndex ri1() const { return Accessor::begin(*impl()) - 1; }
530 
531 #ifndef NDEBUG
532 
535  void check_range(NeuronIndex nid0, NeuronIndex nid1) const
536  {
537  if (nid0 < i0() || nid1 > i1()) {
538  throw std::out_of_range(
539  "Range must be a subset of the source population range.");
540  }
541  }
542 #else
543  void check_range(NeuronIndex, NeuronIndex) const {}
544 #endif
545 
546 public:
547  using iterator = iterator_<1, false>;
548  using const_iterator = iterator_<1, true>;
549  using reverse_iterator = iterator_<-1, false>;
550  using const_reverse_iterator = iterator_<-1, true>;
551 
557  Value operator[](NeuronIndex i) { return Value(*impl(), i0() + i); }
558 
563  const Value operator[](NeuronIndex i) const
564  {
565  return Value(*impl(), i0() + i);
566  }
567 
573  Value operator()(NeuronIndex i) { return Value(*impl(), i0() + i); }
574 
579  const Value operator()(NeuronIndex i) const
580  {
581  return Value(*impl(), i0() + i);
582  }
583 
588  size_t size() { return i1() - i0(); }
589 
594  iterator begin() { return iterator(impl(), i0()); }
595 
599  iterator end() { return iterator(impl(), i1()); }
600 
601  reverse_iterator rbegin() { return reverse_iterator(impl(), ri0()); }
602 
603  reverse_iterator rend() { return reverse_iterator(impl(), ri1()); }
604 
605  const_iterator begin() const { return cbegin(); }
606 
607  const_iterator end() const { return cend(); }
608 
609  const_reverse_iterator rbegin() const { return crbegin(); }
610 
611  const_reverse_iterator rend() const { return crend(); }
612 
613  const_iterator cbegin() const { return const_iterator(impl(), i0()); }
614 
615  const_iterator cend() const { return const_iterator(impl(), i1()); }
616 
618  {
619  return const_reverse_iterator(impl(), ri0());
620  }
621 
623  {
624  return const_reverse_iterator(impl(), ri1());
625  }
626 };
627 }
628 
629 #endif /* CYPRESS_CORE_NETWORK_MIXINS_HPP */
Definition: neurons_base.hpp:54
bool operator>(const Self &o) const
Definition: network_mixins.hpp:430
NeuronIndex operator-(const Self &o) const
Definition: network_mixins.hpp:449
bool operator>=(const Other &o) const
Definition: network_mixins.hpp:223
bool operator<=(const Self &o) const
Definition: network_mixins.hpp:435
static auto smaller_equals(const T &t1, const T &t2)
Definition: comperator.hpp:95
Value operator()(NeuronIndex i)
Definition: network_mixins.hpp:573
Definition: network_base.hpp:67
static PopulationIndex pid(const PopulationBase &pop)
Definition: network_base_objects.hpp:244
iterator end()
Definition: network_mixins.hpp:599
int32_t NeuronIndex
Definition: types.hpp:74
Self operator-(NeuronIndex b)
Definition: network_mixins.hpp:447
std::shared_ptr< PopulationData > population_data(PopulationIndex pid)
Self & operator+=(NeuronIndex n)
Definition: network_mixins.hpp:479
Self operator--(int)
Definition: network_mixins.hpp:472
reverse_iterator rend()
Definition: network_mixins.hpp:603
constexpr Range< size_t > range(ptrdiff_t i)
Definition: range.hpp:85
iterator begin()
Definition: network_mixins.hpp:594
const_iterator cbegin() const
Definition: network_mixins.hpp:613
bool operator<(const Other &o) const
Definition: network_mixins.hpp:202
const Impl * operator->() const
Definition: network_mixins.hpp:110
static auto larger(const T &t1, const T &t2)
Definition: comperator.hpp:102
Definition: network_mixins.hpp:377
bool operator>(const Other &o) const
Definition: network_mixins.hpp:216
Definition: network_base.hpp:70
size_t size()
Definition: network_mixins.hpp:588
const_reverse_iterator rend() const
Definition: network_mixins.hpp:611
const Signals signals() const
Definition: network_mixins.hpp:253
const_reverse_iterator rbegin() const
Definition: network_mixins.hpp:609
Impl & name(const std::string &name)
Definition: network_mixins.hpp:72
const Value operator[](NeuronIndex i) const
Definition: network_mixins.hpp:563
Params parameters()
Definition: network_mixins.hpp:247
static auto equals(const T &t1, const T &t2)
Definition: comperator.hpp:116
Value operator[](NeuronIndex i)
Definition: network_mixins.hpp:557
Self & operator--()
Definition: network_mixins.hpp:466
Definition: network_mixins.hpp:103
Value operator*() const
Definition: network_mixins.hpp:512
static NeuronIndex end(const PopulationBase &pop)
Definition: network_base_objects.hpp:243
iterator_< 1, false > iterator
Definition: network_mixins.hpp:547
Impl & connect_to(TargetIterator tar_begin, TargetIterator tar_end, std::unique_ptr< Connector > connector, const char *name="")
Definition: network_mixins.hpp:143
bool operator==(const Self &o) const
Definition: network_mixins.hpp:421
const NeuronType & type() const
Definition: network_mixins.hpp:232
const_iterator cend() const
Definition: network_mixins.hpp:615
Value operator->()
Definition: network_mixins.hpp:500
Self operator++(int)
Definition: network_mixins.hpp:459
bool operator!=(const Self &o) const
Definition: network_mixins.hpp:423
Value operator[](NeuronIndex n) const
Definition: network_mixins.hpp:516
static auto smaller(const T &t1, const T &t2)
Definition: comperator.hpp:88
size_t size() const
Definition: network_mixins.hpp:81
bool operator<(const Self &o) const
Definition: network_mixins.hpp:425
iterator_< 1, true > const_iterator
Definition: network_mixins.hpp:548
bool operator>=(const Self &o) const
Definition: network_mixins.hpp:440
Self & operator-=(NeuronIndex n)
Definition: network_mixins.hpp:485
const Params parameters() const
Definition: network_mixins.hpp:240
bool operator!=(const Other &o) const
Definition: network_mixins.hpp:195
const View range(NeuronIndex begin, NeuronIndex end) const
Definition: network_mixins.hpp:304
Impl * operator->()
Definition: network_mixins.hpp:109
bool operator<=(const Other &o) const
Definition: network_mixins.hpp:209
View operator()(NeuronIndex begin, NeuronIndex end)
Definition: network_mixins.hpp:351
Self & operator++()
Definition: network_mixins.hpp:454
static NeuronIndex begin(const PopulationBase &)
Definition: network_base_objects.hpp:242
Value operator[](NeuronIndex n)
Definition: network_mixins.hpp:507
Definition: brainscales_lib.hpp:39
const std::string & name() const
Definition: network_mixins.hpp:66
Signals signals()
Definition: network_mixins.hpp:259
const Value operator()(NeuronIndex i) const
Definition: network_mixins.hpp:579
const_reverse_iterator crend() const
Definition: network_mixins.hpp:622
Definition: network_mixins.hpp:363
const View operator()(NeuronIndex begin, NeuronIndex end) const
Definition: network_mixins.hpp:336
const_reverse_iterator crbegin() const
Definition: network_mixins.hpp:617
const Impl & operator*() const
Definition: network_mixins.hpp:112
Self operator+(NeuronIndex b)
Definition: network_mixins.hpp:445
Impl & operator*()
Definition: network_mixins.hpp:111
reverse_iterator rbegin()
Definition: network_mixins.hpp:601
bool homogeneous_data() const
Definition: network_mixins.hpp:99
Definition: network_mixins.hpp:268
const_iterator end() const
Definition: network_mixins.hpp:607
View range(NeuronIndex begin, NeuronIndex end)
Definition: network_mixins.hpp:320
bool homogeneous_record() const
Definition: network_mixins.hpp:94
Value operator*()
Definition: network_mixins.hpp:493
int32_t PopulationIndex
Definition: types.hpp:75
Impl & connect_to(const Target &tar, std::unique_ptr< Connector > connector, const char *name="")
Definition: network_mixins.hpp:161
const_iterator begin() const
Definition: network_mixins.hpp:605
Value operator->() const
Definition: network_mixins.hpp:514
static auto inequal(const T &t1, const T &t2)
Definition: comperator.hpp:123
static NetworkBase network(const PopulationBase &pop)
Definition: network_base_objects.hpp:245
iterator_(ImplPtr impl, NeuronIndex idx)
Definition: network_mixins.hpp:411
static auto larger_equals(const T &t1, const T &t2)
Definition: comperator.hpp:109
iterator_<-1, false > reverse_iterator
Definition: network_mixins.hpp:549
bool operator==(const Other &o) const
Definition: network_mixins.hpp:188
iterator_<-1, true > const_reverse_iterator
Definition: network_mixins.hpp:550
bool homogeneous_parameters() const
Definition: network_mixins.hpp:86