topogym 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topogym/__init__.py +31 -0
- topogym/benchmarks/__init__.py +300 -0
- topogym/core/__init__.py +43 -0
- topogym/core/basemap.py +563 -0
- topogym/core/constants.py +23 -0
- topogym/core/homology.py +382 -0
- topogym/core/metadata.py +126 -0
- topogym/envs/__init__.py +6 -0
- topogym/envs/core.py +267 -0
- topogym/envs/topo2d.py +149 -0
- topogym/envs/topo3d.py +147 -0
- topogym/generation/__init__.py +33 -0
- topogym/generation/config.py +103 -0
- topogym/generation/controls.py +99 -0
- topogym/generation/generator.py +1077 -0
- topogym/generation/graph.py +245 -0
- topogym/generation/shapes.py +193 -0
- topogym/rendering/__init__.py +1 -0
- topogym/rendering/rgb.py +89 -0
- topogym/rendering/svg.py +136 -0
- topogym-0.1.0.dist-info/METADATA +371 -0
- topogym-0.1.0.dist-info/RECORD +25 -0
- topogym-0.1.0.dist-info/WHEEL +5 -0
- topogym-0.1.0.dist-info/licenses/LICENSE +202 -0
- topogym-0.1.0.dist-info/top_level.txt +1 -0
topogym/__init__.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""TopoGym: environments and benchmarks for topological exploration in RL.
|
|
2
|
+
|
|
3
|
+
Quick start::
|
|
4
|
+
|
|
5
|
+
import gymnasium as gym
|
|
6
|
+
import topogym # registers the TopoGym/* env ids
|
|
7
|
+
|
|
8
|
+
env = gym.make("TopoGym/Grid2D-v0", base="torus", n_holes=3, layout_seed=7)
|
|
9
|
+
obs, info = env.reset(seed=0)
|
|
10
|
+
print(info["topology"]["betti_z2"]) # certified: [1, 6, 0]
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from gymnasium.envs.registration import register
|
|
14
|
+
|
|
15
|
+
from topogym.core.metadata import TopologyMetadata
|
|
16
|
+
from topogym.generation import TopoGenConfig2D, TopoGenConfig3D
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
19
|
+
__all__ = ["TopologyMetadata", "TopoGenConfig2D", "TopoGenConfig3D"]
|
|
20
|
+
|
|
21
|
+
register(
|
|
22
|
+
id="TopoGym/Grid2D-v0",
|
|
23
|
+
entry_point="topogym.envs:TopoGrid2DEnv",
|
|
24
|
+
)
|
|
25
|
+
register(
|
|
26
|
+
id="TopoGym/Grid3D-v0",
|
|
27
|
+
entry_point="topogym.envs:TopoGrid3DEnv",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Benchmark entries register their pinned env ids on import.
|
|
31
|
+
from topogym import benchmarks as _benchmarks # noqa: E402,F401
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"""Benchmark collections: frozen (config, layout_seed) suites.
|
|
2
|
+
|
|
3
|
+
Each entry pins a generator config and a layout seed, so every user runs
|
|
4
|
+
byte-identical environments. Entries are also registered as Gymnasium ids
|
|
5
|
+
(``TopoGym/<Collection>-<name>-v0``).
|
|
6
|
+
|
|
7
|
+
Collections
|
|
8
|
+
-----------
|
|
9
|
+
- ``2d_bench_grid_small``: 16 environments covering every 2D base manifold,
|
|
10
|
+
chambers/decoys, and two topologically-trivial controls.
|
|
11
|
+
- ``3d_bench_grid_small``: 8 environments covering the 3D bases, rings
|
|
12
|
+
(b1), voids (b2), rooms, and a 3D maze control.
|
|
13
|
+
- ``2d_bench_grid_small_directed`` / ``3d_bench_grid_small_directed``:
|
|
14
|
+
mirrored suites whose environments contain one-way doors and trapdoors
|
|
15
|
+
(trap rooms, airlocks, trapdoor rooms) — asymmetric traversability, see
|
|
16
|
+
the ``asymmetry`` metadata block.
|
|
17
|
+
|
|
18
|
+
Usage::
|
|
19
|
+
|
|
20
|
+
import topogym.benchmarks as bench
|
|
21
|
+
|
|
22
|
+
for entry in bench.get_benchmark("2d_bench_grid_small"):
|
|
23
|
+
env = entry.make()
|
|
24
|
+
obs, info = env.reset(seed=0)
|
|
25
|
+
print(entry.name, info["topology"]["betti_z2"])
|
|
26
|
+
|
|
27
|
+
rows = bench.benchmark_metadata("2d_bench_grid_small") # list of dicts
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
from dataclasses import dataclass
|
|
33
|
+
|
|
34
|
+
import gymnasium as gym
|
|
35
|
+
from gymnasium.envs.registration import register
|
|
36
|
+
|
|
37
|
+
from topogym.generation import TopoGenConfig2D, TopoGenConfig3D
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"BenchmarkEntry",
|
|
41
|
+
"BENCHMARKS",
|
|
42
|
+
"benchmark_names",
|
|
43
|
+
"get_benchmark",
|
|
44
|
+
"benchmark_metadata",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class BenchmarkEntry:
|
|
50
|
+
name: str
|
|
51
|
+
collection: str
|
|
52
|
+
env_id: str
|
|
53
|
+
dim: int
|
|
54
|
+
config: object # TopoGenConfig2D | TopoGenConfig3D
|
|
55
|
+
layout_seed: int
|
|
56
|
+
description: str
|
|
57
|
+
|
|
58
|
+
def make(self, **kwargs) -> gym.Env:
|
|
59
|
+
return gym.make(self.env_id, **kwargs)
|
|
60
|
+
|
|
61
|
+
def metadata(self):
|
|
62
|
+
"""Generate (or re-generate) the layout and return its certified
|
|
63
|
+
:class:`TopologyMetadata`."""
|
|
64
|
+
from topogym.generation import generate_2d, generate_3d
|
|
65
|
+
|
|
66
|
+
gen = generate_2d if self.dim == 2 else generate_3d
|
|
67
|
+
return gen(self.config, self.layout_seed).metadata
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _c2(**kw) -> TopoGenConfig2D:
|
|
71
|
+
return TopoGenConfig2D(**kw)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _c3(**kw) -> TopoGenConfig3D:
|
|
75
|
+
return TopoGenConfig3D(**kw)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
_RAW = {
|
|
79
|
+
"2d_bench_grid_small": [
|
|
80
|
+
("square-holes", 101, "3 holes on a disc: b1 = 3, nothing hidden",
|
|
81
|
+
_c2(base="square", size=15, n_holes=3, n_chambers=0, n_decoys=0)),
|
|
82
|
+
("square-rooms", 102, "holes + hidden chambers + a decoy",
|
|
83
|
+
_c2(base="square", size=17, n_holes=2, n_chambers=2, n_decoys=1)),
|
|
84
|
+
("square-decoyfield", 103,
|
|
85
|
+
"many identical-looking rooms; most are empty decoys",
|
|
86
|
+
_c2(base="square", size=21, n_holes=0, n_chambers=2, n_decoys=3,
|
|
87
|
+
door_tries=(3, 6))),
|
|
88
|
+
("annulus", 104, "thick annulus base + one chamber and one decoy",
|
|
89
|
+
_c2(base="annulus", size=19, n_holes=0, n_chambers=1, n_decoys=1)),
|
|
90
|
+
("plane-6holes", 105, "plane with 6 large holes: b1 = 6",
|
|
91
|
+
_c2(base="x_holes", size=21, n_base_holes=6, n_holes=0,
|
|
92
|
+
n_chambers=0, n_decoys=0)),
|
|
93
|
+
("cylinder-rooms", 106, "cylinder: one loop is the world itself",
|
|
94
|
+
_c2(base="cylinder", size=17, n_holes=1, n_chambers=1, n_decoys=1)),
|
|
95
|
+
("mobius-rooms", 107, "Mobius band: crossing the seam mirrors you",
|
|
96
|
+
_c2(base="mobius", size=17, n_holes=1, n_chambers=1, n_decoys=1)),
|
|
97
|
+
("torus-holes", 108, "torus with 2 holes: b1 = 3",
|
|
98
|
+
_c2(base="torus", size=15, n_holes=2, n_chambers=0, n_decoys=0)),
|
|
99
|
+
("torus-rooms", 109, "torus with chambers and a decoy",
|
|
100
|
+
_c2(base="torus", size=17, n_holes=1, n_chambers=2, n_decoys=1)),
|
|
101
|
+
("torus-goal-in-chamber", 110,
|
|
102
|
+
"the goal hides inside a chamber: doors must be found",
|
|
103
|
+
_c2(base="torus", size=17, n_holes=1, n_chambers=2, n_decoys=1,
|
|
104
|
+
goal_in_chamber=True, door_tries=(2, 4))),
|
|
105
|
+
("klein-rooms", 111, "Klein bottle: torus-like but non-orientable",
|
|
106
|
+
_c2(base="klein", size=17, n_holes=1, n_chambers=1, n_decoys=1)),
|
|
107
|
+
("rp2-rooms", 112, "RP^2: the antipodal world",
|
|
108
|
+
_c2(base="rp2", size=17, n_holes=1, n_chambers=1, n_decoys=1)),
|
|
109
|
+
("sphere-holes", 113, "cube-sphere with 3 holes",
|
|
110
|
+
_c2(base="sphere", size=7, n_holes=3, n_chambers=0, n_decoys=0)),
|
|
111
|
+
("sphere-rooms", 114, "cube-sphere with chambers and a decoy",
|
|
112
|
+
_c2(base="sphere", size=7, n_holes=1, n_chambers=1, n_decoys=1)),
|
|
113
|
+
("control-maze", 115,
|
|
114
|
+
"control: perfect maze, hard to explore, b1 = 0",
|
|
115
|
+
_c2(base="square", size=17, style="maze")),
|
|
116
|
+
("control-zigzag", 116,
|
|
117
|
+
"control: serpentine corridor, one long path, b1 = 0",
|
|
118
|
+
_c2(base="square", size=17, style="zigzag")),
|
|
119
|
+
],
|
|
120
|
+
"2d_bench_grid_small_directed": [
|
|
121
|
+
("square-traproom", 201, "a one-way room: enter and you stay",
|
|
122
|
+
_c2(base="square", size=19, n_holes=1, n_chambers=0, n_decoys=0,
|
|
123
|
+
n_trap_rooms=1)),
|
|
124
|
+
("square-airlock", 202, "a directed circuit: in one door, out the other",
|
|
125
|
+
_c2(base="square", size=19, n_holes=1, n_chambers=0, n_decoys=0,
|
|
126
|
+
n_airlocks=1)),
|
|
127
|
+
("square-trapdoor", 203,
|
|
128
|
+
"a trapdoor room: the way in seals, a hidden hatch leads out",
|
|
129
|
+
_c2(base="square", size=19, n_holes=1, n_chambers=0, n_decoys=0,
|
|
130
|
+
n_trapdoor_rooms=1, trapdoor_escape_tries=(3, 5))),
|
|
131
|
+
("cylinder-trapdoor", 204, "trapdoor room on a cylinder",
|
|
132
|
+
_c2(base="cylinder", size=19, n_holes=1, n_chambers=0, n_decoys=0,
|
|
133
|
+
n_trapdoor_rooms=1)),
|
|
134
|
+
("torus-traproom", 205, "trap room on a torus",
|
|
135
|
+
_c2(base="torus", size=19, n_holes=1, n_chambers=1, n_decoys=0,
|
|
136
|
+
n_trap_rooms=1)),
|
|
137
|
+
("torus-airlock-mix", 206, "airlock + trapdoor room on a torus",
|
|
138
|
+
_c2(base="torus", size=21, n_holes=1, n_chambers=0, n_decoys=1,
|
|
139
|
+
n_airlocks=1, n_trapdoor_rooms=1)),
|
|
140
|
+
("sphere-traproom", 207, "trap room on the cube-sphere",
|
|
141
|
+
_c2(base="sphere", size=7, n_holes=1, n_chambers=0, n_decoys=0,
|
|
142
|
+
n_trap_rooms=1)),
|
|
143
|
+
("square-gauntlet", 208,
|
|
144
|
+
"one of everything: trap room, airlock, trapdoor room, decoy",
|
|
145
|
+
_c2(base="square", size=25, n_holes=1, n_chambers=1, n_decoys=1,
|
|
146
|
+
n_trap_rooms=1, n_airlocks=1, n_trapdoor_rooms=1)),
|
|
147
|
+
],
|
|
148
|
+
"3d_bench_grid_small": [
|
|
149
|
+
("box-blobs", 301, "2 solid obstacles: b2 = 2 enclosing shells",
|
|
150
|
+
_c3(base="box", size=10, n_rings=0, n_blobs=2, n_chambers=0,
|
|
151
|
+
n_decoys=0)),
|
|
152
|
+
("box-ring", 302, "a ring obstacle: b1 = 1, b2 = 1",
|
|
153
|
+
_c3(base="box", size=10, n_rings=1, n_blobs=0, n_chambers=0,
|
|
154
|
+
n_decoys=0)),
|
|
155
|
+
("box-rooms", 303, "a hollow chamber and a sealed decoy",
|
|
156
|
+
_c3(base="box", size=12, n_rings=0, n_blobs=0, n_chambers=1,
|
|
157
|
+
n_decoys=1)),
|
|
158
|
+
("box-mixed", 304, "ring + void + chamber",
|
|
159
|
+
_c3(base="box", size=12, n_rings=1, n_blobs=1, n_chambers=1,
|
|
160
|
+
n_decoys=0)),
|
|
161
|
+
("solid-torus", 305, "solid torus: one loop is the world itself",
|
|
162
|
+
_c3(base="solid_torus", size=10, n_rings=1, n_blobs=1,
|
|
163
|
+
n_chambers=0, n_decoys=0)),
|
|
164
|
+
("torus3", 306, "3-torus: wraps in every direction, b1 = 3",
|
|
165
|
+
_c3(base="torus3", size=8, n_rings=0, n_blobs=1, n_chambers=0,
|
|
166
|
+
n_decoys=0)),
|
|
167
|
+
("shell", 307, "spherical shell: a big void you can never enter",
|
|
168
|
+
_c3(base="shell", size=10, n_rings=0, n_blobs=0, n_chambers=0,
|
|
169
|
+
n_decoys=0)),
|
|
170
|
+
("control-maze3d", 308, "control: perfect 3D maze, b1 = b2 = 0",
|
|
171
|
+
_c3(base="box", size=9, style="maze")),
|
|
172
|
+
],
|
|
173
|
+
"2d_bench_grid_small_bridges": [
|
|
174
|
+
("square-dumbbell", 501,
|
|
175
|
+
"two rooms, one narrow passage: b1 = 0, all bottleneck",
|
|
176
|
+
_c2(base="square", size=17, n_holes=0, n_chambers=0, n_decoys=0,
|
|
177
|
+
n_partitions=1, partition_gaps=(1, 1),
|
|
178
|
+
partition_hidden_gaps=(0, 0))),
|
|
179
|
+
("square-twin-passages", 502,
|
|
180
|
+
"two passages through one wall: the loop closure env",
|
|
181
|
+
_c2(base="square", size=17, n_holes=0, n_chambers=0, n_decoys=0,
|
|
182
|
+
n_partitions=1, partition_gaps=(2, 2),
|
|
183
|
+
partition_hidden_gaps=(0, 0))),
|
|
184
|
+
("square-moat-hidden", 503,
|
|
185
|
+
"a moat you can see across; one open bridge, one hidden",
|
|
186
|
+
_c2(base="square", size=19, n_holes=0, n_chambers=0, n_decoys=0,
|
|
187
|
+
n_partitions=1, partition_gaps=(2, 2),
|
|
188
|
+
partition_hidden_gaps=(1, 1), partition_material="moat",
|
|
189
|
+
door_tries=(2, 4))),
|
|
190
|
+
("square-triple-rooms", 504, "two dividing walls, three regions",
|
|
191
|
+
_c2(base="square", size=21, n_holes=0, n_chambers=0, n_decoys=0,
|
|
192
|
+
n_partitions=2, partition_gaps=(1, 2),
|
|
193
|
+
partition_hidden_gaps=(0, 1))),
|
|
194
|
+
("cylinder-ring-gate", 505, "a gate across the cylinder",
|
|
195
|
+
_c2(base="cylinder", size=17, n_holes=0, n_chambers=0, n_decoys=0,
|
|
196
|
+
n_partitions=1, partition_gaps=(1, 1),
|
|
197
|
+
partition_hidden_gaps=(0, 0))),
|
|
198
|
+
("torus-meridian", 506,
|
|
199
|
+
"a meridian wall on the torus: close the loop through the wrap",
|
|
200
|
+
_c2(base="torus", size=17, n_holes=1, n_chambers=0, n_decoys=0,
|
|
201
|
+
n_partitions=1, partition_gaps=(1, 1),
|
|
202
|
+
partition_hidden_gaps=(0, 0))),
|
|
203
|
+
("sphere-belt", 507, "an equatorial belt with two passages",
|
|
204
|
+
_c2(base="sphere", size=7, n_holes=0, n_chambers=0, n_decoys=0,
|
|
205
|
+
n_partitions=1, partition_gaps=(2, 2),
|
|
206
|
+
partition_hidden_gaps=(0, 0))),
|
|
207
|
+
("square-bridge-gauntlet", 508,
|
|
208
|
+
"a moat with a hidden bridge, plus a chamber and a decoy",
|
|
209
|
+
_c2(base="square", size=21, n_holes=0, n_chambers=1, n_decoys=1,
|
|
210
|
+
n_partitions=1, partition_gaps=(2, 2),
|
|
211
|
+
partition_hidden_gaps=(1, 1), partition_material="moat")),
|
|
212
|
+
],
|
|
213
|
+
"3d_bench_grid_small_bridges": [
|
|
214
|
+
("box-dumbbell", 601, "two chambers of space, one tunnel",
|
|
215
|
+
_c3(base="box", size=11, n_rings=0, n_blobs=0, n_chambers=0,
|
|
216
|
+
n_decoys=0, n_partitions=1, partition_gaps=(1, 1),
|
|
217
|
+
partition_hidden_gaps=(0, 0))),
|
|
218
|
+
("box-two-tunnels", 602, "two tunnels through one wall: b1 = 1",
|
|
219
|
+
_c3(base="box", size=11, n_rings=0, n_blobs=0, n_chambers=0,
|
|
220
|
+
n_decoys=0, n_partitions=1, partition_gaps=(2, 2),
|
|
221
|
+
partition_hidden_gaps=(0, 0))),
|
|
222
|
+
("box-hidden-tunnel", 603, "one tunnel open, one hidden",
|
|
223
|
+
_c3(base="box", size=11, n_rings=0, n_blobs=0, n_chambers=0,
|
|
224
|
+
n_decoys=0, n_partitions=1, partition_gaps=(2, 2),
|
|
225
|
+
partition_hidden_gaps=(1, 1), door_tries=(2, 4))),
|
|
226
|
+
("solid-torus-gate", 604,
|
|
227
|
+
"a gate disc across the solid torus: the wrap loop passes it",
|
|
228
|
+
_c3(base="solid_torus", size=11, n_rings=0, n_blobs=1,
|
|
229
|
+
n_chambers=0, n_decoys=0, n_partitions=1,
|
|
230
|
+
partition_gaps=(1, 1), partition_hidden_gaps=(0, 0))),
|
|
231
|
+
],
|
|
232
|
+
"3d_bench_grid_small_directed": [
|
|
233
|
+
("box-traproom", 401, "a one-way room in 3D",
|
|
234
|
+
_c3(base="box", size=12, n_rings=0, n_blobs=1, n_chambers=0,
|
|
235
|
+
n_decoys=0, n_trap_rooms=1)),
|
|
236
|
+
("box-airlock", 402, "a 3D airlock: directed circuit through a room",
|
|
237
|
+
_c3(base="box", size=12, n_rings=0, n_blobs=0, n_chambers=0,
|
|
238
|
+
n_decoys=0, n_airlocks=1)),
|
|
239
|
+
("box-trapdoor", 403, "3D trapdoor room with a hidden escape hatch",
|
|
240
|
+
_c3(base="box", size=12, n_rings=0, n_blobs=0, n_chambers=0,
|
|
241
|
+
n_decoys=0, n_trapdoor_rooms=1)),
|
|
242
|
+
("solid-torus-traproom", 404, "trap room in a solid torus",
|
|
243
|
+
_c3(base="solid_torus", size=12, n_rings=0, n_blobs=0,
|
|
244
|
+
n_chambers=0, n_decoys=0, n_trap_rooms=1)),
|
|
245
|
+
],
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
_COLLECTION_ID = {
|
|
249
|
+
"2d_bench_grid_small": "Bench2DSmall",
|
|
250
|
+
"2d_bench_grid_small_directed": "Bench2DSmallDirected",
|
|
251
|
+
"2d_bench_grid_small_bridges": "Bench2DSmallBridges",
|
|
252
|
+
"3d_bench_grid_small": "Bench3DSmall",
|
|
253
|
+
"3d_bench_grid_small_directed": "Bench3DSmallDirected",
|
|
254
|
+
"3d_bench_grid_small_bridges": "Bench3DSmallBridges",
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
BENCHMARKS = {}
|
|
258
|
+
for _coll, _entries in _RAW.items():
|
|
259
|
+
_out = []
|
|
260
|
+
for _name, _seed, _desc, _cfg in _entries:
|
|
261
|
+
_env_id = f"TopoGym/{_COLLECTION_ID[_coll]}-{_name}-v0"
|
|
262
|
+
_dim = 2 if isinstance(_cfg, TopoGenConfig2D) else 3
|
|
263
|
+
register(
|
|
264
|
+
id=_env_id,
|
|
265
|
+
entry_point=(
|
|
266
|
+
"topogym.envs:TopoGrid2DEnv" if _dim == 2
|
|
267
|
+
else "topogym.envs:TopoGrid3DEnv"
|
|
268
|
+
),
|
|
269
|
+
kwargs={"config": _cfg, "layout_seed": _seed},
|
|
270
|
+
)
|
|
271
|
+
_out.append(BenchmarkEntry(
|
|
272
|
+
name=_name, collection=_coll, env_id=_env_id, dim=_dim,
|
|
273
|
+
config=_cfg, layout_seed=_seed, description=_desc,
|
|
274
|
+
))
|
|
275
|
+
BENCHMARKS[_coll] = tuple(_out)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def benchmark_names():
|
|
279
|
+
return list(BENCHMARKS)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def get_benchmark(name: str):
|
|
283
|
+
if name not in BENCHMARKS:
|
|
284
|
+
raise KeyError(
|
|
285
|
+
f"unknown benchmark {name!r}; available: {benchmark_names()}"
|
|
286
|
+
)
|
|
287
|
+
return BENCHMARKS[name]
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def benchmark_metadata(name: str):
|
|
291
|
+
"""Certified metadata dicts for every entry — ready for sweeping
|
|
292
|
+
(each row includes the entry name and env id)."""
|
|
293
|
+
rows = []
|
|
294
|
+
for entry in get_benchmark(name):
|
|
295
|
+
row = entry.metadata().to_dict()
|
|
296
|
+
row["name"] = entry.name
|
|
297
|
+
row["env_id"] = entry.env_id
|
|
298
|
+
row["description"] = entry.description
|
|
299
|
+
rows.append(row)
|
|
300
|
+
return rows
|
topogym/core/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Core abstractions: base manifolds, cubical homology, metadata."""
|
|
2
|
+
|
|
3
|
+
from topogym.core import constants
|
|
4
|
+
from topogym.core.basemap import (
|
|
5
|
+
BASE_MAPS_2D,
|
|
6
|
+
BASE_MAPS_3D,
|
|
7
|
+
AgentState,
|
|
8
|
+
BaseMap2D,
|
|
9
|
+
BaseMapInfo,
|
|
10
|
+
Boundary,
|
|
11
|
+
CubeSphere2D,
|
|
12
|
+
RectGluing2D,
|
|
13
|
+
RectGluing3D,
|
|
14
|
+
make_base_map_2d,
|
|
15
|
+
make_base_map_3d,
|
|
16
|
+
)
|
|
17
|
+
from topogym.core.homology import (
|
|
18
|
+
Complex3DSummary,
|
|
19
|
+
Surface2DSummary,
|
|
20
|
+
analyze_2d,
|
|
21
|
+
analyze_3d,
|
|
22
|
+
gf2_rank,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"constants",
|
|
27
|
+
"AgentState",
|
|
28
|
+
"BaseMap2D",
|
|
29
|
+
"BaseMapInfo",
|
|
30
|
+
"Boundary",
|
|
31
|
+
"CubeSphere2D",
|
|
32
|
+
"RectGluing2D",
|
|
33
|
+
"RectGluing3D",
|
|
34
|
+
"BASE_MAPS_2D",
|
|
35
|
+
"BASE_MAPS_3D",
|
|
36
|
+
"make_base_map_2d",
|
|
37
|
+
"make_base_map_3d",
|
|
38
|
+
"Surface2DSummary",
|
|
39
|
+
"Complex3DSummary",
|
|
40
|
+
"analyze_2d",
|
|
41
|
+
"analyze_3d",
|
|
42
|
+
"gf2_rank",
|
|
43
|
+
]
|