The Tangent Space on the Rotation Group edit page

The tangent space of the rotation group at some rotation \(R\) has 2 different representations. There is a left and a right representation.

The left tangent space is defined by

\[ T_R SO(3) = \{ S \cdot R | S=-S^T \} = \mathfrak{so}(3) \cdot R, \]

where \(\mathfrak{so}(3)\) describes the set of all skew symmetric matrices, i.e. spinTensor's.

R = rotation.byAxisAngle(xvector,20*degree)
S1 = spinTensor(vector3d(0,0,1))
% left tangent vector
matrix(S1) * matrix(R)
R = rotation
 
  Bunge Euler angles in degree
  phi1  Phi phi2
     0   20    0
 
 
S1 = spinTensor (xyz)
  rank: 2 (3 x 3)
 
  0 -1  0
  1  0  0
  0  0  0
ans =
         0   -0.9397    0.3420
    1.0000         0         0
         0         0         0

Analogously the right tangent space is defined by

\[ T_R SO(3) = \{ R \cdot S | S=-S^T \} = R \cdot \mathfrak{so}(3). \]

% right tangent vector
S2 = spinTensor(vector3d(0,sin(20*degree),cos(20*degree)))
matrix(R)*matrix(S2)
S2 = spinTensor (xyz)
  rank: 2 (3 x 3)
 
 *10^-2
      0 -93.97   34.2
  93.97      0      0
  -34.2      0      0
ans =
         0   -0.9397    0.3420
    1.0000         0         0
    0.0000         0         0

Note that the left and right tangent spaces describes the same in different notations.

In MTEX a tangent vectors is defined by its spinTensor and an attribute which describes whether it is right or left. Moreover the spinTensor is saved as vector3d, in the following way:

vL = SO3TangentVector(vector3d(1,2,3))
S = spinTensor(vL)
vL = SO3TangentVector
 TagentSpace: leftVector
  x y z
  1 2 3
 
S = spinTensor (xyz)
  rank: 2 (3 x 3)
 
  0 -3  2
  3  0 -1
 -2  1  0

Note that the default tangent space representation is left. We can construct an right tangent vector by

vR = SO3TangentVector(vector3d(1,2,3),SO3TangentSpace.rightVector)
vR = SO3TangentVector
 TagentSpace: rightVector
  x y z
  1 2 3

Here vL and vR have the same coordinates in different spaces (bases). Hence they describe different tangent vectors.

We can also transform left tangent vectors to right tangent vectors and vice versa. Therefore the rotation in which the tangent space is located is necessary.

vR = right(vL,R)
vL = left(vR,R)
vR = SO3TangentVector
 TagentSpace: rightVector
  x       y       z
  1 2.90545 2.13504
 
vL = SO3TangentVector
 TagentSpace: leftVector
  x y z
  1 2 3

We can do the same manually by

vR = inv(R)*vL
vL = R*vR
vR = vector3d
  x       y       z
  1 2.90545 2.13504
 
vL = vector3d
  x y z
  1 2 3

Vector Fields

Vector fields on the rotation group are functions that maps any rotation to an tangent vector. An important example is the gradient of an SO3Fun.

Hence any vector field has again a left and a right representation.

F = SO3Fun.dubna;
F.SS = specimenSymmetry;
%F = SO3FunHarmonic(F);
rot = rotation.rand(3);

% left gradient in rot
F.grad(rot)

% right gradient in rot
inv(rot) .* F.grad(rot)
F.grad(rot,'right')
ans = SO3TangentVector
 size: 3 x 1
 TagentSpace: leftVector
            x           y           z
  -0.00694584    0.503131  -0.0799776
     0.655921   -0.377658    0.828691
     -0.39319     1.05834    0.410658
 
ans = vector3d
 size: 3 x 1
         x         y         z
  0.038185 -0.200677  0.466751
  -1.03827 -0.255617   0.34094
  0.716779 -0.282973  0.921665
 
ans = SO3TangentVector
 size: 3 x 1
 TagentSpace: rightVector
         x         y         z
  0.038185 -0.200677  0.466751
  -1.03827 -0.255617   0.34094
  0.716779 -0.282973  0.921665

The gradient can also be computed as function, i.e. as SO3VectorField, which internal is an 3 dimensional SO3Fun.

GL = F.grad
GR = F.grad('right')

GL.eval(rot)
GR.eval(rot)
GL = SO3VectorFieldHarmonic (Quartz → xyz)
  bandwidth: 48
  tangent space: leftVector
 
 
GR = SO3VectorFieldHarmonic (1 → xyz)
  bandwidth: 48
  tangent space: rightVector
 
 
ans = SO3TangentVector
 size: 3 x 1
 TagentSpace: leftVector
           x          y          z
  -0.0270414    0.50843 -0.0763921
    0.658906  -0.375212    0.82524
   -0.396355    1.05772   0.413025
 
ans = SO3TangentVector
 size: 3 x 1
 TagentSpace: rightVector
          x         y         z
  0.0470075 -0.219523  0.463323
   -1.03819  -0.25062  0.339585
   0.718042 -0.286741  0.921229

Again we are able to change the tangent space

left(GR)
right(GL)
ans = SO3VectorFieldHarmonic (1 → xyz)
  bandwidth: 48
  tangent space: leftVector
 
 
ans = SO3VectorFieldHarmonic (1 → xyz)
  bandwidth: 48
  tangent space: rightVector

Note that the symmetries do not work in the same way as for SO3Fun's. Dependent from the chosen tangent space representation (left/right) one of the symmetries has other properties.

In case of right tangent space the evaluation in symmetric orientations only make sense w.r.t. the left symmetry. In case of left tangent space vice versa.

ori = orientation.rand(GL.CS,GL.SS)
GR.eval(ori.symmetrise)
GL.eval(ori.symmetrise)
ori = orientation (Quartz → xyz)
 
  Bunge Euler angles in degree
     phi1     Phi    phi2
  96.0578 75.9796 190.491
 
 
ans = SO3TangentVector
 size: 6 x 1
 TagentSpace: rightVector
           x          y          z
   -0.123246  -0.110284   0.369469
   0.0338858   0.161876  -0.369469
  -0.0338858   0.161876   0.369469
    0.123246  -0.110284  -0.369469
    0.157132  -0.051592   0.369469
   -0.157132  -0.051592  -0.369469
 
ans = SO3TangentVector
 size: 6 x 1
 TagentSpace: leftVector
         x        y        z
  0.314259 0.135023 0.216493
  0.314259 0.135023 0.216493
  0.314259 0.135023 0.216493
  0.314259 0.135023 0.216493
  0.314259 0.135023 0.216493
  0.314259 0.135023 0.216493