## SphericalHarmonicExpansions.jl

A Julia package to handle spherical harmonic functions
Author hofmannmartin
Popularity
23 Stars
Updated Last
12 Months Ago
Started In
August 2017

# SphericalHarmonicExpansions

Build Status

The purpose of this package is to provide methods to numerically handle real spherical harmonics expansions in Cartesian coordinates.

## Mathematical Background

### Definition of the Spherical Harmonics

The normalized real spherical harmonics on the unit sphere are defined by

where , , and are the spherical angular coordinates,

is the normalization factor and

are the associated Legendre polynomials which can be derived from the Legendre polynomials

Note that you will also find a convention in literature, where the are scaled by .

### Spherical Harmonics Expansions

Each function satisfying Laplace's equation in a region can be written as a spherical harmonic expansion

for all , where denote the spherical coefficients and .

The term

can be transformed from spherical to Cartesian coordinates, where it can be expressed as a homogeneous polynomial of degree .

## Usage

### Polynomial Representation of the Spherical Harmonics

Generate a `MultivariatePolynomials.Polynomial` representation of

in variables `α`, `β`, and `γ` on the unit sphere by

```using SphericalHarmonics
@polyvar α β γ
l = 7
m = -2

p = ylm(l,m,α,β,γ)
63.28217501963252αβγ⁵ - 48.67859616894809αβγ³ + 6.63799038667474αβγ```

The polynomial representation of

in variables `x`, `y`, and `z` on can be obtained by

```@polyvar x y z

p = rlylm(l,m,x,y,z)
6.63799038667474x⁵yz + 13.27598077334948x³y³z - 35.40261539559861x³yz³ + 6.63799038667474xy⁵z - 35.40261539559861xy³z³ + 21.24156923735917xyz⁵```

### Polynomial Representation of the Spherical Harmonics Expansions

In case where a function is equal to or can be approximated by a finite Spherical harmonic expansion

with its multivariate polynomial representation has finite degree.

Coefficents can be initialized and populated by `c[l,m] = 42.0`.

```L = 2
c = SphericalHarmonicCoefficients(L)
c[0,0] = 42.0 #c₀₀
c[2,-1] = -1.0 #c₂₋₁
c[2,1] = 2.0 #c₂₁```

Internally, the coefficients are lexicographically stored in a vector (`c[0,0]`, `c[1,-1]`, `c[1,0]`, `c[1,1]`, `c[2,-2]`, ...). So the above initialization is equivalent to

```C = [42.0,0,0,0,0,-1,0,2,0]
c = SphericalHarmonicCoefficients(C)
f = sphericalHarmonicsExpansion(c,x,y,z)
2.1850968611841584xz + -1.0925484305920792yz + 11.847981254502882```

Note that `SphericalHarmonicCoefficients(C)` will throw an error if `length(C)` is not for some . From there on the corresponding polynomial representation in cartesian coordinates `x`, `y`, and `z` can be obtained by

```@polyvar x y z

f = sphericalHarmonicsExpansion(c,x,y,z)
2.1850968611841584xz - 1.0925484305920792yz + 11.847981254502882```

Currently, expansions up to \$L=66\$ are supported.

### Transformation of Expansion Coefficients under Translation

If we change from a coordinate sytsem with coordinates `x`, `y`, and `z` into a translated one with new coordinates `u = x + tx`, `v = y + ty`, and `w = z + tz` we need transformed coefficients to express the expansion in these new coordinates. To this end, we can do

```@polyvar u v w
translationVector = [0,0,1.0] # [tx,ty,tz]

cTranslated = translation(c,translationVector)
sphericalHarmonicsExpansion(cTranslated,u,v,w)
2.1850968611841584uw - 1.0925484305920792vw + 2.1850968611841584u - 1.0925484305920792v + 11.847981254502878```

### Numerical Evaluation

If you want to evaluate at a specific point you can use the standard interface of `MultivariatePolynomials`

```f(x=>0.5, y=>-1.0, z=>0.25)
12.394255469798921
f((x,y,z)=>(0.5,-1.0,0.25))
12.394255469798921```

In case where you want to evaluate for a large number of points you might run into performance issues. To this end we provide two methods to dynamically generate fast evaluating functions. Either use

```g = @fastfunc f
g(0.5,-1.0,0.25)
12.394255469798921```

which has moderate generation overhead. Usage from within local scope requires `Base.invokelatest(foo, 1.0,2.0,3.0)` instead of `foo(1.0,2.0,3.0)` to avoid issue #4. Or use

```h = fastfunc(f)
h(0.5,-1.0,0.25)
12.394255469798921```

which uses `GeneralizedGenerated` for function generation and comes with a significant overhead.

For more informations on the `MultivariatePolynomials` package please visit the project page on github.