Definition of an SO3Fun edit page

In MTEX rotational functions \(F\colon\mathcal{SO}(3)\to \mathbb C\) are described by subclasses of the super class SO3Fun. Hence we talk about them as SO3Funs.

Overview on the subclasses of SO3Fun

Internally MTEX represents rotational functions in different ways:

by a harmonic series expansion


as Bingham distribution


as superposition of radial function


as sum of different components


as superposition of fibre elements


explicitely given by a formula


Generalizations of Rotational Functions

rotational vector fields


radial rotational functions


All representations allow the same operations which are specified for the abstact class SO3Fun. In particular it is possible to calculate with \(\mathcal{SO}(3)\) functions as with ordinary numbers, i.e., you can add, multiply arbitrary functions, take the mean, integrate them or compute gradients, see Operations.

Definition of SO3Fun's

Every rotational function has a left and a right symmetry, see symmetric Functions. If we do not specify symmetries by construction then the symmetry group '1' is used as default, i.e. there are no symmetric rotations.

Moreover SO3Fun's have the property antipodal which could be used to set the function as antipodal.

Definition of anonymous functions on SO(3)

Functions of class SO3FunHandle are defined by an anonymous function.

f = @(ori) angle(ori)./degree
SO3F1 = SO3FunHandle(f)

cs = crystalSymmetry('cubic');
SO3F2 = SO3FunHandle(f,cs)
f =
  function_handle with value:
SO3F1 = SO3FunHandle (xyz → xyz)
SO3F2 = SO3FunHandle (m-3m → xyz)

Now we are able to evaluate this SO3FunHandle

rot = rotation.rand(2);
ans =

And following that, it is easy to describe every SO3Fun by an SO3FunHandle.

SO3FunHandle(@(rot) SO3F1.eval(rot))
ans = SO3FunHandle (xyz → xyz)

Definition of Harmonic Series on SO(3)

The class SO3FunHarmonic described rotational functions by there harmonic series. MTEX is very fast by computing with this SO3FunHarmonic's. Hence sometimes it might be a good idea to expand any SO3Fun in its harmonic series. Therefore only the command SO3FunHarmonic is needed. But note that this approximation may lead to inaccuracies.

SO3F3 = SO3FunHarmonic(SO3F2)
SO3F3 = SO3FunHarmonic (m-3m → xyz)
  bandwidth: 64
  weight: 41

Moreover if MTEX computes with an SO3FunHarmonic and any SO3Fun it is also expanded to an SO3FunHarmonic. You can prevent that by transformation to a SO3FunHandle like before.

Generally SO3FunHarmonic's are defined by there Fourier coefficient vector.

fhat = rand(1e4,1);
SO3F4 = SO3FunHarmonic(fhat,cs)
SO3F4 = SO3FunHarmonic (m-3m → xyz)
  isReal: false
  bandwidth: 19
  weight: 0.34

The bandwith decribes the maximal harmonic degree of the harmonic series expansion.

By the property isReal we are able to change between real and complex valued SO3FunHarmonic's. Note that creation of an real vealued SO3FunHarmonic changes the Fourier coefficient vector. So it is not possible to reconstruct the previous function. But computing with real valued functions is much faster.


SO3F4.isReal = 1
ans =
  -3.8112 + 0.4626i
  32.2917 + 2.1982i
SO3F4 = SO3FunHarmonic (m-3m → xyz)
  bandwidth: 19
  weight: 0.34
ans =

For further information on the Fourier coefficients, the bandwidth and other properties , see Harmonic Representation of Rotational Functions.

Definition of Radial Basis Functions

Radial Basis functions are of class SO3FunRBF. They are defined by a kernel function SO3Kernel which is cenetered on orientations with some weights.

ori = orientation.rand(1e3,cs);
w = ones(1e3,1);
psi = SO3DeLaValleePoussinKernel
SO3F5 = SO3FunRBF(ori,psi,w,1.2)
psi = SO3DeLaValleePoussinKernel
  bandwidth: 25
  halfwidth: 10°
SO3F5 = SO3FunRBF (m-3m → xyz)
  <strong>uniform component</strong>
  weight: 1.2
  <strong>multimodal components</strong>
  kernel: de la Vallee Poussin, halfwidth 10°
  center: 1000 orientations

For further information on them, see SO3FunRBF.

Definition of fibre elements

They are described by the class SO3FunCBF. We construct them by a fibre on SO(3) together with some halfwidth.

f = fibre.beta(cs)
SO3F6 = SO3FunCBF(f,'halfwidth',10*degree)
f = fibre (m-3m → xyz)
  h || r: (-6-12-11) || (1,-1,-4)
 o1 → o2: (0°,35.3°,45°) → (270°,62.8°,45°)
SO3F6 = SO3FunCBF (m-3m → xyz)
  kernel: de la Vallee Poussin, halfwidth 10°
  fibre : (-6-12-11) || 1,-1,-4
  weight: 1

For further information, see SO3FunCBF.

Definition of Bingham distributions

Bingham distribution functions are described by the class SO3FunBingham. One can construct them by

kappa = [100 90 80 0];
U = eye(4);
SO3F7 = BinghamODF(kappa,U,cs)
SO3F7 = SO3FunBingham (m-3m → xyz)
  kappa: 100 90 80 0
  weight: 1

For further information, see SO3FunBingham.

Sum of different subclasses of SO3Fun

By adding some subclasses of SO3Fun we can save the sum by storing the single components itself.

SO3F2 + SO3FunComposition(SO3F4) + SO3F5 + SO3F6 + SO3F7
ans = SO3FunComposition (m-3m → xyz)
  <strong>uniform component</strong>
  weight: 1.2
  <strong>harmonic component</strong>
  bandwidth: 19
  weight: 0.34
  <strong>function handle component</strong>
  <strong>multimodal components</strong>
  kernel: de la Vallee Poussin, halfwidth 10°
  center: 1000 orientations
  <strong>fibre component</strong>
  kernel: de la Vallee Poussin, halfwidth 10°
  fibre : (-6-12-11) || 1,-1,-4
  weight: 1
  <strong>bingham component</strong>
  kappa: 100 90 80 0
  weight: 1

Note that the sum of any SO3Fun with an SO3FunHarmonic yields an SO3FunHarmonic. Hence you need to add an SO3FunHarmonic in exactly that way. Otherwise the sum is expanded to an SO3FunHarmonic in every summation step.