Convolution of Orientational Dependent and Spherical Functions edit page

On this page we will show how the convolution of ODFs (SO3Fun's), Spherical functions (S2Fun's), SO3Kernel's and S2Kernel's is defined.

The convolution is a integral operator which has several slightly different definitions. It is often used to smooth functions or compute there cross correlation.

We have to distinguish which objects are convoluted.

Convolution of two rotational functions

Here we distinguish two definitions. They are named the left \(*_L\) and right \(*_R\) sided convolution.

  • The left sided convolution (default)*

Let two SO3Fun's \(f \colon {}_{S_L } \backslash SO(3) /_{S_x} \to \mathbb{C}\) where \(S_L\) is the left symmetry and \(S_x\) is the right symmetry and \(g: {}_{S_x} \backslash SO(3) /_{S_R} \to \mathbb C\) where \(S_x\) is the left symmetry and \(S_R\) is the right symmetry be given.

ss = specimenSymmetry;
cs = crystalSymmetry('222');
f = SO3FunRBF(orientation.rand(ss,cs))
g = SO3FunHarmonic.example
f = SO3FunRBF (xyz → 222)
 
  unimodal component
  kernel: de la Vallee Poussin, halfwidth 10°
  center: 1 orientations
 
  Bunge Euler angles in degree
     phi1     Phi    phi2  weight
  48.1639 39.6527 20.3528       1
 
 
g = SO3FunHarmonic (Quartz → xyz)
  bandwidth: 48
  weight: 1

Then the convolution \(f {*}_L g \colon {}_{S_L} \backslash SO(3) /_{S_R} \to \mathbb C\) is defined by

\[ (f {*}_L g)(R) = \frac{1}{8\pi^2} \int_{SO(3)} f(q) \cdot g(q^{-1}\,R) \, dq \]

where the right symmetry of \(f\) have to coincide with the left symmetry of \(g\). The normalization factor of the integral reads as \(vol(SO(3)) = \int_{SO(3)} 1 \, dR = 8\pi^2\).

c = conv(f,g)

% Test
r = orientation.rand(c.CS,c.SS);
c.eval(r)
mean(SO3FunHandle(@(q) f.eval(q).*g.eval(inv(q).*r)))
c = SO3FunHarmonic (Quartz → 222)
  bandwidth: 25
  weight: 1
 
ans =
    3.6302
Warning: Possibly applying an inverse orientation to an object in
crystal coordinates! 
ans =
    3.6328

Note that the left sided convolution \(*_L\) is used as default in MTEX.

  • The right sided convolution*

As contrast we have the second definition:

Let two SO3Fun's \(f \colon {}_{S_x } \backslash SO(3) /_{S_R} \to \mathbb{C}\) where \(S_x\) is the left symmetry and \(S_R\) is the right symmetry and \(g: {}_{S_L} \backslash SO(3) /_{S_x} \to \mathbb C\) where \(S_L\) is the left symmetry and \(S_x\) is the right symmetry be given.

ss = specimenSymmetry;
cs = crystalSymmetry('222');
f = SO3FunHarmonic.example
g = SO3FunRBF(orientation.rand(ss,cs))
f = SO3FunHarmonic (Quartz → xyz)
  bandwidth: 48
  weight: 1
 
 
g = SO3FunRBF (xyz → 222)
 
  unimodal component
  kernel: de la Vallee Poussin, halfwidth 10°
  center: 1 orientations
 
  Bunge Euler angles in degree
     phi1     Phi    phi2  weight
  275.645 40.7705 268.087       1

The convolution \(f {*}_R g \colon {}_{S_L}\backslash SO(3) /_{S_R} \to \mathbb{C}\) is defined by

\[ (f {*}_R g)(R) = \frac1{8\pi^2} \int_{SO(3)} f(q) \cdot g(R\,q^{-1}) \, dq \]

where the left symmetry of \(f\) have to coincide with the right symmetry of \(g\).

c = conv(f,g,'right')

% Test
r = orientation.rand(c.CS,c.SS);
c.eval(r)
mean(SO3FunHandle(@(q) f.eval(q).*g.eval(r.*inv(q))))
c = SO3FunHarmonic (Quartz → 222)
  bandwidth: 25
  weight: 1
 
ans =
    0.5770
Warning: Possibly applying an orientation to an object in specimen
coordinates! 
ans =
    0.5772

The convolution of matrices of SO3FunHarmonic's with matrices of SO3Functions works elementwise, see at multivariate SO3Fun's for there definition.

Convolution of two spherical functions

Consider there are two S2Fun's \(f: \mathbb S^2 /_{S_R} \to \mathbb{C}\) \(g: \mathbb S^2 /_{S_L} \to \mathbb{C}\) given, where \(S_R\) and \(S_L\) denotes the symmetries.

cs = crystalSymmetry;
f = S2FunHarmonicSym(S2Fun.smiley,cs)
g = S2FunHarmonic(S2DeLaValleePoussinKernel)
f = S2FunHarmonicSym (1)
  bandwidth: 128
  isReal: true
 
 
g = S2FunHarmonic
  bandwidth: 25
  isReal: true

Then the spherical convolution yields a orientation dependent function \(f*g: {}_{S_L} \backslash SO(3) /_{S_R} \to \mathbb{C}\) with right symmetry \(S_R\) and left symmetry \(S_L\). The convolution is defined by

\[ (f * g)(R) = \frac1{4\pi} \int_{S^2} f(R^{-1}\xi) \cdot g(\xi) \, d\xi. \]

The normalization factor of the integral reads as \(vol(S^2) = \int_{S^2} 1 \, d\xi = 4\pi\).

c = conv(f,g)

% Test
r = orientation.rand(c.CS,c.SS);
c.eval(r)
c2 = S2FunHandle(@(v) f.eval(inv(r)*v).*g.eval(v));
v = equispacedS2Grid('resolution',0.2*degree);
mean(c2.eval(v))
c = SO3FunHarmonic (1 → xyz)
  bandwidth: 25
  weight: 0.0064
 
ans =
   1.4603e-07
ans =
   1.4622e-07

Convolution of a rotational function with a spherical function

We consider a SO3Fun \(f: {}_{S_h} \backslash SO(3) /_{S_R} \to \mathbb{C}\) with left symmetry \(S_h\) and right symmetry \(S_R\) and a S2Fun \(h \colon \mathbb S^2 /_{S_h} \to \mathbb C\) with symmetry group \(S_h\).

f = SO3FunHarmonic.example
h = S2FunHarmonicSym(S2Fun.smiley,ss)
f = SO3FunHarmonic (Quartz → xyz)
  bandwidth: 48
  weight: 1
 
 
h = S2FunHarmonicSym (xyz)
  bandwidth: 128
  isReal: true

The convolution yields a S2Fun \(f*h \colon \mathbb S^2/_{S_R} \to \mathbb C\). In MTEX it is defined by

\[ (f * h)(\xi) = \frac1{8\pi^2} \int_{SO(3)} f(q) \cdot h(q\,\xi) \, dq. \]

c = conv(f,h)

% Test
v = Miller.rand(c.CS);
c.eval(v)
mean(SO3FunHandle(@(q) f.eval(q).*h.eval(q*v)))
c = S2FunHarmonicSym (Quartz)
  bandwidth: 48
  isReal: true
 
ans =
   8.5393e-05
Warning: Possibly applying an inverse orientation to an object in
crystal coordinates! 
ans =
   8.0813e-05

If you want to compute the convolution of \(f: {}_{'1'} \backslash SO(3) /_{S_R} \to \mathbb{C}\) and \(h \colon \mathbb S^2 /_{S_R} \to \mathbb C\) which yields \(f*h \colon \mathbb S^2/_{S_R} \to \mathbb C\) and is defined as

\[ (f * h)(\xi) = \frac1{8\pi^2} \int_{SO(3)} f(q) \cdot h(q^{-1}\,\xi) \, dq. \]

f = SO3FunHarmonic.example
h = S2FunHarmonicSym(S2Fun.smiley,f.CS)

c = conv(inv(f),h)

% Test
v = vector3d.rand;
c.eval(v)
mean(SO3FunHandle(@(q) f.eval(q).*h.eval(inv(q)*v)))
f = SO3FunHarmonic (Quartz → xyz)
  bandwidth: 48
  weight: 1
 
 
h = S2FunHarmonicSym (Quartz)
  bandwidth: 128
  antipodal: true
  isReal: true
 
 
c = S2FunHarmonicSym (xyz)
  bandwidth: 48
  antipodal: true
  isReal: true
 
ans =
    0.0331
ans =
    0.0331

Convolution with kernel function

  • rotational kernel functions *

Since SO3Kernel's are special orientation dependent functions we can easily describe them as SO3Fun's. Hence the convolution with SO3Kernel's is exactly the same as above.

Note that SO3Kernel's are radial basis functions which only depends on the rotation angle \(\omega\). Since the rotation angle of two matrices satisfies \(\omega(q^{-1}\,R)=\omega(R\,q^{-1})\), the left and right sided convolution are equivalent by convoluting with SO3Kernels. Moreover the convolution is commutative in this case.

f = SO3FunHarmonic.example
psi = SO3DeLaValleePoussinKernel

c = conv(f,psi)
f = SO3FunHarmonic (Quartz → xyz)
  bandwidth: 48
  weight: 1
 
 
psi = SO3DeLaValleePoussinKernel
  bandwidth: 25
  halfwidth: 10°
 
 
c = SO3FunHarmonic (Quartz → xyz)
  bandwidth: 25
  weight: 1
  • spherical kernel functions *

Let a spherical kernel function \(\psi(\vec v \cdot \vec e_3)\) be defined as in S2Kernel's. Then the convolution with a S2Fun reads as

\[ (f * \psi) (\vec v) = \frac1{4\pi} \int_{S^2} f(\xi) \, \psi(\xi \cdot \vec v) \, d\xi. \]

Note that S2Kernel's are special spherical functions. Hence we can easily describe them as S2Fun's and convolute them as described above for convolution of two spherical functions

\[ (f * \psi) (R) = \frac1{4\pi} \int_{S^2} f(R^{-1}\,\xi) \, \psi(\xi \cdot \vec e_3) \, d\xi. \]

The first formula yields a S2Fun while the second formula yields a SO3Fun. They are equal for \(\vec v = R^{-1} \vec e_3\).

% Test
f = S2Fun.smiley
psi = S2DeLaValleePoussinKernel

c1 = conv(f,psi)

% Test
v = vector3d.rand;
c1.eval(v)
xi = equispacedS2Grid('resolution',0.2*degree);
mean(f.eval(xi).*psi.eval(cos(angle(xi,v).')))

% compare with spherical convolution
r = rotation.map(v,zvector);
h = S2FunHarmonic(psi);
c2 = conv(f,h);
c2.eval(r)
mean(f.eval(inv(r)*xi).*h.eval(xi))
f = S2FunHarmonic
  bandwidth: 128
  isReal: true
 
 
psi = S2DeLaValleePoussinKernel
  bandwidth: 25
  halfwidth: 10°
 
 
c1 = S2FunHarmonic
  bandwidth: 25
  isReal: true
 
ans =
   3.4677e-05
ans =
   3.4700e-05
ans =
   3.4677e-05
ans =
   3.4676e-05