1 from . import DifferentiableManifold
2
3 SYMBOL_ISOMORPHISM = '~'
4 SYMBOL_EMBEDDING = '<'
5 SYMBOL_PROJECTION = '>'
6
7
22
23
25 visited = set()
26
27 class AutoVivification(dict):
28 def __getitem__(self, item):
29 try:
30 return dict.__getitem__(self, item)
31 except KeyError:
32 value = self[item] = type(self)()
33 return value
34
35 isomorphisms = AutoVivification()
36 embeddings = AutoVivification()
37
38 def visit(m1):
39 if m1 in visited:
40 return
41 visited.add(m1)
42
43 for m2 in m1._isomorphisms:
44 isomorphisms[m1][m2] = [(m1, SYMBOL_ISOMORPHISM, m2)]
45
46 for m2 in m1._isomorphisms:
47 visit(m2)
48 for m3 in isomorphisms[m2]:
49 if not m3 in isomorphisms[m1] and m3 != m1:
50 isomorphisms[m1][m3] = (isomorphisms[m1][m2] +
51 isomorphisms[m2][m3])
52
53 for m2 in m1._embedding:
54 embeddings[m1][m2] = [(m1, SYMBOL_EMBEDDING, m2)]
55
56 for m2 in list(embeddings[m1].keys()):
57 visit(m2)
58 for m3 in embeddings[m2]:
59 if not m3 in embeddings[m1]:
60 embeddings[m1][m3] = (embeddings[m1][m2] +
61 embeddings[m2][m3])
62
63 for m2 in list(isomorphisms[m1].keys()):
64 visit(m2)
65 for m3 in embeddings[m2]:
66 if not m3 in embeddings[m1]:
67 embeddings[m1][m3] = (isomorphisms[m1][m2] +
68 embeddings[m2][m3])
69
70
71
72
73 for m1 in manifolds:
74 visit(m1)
75
76 return isomorphisms, embeddings
77
78
80 for m1 in isomorphisms:
81 for m2 in isomorphisms[m1]:
82 steps = isomorphisms[m1][m2]
83
84 m1_to_m2 = steps2function(steps)
85 m2_to_m1 = steps2function(reverse_steps(steps))
86 desc = str(steps)
87
88
89 if len(steps) == 1:
90 DifferentiableManifold.embedding(
91 m1, m2, m1_to_m2, m2_to_m1, itype='isomorphism',
92 steps=steps, desc=desc)
93 continue
94 DifferentiableManifold.isomorphism(
95 m1, m2, m1_to_m2, m2_to_m1, itype='derived',
96 steps=steps, desc=desc)
97
98
112
113
121 return [reverse_step(step) for step in reversed(steps)]
122
123
125 functions = []
126 for m1, operation, m2 in steps:
127 if operation == SYMBOL_EMBEDDING:
128 functions.append(m1._embedding[m2].A_to_B)
129 elif operation == SYMBOL_PROJECTION:
130 functions.append(m1._projection[m2].A_to_B)
131 elif operation == SYMBOL_ISOMORPHISM:
132 functions.append(m1._isomorphisms[m2].A_to_B)
133
134 if len(functions) == 1:
135 return functions[0]
136
137 def conversion(x):
138 try:
139 for f in functions:
140 x = f(x)
141 return x
142 except:
143 print('error during %s' % steps)
144 print(' functions %s' % functions)
145 raise
146
147 return conversion
148