---
jupytext:
  formats: ipynb,md:myst
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.15.2
kernelspec:
  display_name: Python 3
  language: python
  name: python3
---

```{code-cell} ipython3
:tags: [hide-cell]

import mmf_setup;mmf_setup.nbinit()
import logging;logging.getLogger('matplotlib').setLevel(logging.CRITICAL)
%matplotlib inline
import numpy as np, matplotlib.pyplot as plt
```

:::{margin}
**Prerequisites:** Please review {ref}`sec:ODEs`, {ref}`sec:SturmLiouville`, and {ref}`sec:OrthogonalPolynomials`.
:::
(sec:LegendreFunctions)=
# 15: Legendre Functions

The [Legendre functions][] $P_{\lambda}(x)$ and $Q_{\lambda}(x)$ are the generalization
of the [Legendre polynomials][] to non-integer $\lambda$ and the related Sturm Liouville
problem. The [Legendre polynomials][] satisfy (see also  {ref}`sec:OrthogonalPolynomials`) 
* Interval: $x \in [-1, 1]$.
* Weight: $W(x) = 1$.
:::{margin}
  Thus, we should normalize the orthonormal unit vectors $\ket{P_l}$ as:
  \begin{gather*}
    \braket{x|P_l} = \sqrt{\frac{2l+1}{2}}P_{l}(x).
  \end{gather*}
:::
* Normalization (leading coefficient is $x^{l}$ with coefficient 1): 
  \begin{gather*}
    \int_{-1}^{1} P_k(x)P_l(x)\d{x} = \frac{2}{2l+1}\delta_{kl}.
  \end{gather*}
* Completeness:
  :::{margin}
  Note this is just $\sum_{l}\ket{P_l}\!\bra{P_l} = \mat{1}$.
  :::
  \begin{gather*}
    \sum_{l=0}^{\infty} \frac{2l+1}{2}P_{l}(x) P_{l}(y) = \delta(x-y).
  \end{gather*}
* Generating function:
  \begin{gather*}
    \frac{1}{\sqrt{1 - 2xt + t^2}} = \sum_{n=0}^{\infty}P_{l}(x)t^l.
  \end{gather*}
:::{margin}
  Try to derive the following by differentiating the generating function.
:::
* Recurrence Relation:
  \begin{align*}
    P_{0}(x) &= 1, \\
    P_{1}(x) &= x, \\
    (l+1)P_{l+1}(x) &= (2l+1)xP_{l}(x) - lP_{l-1}(x).\tag{15.18}
  \end{align*}
* Rodrigues' formula:
  \begin{gather*}
    P_{l}(x) = \frac{1}{2^l l!}\diff[l]{}{x}(x^2-1)^l.\tag{15.30}
  \end{gather*}
:::{margin}
  Derive this from Rodrigues' formula using Cauchy's integral formula for computing
  the derivatives.
:::
* Schläfli Integral:
  \begin{gather*}
    P_{l}(z) = \frac{1}{2^{l}}\oint_C \frac{(w^2 -1)^l}{(w-z)^{l+1}}\frac{\d{w}}{2\pi \I}
  \end{gather*}
  where the contour is closed, encloses the pole $w=z$, and avoids any branch cuts (see below).
* The [Legendre polynomials][] satisfy the following second-order homogeneous linear
  differential equation (see also {ref}`sec:ODEs`, {ref}`sec:SturmLiouville`):
  \begin{gather*}
    (1-x^2)y'' - 2xy' +l(l+1)y = 0, \qquad y(x) = P_{l}(x)
  \end{gather*}

The [Legendre functions][] $P_{\lambda}(z)$ extend these to non-integer $l$.  This
presents the following issues:
* The functions are no-longer orthogonal.
* The generating function relation should still hold, but now with appropriately defined
  fractional derivatives.  Similarly with Rodrigues' formula.
* The recurrence relations likely hold, but need new based cases for all non-integer streams.
* The Schläfli integral is promising, but we must now be careful of the contour since
  the non-integer power introduced branch cuts.
* The differential equation remains valid.




and satisfy 
\begin{gather*}
  -\nabla^2 \psi   
\end{gather*}


## Associated Legendre Functions

The associated functions $P^{m}_{l}(x)$ add an extra piece to the differential equation:
\begin{gather*}
  (1-x^2)y'' - 2xy' + \left(l(l+1) - \frac{m^2}{1-x^2}\right)y = 0, \qquad y(x) = P^{m}_{l}(x).
\end{gather*}
They can be found by differentiating:
\begin{gather*}
  P^{m}_{l}(x) = (-1)^{m}(1-x^2)^{m/2} \diff[m]{}{x}P_{l}(x), \qquad m \geq 0,\\
  P^{-m}_{l}(x) = (-1)^{m}\frac{(l-m)!}{(l+m)!}P^{m}_{l}(x).
\end{gather*}
:::{margin}
E.g.,
\begin{gather*}
  P^{1}_{1}(x) = -\sqrt{\frac{1-x^2}},\\
  P^{2}_{2}(x) = 3(1-x^2).
\end{gather*}
:::

When $m$ is even, the set of polynomials $\bigl\{P^{m}_{l}(x) \quad \mid\quad l\in \{m,
m+1, \cdots\}\bigr\}$ forms a completed orthogonal basis.  For odd $m$, we have a
similar basis, but the functions are no longer polynomials.


For each value of $0 \leq m\leq l$, we have a new set of orthogonal polynomials:
* Interval: $x \in [-1, 1]$.
* Weight: $W(x) = 1$.
:::{margin}
  Thus, we should normalize the orthonormal unit vectors $\ket{P_l}$ as:
  \begin{gather*}
    \braket{x|P^{m}_l} = \sqrt{\frac{2(l+m)!}{(2l+1)(l-m)!}}P^{m}_{l}(x).
  \end{gather*}
:::
* Orthogonality and Normalization (leading coefficient is $x^{n}$ with coefficient 1):
  \begin{gather*}
    \int_{-1}^{1} P^{m}_{k}(x)P^{m}_{l}(x)\d{x} = \frac{2(l+m)!}{(2l+1)(l-m)!}\delta_{kl}.
  \end{gather*}
  Note that they also satisfy the following orthogonality for fixed $l$:
  \begin{gather*}
    \int_{-1}^{1} \frac{P^{m}_{l}(x)P^{m}_{l}(x)}{1-x^2}\d{x} = \frac{(l+m)!}{m(l-m)!}\delta_{mn}.
  \end{gather*}
* Parity:
  \begin{gather*}
    P^{m}_{l}(-x) = (-1)^{l-m}P^{m}_{l}(x).
  \end{gather*}
* Recurrence Relation: (one of many!)
  \begin{align*}
    (l-m+1)P^{m}_{l+1}(x) &= (2l+1)xP^{m}_{l}(x) - (l+m)P^{m}_{l-1}(x).\tag{15.88}
  \end{align*}
* Rodrigues' formula:
  \begin{gather*}
    P^{m}_{l}(x) = \frac{(-1)^{m}}{2^l l!}(1-x^2)^{m/2}\diff[l+m]{}{x}(x^2-1)^l.
  \end{gather*}
* Schläfli Integral:
  \begin{gather*}
    P^{m}_{l}(z) = \frac{(-1)^{m}(l+m)!}{2^{l}l!}(1-z^2)^{m/2}
                   \oint_C \frac{(w^2 - 1)^{l}}{(w-z)^{l+m+1}}\frac{\d{w}}{2\pi \I}
  \end{gather*}
  where the contour is closed, encloses the pole $w=z$, and avoids any branch cuts (see
  below).  *(MMF: I am not certain yet that the same branch trick works here if $m$ is
  not integer since the numerator and denominator have different powers.)*


### Schläfli Integral Countour

:::{margin}
See e.g. {cite}`Szmytkowski:2006, Szmytkowski:2007, Whittaker:2021`.
:::

```{code-cell}
:tags: [margin, hide-input]
plt.rcParams['mathtext.fontset'] = 'cm'
from matplotlib_inline.backend_inline import set_matplotlib_formats
set_matplotlib_formats('svg')

rng = np.random.default_rng(seed=2)
th = np.linspace(0, 2*np.pi, 500)
n = np.arange(-5, 6)
dr = (np.exp(1j * n[:, None] * th[None, :])
      * (rng.random(size=len(n)*2)-0.5).view(dtype=complex)[:, None]).sum(axis=0)
z = 1.5 + 1j
w0 = (z + 1)/2
r = 2*abs(z-w0)
C = ((r + 0.1*dr.real)*np.exp(1j*th) + w0)

eta = 1/np.linspace(1, 0, 200)[:-1]
br = (1+eta*z)/(z+eta)

fig, ax = plt.subplots(figsize=(4, 2))
ax.plot(C.real, C.imag, lw=2)
ax.plot([-1, 1, z.real], [0, 0, z.imag], 'ko', ms=10)
ax.plot(br.real, br.imag, '-k', lw=3)
ax.plot([-3, -1], [0, 0], '-k', lw=3)
ax.text(z.real-0.3, z.imag + 0.1, "$z$", size=15)
ax.grid(True)
ax.set(xlim=(-1.5, 2.5), aspect=1, xticks=[-1, 0, 1, 2], yticks=[-1, 0, 1],
    xlabel=r"$\mathrm{Re}(w)$", ylabel=r"$\mathrm{Im}(w)$");
```
The Legendre function $P_{l}(z)$ has the following  Schläfli contour integral
representation:
\begin{gather*}
  P_{l}(z) = \frac{1}{2^{l}}\oint_{C} \frac{(w^2-1)^l}{(w-z)^{l+1}}\frac{\d{w}}{2\pi \I}
\end{gather*}
with the contour shown on the right after choosing the branch cuts as shown.



[Legendre functions]: <https://en.wikipedia.org/wiki/Legendre_function>
[Legendre polynomials]: <https://en.wikipedia.org/wiki/Legendre_polynomials>




(sec:MultipoleExpansion)=
## 15.3: Multipole Expansion
