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 an integral operator which is often used to smooth functions or compute their cross correlation.

We have to distinguish which objects are convoluted.

Convolution of two rotational functions

Let two SO3Fun's f:SLSO(3)/SxC where SL is the left symmetry and Sx is the right symmetry and g:SxSO(3)/SRC where Sx is the left symmetry and SR is the right symmetry be given.

g = SO3FunHarmonic.example

ss1 = specimenSymmetry;
ss2 = specimenSymmetry('222');
f = SO3FunRBF(orientation.rand(ss1,ss2))
g = SO3FunHarmonic (Quartz → y↑→x)
  bandwidth: 48
  weight: 1
 
 
f = SO3FunRBF (y↑→x → y↑→x (222))
 
  unimodal component
  kernel: de la Vallee Poussin, halfwidth 10°
  center: 1 orientations
 
  Bunge Euler angles in degree
     phi1     Phi    phi2  weight
  156.958 161.468 197.878       1

Then the convolution fg:SLSO(3)/SRC is defined by

(fg)(R)=18π2SO(3)f(q)g(q1R)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))=SO(3)1dR=8π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 → y↑→x (222))
  bandwidth: 25
  weight: 1
 
ans =
    0.2769
ans =
    0.2766

Note that the left sided convolution from the above definition is used as default in MTEX.

The right sided convolution coincides with the commutation

(gf)(R)=18π2SO(3)f(q)g(Rq1)dq

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

f = SO3FunRBF(orientation.rand(g.CS,g.CS))

c = conv(g,f)

% Test
r = orientation.rand(c.CS,c.SS);
c.eval(r)
mean(SO3FunHandle(@(q) f.eval(q).*g.eval(r.*inv(q)),c.CS))
f = SO3FunRBF (Quartz → Quartz)
 
  unimodal component
  kernel: de la Vallee Poussin, halfwidth 10°
  center: 1 orientations
 
  Bunge Euler angles in degree
     phi1     Phi    phi2  weight
  73.6735 76.1995 107.876       1
 
 
c = SO3FunHarmonic (Quartz → y↑→x)
  bandwidth: 25
  weight: 1
 
ans =
    0.5927
ans =
    0.5926

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

Convolution of two spherical functions

Consider there are two S2Fun's f:S2/SRC g:S2/SLC given, where SR and SL denotes the symmetries.

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

Then the spherical convolution yields a orientation dependent function fg:SLSO(3)/SRC with right symmetry SR and left symmetry SL. The convolution is defined by

(fg)(R)=14πS2f(R1ξ)g(ξ)dξ.

The normalization factor of the integral reads as vol(S2)=S21dξ=4π.

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 → y↑→x)
  bandwidth: 25
  weight: 0.0064
 
ans =
    0.2349
ans =
    0.2349

Convolution of a rotational function with a spherical function

We consider a SO3Fun f:ShSO(3)/SRC with left symmetry Sh and right symmetry SR and a S2Fun h:S2/ShC with symmetry group Sh.

f = SO3FunHarmonic.example
h = S2FunHarmonicSym(S2Fun.smiley,ss1)
f = SO3FunHarmonic (Quartz → y↑→x)
  bandwidth: 48
  weight: 1
 
 
h = S2FunHarmonicSym (y↑→x)
  bandwidth: 128
  isReal: true

The convolution yields a S2Fun fh:S2/SRC. In MTEX it is defined by

(fh)(ξ)=18π2SO(3)f(q)h(qξ)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.CS))
c = S2FunHarmonicSym (Quartz)
  bandwidth: 48
  isReal: true
 
ans =
    0.0014
ans =
    0.0655

If you want to compute the convolution of f:1SO(3)/SRC and h:S2/SRC which yields fh:S2/SRC and is defined as

(fh)(ξ)=18π2SO(3)f(q)h(q1ξ)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 → y↑→x)
  bandwidth: 48
  weight: 1
 
 
h = S2FunHarmonicSym (Quartz)
  bandwidth: 128
  antipodal: true
  isReal: true
 
 
c = S2FunHarmonicSym (y↑→x)
  bandwidth: 48
  antipodal: true
  isReal: true
 
ans =
    0.0374
ans =
    0.0374

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 ω. Since the rotation angle of two matrices satisfies ω(q1R)=ω(Rq1), the convolution with SO3Kernels is commutative.

f = SO3FunHarmonic.example
psi = SO3DeLaValleePoussinKernel

c = conv(f,psi)
f = SO3FunHarmonic (Quartz → y↑→x)
  bandwidth: 48
  weight: 1
 
 
psi = SO3DeLaValleePoussinKernel
  bandwidth: 25
  halfwidth: 10°
 
 
c = SO3FunHarmonic (Quartz → y↑→x)
  bandwidth: 25
  weight: 1

Spherical kernel functions

Let a spherical kernel function ψ(ve3) be defined as in S2Kernel's. Then the convolution with a S2Fun f reads as

(fψ)(v)=14πS2f(ξ)ψ(ξv)dξ.

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

(fψ)(R)=14πS2f(R1ξ)ψ(ξe3)dξ.

The first formula yields a S2Fun while the second formula yields a SO3Fun. They are equal for v=R1e3.

% 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 (y←↑x)
  bandwidth: 128
  isReal: true
 
 
psi = S2DeLaValleePoussinKernel
  bandwidth: 25
  halfwidth: 10°
 
 
c1 = S2FunHarmonic (y←↑x)
  bandwidth: 25
  isReal: true
 
ans =
   2.7557e-08
ans =
  -4.5941e-13
ans =
   2.7557e-08
ans =
   2.5757e-08