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, z
is 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
x
to 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
Legendre
polynomials- 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(*args, **kwargs)[source]
GraphModule is an nn.Module generated from an fx.Graph. Graphmodule has a
graph
attribute, as well ascode
andforward
attributes generated from thatgraph
.Warning
When
graph
is reassigned,code
andforward
will be automatically regenerated. However, if you edit the contents of thegraph
without reassigning thegraph
attribute itself, you must callrecompile()
to update the generated code.Note
Backwards-compatibility for this API is guaranteed.