Program Listing for File ToroidalTopologyFactory.hpp

Return to documentation for file (include/netuit/arrange/ToroidalTopologyFactory.hpp)

#pragma once
#ifndef NETUIT_ARRANGE_TOROIDALTOPOLOGYFACTORY_HPP_INCLUDE
#define NETUIT_ARRANGE_TOROIDALTOPOLOGYFACTORY_HPP_INCLUDE

#include <algorithm>
#include <cmath>
#include <list>
#include <numeric>
#include <tuple>

#include "../../../third-party/Empirical/source/base/vector.h"
#include "../../../third-party/Empirical/source/tools/tuple_utils.h"

#include "../topology/TopoEdge.hpp"
#include "../topology/Topology.hpp"
#include "../topology/TopoNode.hpp"

#include "uitsl/math/mapping_utils.hpp"
#include "uitsl/math/math_utils.hpp"
#include "uitsl/utility/UIDMap.hpp"

namespace netuit {

netuit::Topology make_toroidal_topology(const Dims& dim_cardinality) {
  /*
  * goal
  * make toroidal topology (such that opposite edges are the same edge)
  */
  const size_t cardinality = std::accumulate(
    dim_cardinality.begin(),
    dim_cardinality.end(),
    1,
    std::multiplies<size_t>()
  );

  emp::vector<netuit::TopoNode> nodes(cardinality);
  uitsl::UIDMap<size_t> node_edge_map;

  auto get_neighbor = [&dim_cardinality](Point p, const size_t dim, const int n) -> Point {
    p[dim] = uitsl::circular_index(p[dim], dim_cardinality[dim], n);
    return p;
  };

  // returns a vector containing all neighbors
  auto get_neighbors = [&get_neighbor](const Point& p) {
    emp::vector<Point> neighbors;

    for (size_t i = 0; i < p.size(); ++i) {
      neighbors.push_back(get_neighbor(p, i, +1));
      neighbors.push_back(get_neighbor(p, i, -1));
    }

    return neighbors;
  };

  for (auto it = nodes.begin(); it != nodes.end(); ++it) {
    const size_t my_id = std::distance(nodes.begin(), it);
    const auto n = uitsl::linear_decode(my_id, dim_cardinality);
    const auto neighbors = get_neighbors(n);
    for (const auto& neighbor : neighbors) {
      const auto neighbor_node = uitsl::linear_encode(neighbor, dim_cardinality);

      it->AddInput(node_edge_map[{false, neighbor_node, my_id}]);
      it->AddOutput(node_edge_map[{true, my_id, neighbor_node}]);
    }
  }
  return nodes;
}

struct ToroidalTopologyFactory {

  netuit::Topology operator()(const Dims& dim_cardinality) const {
    return make_toroidal_topology(dim_cardinality);
  }

  static std::string GetName() { return "Toroidal Topology"; }

  static std::string GetSlug() { return "toroidal"; }

};

} // namespace netuit

#endif // #ifndef NETUIT_ARRANGE_TOROIDALTOPOLOGYFACTORY_HPP_INCLUDE