Package geometry :: Package manifolds :: Module matrix_lie_group
[hide private]
[frames] | no frames]

Source Code for Module geometry.manifolds.matrix_lie_group

  1  from . import np, DifferentiableManifold, Group, contract 
  2  from .. import logm, expm 
  3  from contracts import new_contract 
4 5 6 -class MatrixLieGroup(Group, DifferentiableManifold):
7 ''' 8 This is the base class for matrix Lie groups. 9 10 Subclasses should provide a MatrixLieAlgebra 11 object. Given the Lie algebra, we can compute everything. 12 However, subclasses can choose to overload 13 some functions if they know a more numerically stable implementation. 14 15 ''' 16
17 - def __init__(self, n, dimension, algebra):
18 ''' 19 Initializes the Lie group. 20 21 :param n: dimension of the matrix group. 22 :param algebra: instance of :py:class:MatrixLieAlgebra 23 ''' 24 DifferentiableManifold.__init__(self, dimension=dimension) 25 self.n = n 26 self.algebra = algebra 27 assert self.algebra.n == self.n 28 29 from . import MatrixLieGroupTangent 30 self._tangent_bundle_algebra_rep = MatrixLieGroupTangent(self)
31
32 - def tangent_bundle(self):
33 return self._tangent_bundle_algebra_rep
34
35 - def get_algebra(self):
36 ''' Returns the interface to the corresponding Lie algebra. ''' 37 return self.algebra
38
39 - def unity(self):
40 return np.eye(self.n)
41 42 @contract(g='belongs', h='belongs')
43 - def multiply(self, g, h):
44 return np.dot(g, h)
45 46 @contract(g='belongs', returns='belongs')
47 - def inverse(self, g):
48 return np.linalg.inv(g)
49 50 @new_contract
51 - def belongs_algebra(self, x):
52 self.algebra.belongs(x)
53 54 @contract(bv='tuple(belongs, *)')
55 - def project_ts(self, bv):
56 ''' 57 Projects the vector *x* to the tangent space at point *base*. 58 59 In the case of Lie Groups, we do this by translating the 60 vector to the origin, projecting it to the Lie Algebra, 61 and then translating it back. 62 ''' 63 # get it to the origin 64 base, vel = bv 65 y = np.dot(self.inverse(base), vel) 66 # project it to the algebra 67 ty = self.algebra.project(y) 68 # get it back where it belonged 69 tty = np.dot(base, ty) 70 return base, tty
71 72 @contract(a='belongs', b='belongs')
73 - def distance(self, a, b):
74 ''' 75 Computes the distance between two points. 76 77 In the case of Lie groups, this is done by 78 translating everything to the origin, computing the 79 logmap, and using the norm defined in the Lie Algebra object. 80 81 ''' 82 x = self.multiply(a, self.inverse(b)) 83 xt = self.algebra_from_group(x) 84 return self.algebra.norm(xt)
85 86 @contract(base='belongs', target='belongs', returns='belongs_ts',)
87 - def logmap(self, base, target):
88 ''' 89 Returns the direction from base to target. 90 91 In the case of Lie groups, this is implemented 92 by using the usual matrix logarithm at the origin. 93 94 Here the :py:func:`MatrixLieAlgebra.project` function 95 is used to mitigate numerical errors. 96 ''' 97 diff = self.multiply(self.inverse(base), target) 98 X = self.algebra_from_group(diff) 99 bX = np.dot(base, X) 100 return (base, bX)
101 102 @contract(bv='belongs_ts', returns='belongs')
103 - def expmap(self, bv):
104 ''' 105 This is the inverse of :py:func:`logmap_`. 106 107 In the case of Lie groups, this is implemented using 108 the usual matrix exponential. 109 110 Here the :py:func:`MatrixLieAlgebra.project` function 111 is used to mitigate numerical errors. 112 ''' 113 base, vel = bv 114 tv = np.dot(self.inverse(base), vel) 115 tv = self.algebra.project(tv) 116 x = self.group_from_algebra(tv) 117 return np.dot(base, x)
118 119 @contract(g='belongs', returns='belongs_algebra')
120 - def algebra_from_group(self, g):
121 ''' 122 Converts an element of the group to the algebra. 123 Uses generic matrix logarithm plus projection. 124 ''' 125 X = np.array(logm(g).real) 126 # mitigate numerical errors 127 X = self.algebra.project(X) 128 return X
129 130 @contract(a='belongs_algebra', returns='belongs')
131 - def group_from_algebra(self, a):
132 ''' 133 Converts an element of the algebra to the group. 134 135 Uses generic matrix exponential. 136 ''' 137 return expm(a)
138 139 # TODO: write tests for this 140 @contract(a='belongs', b='belongs', returns='belongs_ts')
141 - def velocity_from_points(self, a, b, delta=1):
142 ''' 143 Find the velocity in local frame to go from *a* to *b* in 144 *delta* time. 145 ''' 146 x = self.multiply(self.inverse(a), b) 147 xt = self.algebra_from_group(x) 148 # xt = self.logmap(self.unity(), x) # XXX 149 # xt = self.algebra.project(xt) 150 return self.identity(), xt / delta
151