Skip to content

Commit a8b293b

Browse files
authored
Merge pull request #245 from eric-wieser/bi_map
Deprecate a bunch of similar members of `Ga`
2 parents 635c92f + 9322ad0 commit a8b293b

File tree

4 files changed

+124
-39
lines changed

4 files changed

+124
-39
lines changed

doc/changelog.rst

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,28 @@
22
Changelog
33
=========
44

5-
- :support:`64` :attr:`galgebra.ga.Ga.indexes_lst`, :attr:`galgebra.ga.Ga.bases_lst`, :attr:`galgebra.ga.Ga.blades_lst`, and :attr:`galgebra.ga.Ga.mv_blades_lst` are deprecated in favor of the new :attr:`~galgebra.ga.GradedTuple.flat` attribute of :attr:`galgebra.ga.Ga.indexes`, :attr:`galgebra.ga.Ga.bases`, :attr:`galgebra.ga.Ga.blades`, and :attr:`galgebra.ga.Ga.mv_blades`.
6-
Since the new properties also include the scalar element, so ``ga.blades_lst`` is equivalent to ``ga.blades.flat[1:]`` (and likewise for the other two properties).
5+
- :support:`245` The following attributes have been deprecated to reduce the number of similar members in :class:`~galgebra.ga.Ga`.
6+
7+
* Unified into :attr:`galgebra.ga.Ga.indexes_to_bases_dict`:
8+
9+
* :attr:`galgebra.ga.Ga.indexes_to_bases` |rarr| ``indexes_to_bases_dict.items()``
10+
* :attr:`galgebra.ga.Ga.bases_to_indexes` |rarr| ``indexes_to_bases_dict.inverse.items()``
11+
* :attr:`galgebra.ga.Ga.bases_to_indexes_dict` |rarr| ``indexes_to_bases_dict.inverse``
12+
13+
* Unified into :attr:`galgebra.ga.Ga.indexes_to_bases_dict`:
14+
15+
* :attr:`galgebra.ga.Ga.indexes_to_blades` |rarr| ``indexes_to_blades_dict.items()``
16+
* :attr:`galgebra.ga.Ga.blades_to_indexes` |rarr| ``indexes_to_blades_dict.inverse.items()``
17+
* :attr:`galgebra.ga.Ga.blades_to_indexes_dict` |rarr| ``indexes_to_blades_dict.inverse``
18+
19+
- :support:`64` The following attributes have been deprecated in favor of using the new :attr:`~galgebra.ga.GradedTuple.flat` attribute:
20+
21+
* :attr:`galgebra.ga.Ga.indexes_lst` |rarr| :attr:`galgebra.ga.Ga.indexes` ``.flat``
22+
* :attr:`galgebra.ga.Ga.bases_lst` |rarr| :attr:`galgebra.ga.Ga.bases` ``.flat``
23+
* :attr:`galgebra.ga.Ga.blades_lst` |rarr| :attr:`galgebra.ga.Ga.blades` ``.flat``
24+
* :attr:`galgebra.ga.Ga.mv_blades_lst` |rarr| :attr:`galgebra.ga.Ga.mv_blades` ``.flat``
25+
26+
Since the replacement properties also include the scalar element, ``ga.blades_lst`` is equivalent to ``ga.blades.flat[1:]`` (and likewise for the other properties).
727

828
- :release:`0.4.5 <2019.12.31>`
929
- :support:`83` This is the last release to support Python 2.7.
@@ -144,3 +164,5 @@ Changelog
144164
- :support:`2` Clean up obsolete code in setup.py and make it simple
145165
- :bug:`2` Fixes `brombo/galgebra#19 <https://github.com/brombo/galgebra/issues/19>`_: Failures in `test_noneuclidian_distance_calculation`
146166
- :bug:`2` Fixes `brombo/galgebra#20 <https://github.com/brombo/galgebra/issues/20>`_: Incorrect LaTeX output in `test_derivatives_in_spherical_coordinates`
167+
168+
.. include:: <isonum.txt>

galgebra/ga.py

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from itertools import combinations
99
import functools
1010
from functools import reduce
11-
from typing import Tuple, TypeVar, Callable
11+
from typing import Tuple, TypeVar, Callable, Mapping
1212

1313
from sympy import (
1414
diff, Rational, Symbol, S, Mul, Add,
@@ -137,7 +137,7 @@ def nc_subs(expr, base_keys, base_values=None):
137137

138138

139139
_T = TypeVar('T')
140-
_U = TypeVar('T')
140+
_U = TypeVar('U')
141141

142142

143143
class GradedTuple(Tuple[Tuple[_T, ...], ...]):
@@ -170,6 +170,20 @@ def _map(self, func: Callable[[_T], _U]) -> 'GradedTuple[_U]':
170170
)
171171

172172

173+
class OrderedBiMap(OrderedDict, Mapping):
174+
""" A dict with an ``.inverse`` attribute mapping in the other direction """
175+
def __init__(self, items):
176+
# set up the inverse mapping, bypassing our __init__
177+
self.inverse = OrderedBiMap.__new__(type(self))
178+
179+
# populate both
180+
OrderedDict.__init__(self, items)
181+
OrderedDict.__init__(self.inverse, [(v, k) for k, v in items])
182+
183+
# and complete the inverse loop
184+
self.inverse.inverse = self
185+
186+
173187
class Ga(metric.Metric):
174188
r"""
175189
The vector space (basis, metric, derivatives of basis vectors) is
@@ -245,21 +259,17 @@ class Ga(metric.Metric):
245259
Linear combination of coordinates and basis vectors. For
246260
example in orthogonal 3D :math:`x*e_x+y*e_y+z*e_z`.
247261
248-
.. attribute:: blades_to_indexes_dict
249-
250-
Map basis blades to index tuples (dictionary).
251-
252262
.. attribute:: indexes_to_blades_dict
253263
254-
Map index tuples to basis blades (dictionary).
255-
256-
.. attribute:: bases_to_indexes_dict
264+
Bidirectional map from index tuples (:attr:`indices`) to basis blades (:attr:`blades`)
257265
258-
Map basis bases to index tuples (dictionary).
266+
:type: OrderedBiMap[Tuple[int, ...], sympy.Symbol]
259267
260268
.. attribute:: indexes_to_bases_dict
261269
262-
Map index tuples to basis bases (dictionary).
270+
Bidirectional map from index tuples (:attr:`indices`) to basis bases (:attr:`bases`)
271+
272+
:type: OrderedBiMap[Tuple[int, ...], sympy.Symbol]
263273
264274
.. rubric:: Multiplication tables data structures
265275
@@ -830,13 +840,7 @@ def _build_bases(self):
830840
self.blades = self.indexes._map(
831841
lambda index: self._build_basis_blade_symbol(index))
832842

833-
self.blades_to_indexes = []
834-
self.indexes_to_blades = []
835-
for index, blade in zip(self.indexes.flat, self.blades.flat):
836-
self.blades_to_indexes.append((blade, index))
837-
self.indexes_to_blades.append((index, blade))
838-
self.blades_to_indexes_dict = OrderedDict(self.blades_to_indexes)
839-
self.indexes_to_blades_dict = OrderedDict(self.indexes_to_blades)
843+
self.indexes_to_blades_dict = OrderedBiMap(list(zip(self.indexes.flat, self.blades.flat)))
840844

841845
self.blades_to_grades_dict = {
842846
blade: igrade
@@ -848,13 +852,7 @@ def _build_bases(self):
848852
self.bases = self.indexes._map(
849853
lambda index: self._build_basis_base_symbol(index))
850854

851-
self.bases_to_indexes = []
852-
self.indexes_to_bases = []
853-
for index, base in zip(self.indexes.flat, self.bases.flat):
854-
self.bases_to_indexes.append((base, index))
855-
self.indexes_to_bases.append((index, base))
856-
self.bases_to_indexes_dict = OrderedDict(self.bases_to_indexes)
857-
self.indexes_to_bases_dict = OrderedDict(self.indexes_to_bases)
855+
self.indexes_to_bases_dict = OrderedBiMap(list(zip(self.indexes.flat, self.bases.flat)))
858856

859857
self.bases_to_grades_dict = {
860858
base: igrade
@@ -879,13 +877,11 @@ def _build_bases(self):
879877
if self.debug:
880878
printer.oprint('indexes', self.indexes, 'list(indexes)', self.indexes.flat,
881879
'blades', self.blades, 'list(blades)', self.blades.flat,
882-
'blades_to_indexes_dict', self.blades_to_indexes_dict,
883880
'indexes_to_blades_dict', self.indexes_to_blades_dict,
884881
'blades_to_grades_dict', self.blades_to_grades_dict,
885882
'blade_super_scripts', self.blade_super_scripts)
886883
if not self.is_ortho:
887884
printer.oprint('bases', self.bases, 'list(bases)', self.bases.flat,
888-
'bases_to_indexes_dict', self.bases_to_indexes_dict,
889885
'indexes_to_bases_dict', self.indexes_to_bases_dict,
890886
'bases_to_grades_dict', self.bases_to_grades_dict)
891887

@@ -897,6 +893,54 @@ def _build_bases(self):
897893
for obj in self.basis
898894
)
899895

896+
@property
897+
def indexes_to_bases(self):
898+
# galgebra 0.5.0
899+
warnings.warn(
900+
"`ga.indexes_to_bases` is deprecated, use `ga.indexes_to_bases_dict.items()`",
901+
DeprecationWarning, stacklevel=2)
902+
return self.indexes_to_bases_dict.items()
903+
904+
@property
905+
def indexes_to_blades(self):
906+
# galgebra 0.5.0
907+
warnings.warn(
908+
"`ga.indexes_to_blades` is deprecated, use `ga.indexes_to_blades_dict.items()`",
909+
DeprecationWarning, stacklevel=2)
910+
return self.indexes_to_blades_dict.items()
911+
912+
@property
913+
def bases_to_indexes(self):
914+
# galgebra 0.5.0
915+
warnings.warn(
916+
"`ga.bases_to_indexes` is deprecated, use `ga.indexes_to_bases_dict.inverse.items()`",
917+
DeprecationWarning, stacklevel=2)
918+
return self.indexes_to_bases_dict.inverse.items()
919+
920+
@property
921+
def blades_to_indexes(self):
922+
# galgebra 0.5.0
923+
warnings.warn(
924+
"`ga.blades_to_indexes` is deprecated, use `ga.indexes_to_blades_dict.inverse.items()`",
925+
DeprecationWarning, stacklevel=2)
926+
return self.indexes_to_blades_dict.inverse.items()
927+
928+
@property
929+
def bases_to_indexes_dict(self):
930+
# galgebra 0.5.0
931+
warnings.warn(
932+
"`ga.bases_to_indexes_dict` is deprecated, use `ga.indexes_to_bases_dict.inverse.`",
933+
DeprecationWarning, stacklevel=2)
934+
return self.indexes_to_bases_dict.inverse
935+
936+
@property
937+
def blades_to_indexes_dict(self):
938+
# galgebra 0.5.0
939+
warnings.warn(
940+
"`ga.blades_to_indexes_dict` is deprecated, use `ga.indexes_to_blades_dict.inverse`",
941+
DeprecationWarning, stacklevel=2)
942+
return self.indexes_to_blades_dict.inverse
943+
900944
def _build_basis_product_tables(self):
901945
"""
902946
For the different products of geometric algebra bases/blade
@@ -954,8 +998,8 @@ def geometric_product_basis_blades(self, blade12):
954998
# geometric (*) product for orthogonal basis
955999
if self.is_ortho:
9561000
blade1, blade2 = blade12
957-
index1 = self.blades_to_indexes_dict[blade1]
958-
index2 = self.blades_to_indexes_dict[blade2]
1001+
index1 = self.indexes_to_blades_dict.inverse[blade1]
1002+
index2 = self.indexes_to_blades_dict.inverse[blade2]
9591003
blade_index = list(index1 + index2)
9601004
repeats = []
9611005
sgn = 1
@@ -1137,8 +1181,8 @@ def wedge_product_basis_blades(self, blade12): # blade12 = blade1*blade2
11371181
# outer (^) product of basis blades
11381182
# this method works for both orthogonal and non-orthogonal basis
11391183
blade1, blade2 = blade12
1140-
index1 = self.blades_to_indexes_dict[blade1]
1141-
index2 = self.blades_to_indexes_dict[blade2]
1184+
index1 = self.indexes_to_blades_dict.inverse[blade1]
1185+
index2 = self.indexes_to_blades_dict.inverse[blade2]
11421186
index12 = list(index1 + index2)
11431187

11441188
if len(index12) > self.n:
@@ -1177,8 +1221,8 @@ def dot_product_basis_blades(self, blade12, mode):
11771221
# dot (|), left (<), and right (>) products
11781222
# dot product for orthogonal basis
11791223
blade1, blade2 = blade12
1180-
index1 = self.blades_to_indexes_dict[blade1]
1181-
index2 = self.blades_to_indexes_dict[blade2]
1224+
index1 = self.indexes_to_blades_dict.inverse[blade1]
1225+
index2 = self.indexes_to_blades_dict.inverse[blade2]
11821226
index = list(index1 + index2)
11831227

11841228
grade = self._dot_product_grade(len(index1), len(index2), mode=mode)
@@ -1265,7 +1309,7 @@ def _build_non_orthogonal_mul_table(self):
12651309
def non_orthogonal_bases_products(self, base12): # base12 = (base1, base2)
12661310
# geometric product of bases for non-orthogonal basis vectors
12671311
base1, base2 = base12
1268-
index = self.bases_to_indexes_dict[base1] + self.bases_to_indexes_dict[base2]
1312+
index = self.indexes_to_bases_dict.inverse[base1] + self.indexes_to_bases_dict.inverse[base2]
12691313

12701314
coefs, indexes = self.reduce_basis(index)
12711315

@@ -1281,7 +1325,7 @@ def _build_base_blade_conversions(self):
12811325

12821326
# expand blade basis in terms of base basis
12831327
for blade in self.blades.flat:
1284-
index = self.blades_to_indexes_dict[blade]
1328+
index = self.indexes_to_blades_dict.inverse[blade]
12851329
grade = len(index)
12861330
if grade <= 1:
12871331
blade_expansion.append(blade)
@@ -1766,7 +1810,7 @@ def blade_derivation(self, blade, ib):
17661810
if key in self._dbases:
17671811
return self._dbases[key]
17681812

1769-
index = self.blades_to_indexes_dict[blade]
1813+
index = self.indexes_to_blades_dict.inverse[blade]
17701814
grade = len(index)
17711815
if grade == 1:
17721816
db = self.de[ib][index[0]]

galgebra/lt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ def __call__(self, v, obj=False):
277277
self.mv_dict = copy(self.lt_dict)
278278
for key in self.Ga.blades[2:]:
279279
for blade in key:
280-
index = self.Ga.blades_to_indexes_dict[blade]
280+
index = self.Ga.indexes_to_blades_dict.inverse[blade]
281281
lt_blade = self(self.Ga.basis[index[0]], obj=True)
282282
for i in index[1:]:
283283
lt_blade = self.Ga.wedge(lt_blade, self(self.Ga.basis[i], obj=True))

test/test_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,22 @@ def test_deprecations(self):
435435
assert ga.bases_lst[0] == e_1.obj
436436
with pytest.warns(DeprecationWarning):
437437
assert ga.indexes_lst[1] == (1,)
438+
439+
# deprecated to reduce the number of similar members
440+
with pytest.warns(DeprecationWarning):
441+
ga.blades_to_indexes
442+
with pytest.warns(DeprecationWarning):
443+
ga.bases_to_indexes
444+
with pytest.warns(DeprecationWarning):
445+
ga.blades_to_indexes_dict
446+
with pytest.warns(DeprecationWarning):
447+
ga.bases_to_indexes_dict
448+
with pytest.warns(DeprecationWarning):
449+
ga.indexes_to_blades
450+
with pytest.warns(DeprecationWarning):
451+
ga.indexes_to_bases
452+
453+
# all the above are deprecated in favor of these two, which are _not_
454+
# deprecated
455+
ga.indexes_to_blades_dict
456+
ga.indexes_to_bases_dict

0 commit comments

Comments
 (0)