Spherical Harmonics
The spherical harmonics \(Y^l(x)\) are functions defined on the sphere \(S^2\). They form a basis of the space on function on the sphere:
On this space it is natural how the group \(O(3)\) acts, Given \(p_a, p_v\) two scalar representations:
\(L\) is representation of \(O(3)\). But \(L\) is not irreducible. It can be decomposed via a change of basis into a sum of irreps, In a handwavey notation we can write:
where the change of basis are the spherical harmonics! This notation is handwavey because \(x\) is a continuous variable, and therefore the change of basis \(Y\) is not a matrix.
As a consequence, the spherical harmonics are equivariant,
r = s2_grid()
r is a grid on the sphere.
Each point on the sphere has 3 components. If we plot the value of each of the 3 component separately we obtain the following figure:
plot(r, radial_abs=False)
x, y and z are represented as 3 scalar fields on 3 different spheres. To obtain a nicer figure (that looks like the spherical harmonics shown on Wikipedia) we can deform the spheres into a shape that has its radius equal to the absolute value of the plotted quantity:
plot(r)
\(Y^1\) is the identity function. Now let’s compute \(Y^2\), for this we take the tensor product \(r \otimes r\) and extract the \(L=2\) part of it.
tp = o3.ElementwiseTensorProduct("1o", "1o", ['2e'], irrep_normalization='norm')
y2 = tp(r, r)
plot(y2)
Similarly, the next spherical harmonic function \(Y^3\) is the \(L=3\) part of \(r \otimes r \otimes r\):
tp = o3.ElementwiseTensorProduct("2e", "1o", ['3o'], irrep_normalization='norm')
y3 = tp(y2, r)
plot(y3)
The functions below are more efficient versions not using e3nn.o3.ElementwiseTensorProduct:
Details
- e3nn.o3.spherical_harmonics(l: int | List[int] | str | Irreps, x: Tensor, normalize: bool, normalization: str = 'integral')[source]
Spherical harmonics
Polynomials defined on the 3d space \(Y^l: \mathbb{R}^3 \longrightarrow \mathbb{R}^{2l+1}\)Usually restricted on the sphere (withnormalize=True) \(Y^l: S^2 \longrightarrow \mathbb{R}^{2l+1}\)who satisfies the following properties:are polynomials of the cartesian coordinates
x, y, zis equivariant \(Y^l(R x) = D^l(R) Y^l(x)\)
are orthogonal \(\int_{S^2} Y^l_m(x) Y^j_n(x) dx = \text{cste} \; \delta_{lj} \delta_{mn}\)
The value of the constant depends on the choice of normalization.
It obeys the following property:
\[ \begin{align}\begin{aligned}Y^{l+1}_i(x) &= \text{cste}(l) \; & C_{ijk} Y^l_j(x) x_k\\\partial_k Y^{l+1}_i(x) &= \text{cste}(l) \; (l+1) & C_{ijk} Y^l_j(x)\end{aligned}\end{align} \]Where \(C\) are the
wigner_3j.Note
This function match with this table of standard real spherical harmonics from Wikipedia when
normalize=True,normalization='integral'and is called with the argument in the ordery,z,x(instead ofx,y,z).- Parameters:
x (
torch.Tensor) – tensor \(x\) of shape(..., 3).normalize (bool) – whether to normalize the
xto unit vectors that lie on the sphere before projecting onto the spherical harmonicsnormalization ({'integral', 'component', 'norm'}) – normalization of the output tensors — note that this option is independent of
normalize, which controls the processing of the input, rather than the output. Valid options: * component: \(\|Y^l(x)\|^2 = 2l+1, x \in S^2\) * norm: \(\|Y^l(x)\| = 1, x \in S^2\),component / sqrt(2l+1)* integral: \(\int_{S^2} Y^l_m(x)^2 dx = 1\),component / sqrt(4pi)
- Returns:
a tensor of shape
(..., 2l+1)\[Y^l(x)\]- Return type:
Examples
>>> spherical_harmonics(0, torch.randn(2, 3), False, normalization='component') tensor([[1.], [1.]])
- e3nn.o3.spherical_harmonics_alpha_beta(l, alpha, beta, *, normalization: str = 'integral')[source]
Spherical harmonics of \(\vec r = R_y(\alpha) R_x(\beta) e_y\)
\[Y^l(\alpha, \beta) = S^l(\alpha) P^l(\cos(\beta))\]where \(P^l\) are the
Legendrepolynomials- Parameters:
alpha (
torch.Tensor) – tensor of shape(...).beta (
torch.Tensor) – tensor of shape(...).
- Returns:
a tensor of shape
(..., 2l+1)- Return type:
- e3nn.o3.Legendre(ls) None[source]
GraphModule is an nn.Module generated from an fx.Graph. Graphmodule has a
graphattribute, as well ascodeandforwardattributes generated from thatgraph.Warning
When
graphis reassigned,codeandforwardwill be automatically regenerated. However, if you edit the contents of thegraphwithout reassigning thegraphattribute itself, you must callrecompile()to update the generated code.Note
Backwards-compatibility for this API is guaranteed.