Correct and Alternative Numerical Algorithms for the Complete Elliptic Integral of the First Kind in MATLAB and Mathematica

Abstract: The complete elliptic integral of the first kind (CEI-1) plays in a significant role in mathematics, physics and engineering. There is no simple formulae for its computation, thus numerical algorithms and solution are essential in practical problems. However, we find that the numerical solutions obtained via both MATLAB and Mathematica are not acceptable and should be treated seriously. For the purpose of obtaining correct and alternative numerical algorithms for the CEI-1, the infinite series method, arithmetic-geometric mean (AGM) method, Gauss-Chebyshev method and Gauss-Legendre methods are discussed in details with a top-down strategy. The four key algorithms for computing CEI-1 are designed, verified, validated and tested, which can be utilized in R & D and be reused properly. In the sense of STEM education, system engineering and computational thinking, the Verification-Validation-Testing (VVT) stage is crucial for applications and teaching college students in order to avoid unnecessary losses.

\section{Introduction}  \label{sec-Intro}

The \textit{Complete Elliptic Integral of the first kind} (CEI-1) is an interesting special function in mathematics which also plays a significant role in physics and engineering applications. The CEI-1 is defined by \cite{TableISP2015,Abramo1965}
\begin{equation} \label{eq-K-ku}
K(k) = \int^{\pi/2}_0 \frac{\dif u}{\sqrt{1-k^2 \sin^2 u}}, \quad k\in [0,1].
\end{equation}
For such a special function defined by integral, the computation should be done with proper numerical algorithm. In practical applicaitons, there are different implementations of numerical algorithms for  CEI-1 such as the \lstinline|ellipticK| function in MATLAB and the \lstinline|EllipticK| function in Mathematica. \textbf{Figure}~ \ref{K-numer-commer} illustrates the numerical results obtained by    the functions \lstinline|ellipticK| and \lstinline|EllipticK|. Unfortunately, these results are not acceptable although they are the same essentially.

\begin{figure}[h]
\centering
\subfigure[Output of \lstinline|EllipticK| in Mathematica]{
\boxed{\includegraphics[width=0.45\textwidth]{Fig-7a-EllipticK-Mathematica}}
}
\subfigure[Output of \lstinline|ellipticK| in MATLAB]{
\boxed{\includegraphics[width=0.45\textwidth]{Fig-7b-EllipticK-MATLAB}}
}
\caption{Unacceptable solutions via commercial softwares Mathematica and MATLAB} \label{K-numer-commer}
\end{figure}

Actually, we can find some fundamental types of methods to compute the CEI-1 properly:
\begin{itemize}
	\item expanding the CEI-1 into an infinite series which converges rapidly;
	\item computing the CEI-1 with the arithmetic-geometric mean (AGM) method which converges rapidly and iterates simply;
	\item converting the CEI-1 into a finite sum with $2n-1$ order algebraic precision by taking $n$-th order orthogonal polynomials via Gauss numerical integration approach.
\end{itemize}
The Gauss numerical method can be expressed by	\cite{Atkinson2009}
\begin{equation}
I(f) = \int^b_a \rho(x)f(x)\dif x
	= \sum^n_{i=1}w_if(x_i) + \mathcal{E}_n(f)
\end{equation}
	where $n$ is a positive integer, $\set{x_i: 0 \le i\le n-1}$ is the set of $n$ roots of an orthogonal polynomial, say $ G_n(x)$, $w_i$ are the weights specified by $x_i$ and $G_n(x)$, and $\mathcal{E}_n(f)$ is the error of optimal approximation which will be omitted according to the requirement of precision in practice.
	However, the integral $K(k)$ is more complicated since it is a function  defined by an integral. With the help of the concepts of abstract function defined by an integral, we can use the following form
\begin{equation}
\begin{split}
K(k) &=\int^b_a f(x,k)\dif \mu
= \int^b_a f(x,k)\rho(x)\dif x \\
&= \sum^n_{i=1} w_i f(x_i, k) + \mathcal{E}_n(f).
\end{split}
\end{equation}
	There are two feasible methods in this way:
	\begin{itemize}
		\item Gauss-Chebyshev method, where $\displaystyle \rho(x) = \frac{1}{\sqrt{1-x^2}}$and $b= -a = 1$;
		\item Gauss-Legendre method, where $\rho(x) = 1$, $a=0$ and $b= \pi/2$.
	\end{itemize}

We now discuss the fundamental principles of four methods for computing the $K(k)$ one by one in the following subsections.

In this paper, we will discuss four methods to calculate the special function $K(k)$ as shown in \textbf{Figure}~  \ref{fig-ways2K}.
\begin{figure}[h]
	\centering
	\includegraphics[width=0.5\textwidth]{Fig-5-FourAppr4K}
	\caption{Four methods for computing CEI-1}
	\label{fig-ways2K}
\end{figure}

The contents of this paper are organized as following: section \ref{sec-preliminaryies} deals with the mathematical preliminaries for the infinte series methods, AGM method, Gauss-Chebyshev method and Gauss-Legendre method for computing CEI-1; section \ref{sec-numer-alg} copes with the numerical algorithms for the four methods mentioned above; section \ref{sec-vvt} gives the numerical results for verification and validation of the numerical solvers proposed and finally section \ref{sec-conclusions}  gives the conclusions.

\section{Mathematical Preliminaries} \label{sec-preliminaryies}

\subsection{Infinite Series Method}

The first method for computing the CEI-1 is to take the series expansion of variable $k$. Actually, with the help of the generalized Newton's binomial theorem, we have \cite{TAOCP1}
\begin{equation} \label{eq-alpha-series}
	(1+z)^\alpha = \sum^\infty_{m=0} \binom{\alpha}{m}z^m, \quad \abs{z}\le 1, \forall \alpha \in \mathbb{R}
\end{equation}
where
\begin{equation}
	\binom{\alpha}{0} = 1
\end{equation}
and
\begin{equation}
	\binom{\alpha}{m} = \frac{\alpha(\alpha-1)\cdots(\alpha-m+1)}{m!}=\prod^{m-1}_{i=0}\frac{\alpha-i}{m-i}
\end{equation}
is the binomial coefficient.
Put $z = -k^2 \sin^2 u$ and $\alpha = -\frac{1}{2}$, we can obtain
\begin{equation}
	\frac{1}{ \sqrt{1-k^2\sin^2u}} = \sum^\infty_{m=0}(-1)^m\binom{-\frac{1}{2}}{m}k^{2m}\sin^{2m}u.
\end{equation}
According to the identity
\begin{equation}
	(-1)^m \binom{-r}{m} = \binom{r+m-1}{m}, \quad r\in \mathbb{R}, m\in \mathbb{N}
\end{equation}
and integral formulae
\begin{equation}
	\int^{\pi/2}_0 \sin^{2m} u \dif u = \frac{(2m-1)!!}{(2m)!!}\cdot\frac{\pi}{2}, \quad m\in \mathbb{N}
\end{equation}
where
\begin{equation}
\left\{
	\begin{split}
		(2m-1)!! &= (2m-1)(2m-3)\cdots 3 \cdot 1\\
		(2m)!! &= (2m)(2m-2)\cdots 4\cdot 2\\
		0!! &= (-1)!! = 1
	\end{split}
\right.
\end{equation}
are the double factorial. Therefore, we can find the infinite series for the CEI-1, viz.,
\begin{equation} \label{eq-K-infinite-series}
K(k) = \frac{\pi}{2} \cdot  \sum^\infty_{m=0}\left[\frac{(2m-1)!!}{(2m)!!} \right]^2k^{2m}
\end{equation}
Simple algebraic operations show that
\begin{equation} \label{eq-K-expansion}
K(k)=  \frac{\pi}{2} \cdot\left[ 1 + \frac{1}{4} k^2 + \frac{9}{64} k^4 + \frac{25}{256} k^6 + \cdots \right]
\end{equation}
From a computational point of view, we just need to calculate the sum of a convergent infinite series with the form
\begin{equation} \label{eq-series}
	S = \sum^\infty_{m=0} c_m x^m,
\end{equation}
such that
\begin{equation} \label{eq-cm}
	x = k^2,  \quad c_m = \left[\frac{(2m-1)!!}{(2m)!!}\right]^2, \quad m\in \mathbb{N}
\end{equation}
It is easy to see that the key for determining CEI-1 lies in designing an algorithm for computing the infinite series \eqref{eq-series} and designing a procedure to calculate the coefficient $c_m$ specified by \eqref{eq-cm}.

It should be emphasized that  it is easy to verify that the numerical results illustrated in \textbf{Figure}~ \ref{K-numer-commer} are not correct with the help of \eqref{eq-K-expansion}.

\subsection{AGM Method}

The second method for calculating the CEI-1 is the AGM method proposed by King \cite{King1924AGM}. The AGM method was first discovered by Lagrange and then rediscovered and pushed forward greatly by Gauss. The relation of AGM method and CEI-1 was also discussed by Borwein \cite{Borwein1987} for the purpose of calculating the constant $\pi$.   For the 2-dim sequence $\set{(u_i, v_i)}^\infty_{i=0}$
such that
\begin{equation} \label{eq-AGM}
	\left\{
	\begin{split}
		u_{i+1} &= \frac{u_i +v_i}{2},\quad i\ge 0\\
		v_{i+1} & = \sqrt{u_i \cdot v_i}, \quad i\ge 0\\
		u_0 & = a\\
		v_0 & = b
	\end{split}
	\right.
\end{equation}
it is easy to show that: both the limit of arithmetic mean $u_i$ and the limit of geometric mean $v_i$ exist, and the limits for $u_i$ and $v_i$ are equal. Obviously, the common limit just depends on the initial non-negative values  $a$ and $b$. This limit specified by the arithmetic-geometric mean (AGM) can be denoted by
\begin{equation} \label{eq-agm-limit}
	\AGM(a,b) = \lim_{i\to \infty} u_i = \lim_{i\to \infty} v_i.
\end{equation}

The updating relation in equation \eqref{eq-AGM} implies that both the symmetric property
\begin{equation} \label{eq-AGM-symmetric}
	\AGM(a,b) = \AGM(b,a)
\end{equation}
and the iterative property
\begin{equation} \label{eq-AGM-iterative}
	\AGM(a,b) = \AGM\left(\frac{a+b}{2}, \sqrt{ab}\right)
\end{equation}
hold obviously.

There are lots of formulaes about the AGM and the CEI-1, we just list the following necessary ones according to our requirements:
\begin{align}
	\frac{1}{\AGM(1+x,1-x)} &= \sum^\infty_{m=0} \left[\frac{(2m-1)!!}{(2m)!!} \right]^2x^{2m} \label{eq-AGM-series}\\
	\frac{1}{\AGM(a,b)}
	&=\frac{2}{\pi}\int^{\frac{\pi}{2}}_0 \frac{\dif \theta}{\sqrt{a^2\cos^2 \theta + b^2\sin^2\theta}} \label{eq-AGM-integral}\\
	&=\frac{4}{(a+b)\pi}K\left(\abs{\frac{a-b}{a+b}}\right) \label{eq-AGM-K}
\end{align}
For $k\in [0,1], a = 1+k$ and $b = 1-k$, we can deduce that
\begin{equation}
	K(k) = \frac{\pi/2}{\AGM(1+k,1-k)}
\end{equation}
from \eqref{eq-AGM-series}. Consequently, we can obtain
\begin{equation}
	\AGM(1+k,1-k) = \AGM(1, \sqrt{1-k^2})
\end{equation}
by the iterative property \eqref{eq-AGM-iterative}. Hence we have
\begin{equation}
K(k) = \frac{\pi/2}{\AGM(1+k,1-k)} = \frac{\pi/2}{\AGM(1,\sqrt{1-k^2})}
\end{equation}

This is the famous AGM method proposed by King in 1924.
Thus, in the sense of computation, the calculation of CEI-1 is equivalent to computing the function $\AGM(a,b)$ via iterative algorithm and calling it with 2-dim parameter $(a, b) = (1, \sqrt{1-k^2})$ or equivalently $(a,b) = (1+k, 1-k)$. Moreover, the symmetric property of AGM says that the position of $a$ and $b$ in $\AGM(a,b)$ can be swapped without changing the value.

\subsection{Gauss-Chebyshev Method}

According to Appendix \ref{appendix-ErrEstGC}, for the abstract function
\begin{equation}
	\scrd{F}{C}(k)  = \int^a_{-a} \frac{f(x, k)}{\sqrt{a^2 - x^2}}\dif x
	= \int^1_{-1} \frac{f(at, k)}{\sqrt{1-t^2}}\dif t,
\end{equation}
of the Chebyshev type  defined by the integral of $\displaystyle{\frac{f(x,k)}{\sqrt{a^2-x^2}}}$ with parameter $k$, we can computed
it by the extended Gauss-Chebyshev formulae of numerical integration. Let
$\scru{x}{gc}_i$ denote the $i$-th root of $T_n(x) = \cos(n \arccos x)$, i.e. the $n$-th order Chebyshev polynomial of the first kind, and $\scru{w}{gc}_i$ denote the $i$-th weight corresponding to $\scru{x}{gc}_i$,  then we have
\begin{equation} \label{eq-x-w-gc}
	\scru{x}{gc}_i = \cos \frac{(2i-1)\pi}{2n}, \quad \scru{w}{gc}_i = \frac{\pi}{n}, \quad 1\le i\le n
\end{equation}
and
\begin{equation} \label{eq-F-Chebyshev-sum}
	\scrd{F}{C}(k) = \sum^{n}_{i=1} \scru{w}{gc}_i f(a\scru{x}{gc}_i, k) + \scru{\mathcal{E}}{gc}_n(f,a,k).
\end{equation}
where
\begin{equation}
	\scru{\mathcal{E}}{gl}_n(f,a,k) = \frac{2\pi\cdot a^{2n}}{2^{2n}(2n)!}f^{(2n)}(\xi,k), \quad \xi \in (-a,a)
\end{equation}
is the approximation error.

We now introduce three $n$-dim vectors
\begin{equation}
	\left\{
	\begin{split}
		&\scru{\vec{x}}{gc} = \trsp{[\scru{x}{gc}_1, \cdots, \scru{x}{gc}_n]},\\
		&\scru{\vec{w}}{gc} = \trsp{[\scru{w}{gc}_1, \cdots, \scru{w}{gc}_n]},\\
		&\scru{\vec{v}}{gc}_{f}(k,a) = \trsp{[f(a\scru{x}{gc}_1,k), \cdots, f(a\scru{x}{gc}_n,k)]}
	\end{split}
	\right.
\end{equation}
then CEI-1 can be represented by the inner product of $\scru{\vec{w}}{gc}$ and $\scru{\vec{v}}{gc}_f(k)$, viz.,

\begin{equation} \label{eq-F-Chebyshev-innerproduct}
	\scrd{F}{C}(k) = \braket{\scru{\vec{w}}{gc}}{\scru{\vec{v}}{gc}_{f}(k,a)} + \scru{\mathcal{E}}{gc}_n(f,a,k)
\end{equation}
in which the inner product is defined by
\begin{equation}
	\braket{\vec{w}}{\vec{v}} = \sum^n_{i=1}w_iv_i, \quad \forall \vec{w}, \vec{v}\in \ES{R}{n}{1}.
\end{equation}

Our objective here is to give a computational method for CEI-1 by establishing the relation of CEI-1 and $\scrd{F}{C}(k)$. Let $t= \sin u$, then we have
\begin{equation}
	\begin{split}
		K(k) &= \int^{\pi/2}_0 \frac{\dif t}{\sqrt{1-k^2\sin^2 u}}
		=\int^1_0 \frac{\dif t}{\sqrt{(1-t^2)(1-k^2t^2)}}\\
		&=\int^1_{-1}\frac{1}{\sqrt{1-t^2}}\cdot \frac{1/2}{\sqrt{1-k^2t^2}}\dif t
	\end{split}
\end{equation}
Now put $a=1$ and
\begin{equation}\label{eq-f-gc}
	\scrd{f}{gc}(t,k) = \frac{1/2}{\sqrt{1-k^2t^2}}, \quad t \in(-1,1), k\in[0,\sqrt{2}/2)
\end{equation}
then
\begin{equation}\label{eq-K-gc}
	\boxed{
		\begin{split}
			K(k) &= \sum^{n}_{i=1} \scru{w}{gc}_i \scrd{f}{gc}(\scru{x}{gc}_i, k) + \scru{R}{gc}_n(\scrd{f}{gc})\\
			&=\braket{\scru{\vec{w}}{gc}}{\scru{\vec{v}}{gc}_{\scrd{f}{gc}}(\scru{\vec{x}}{gc},k,1)} +
			\scru{\mathcal{E}}{gc}_n(\scrd{f}{gc},1,k)
		\end{split}
	}
\end{equation}
Therefore, for any $\varepsilon >0$, the CEI-1 can be computed directly with the inner product of vectors $\scru{\vec{w}}{gc}$ and $\scru{\vec{v}}{gc}_{\scrd{f}{gc}}(k,1)$ if we take a sufficiently large $n$ such that $\abs{\scru{\mathcal{E}}{gc}_n(\scrd{f}{gc},1,k)}<\varepsilon$ for approximating the integral with fixed parameter $k$.

\subsection{Gauss-Legendre Method}

According to the Appendix \ref{appendix-ErrEstGL}, the abstract function
\begin{equation}
		\scrd{F}{L}(k)
		=\int^b_a f(x,k)\dif x
		= \frac{b-a}{2}\int^1_{-1} f\left(\frac{b+a}{2}+\frac{b-a}{2}t \right)\dif t
\end{equation}
defined by the integral of $f(x,k)$ with parameter $k$ such that $f(\cdot,k)\in C^{2n}[a,b]$ can be computed by the extended Gauss-Legendre formulae of numerical integration. Let $\scru{x}{gl}_i$ denote the $i$-th root of the $n$-th order Legendre polynomial $P_n(x)$ and
$\scru{w}{gl}_i$ denote the $i$-th weight corresponding to $\scru{x}{gl}_i$ such that
\begin{equation} \label{eq-weight-Legendre}
		\scru{w}{gl}_i
		= \frac{2}{n}\cdot \frac{1}{P_{n-1}(\scru{x}{gl}_i)P'_n(\scru{x}{gl}_i)}
		= \frac{2}{[1-(\scru{x}{gl}_i)^2]\cdot[P'_n(\scru{x}{gl}_i)]^2}
\end{equation}
where $P'_n(x)$ is the derivative function of $P_n(x)$, then we have
\begin{equation}
		\scrd{F}{L}(k)
		 = \frac{b-a}{2}\sum^n_{i=1} \scru{w}{gl}_i
		f\left(\frac{b+a+ (b-a)\scru{x}{gl}_i}{2}, k\right)
		   + \scru{\mathcal{E}}{gl}_n(f,a,b,k)
\end{equation}
where
\begin{equation}
	\scru{\mathcal{E}}{gl}_n(f,a,b,k)
	= \frac{(n!)^4}{[(2n)!]^3}\cdot \frac{(b-a)^{2n+1}}{2n+1}f^{(2n)}(\xi,k)
\end{equation}
is the approximation error in which $\xi\in(a,b)$.

We remark that there are no analytical solutions for the roots of $P_n(x) = 0$ if $n \ge 4$. Fortunately, it can be solved by the Newton's method for nonlinear equation. For small $n$, say $n \le 20$, we can look up some available handbooks of mathematics to get the roots $\set{\scru{x}{gl}_i: 1\le i \le n}$. However, this method is not suggested if the $n$ is unknown or not sure. In this case, a feasible, convenient and effective way is to calculate the roots of $P_n(x)$ automatically with proper algorithms implemented via some concrete computer programming language and programs.

Let
\begin{equation}
	\left\{
	\begin{split}
		&\scru{\vec{x}}{gl}  = \trsp{\left[\scru{x}{gl}_1, \cdots, \scru{x}{gl}_n\right]}\\
		&\scru{\vec{w}}{gl}  = \trsp{\left[\scru{w}{gl}_1, \cdots, \scru{w}{gl}_n\right]}\\
		&\scru{u}{gl}_i  = \frac{b+a + (b-a)\scru{x}{gl}_i}{2}, \quad 1\le i\le n \\
		&\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gl},k,a,b)  = \frac{b-a}{2}\trsp{\left[f(\scru{u}{gl}_i,k), \cdots, f(\scru{u}{gl}_n)\right]}
	\end{split}
	\right.
\end{equation}
then $\scrd{F}{L}(k)$ can be represented by the inner product of $\scru{\vec{w}}{gl}$ and $\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gl},k,a,b)$, viz.,
\begin{equation}
	\scrd{F}{L}(k) = \braket{\scru{\vec{w}}{gl}}{\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gl},k,a,b)} + \scru{\mathcal{E}}{gl}_n(f,a,b,k)
\end{equation}

Suppose that the root-weight pairs $(\scru{x}{gl}_i, \scru{w}{gl}_i)$ for $1\le i\le n$  were known, we can establish the relation of $\scrd{F}{L}(k)$ and CEI-1. For $k\in [0,1)$, let $a=0$, $b= \pi/2$, and
\begin{equation} \label{eq-f-gl}
	\scrd{f}{gl}(u,k) = \frac{1}{\sqrt{1-k^2\sin^2u}}
\end{equation}
then
\begin{equation} \label{eq-K-gl}
	\begin{split}
			K(k) &= \frac{\pi}{4}\sum^n_{i=1} \scru{w}{gl}_i \scrd{f}{gl}\left(\frac{\pi}{4}(1+\scru{x}{gl}_i), k\right)
			+  \scru{\mathcal{E}}{gl}_n\left(\scrd{f}{gl},0,\frac{\pi}{2},k\right) \\
			&= \braket{\scru{\vec{w}}{gl}}{\scru{\vec{v}}{gl}_{\scrd{f}{gl}}(\scru{\vec{x}}{gl},k,0,\frac{\pi}{2})} +   \scru{\mathcal{E}}{gl}_n\left(\scrd{f}{gl},0,\frac{\pi}{2},k\right)
		\end{split}
\end{equation}
For any positive $\varepsilon >0$ and fixed parameter $k\in[0,1)$, we can choose a sufficiently large integer $n$ such that the approximation error is small enough, i.e.,
$$\abs{\scru{\mathcal{E}}{gl}_n\left(\scrd{f}{gl},0,\frac{\pi}{2},k\right)}
< \varepsilon.$$
The expression above for CEI-1 means that the essential work left for calculating $K(k)$ is to find the root-weight pairs for the Legendre polynomial $P_n(x)$.

Although there are several equivalent definitions for the Legendre polynomial, the best way for computing the Legendre polynomial $P_n(x)$ is the following iterative formulae
\begin{equation}
	\left\{
	\begin{split}
		P_n(x) & = \frac{2n-1}{n}xP_{n-1}(x) -\frac{n-1}{n}P_{n-2}(x), ~n \ge 2 \\
		P_0(x) & = 1; \\
		P_1(x) & = x.
	\end{split}
	\right.
\end{equation}
This formulae implies that we can compute $P_n(x)$  one by one with an iterative process.

The Newton's method for solving root of a nonlinear equation $f(x,\alpha) = 0$ with a constant parameter $\alpha$ is specified by the iterative process with the form
\begin{equation} \label{eq-Newton-root-iter}
	\begin{split}
		x[j+1] &= \scrd{\mathcal{A}}{Newton}(x[j])\\
		&= x[j] - \frac{f(x[j],\alpha)}{f'(x[j],\alpha)}, \quad j = 0, 1, 2, \cdots
	\end{split}
\end{equation}
which starts from the initial value (guess of the root) $x[0] = x_0$ and ends when
\begin{equation}
	\abs{x[j+1]-x[j]} < \varepsilon
\end{equation}
for sufficiently large $j$ and fixed computational error $\varepsilon$. The updating mapping $\scrd{\mathcal{A}}{Newton}: x[j]\mapsto x[j+1]$ is a contractive mapping defined by
\begin{equation} \label{eq-Newton-map}
	\begin{split}
		\scrd{\mathcal{A}}{Newton}: \mathbb{R} &\to \mathbb{R} \\
		x &\mapsto x - \frac{f(x,\alpha)}{f'(x,\alpha)}
	\end{split}
\end{equation}

For the Legendre polynomial $P_n(x)$, there are $n$ different roots $\scru{x}{gl}_i$ where $i\in \set{1, 2, \cdots, n}$. The iterative process can be described by
\begin{equation} \label{eq-init-values-for-Pn}
	\left\{
	\begin{split}
		\scru{x}{gl}_i[j+1] &= \scru{x}{gl}_i[j] - \frac{P_n(\scru{x}{gl}_i[j])}{P'_n(\scru{x}{gl}_i[j])}, \quad j = 0, 1, 2 \cdots \\
		\scru{x}{gl}_i[0]   &= \cos \frac{\pi(i + 0.75)}{n + 0.25}, \quad 1\le i \le n.
	\end{split}
	\right.
\end{equation}
This iterative process is the basis for designing algorithm for solving the roots of interest. Note that we can set $f(x,\alpha) = P_n(x)$ where $\alpha = n$ here.

\section{Numerical Algorithms} \label{sec-numer-alg}

Different numerical algorithms can be obtained according to the four methods discussed to compute the CEI-1 efficiently, robustly and precisely. In order to broaden the applications of the algorithms, we will generalize some specific constants to corresponding variables.

\subsection{Infinite Series Algorithm}

The equation \eqref{eq-K-infinite-series} and its connection with the general infinite series show that there are some key  issues for computing CEI-1:
\begin{itemize}
	\item designing an algorithm to compute the general infinite series $S(x) = \sum\limits_{m=0}^\infty c_m x^m$ which consists of four sub-tasks:
	\begin{itemize}
		\item calculating the coefficient $c_m$ for each $m\in \mathbb{N}$,
		\item computing the value of the general term $c_m x^m$ for fixed $x\in \mathbb{R}$,
		\item deciding whether the general term $c_mx^m$ is negligible  or not for the sum of the infinite series, and
		\item calculating the sum of the not-negligible terms;
	\end{itemize}
	\item specifying the parameters involved
	\begin{itemize}
		\item designing a procedure to compute the coefficient $c_m$ in the infinite series of CEI-1, and
		\item specifying the variable $x$ according to its connection with the variable $k$, i.e., $x = k^2$.
	\end{itemize}
	\item calling the procedure for the infinite series and multiplying some constant if necessary.
\end{itemize}

The procedures for calculating CEI-1 with infinite series method is shown in
\textbf{Figure}~ \ref{fig-Kseries-procedures}, in which \PtrToFun{CoefFun} is a procedure name (pointer to function or similar entity)  used to calling the procedure of computing $c_m$.

\begin{figure}[h]
	\centering
	\begin{forest}
		[\fbox{\ProcName{Kseries}}
		[\fbox{\ProcName{InfinteSeriesSolver}}
		[\PtrToFun{CoefFun}[\fbox{\ProcName{CalcCoefCm}}]]
		[\fbox{\ProcName{IsNegligible}}]
		]
		]
	\end{forest}
	\caption{Procedures involved in calculating the complete elliptic integral CEI-1 with infinite series method.}
	\label{fig-Kseries-procedures}
\end{figure}

There is a practical technique for computing $c_m$. The double factorials $(2m)!!$ and $(2m-1)!!$ may be large numbers if $m>10$ and the overflow problem may happen in some computer language if the type of data is integer. However, we can cope with the the value of fraction safely instead of dealing with its denominator and numerator separately. Actually, we have

\begin{equation}
		\frac{(2m-1)!!}{(2m)!!}
		=\prod^{m-1}_{i=0}\frac{2(m-i)-1}{2(m-i)}
		=\prod^{m}_{i=1}\left[
		1-\frac{0.5}{i}\right], \quad m \ge 1.
\end{equation}

Thus the fraction $\frac{(2m-1)!!}{(2m)!!} $ can be computed by multiplying  $1-0.5/i$ one by one with a simple iteration, which not only reduces the computational complexity but also avoid the overflow problem of the factorial operations. \textbf{Algorithm}~ \ref{alg-CalcCoefCm} gives the steps of procedure \ProcName{CalcCoefCm}  for computing the coefficient $c_m =\frac{(2m-1)!!}{(2m)!!}$  by the for-loop construction in computer programming language.

\begin{breakablealgorithm}
	\caption{Calculate the coefficient $c_m=\left(\frac{(2m-1)!!}{(2m)!!}\right)^2$ for the $m$-th term of the infinite series for CEI-1} \label{alg-CalcCoefCm}
	\begin{algorithmic}[1]
		\Require Non-negative integer $m$;
		\Ensure The coefficient $c_m$ of the infinite series in the function $K(k)=\frac{\pi}{2}\sum\limits^\infty_{m=0}c_mk^{2m}$
		\Function{CalcCoefCm}{$m$}
		\If{$m == 0$}
		\State \Return 1;
		\EndIf
		\State $\cpvar{prod} \gets 1$;
		\For{$i\in\seq{1,2,\cdots,m-1,m}$}
		\State $\cpvar{prod} \gets \cpvar{prod} \cdot (1 - 0.5/i)$;
		\EndFor
		\State $c_m \gets \cpvar{prod} \cdot \cpvar{prod}$;
		\State \Return $c_m$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

For a fixed $x$, the value of the infinite series $S(x) = \sum\limits^\infty_{m=0}c_mx^m$ is defined by
\begin{equation}
	S(x) = \lim_{m\to \infty} S_m(x), \quad S_m(x)=\sum^{m-1}_{i=0}c_ix^i
\end{equation}
The Cauchy's criteria of convergence shows that the sequence $\set{S_m(x)}^\infty_{m=0}$ converges if and only if
\begin{equation}
	\forall \varepsilon>0, \quad \abs{S_m(x) - S_{m-1}(x)} = \abs{c_mx^m} < \varepsilon.
\end{equation}
In practice, the relative error relation $\frac{\abs{S_m(x) - S_{m-1}(x)} }{\abs{S_m(x)}}< \varepsilon$ is better than the absolute error relation $\abs{S_m(x) - S_{m-1}(x)}< \varepsilon $.  This fact can be used to design the procedure for deciding whether the general term $c_mx^m$ is negligible or not.

\begin{breakablealgorithm}
	\caption{Decide whether the general term $c_mx^m$ is negligible or not}  \label{alg-IsNotNeglegible}
	\begin{algorithmic}[1]
		\Require The value of the general term $c_mx^m$: $\cpvar{term}$, the sum of finite terms: $\cpvar{sum}$, and the value of error (precision) $\varepsilon$ with default value $\varepsilon = 10^{-9}$.
		\Ensure  The logical value $\texttt{TRUE}$ or $\texttt{FALSE}$
		\Function{IsNegligible}{$\cpvar{term},\cpvar{sum},\varepsilon$}
		\State Set a sufficiently small number: $\delta \gets 10^{-10}$;
		\If{$\abs{\cpvar{term}}/(\abs{\cpvar{sum}} + \delta) < \varepsilon$}
		\State   \Return $\texttt{TRUE}$;
		\Else
		\State  \Return $\texttt{FALSE}$;
		\EndIf
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\textbf{Algorithm}~ \ref{alg-IsNotNeglegible}, named by \ProcName{IsNegligible}, is utilized to decide whether the $m$-th term $c_m x^m$ is important for the sum of infinite series $\sum\limits_{m=0}^\infty c_mx^m$ or not. We remark that in \textbf{Algorithm}~ \ref{alg-IsNotNeglegible} the small number $\delta$ is used to improve the robustness when $\abs{S_m(x)}$ is near to zero.

The procedure for solving the infinite series $\sum\limits^\infty_{m=0}c_mx^m$ can be designed with a do-while or while-do loop, which is named with \ProcName{InfiniteSeriesSolver}  and shown in \textbf{Algorithm}~ \ref{alg-InfinteSeriesSolver}. Obviously, the computation of CEI-1 is treated as a special problem of sovling the infinite series by designing a system with the strategy of top-down.

\begin{breakablealgorithm}
	\caption{Calculate the sum of the convergent infinite series $\displaystyle\sum^\infty_{m=0} c_m x^m$ (\ProcName{InfinteSeriesSolver})}
	\label{alg-InfinteSeriesSolver}
	\begin{algorithmic}[1]
		\Require Pointer to function $\PtrToFun{CoefFun}: \mathbb{N}\to \mathbb{R}$  for comoputing the coefficient $c_m$,  variable $x$, and precision $\varepsilon$ with default value $\varepsilon = 10^{-9}$.
		\Ensure The sum of the infinite series
		\Function{InfinteSeriesSolver}{$\PtrToFun{CoefFun}, x, \varepsilon$}
		\State Set initial values: $\cpvar{sum}\gets 0, \cpvar{term} \gets 0,
		m \gets 0$;
		\Repeat
		\State $c_m \gets \PtrToFun{CoefFun}(m)$;
		\State $\cpvar{term} \gets c_m\cdot x^m$;
		\State $\cpvar{sum} \gets \cpvar{sum} + \cpvar{term}$;
		\State $m \gets m + 1$;
		\Until{$(~!~\ProcName{IsNeglibible}(\cpvar{term}, \cpvar{sum}, \varepsilon))$}
		\State \Return \cpvar{sum};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

It should be noted that the function $\PtrToFun{CoefFun}: \mathbb{N}\to \mathbb{R}$ is used as an argument for the procedure \ProcName{InfiniteSeries} in \textbf{Algorithm}~ \ref{alg-InfinteSeriesSolver}, which implies that the \ProcName{InfiniteSeries} is a high order function and the pointer to function will be involved for the implementation with different computer programming languages. We remark that the pointer to function is a concept in the C programming language and its counterparts in Python and MATLAB are lambda expression and function handle respectively.

Now we can design the procedure  for calculating the CEI-1  conveniently. \textbf{Algorithm}~ \ref{alg-Kseries} describes the procedure \ProcName{Kseries} for computing CEI-1 with the infinite series method.
\begin{breakablealgorithm}
	\caption{Calcualting the function CEI-1 with the infinite series method (\ProcName{Kseries})}
	\label{alg-Kseries}
	\begin{algorithmic}[1]
		\Require The variable $k\in[0,1)$, precision $\varepsilon$ with the default value $\varepsilon = 10^{-9}$.
		\Ensure The value of CEI-1
		\Function{Kseries}{$k, \varepsilon$}
		\State $\PtrToFun{CoefFun}\gets \ProcName{CalcCoefCm}$;
		\State $x\gets k^2$; // Attention, please!
		\State $\cpvar{sum} \gets \ProcName{InfinteSeriesSolver}(\PtrToFun{CoefFun}, x, \varepsilon)$;
		\State $K \gets \cpvar{sum} \cdot \pi/2$;
		\State \Return $K$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\subsection{AGM Algorithm}

The key issue of the AGM is to compute the limits
$\lim\limits_{i\to \infty} u_i$ and $\lim\limits_{i\to \infty} v_i$ according to \eqref{eq-AGM}.
The procedures for calculating CEI-1 with the AGM method is shown in \textbf{Figure}~ \ref{fig-Kagm-procedures}, in which \PtrToFun{Update} and \PtrToFun{Dist} are two pointers to functions and will be assigned by \ProcName{AgmUpdate} in \textbf{Algorithm}~ \ref{alg-AgmUpdate} and \ProcName{DistEuclid} in \textbf{Algorithm}~ \ref{alg-DistEuclid} respectively.

\begin{figure}[h]
	\centering
	\begin{forest}
		[\fbox{\ProcName{Kagm}}
		[\fbox{\ProcName{AGM}}
		[\fbox{\ProcName{FixedPointSolver}}
		[\PtrToFun{Update}[\fbox{\ProcName{AgmUpdate}}]]
		[\PtrToFun{Dist}[\fbox{\ProcName{DistEuclid}}]]
		]
		[$a$]
		[$b$]
		[$\varepsilon$]
		]
		]
	\end{forest}
	\caption{Procedures for calculating CEI-1 with AGM method.}
	\label{fig-Kagm-procedures}
\end{figure}

Let $\vec{x} = \trsp{[x_1, x_2]}\in \ES{R}{2}{1}$,
then the AGM method can be converted to a 2-dim fixed-point problem with the iterative formulae
\begin{equation} \label{eq-fixed-point}
	\vec{x}_{i+1} = \scrd{\mathcal{A}}{agm}(\vec{x}_i), \quad i= 0, 1, 2, \cdots
\end{equation}
such that $\vec{x}_i \in \ES{R}{2}{1}_+$ and
\begin{equation} \label{eq-agm-iter}
	\scrd{\mathcal{A}}{agm}(\vec{x}) = \begin{bmatrix}
		(x_1+x_2)/2\\
		\sqrt{x_1x_2}
	\end{bmatrix}, \quad
	\vec{x}_0 = \begin{bmatrix}a\\b\end{bmatrix}
\end{equation}
for non-negative $a$ and $b$.
The Banach's fixed-point theorem in functional analysis shows that \eqref{eq-fixed-point} is convergent when $\scrd{\mathcal{A}}{agm}$ is contractive ($\norm{\scrd{\mathcal{A}}{agm}} < 1$). Without doubt, \eqref{eq-agm-iter} satisfies the convergent condition for any non-negative components $a$ and $b$ of the initial vector $\vec{x}_0$.

The updating process in AGM method gives a typical nonlinear mapping which is described by the procedure \ProcName{AgmUpdate} in \textbf{Algorithm}~ \ref{alg-AgmUpdate}.
\begin{breakablealgorithm}
	\caption{AGM updating (\ProcName{AgmUpdate})}
	\label{alg-AgmUpdate}
	\begin{algorithmic}[1]
		\Require {2-dim vector $\vec{x}=\trsp{[x_1, x_2]}$}
		\Ensure 2-dim vector $\vec{y} = \mathcal{A}(\vec{x})$
		\Function{AgmUpdate}{$\vec{x}$}
		\State $y_1 \gets (x_1+x_2)/2$;
		\State $y_2 \gets \sqrt{x_1 x_2}$;
		\State $\vec{y} \gets \trsp{[y_1, y_2]}$;
		\State \Return $\vec{y}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

It is wise to design a general algorithm for solving the fixed-point in a general way since the fixed-point may be frequently encountered in different STEM problems. The computation of fixed-point is based on the concept of norm. In consequence, it is necessary to design the norm for the vector $\vec{x}$. Usually, the Euclidean norm $\norm{\vec{x}} = \sqrt{\sum\limits^n_{j=1}x^2_j}$ for $\vec{x}=\trsp{[x_1, \cdots, x_n]}\in \ES{R}{n}{1}$ will be a good choice and the induced 2-dim Euclidean distance will be
\begin{equation}
	\dist(\vec{x}, \vec{y}) =\normp{\vec{x}-\vec{y}}{2}
	= \sqrt{\sum^n_{j=1}(x_j-y_j)^2}
\end{equation}
for $\vec{x} = \trsp{[x_1, \cdots, x_n]}$ and $\vec{y} = \trsp{[y_1, \cdots, y_n]}$.
The procedure \ProcName{DistEuclid} described in \textbf{Algorithm}~ \ref{alg-DistEuclid} is used to compute the $n$-dim Euclidean distance.
\begin{breakablealgorithm}
	\caption{Calculate the Euclidean distance of two $n$-dim vectors (\ProcName{DistEuclid}).}
	\label{alg-DistEuclid}
	\begin{algorithmic}[1]
		\Require Two $n$-dim vectors $\vec{x},\vec{y}\in \ES{R}{n}{1}$.
		\Ensure The distance between $\vec{x}$ and $\vec{y}$.
		\Function{DistEuclid}{$\vec{x}, \vec{y}, n$}
		\State $\cpvar{sum} \gets 0$ ;
		\For{$i\in \set{1, \cdots, n}$}
		\State $\cpvar{sum} \gets \cpvar{sum} + (x_i - y_i)^2$;
		\EndFor
		\State $\cpvar{dist} \gets \sqrt{\cpvar{sum}}$;
		\State \Return $\cpvar{dist}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

The iterative process of AGM implies a special kind of iteration of fixed-point, which can be computed in a generic way with the help of while-do or do-while loop. The procedure \ProcName{FixedPointSolver}, as shown in \textbf{Algorithm}~ \ref{alg-AbstractFixedPointSolver}, computes the $n$-dim fixed-point iteratively. Note that the pointers to functions, viz. \PtrToFun{Update} and \PtrToFun{Dist} should be assigned with concrete procedures according to the data type of $\vec{x}$.

\begin{breakablealgorithm}
	\centering
	\caption{Compute the abstract fixed-point iteratively
		(\ProcName{AbstractFixedPointSolver})}\label{alg-AbstractFixedPointSolver}
	\begin{algorithmic}[1]
		\Require Dimension $n$, initial data $\vec{x}_0$, precision $\varepsilon$, updating function $\PtrToFun{Update}$ for the contractive mapping $\mathcal{A}: \mathcal{V}\to \mathcal{V}$, and distance function $\PtrToFun{Dist}: \mathcal{V}\times \mathcal{V}\to \mathbb{R}^+$.
		\Ensure The fixed-point $\vec{x}$ such that $\vec{x} = \mathcal{A}(\vec{x})$.
		\Function{AbstractFixedPointSolver}{$n$, \PtrToFun{Update}, \PtrToFun{Dist}, $\vec{x}_0$, $\varepsilon$}
		\State $\cpvar{guess} \gets \vec{x}_0$;
		\State $\cpvar{improve}\gets  \PtrToFun{Update}(\vec{x}_0)$;
		\While{$(\PtrToFun{Dist}(\cpvar{guess}, \cpvar{improve}, n) \ge \varepsilon)$}
		\State $\cpvar{guess} \gets \cpvar{improve}$;
		\State $\cpvar{improve}\gets  \PtrToFun{Update}(\cpvar{guess})$;
		\EndWhile
		\State \Return \cpvar{improve};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

If the general Banach space $\mathcal{V}$ is just the $n$-dim Euclidean space $\ES{R}{n}{1}$ and the distance is just the Eudlidean distance, then the computation of distance will be easy. Consequently, we can design a procedure \ProcName{FixedPointSolver} for computing the fixed-point in $\ES{R}{n}{1}$. For more details, please see
\textbf{Algorithm}~ \ref{alg-FixedPointSolver}.

For the AGM problem concerned, we have the dimension $n = 2$ and the 2-dim vectors can be represented by a 1-dim array of size $2$ or \cpvar{struct} with two components when coding with some concrete computer programming language. Therefore, the AGM method can be implemented by taking the
procedure \ProcName{FixedPointSolver}  in \textbf{Algorithm}~ \ref{alg-FixedPointSolver}  and assigning the pointers to function \PtrToFun{Update} with the procedures \ProcName{AgmUpdate} in
\textbf{Algorithm}~ \ref{alg-AgmUpdate}. Once the iteration ends, we can return the arithmetic mean or the geometric mean in the 2-dim vector according to \eqref{eq-agm-limit}. For more details, please see the procedure \ProcName{AGM} in \textbf{Algorithm}~ \ref{alg-AGM}.

\begin{breakablealgorithm}
	\centering
	\caption{Compute the $n$-dim fixed-point $\vec{x}\in \ES{R}{n}{1}$ such that $\vec{x} = \mathcal{A}(\vec{x})$ with iterative method  (\ProcName{FixedPointSolver}). }
	\label{alg-FixedPointSolver}
	\begin{algorithmic}[1]
		\Require Dimension $n$, initial data $\vec{x}_0$, precision $\varepsilon$, updating function $\PtrToFun{Update}$ for the contractive mapping $\mathcal{A}: \ES{R}{n}{1}\to \ES{R}{n}{1}$.
		\Ensure The $n$-dim fixed-point $\vec{x}\in \ES{R}{n}{1}$ such that $\vec{x} = \mathcal{A}(\vec{x})$.
		\Function{FixedPointSolver}{$n$, \PtrToFun{Update}, $\vec{x}_0$, $\varepsilon$}
		\State $\cpvar{guess} \gets \vec{x}_0$;
		\State $\cpvar{improve}\gets  \PtrToFun{Update}(\vec{x}_0)$;
		\While{$(\ProcName{DistEuclid}(\cpvar{guess}, \cpvar{improve}, n) \ge \varepsilon)$}
		\State $\cpvar{guess} \gets \cpvar{improve}$;
		\State $\cpvar{improve}\gets  \PtrToFun{Update}(\cpvar{guess})$;
		\EndWhile
		\State \Return \cpvar{improve};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the value of the arithmetic-geometric mean of non-negative values $a$ and $b$ (\ProcName{AGM}).}
	\label{alg-AGM}
	\begin{algorithmic}[1]
		\Require Non-negative values $a$ and $b$ and precision $\varepsilon$.
		\Ensure The value of the AGM for $a$ and $b$.
		\Function{AGM}{$a,b, \varepsilon$}
		\State $\vec{x}_0 \gets \trsp{[a,b]}$;
		\State $\PtrToFun{Update}\gets \ProcName{AgmUpdate}$;
		\State $\PtrToFun{Dist}\gets \ProcName{DistEuclid}$;
		\State $\cpvar{dim} \gets 2$;
		\State $\vec{x}\gets \ProcName{FixedPointSolver}
		(\cpvar{dim}, \PtrToFun{Update}, \PtrToFun{Dist}, \vec{x}_0, \varepsilon)$;
		\State \Return $x_1$;  // return one component of $\vec{x}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

The procedure for computing CEI-1 with the AGM method, named by \ProcName{Kagm}, is illustrated in \textbf{Algorithm}~~\ref{alg-Kagm} in which the procedure \ProcName{AGM} is called directly by setting proper parameters $a \gets 1$ and $b \gets \sqrt{1-k^2}$.

\begin{breakablealgorithm}
	\caption{Calculate the CEI-1 with the AGM method (\ProcName{Kagm})}
	\label{alg-Kagm}
	\begin{algorithmic}[1]
		\Require The variable $k\in[0,1)$, precision $\varepsilon$ with default value $\varepsilon = 10^{-9}$.
		\Ensure The value of CEI-1
		\Function{Kagm}{$k, \varepsilon$}
		\State $a \gets 1$;
		\State $b \gets \sqrt{1-k^2}$;
		\State $K \gets (\pi/2)/\ProcName{AGM}(a,b, \varepsilon)$;
		\State \Return $K$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\subsection{Gauss-Chebyshev Algorithm}

The algorithm of Gauss-Chebyshev for computing CEI-1 is relatively simple due to the
equations \eqref{eq-x-w-gc}, \eqref{eq-f-gc} and \eqref{eq-K-gc}.
\textbf{Figure}~\ref{fig-Kintgc-procedures} demonstrates the procedures involved in calculating CEI-1 with the Gauss-Chebyshev method.

\begin{figure}[h] \label{fig-Kintgc-relations}
	\centering
	\begin{forest}
		[\fbox{\ProcName{Kintgc}}
		[\fbox{\ProcName{IntegralSolverGC}}
		[\PtrToFun{f}[\fbox{\ProcName{KerGC}}]]
		[\fbox{\ProcName{InnerProduct}}
		[$\scru{\vec{w}}{gc}$
		[\fbox{\ProcName{CalcWeightsGC}}]
		]
		[$\scru{\vec{v}}{gc}_f$
		[\fbox{\ProcName{CalcVectorVfGC}}
		[$\scru{\vec{x}}{gc}$
		[\fbox{\ProcName{CalcRootsChebyshev}}]
		]
		[\PtrToFun{f}]
		[$n$]
		[$k$]
		[$a$]
		]
		]
		[$n$]
		]
		]
		]
	\end{forest}
	\caption{Procedures involved in calculating complete elliptic integral CEI-1 with Gauss-Chebyshev method.}
	\label{fig-Kintgc-procedures}
\end{figure}
The computation of CEI-1 is recognized as a special problem of solving the general numerical integration
$\scrd{F}{C}(k)$ according to  \eqref{eq-F-Chebyshev-innerproduct}, which corresponds to the procedure
\ProcName{IntegralSolverGC} in \textbf{Algorithm}~ \ref{alg-IntegralSolverGC},
by setting the pointer to function \PtrToFun{f} with \ProcName{KerGC} in \textbf{Algorithm}~ \ref{alg-KerGC}.

We now give some interpretation for designing  the algorithm:
\begin{itemize}
	\item The procedure \ProcName{KerGC} in \textbf{Algorithm}~ \ref{alg-KerGC} is defined to compute the function $\displaystyle \scrd{f}{gc}(t,k) = \frac{1/2}{\sqrt{1-k^2t^2}}$ and
	use a pointer to function \cpvar{KerFun} to represent the $\scrd{f}{gc}$ in the design and implementation of the algorithm.
	\item
	The root vector $\scru{\vec{x}}{gc}$ is set by the procedure \ProcName{CalcRootschebyshev} in  \textbf{Algorithm}~ \ref{alg-CalcRootsChebyshev}.
	\item
	The value of integral is computed by the procedure \ProcName{InnerProduct} in \textbf{Algorithm}~ \ref{alg-InnerProduct}.
	\item The arguments of \textbf{Algorithm}~ \ref{alg-CalcRootsChebyshev}, namely the vector $\scru{\vec{w}}{gc}$ and vector $\scru{\vec{v}}{gc}_f(\scru{\vec{x}}{gc}, k, a)$,  are calculated by the procedures \ProcName{CalcWeightsGC} in \textbf{Algorithm}~ \ref{alg-CalcWeightsGC} and
	\ProcName{CalcVectorVfGC} in \textbf{Algorithm}~ \ref{alg-CalcVectorVfGC} respectively.
\end{itemize}

\begin{breakablealgorithm}
	\caption{Calcualte the integral  (abstract function)
		\[
		\scrd{F}{C}(y) = \int^a_{-a} \frac{f(x,k)}{\sqrt{a^2 - x^2}}\dif x = \braket{\scru{\vec{w}}{gc}}{\scru{\vec{v}}{gc}_f(\scru{\vec{x}}{gc}, k,a)} + \mathcal{E}_n(f)
		\]
		with the parameter $k$ via the $n$-nodes Gauss-Chebyshev numerical integration method (\ProcName{IntegralSolverGC}).}
	\label{alg-IntegralSolverGC}
	\begin{algorithmic}[1]
		\Require Variable $k$, pointer to function $\PtrToFun{f}: \mathbb{R} \times \mathbb{R} \to \mathbb{R}$, positive integral $n$, $n$-dim root vector $\scru{\vec{x}}{gc}$, $n$-dim weight vector $\scru{\vec{w}}{gc}$, positive  $a$.
		\Ensure The value  of $\scrd{F}{C}(y)$.
		\Function{IntegralSolverGC}{$k, \PtrToFun{f}, n, \scru{\vec{x}}{gc}, \scru{\vec{w}}{gc}, a$}
		\State $\scru{\vec{v}}{gc}\gets \ProcName{CalcVectorVfGC}(
		\PtrToFun{f}, n, \scru{\vec{x}}{gc}, k, a)$;
		\State $\cpvar{I}\gets \ProcName{InnerProduct}(\scru{\vec{w}}{gc}, \scru{\vec{v}}{gc}, n)$;
		\State \Return \cpvar{I};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the function $\scrd{f}{gc}(t,k)$ in the Gauss-Chebyshev method for calculating the value CEI-1 (\ProcName{KerGC})}
	\label{alg-KerGC}
	\begin{algorithmic}[1]
		\Require {Variables $t\in [-1,1], k\in [0,1)$}
		\Ensure The value of $\scrd{f}{gc}(t,k)$
		\Function{KerGC}{$t,k$}
		\State $u \gets kt$;
		\State $v\gets 0.5/\sqrt{1-u^2}$;
		\State \Return $v$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the root vector for the $n$ roots of the Chebyshev polynomial $T_n(x)=\cos(n\arccos x)$ (\ProcName{CalcRootsChebyshev})}
	\label{alg-CalcRootsChebyshev}
	\begin{algorithmic}[1]
		\Require {Positive integer $n$.}
		\Ensure The $n$ roots of $T_n(x)$.
		\Function{CalcRootsChebyshev}{$n$}
		\For{$i\in \set{1, \cdots, n}$}
		\State $\scru{x}{gc}_i \gets \cos \cfrac{(2i-1)\pi}{2n}$;
		\EndFor
		\State \Return $\scru{\vec{x}}{gc}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the inner product of two $n$-dim vectors. (\ProcName{InnerProduct})}
	\label{alg-InnerProduct}
	\begin{algorithmic}[1]
		\Require Two vectors $\vec{w}$ and $\vec{v}$, dimension $n$ of the vectors.
		\Ensure Inner product $\braket{\vec{w}}{\vec{v}}=\sum\limits^n_{i=1}w_iv_i$.
		\Function{InnerProduct}{$\vec{w},\vec{v}, n$}
		\State $\cpvar{sum} \gets 0$;
		\For{$i\in \set{1,\cdots, n}$}
		\State $\cpvar{sum} \gets \cpvar{sum} + w_i\cdot v_i$;
		\EndFor
		\State \Return \cpvar{sum};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the weight vector $\scru{\vec{w}}{gc}$ for the abstract function (parametric integral with parameter $k$)
		$\scrd{F}{C}(k) = \displaystyle{\int^a_{-a} \frac{f(x,k)}{\sqrt{a^2 -x^2}}\dif x} = \braket{\scru{\vec{w}}{gc}}{\scru{\vec{v}}{gc}_f(\scru{\vec{x}}{gc},k,a)} + \mathcal{E}_n(f)$ with the $n$-nodes Gauss-Chebyshev numerical integration method (\ProcName{CalcWeightsGC})}
	\label{alg-CalcWeightsGC}
	\begin{algorithmic}[1]
		\Require Positive integer $n$
		\Ensure The weight vector $\scru{\vec{w}}{gc}$
		\Function{CalcWeightsGC}{$n$}
		\For{$i\in \set{1, \cdots, n}$}
		\State $\scru{w}{gc}_i \gets \pi/n$;
		\EndFor
		\State \Return $\scru{\vec{w}}{gc}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the vector $\scru{\vec{v}}{gc}_f(\scru{\vec{x}}{gc}, k,a)$ of function $f(x,k)$ at the x-nodes with the coordinates $\scru{u}{gc}_i=a \scru{x}{gc}_i$ (\ProcName{CalcVectorVfGC}).}
	\label{alg-CalcVectorVfGC}
	\begin{algorithmic}[1]
		\Require Pointer to function $\PtrToFun{f}: \mathbb{R}\times \mathbb{R} \to \mathbb{R}$, positive integer $n$, $n$-dim root vector $\scru{\vec{x}}{gc}$, positive $a$, and variable $k$.
		\Ensure The vector $\scru{\vec{v}}{gc}_f(k,a)$.
		\Function{CalcVectorVfGC}{\PtrToFun{f}, $n$, $\scru{\vec{x}}{gc}$, $k$, $a$}
		\For{$i\in \set{1, \cdots, n}$}
		\State $\scru{v}{gc}_i \gets \PtrToFun{f}(a\cdot \scru{x}{gc}_i, k)$ ;
		\EndFor
		\State \Return $\scru{\vec{v}}{gc}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the CEI-1 with the Gauss-Chebyshev method (\ProcName{Kintgc})}
	\label{alg-Kintgc}
	\begin{algorithmic}[1]
		\Require Variable $k\in [0,1)$, positive integer $n$ with default value $n = 50$
		\Ensure The value of CEI-1
		\Function{Kintgc}{$k, n$}
		\State $\scru{\vec{x}}{gc}\gets \ProcName{CalcRootsChebyshev}(n)$;
		\State $\scru{\vec{w}}{gc}\gets \ProcName{CalcWeightsGC}(\scru{\vec{x}}{gc},n)$;
		\State $\PtrToFun{f}\gets \ProcName{KerGC}$;
		\State $a\gets 1.0$;
		\State $K \gets \ProcName{IntegralSolverGC}(k, \PtrToFun{f}, n, \scru{\vec{x}}{gc}, \scru{\vec{w}}{gc}, a)$;
		\State \Return $K$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\subsection{Gauss-Legendre Algorithm}

The key idea of the Gauss-Legendre method is the same as that of the Gauss-Chebyshev. However, it is more complex due to the following reasons:
\begin{itemize}
	\item it is necessary for us to compute the Legendre polynomials $P_n(x)$ and their derivatives $P'_n(x)$ automatically;
	\item the root vector $\scru{\vec{x}}{gl} = \trsp{\left[\scru{x}{gl}_1, \cdots,\scru{x}{gl}_n\right]}$ of $P_n(x)$ must be solved iteratively with the Newton's method;
	\item the weight vector $\scru{\vec{w}}{gl}=\trsp{\left[\scru{w}{gl}_1, \cdots, \scru{w}{gl}_n\right]}$ must be solved with the help of $\scru{\vec{x}}{gl}$, $P_n(x)$ and $P'_n(x)$;
	\item the Newton's method for solving roots of nonlinear equation should be designed.
\end{itemize}
The strategy for design algorithm for CEI-1 with Gauss-Legendre method is still top-down. In other words, we first design an algorithm to the general problem of computing the integral $\displaystyle{\int^b_a f(x,k)\dif x} = \braket{\scru{\vec{w}}{gl}}{\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gc}, k,a,b)} + \mathcal{E}_n(f)$ with
inner product, then we calculate the vectors $\scru{\vec{x}}{gl}$ and $\scru{\vec{w}}{gl}$ with orthogonal polynomials and Newton's method for solving roots.

There is also an alternative way to get the root vector $\scru{\vec{x}}{gl}$  and $\scru{\vec{w}}{gl}$ by reading some handbooks about special functions and/or numerical analysis. However, the tables obtained are just for some fixed significant digits and fixed order $n$ such that $n \le 20$ for $P_n(x)$. It is necessary for us to point out that a smart way born in 1900s is not always a wise way in 2020s. Moreover, the tables given in references can be used to check whether the output of the implementation of our algorithms is correct or not. It is a good idea that we respect the tradition, stand on the tradition, but also try to go beyond the tradition.

The complete design for the algorithm of Gauss-Legendre for CEI-1 can be divided into four subtasks. We now discuss them one-by-one with a strategy of top-down. \textbf{Figure}~
\ref{fig-Kgl-procedures} demonstrates the structure of  procedures in the Gauss-Legendre method.

\begin{figure}[h]
	\centering
	\begin{forest}
		[\fbox{\ProcName{Kintgl}}
		[\fbox{\ProcName{IntegralSolverGL}}
		[\PtrToFun{f}[\fbox{\ProcName{KerGL}}]]
		[\fbox{\ProcName{InnerProduct}}
		[$\scru{\vec{w}}{gl}$[\fbox{\ProcName{CalcWeightsGL}}]]
		[$\scru{\vec{v}}{gl}_f$
		[\fbox{\ProcName{CalcVectorVfGL}}
		[$\scru{\vec{x}}{gl}$
		[\fbox{\ProcName{CalcRootsLegendre}}]
		]
		[\PtrToFun{f}]
		[$n$]
		[$k$]
		[$a$]
		[$b$]
		]
		]
		[$n$]
		]
		]
		]
	\end{forest}
	\caption{Procedures involved in calculating the complete elliptic integral CEI-1 with Gauss-Legendre method.}
	\label{fig-Kgl-procedures}
\end{figure}

\subsection{Compute CEI-1 with the Gauss-Legendre based on the roots, weights and kernel function}.

Firstly, recognize the computation of CEI-1 as a special problem of computing the integral $\scrd{F}{L}(k)$ with numerical integration via  \eqref{eq-f-gl} and  \eqref{eq-K-gl}. The procedure \ProcName{IntegralSolverGL} in \textbf{Algorithm}~ \ref{alg-IntegralSolverGL} is used to compute $\scrd{F}{L}(k)$ based on the
procedure \ProcName{InnerProduct} in \textbf{Algorithm}~ \ref{alg-InnerProduct} and the procedure \ProcName{KerGL} in \textbf{Algorithm}~ \ref{alg-KerGL} to compute the function $\scrd{f}{gl}(t,k) = 1/\sqrt{1-k^2\sin^2t}$.

\begin{breakablealgorithm}
	\caption{Calcualte the parametric integral
		$$\displaystyle
		\scrd{F}{L}(y) =\int^b_a f(x,k)\dif x = \braket{\scru{\vec{w}}{gl}}{\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gl},k,a,b)} + \mathcal{E}_n(f)
		$$
		via the $n$-nodes Gauss-Legendre numerical integration method (\ProcName{IntegralSolverGL}).}
	\label{alg-IntegralSolverGL}
	\begin{algorithmic}[1]
		\Require Variable $k$, pointer to function $\PtrToFun{f}: \mathbb{R} \times \mathbb{R} \to \mathbb{R}$, positive integral $n$, $n$-dim root vector $\scru{\vec{x}}{gl}$, $n$-dim weight vector $\scru{\vec{w}}{gl}$, variable $a$ and variable $b$.
		\Ensure The value  of $\scrd{F}{L}(y)$.
		\Function{IntegralSolverGL}{$k$, \PtrToFun{f}, $n$, $\scru{\vec{x}}{gl}$, $\scru{\vec{w}}{gl}$, $a$, $b$}
		\State $\scru{\vec{v}}{gl}\gets \ProcName{CalcVectorVfGL}(
		\PtrToFun{f}, n, \scru{\vec{x}}{gl}, k, a, b)$;
		\State $\cpvar{I}\gets \ProcName{InnerProduct}(\scru{\vec{w}}{gl}, \scru{\vec{v}}{gl}, n)$;
		\State \Return \cpvar{I};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the function $\scrd{f}{gl}(t,k)$ in the Gauss-Legendre method for calculating the value CEI-1 (\ProcName{KerGL})}
	\label{alg-KerGL}
	\begin{algorithmic}[1]
		\Require Variables $t\in [-1,1], k\in [0,1)$
		\Ensure The value of $\scrd{f}{gl}(t,k)$
		\Function{KerGL}{$t,k$}
		\State $u \gets k\cdot \sin t$;
		\State $v\gets 1/\sqrt{1-u^2}$;
		\State \Return $v$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the vector $\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gl},k,a,b)$ of function $f(x,k)$ at the x-nodes with the coordinates $\scru{u}{gl}_i=\left[b+a + (b-a)\scru{x}{gc}_i\right]/2$ (\ProcName{CalcVectorVfGL}).}
	\label{alg-CalcVectorVfGL}
	\begin{algorithmic}[1]
		\Require Pointer to function $\PtrToFun{f}: \mathbb{R}\times \mathbb{R} \to \mathbb{R}$, order $n$, $n$-dim root vector $\scru{\vec{x}}{gl}$, variable $a$, variable $b$, and variable $k$.
		\Ensure Vector $\scru{\vec{v}}{gc}_f(\scru{\vec{x}}{gl},k,a,b)$.
		\Function{CalcVectorVfGL}{\PtrToFun{f}, $n$, $\scru{\vec{x}}{gc}$, $k$, $a$, $b$}
		\For{$i\in \set{1, \cdots, n}$} \quad //$\scru{v}{gl}_{f,i}(\scru{\vec{x}}{gl},k,a,b)$;
		\State $\scru{u}{gl} \gets (b+a + (b-a)\scru{x}{gc}_i)/2$;
		\State $\scru{v}{gl}_i \gets \PtrToFun{f}(\scru{u}{gl}, k)\cdot \frac{b-a}{2}$;
		\EndFor
		\State \Return $\scru{\vec{v}}{gl}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the CEI-1 with the Gauss-Legendre method (\ProcName{Kintgl})}
	\label{alg-Kintgl}
	\begin{algorithmic}[1]
		\Require The variable $k\in [0,1)$, positive integer $n$ with default value $n = 50$
		\Ensure The value of CEI-1
		\Function{Kintgl}{$k, n$}
		\State $\scru{\vec{x}}{gl}\gets \ProcName{CalcRootsLegendre}(n)$;
		\State $\scru{\vec{w}}{gl}\gets \ProcName{CalcWeightsGL}(\scru{\vec{x}}{gl},n)$;
		\State $\PtrToFun{f}\gets \ProcName{KerGL}$;
		\State $a\gets 0$;
		\State $b\gets \pi/2$;
		\State $K \gets \ProcName{IntegralSolverGL}(k, f, n, \scru{\vec{x}}{gl},
		\scru{\vec{w}}{gl}, a, b)$;
		\State \Return $K$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\subsection{Generating the Weights Specified by the Legendre polynomial and its Derivative}

The weight vector $\scru{\vec{w}}{gl}$ for the Gauss-Legendre numerical integration can be generated with the help of the root vector $\scru{\vec{x}}{gl}$. 	According to \eqref{eq-weight-Legendre}, we design a procedure \ProcName{CalcWeightsGL} in \textbf{Algorithm}~ \ref{alg-CalcWeightsGL} to calculate $\scru{\vec{w}}{gl}$ by calling the procedure \ProcName{DerivPolynomLegendre} in \textbf{Algorithm}~ \ref{alg-DerivPolynomLegendre}. The details for the procedure \ProcName{CalcWeightsGL} are given in \textbf{Algorithm}~~\ref{alg-CalcWeightsGL}, which is a direct translation of \eqref{eq-weight-Legendre} from mathematics to pseudo-code. The structure of procedures for calculating the weights is shown in \textbf{Figure}~ \ref{fig-Kintgl-calc-weights}.

\begin{figure}[h]
	\centering
	\begin{forest}
		[\fbox{\ProcName{CalcWeightsGL}}
		[$\scru{\vec{x}}{gc}$[\fbox{\ProcName{CalcRootsLegendre}}]]
		[$P'_n(x)$[\fbox{\ProcName{DerivPolynomLegendre}}]]
		]
	\end{forest}
	\caption{Procedures involved in computing the $n$ weights for the numerical integration with Gauss-Legendre method.} \label{fig-Kintgl-calc-weights}
\end{figure}

\begin{breakablealgorithm}
	\caption{Calculate the weight vector $\scru{\vec{w}}{gl}$ for the abstract function (parametric integral with parameter $k$)
		$\scrd{F}{L}(k) = \displaystyle{\int^b_a f(x,k)\dif x} = \braket{\scru{\vec{w}}{gl}}{\scru{\vec{v}}{gl}_f(\scru{\vec{x}}{gl},k,a,b)} + \mathcal{E}_n(f)$ with the $n$-nodes Gauss-Legendre numerical integration method (\ProcName{CalcWeightsGL}).}
	\label{alg-CalcWeightsGL}
	\begin{algorithmic}[1]
		\Require Positive integer $n$ for the number of weights, root vector
		$\scru{\vec{x}}{gl}$ of $P_n(x)$.
		\Ensure Weight vector $\scru{\vec{w}}{gl}$ for the Gauss-Legendre numerical integration.
		\Function{CalcWeightsGL}{$\scru{\vec{x}}{gl}, n$}
		\For{$i\in \set{1, \cdots, n}$}
		\State $u \gets \ProcName{DerivPolynomLegendre}(\scru{x}{gl}_i,n)$;
		\State $\scru{w}{gl}_i \gets \cfrac{2}{[1-(\scru{x}{gl}_i)^2]u^2}$;
		\EndFor
		\State \Return $\scru{\vec{w}}{gl}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\subsection{Solving the $n$ Roots of the Legendre Polynomial $P_n(x)$}

The steps for solving the $n$ roots of $P_n(x)$  lie in three issuses:
\begin{itemize}
	\item designing the update procedure \ProcName{NewtonUpdate} in \textbf{Algorithm}~ \ref{alg-NewtonUpdate}  by using $P_n(x)$ with the iteration formulae in Newton's method;
	\item setting proper initial values $\scru{x}{gl}_i[0]$ for the $n$ roots of $P_n(x)$ according to  \eqref{eq-init-values-for-Pn} and call the procedure \ProcName{CalcRootsLegendre} in \textbf{Algorithm}~ \ref{alg-CalcRootsLegendre};
	\item computing one root of $P_n(x)$ by the Newton's method encapsulated by the procedure \ProcName{RootSolverOrthoPolynom}  in \textbf{Algorithm}~ \ref{alg-RootSolverOrthPolynom}.
\end{itemize}
The structure of procedures for calculating the roots is illustrated in \textbf{Figure}~ \ref{fig-calc-roots-Legendre-procedures}.

\begin{figure}[h]
	\centering
	\begin{forest}
		[\fbox{\ProcName{CalcRootsLegendre}}
		[\fbox{\ProcName{RootSolverOrthoPolynom}}
		[\fbox{\ProcName{IsGoodEnough}}[\fbox{\ProcName{DistEuclid}}]]
		[\fbox{\ProcName{NewtonUpdate}}
		[\PtrToFun{Df}[\fbox{\ProcName{DerivPolynomLegendre}}]]
		[\PtrToFun{f}[\fbox{\ProcName{PolynomLegendre}}]]
		]
		]
		]
	\end{forest}
	\caption{Procedures involved in calculating the $n$ roots of $P_n(x)$. }
	\label{fig-calc-roots-Legendre-procedures}
\end{figure}

\begin{breakablealgorithm}
	\caption{Calculte the root of orthogonal polynomial $Y_n(x)$ with an initial value $x_0$ via Newton's method (\ProcName{RootSolverOrthoPolynom}). }
	\label{alg-RootSolverOrthPolynom}
	\begin{algorithmic}[1]
		\Require Pointer to function  $\PtrToFun{f}: \mathbb{R} \times \mathbb{N}\to \mathbb{R}$ for $Y_n(x)$,  pointer to function $\PtrToFun{Df}: \mathbb{R} \times \mathbb{N}\to \mathbb{R}$ for the derivative function $Y'_n(x)$, initial value $x_0$, order $n$, and the precision $\varepsilon$.
		\Ensure The root $x$ of $Y_n(x) = 0$ iterated from $x_0$.
		\Function{RootSolverOrthoPolynom}{\PtrToFun{f}, \PtrToFun{Df}, $x_0$, $n$, $\varepsilon$}
		\State $\cpvar{guess}\gets 0$ ;
		\State $\cpvar{improve} \gets x_0$;
		\Repeat
		\State \cpvar{guess} $\gets$ \cpvar{improve};
		\State \cpvar{improve}   $\gets$ \ProcName{NewtonUpdate}(\PtrToFun{f}, \PtrToFun{Df}, \cpvar{guess}, $n$);
		\Until{$(\ProcName{DistEuclid}(\cpvar{guess}, \cpvar{improve},1)\ge \varepsilon)$}
		\State \Return \cpvar{improve};
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Updating function $\scrd{\mathcal{A}}{Newton}$ for solving a root of the orthogonal polynomial $Y_n(x)$ with the Newton method  (\ProcName{NewtonUpdate}).}
	\label{alg-NewtonUpdate}
	\begin{algorithmic}[1]
		\Require Two pointers to function:  \PtrToFun{f} and \PtrToFun{Df} for $Y_n(x)$ and its derivative $Y'_n(x)$ respectively, variable $x$ and order $n\in \mathbb{N}$.
		\Ensure Updated value of the approximation for the root of interest
		\Function{NewtonUpdate}{\PtrToFun{f}, \PtrToFun{Df}, $x$, $n$}
		\State $\cpvar{slope}\gets \PtrToFun{Df}(x,n)$; // Compute  $Y'_n(x)$
		\State \ProcName{CheckSlope}(\cpvar{slope});  // Check $Y'_n(x)$;
		\State $\scrd{x}{new}  \gets x - \cfrac{\PtrToFun{f}(x, n)}{\cpvar{slope}}$;
		// $x_{i+1} = x_i - \cfrac{Y_n(x_i)}{Y'_n(x_i)}$
		\State \Return $\scrd{x}{new} $;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Check whether the slope/derivative at point $x$ is zero or not (\ProcName{CheckSlope}).}
	\label{alg-CheckSlope}
	\begin{algorithmic}[1]
		\Require The slope (value of derivative function) $\cpvar{slope}$
		\Ensure Void or exception information if necessary
		\Function{CheckSlope}{\cpvar{slope}}
		\State $\delta \gets 10^{-10}$;
		\If{($\abs{\cpvar{slope}}< \delta$)}
		\State  \cpvar{Print Exception Information!}
		\State  \textbf{Exit};
		\EndIf
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Calculate the $n$-dim root vector  $\scru{\vec{x}}{gl}=\trsp{[\scru{x}{gl}_1, \cdots, \scru{x}{gl}_n]}$ of the $n$--th order Legendre polynomial $P_n(x)$ such that
		$P_n(\scru{x}{gl}_i) = 0$ for $1\le i\le n$ (\ProcName{CalcRootsLegendre}).}
	\label{alg-CalcRootsLegendre}
	\begin{algorithmic}[1]
		\Require Positive integer $n$
		\Ensure The root vector $\scru{\vec{x}}{gl}$ of $P_n(x)$
		\Function{CalcRootsLegendre}{$n$}
		\State Allocate memory for $\scru{\vec{x}}{gl}=\trsp{[\scru{x}{gl}_1, \cdots, \scru{x}{gl}_n]}$;
		\State $\varepsilon \gets 10^{-9}$; //set the precision for root
		\State $\PtrToFun{f} \gets \ProcName{PolynomLegendre}$;  // $f (x)= P_n(x)$
		\State $\PtrToFun{Df} \gets \ProcName{DerivPolynomLegendre}$; // $f'=P'_n(x)$
		\For{$i\in \set{1,2,\cdots,n}$}
		\State $x_0 \gets \cos \cfrac{\pi(i+0.75)}{n+0.25}$; //initial value;
		\State $\scru{x}{gl}_i\gets$ \ProcName{RootSolverOrthoPolynom}(\PtrToFun{f}, \PtrToFun{Df}, $x_0$, $n$, $\varepsilon$);
		\EndFor
		\State \Return $\scru{\vec{x}}{gl}$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\subsection{Generating the Legendre polynomials and their derivatives}

The general form of four typical different orthogonal polynomials (such as Legendre polynomials $P_n(x)$, Chebyshev polynomials $T_n(x)$, Laguerre polynomials $L_n(x)$ and Hermite polynomials $H_n(x)$), denoted by $Y_n(x)$,  can be specified by the following iterative formulae
\begin{equation}
	\left\{
	\begin{split}
		Y_n(x) & = (A_nx + B_n)Y_{n-1}(x) - C_n Y_{n-2}(x), \quad  n\ge 2	 \\
		Y_0(x) & = c_0 \\
		Y_1(x) & = c_1 x + c_2
	\end{split}
	\right.
\end{equation}
where $c_0, c_1, c_2$ are constants, $A_n, B_n, C_n$ are functions depending on $n$.
Taking the derivative on the two sides, we immediately have
\begin{equation}
	\left\{
	\begin{split}
		Y'_n(x) &= A_n Y_{n-1}(x) + (A_nx + B_n)Y'_{n-1}(x)
		- C_n Y'_{n-2}(x) \\
		Y'_0(x) & = 0 \\
		Y'_1(x) & = c_1
	\end{split}
	\right.
\end{equation}
where $n\ge 2$.
Particularly, let
\begin{equation}
	\left\{
	\begin{split}
		\scru{A}{le}_n &= \frac{2n-1}{n}, \scru{B}{le}_n = 0, \scru{C}{le}_n = \frac{n-1}{n} \\
		\scru{c}{le}_0 &= 1,\scru{c}{le}_1 = 1, \scru{c}{le}_2 = 0
	\end{split}
	\right.
\end{equation}
then for $n\ge 2$ we can deduce that
\begin{equation}
	\left\{
	\begin{split}
		P_n(x) & = \scru{A}{le}_nxP_{n-1}(x) - \scru{C}{le}_n P_{n-2}(x)	 \\
		P_0(x) & = 1 \\
		P_1(x) & = x
	\end{split}
	\right.
\end{equation}
and
\begin{equation}
	\left\{
	\begin{split}
		P'_n(x) &= \scru{A}{le}_n P_{n-1}(x) + \scru{A}{le}_nxP'_{n-1}(x)
		- \scru{C}{le}_n P'_{n-2}(x) \\
		P'_0(x) & = 0 \\
		P'_1(x) & = 1
	\end{split}
	\right.
\end{equation}
This implies that we can compute the $n$-th order Legendre polynomial $P_n(x)$ and its derivative $P'_n(x)$ iteratively with a  strategy of top-down:
\begin{itemize}
	\item firstly, we design general procedures \ProcName{OrthoPolynom} in \textbf{Algorithm}~ \ref{alg-OrthoPolynom} and \ProcName{DerivOrthoPolynom} in \textbf{Algorithm}~ \ref{alg-DerivOrthoPolynom} for generating $Y_n(x)$ and $Y'_n(x)$ respectively with the iterative formulaes directly;
	\item secondly, we design specific procedures --- \ProcName{AnLegendre} in \textbf{Algorithm}~ \ref{alg-AnLegendre}, \ProcName{BnLegendre} in \textbf{Algorithm}~ \ref{alg-BnLegendre} and \ProcName{CnLegendre} in \textbf{Algorithm}~ \ref{alg-CnLegendre} --- to calculate $A(n), B(n)$ and $C(n)$ respectively and use pointer to functions to compute the Legendre polynomials $P_n(x)$ and $P'_n(x)$.
\end{itemize}
The procedures involved in computing the Legendre polynomial $P_n(x)$ and its derivative $P'_n(x)$ are illustrated in \textbf{Figure}~\ref{fig-procs-Pn} and  \textbf{Figure}~ \ref{fig-procs-Deriv-Pn} respectively.

\begin{figure}[htp]
	\centering
	\begin{forest}
		[\fbox{\ProcName{PolynomLegendre}}
		[\fbox{\ProcName{OrthoPolynom}}
		[\PtrToFun{A}[\fbox{\ProcName{AnLegendre}}]]
		[\PtrToFun{B}[\fbox{\ProcName{BnLegendre}}]]
		[\PtrToFun{C}[\fbox{\ProcName{CnLegendre}}]]
		]
		]
	\end{forest}
	\caption{Procedures for calculating $P_n(x)$ with a top-down strategy: \PtrToFun{A}, \PtrToFun{B} and \PtrToFun{C} are pointers to function with the assignments $\PtrToFun{A}\gets \ProcName{AnLegendre}$, $\PtrToFun{B}\gets \ProcName{BnLegendre}$ and $\PtrToFun{C}\gets \ProcName{CnLegendre}$ respectively. }
	\label{fig-procs-Pn}
\end{figure}

\begin{figure}[htp]
	\centering
	\begin{forest}
		[\fbox{\ProcName{DerivPolynomLegendre}}
		[\fbox{\ProcName{DerivOrthoPolynom}}
		[\PtrToFun{A}[\fbox{\ProcName{AnLegendre}}]]
		[\PtrToFun{B}[\fbox{\ProcName{BnLegendre}}]]
		[\PtrToFun{C}[\fbox{\ProcName{CnLegendre}}]]
		]
		]
	\end{forest}
	\caption{Procedures for calculating $P'_n(x)$ with a top-down strategy: \PtrToFun{A}, \PtrToFun{B} and \PtrToFun{C} are pointers to function with the assignments $\PtrToFun{A}\gets \ProcName{AnLegendre}$, $\PtrToFun{B}\gets \ProcName{BnLegendre}$ and $\PtrToFun{C}\gets \ProcName{CnLegendre}$ respectively. }
	\label{fig-procs-Deriv-Pn}
\end{figure}

\begin{breakablealgorithm}
	\caption{Compute the orthogonal polynomials $Y_n(x)$ according to the iterative formulaes. (\ProcName{OrthoPolynom})}
	\label{alg-OrthoPolynom}
	\begin{algorithmic}[1]
		\Require The variable $x$, order $n\in \mathbb{N}$, three constants$\set{c_0, c_1, c_2}$, three pointers to function  $\PtrToFun{A}, \PtrToFun{B},\PtrToFun{C}: \mathbb{N}\to \mathbb{R}$.
		\Ensure The value of $Y_n(x)$
		\Function{OrthoPolynom}{$x,n,c_0,c_1,c_2, \PtrToFun{A},\PtrToFun{B},\PtrToFun{C})$}
		\State $Y_0 \gets c_0$;   // $Y_0(x) = c_0$;
		\State $Y_1 \gets c_1 x + c_2$;  // $Y_1(x) = c_1 x +c_2$;
		\State $Y_n \gets 0$;  // Initialize $Y_n(x)$ with $0$;
		\If{$(n == 0)$}  \State $Y_n \gets Y_0$; \EndIf
		\If{$(n == 1)$}  \State $Y_n \gets Y_1$; \EndIf
		\For{$k\in \set{2, \cdots, n}$}
		\State $Y_n \gets (\PtrToFun{A}(k) \cdot x + \PtrToFun{B}(k))\cdot Y_1 - \PtrToFun{C}(k)\cdot Y_0$;
		\State $Y_0\gets Y_1$; // Update $Y_{k-2}(x)$ with $Y_{k-1}(x)$;
		\State $Y_1\gets Y_n$; // Update $Y_{k-1}(x)$ with $Y_{k}(x)$;
		\EndFor
		\State \Return $Y_n$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the derivative $Y'_n(x)$ of the orthogonal polynomial $Y_n(x)$ according to the
		iterative formulaes (\ProcName{DerivOrthoPolynom}).}
	\label{alg-DerivOrthoPolynom}
	\begin{algorithmic}[1]
		\Require The variable $x$, order $n\in \mathbb{N}$,  constants $c_0, c_1$ and $c_2$, three pointers to function  \PtrToFun{A}, \PtrToFun{B} and \PtrToFun{C}.
		\Ensure The value of the derivative function $Y'_n(x)$
		\Function{DerivOrthoPolynom}{$x$,$n$,$c_0$,$c_1$,$c_2$,\PtrToFun{A},\PtrToFun{B},\PtrToFun{C}}
		\State $Y_0 \gets c_0$;  // $Y_0(x) = c_0$
		\State $Y_1 \gets c_1 x + c_2$;  // $Y_1(x) =c_1 x + c_2$
		\State $ Y'_0 \gets 0$; // $Y_0(x) = c_1 \Longrightarrow Y'_0(x)=0$
		\State $Y'_1 \gets c_1$; // $ Y_1(x) = c_1x+c_2 \Longrightarrow Y'_1(x)=c_1$
		\State $Y_n \gets 0$;  // Initialize $Y_n(x)$ with $0$
		\State $Y'_n \gets 0$;  // Initialize $Y'_n(x)$ with $0$;
		\If{$(n == 0)$}
		\State $Y_n \gets Y_0$;
		\State $Y'_n \gets Y'_0$;
		\EndIf
		\If{$(n == 1)$}
		\State $Y_n \gets Y_1$;
		\State $Y'_n \gets Y'_0$;
		\EndIf
		\For{$k\in \set{2, \cdots, n}$}
		\State  $Y_n \gets (\PtrToFun{A}(k) \cdot x + \PtrToFun{B}(k))\cdot Y_1 - \PtrToFun{C}(k)\cdot Y_0$;
		\State  $Y'_n \gets \PtrToFun{A}(k)\cdot Y_1 + (\PtrToFun{A}(k) \cdot x + \PtrToFun{B}(k))\cdot Y'_1  - \PtrToFun{C}(k)\cdot Y'_0$;
		\State  $Y_0\gets Y_1$;  // Update $Y_{k-2}(x)$ with $Y_{k-1}(x)$;
		\State $Y_1\gets Y_n$;   // Update $Y_{k-1}(x)$ with $Y_k(x)$;
		\State $Y'_0\gets Y'_1$; // Update $Y'_{k-2}(x)$ with $Y'_{k-1}(x)$;
		\State  $Y'_1\gets Y'_n$;// Update $Y'_{k-1}(x)$ with $Y'_k(x)$;
		\EndFor
		\State \Return $Y'_n$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the coefficient $A(n)$ in the iterative formulae for Legendre polynomial (\ProcName{AnLegendre}).}
	\label{alg-AnLegendre}
	\begin{algorithmic}[1]
		\Require Order $n\in \mathbb{N}$
		\Ensure The value of $\scru{A}{le}_n$
		\Function{AnLegendre}{$n$}
		\State  $A\gets 2.0 -1.0/n$;
		\State \Return $A$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the coefficient $B(n)$ in the iterative formulae for Legendre polynomial (\ProcName{BnLegendre}).}
	\label{alg-BnLegendre}
	\begin{algorithmic}[1]
		\Require Order $n\in \mathbb{N}$
		\Ensure The value of $\scru{B}{le}_n$
		\Function{BnLegendre}{$n$}
		\State \Return $0$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the coefficient $C(n)$ in the iterative formulae for Legendre polynomial (\ProcName{CnLegendre}).}
	\label{alg-CnLegendre}
	\begin{algorithmic}[1]
		\Require Order $n\in \mathbb{N}$
		\Ensure The value of $\scru{C}{le}_n$
		\Function{CnLegendre}{$n$}
		\State $C\gets 1.0 -1.0/n$;
		\State \Return $C$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the Legendre Polynomial $P_n(x)$ (\ProcName{PolynomLegendre}).}
	\label{alg-PolynomLegendre}
	\begin{algorithmic}[1]
		\Require The variable $x$, order $n\in \mathbb{N}$
		\Ensure The value of $P_n(x)$
		\Function{PolynomLegendre}{$x,n$}
		\State $c_0\gets 1, c_1\gets 1, c_2 \gets 0$;
		\State $\PtrToFun{A}\gets \ProcName{AnLegendre}$;
		\State $\PtrToFun{B}\gets \ProcName{BnLegendre}$;
		\State $\PtrToFun{C}\gets \ProcName{CnLegendre}$;
		\State $P_n \gets \ProcName{OrthoPolynom}(x,n,c_0,c_1,c_2,\PtrToFun{A},\PtrToFun{B},\PtrToFun{C})$;
		\State \Return $P_n$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

\begin{breakablealgorithm}
	\caption{Compute the derivative of Legendre polynomial (\ProcName{DerivPolynomLegendre}).}
	\label{alg-DerivPolynomLegendre}
	\begin{algorithmic}[1]
		\Require The variable $x$, order $n\in \mathbb{N}$
		\Ensure  The derivative of $P_n(x)$, i.e., the value of $P'_n(x)$
		\Function{DerivPolynomLegendre}{$x,n$}
		\State $c_0\gets 1$;
		\State $c_1\gets 1$;
		\State $c_2 \gets 0$;
		\State $\PtrToFun{A}\gets \ProcName{AnLegendre}$;
		\State $\PtrToFun{B}\gets \ProcName{BnLegendre}$;
		\State $\PtrToFun{C}\gets \ProcName{CnLegendre}$;
		\State $P'_n \gets \ProcName{DerivOrthoPolynom}(
		x,n,c_0,c_1,c_2,\PtrToFun{A},\PtrToFun{B},\PtrToFun{C})$;
		\State \Return $P'_n$;
		\EndFunction
	\end{algorithmic}
\end{breakablealgorithm}

It should be remarked that designing is a mixture of multiple factors in a general viewpoint.  Our discussion is limited in a narrow perspective which emphasizing algorithm design. For more deep thinking about design, please see Brooks' famous book on design\cite{Brooks2010}.

\section{Verification, Validation and Testing} \label{sec-vvt}

For the algorithms desined for computing the CEI-1, it is  necessary for us to construct some simple but useful test cases for verification, validation and testing.

The verification of the four methods for solving CEI-1 is simple if each modules involved have been verified and validated. In Appendix \ref{sec-testcases-VVT}, we illustrate some typical test cases and omit the details for testing the modules for constructing the four numerical solvers for CEI-1 since it is  simple and straight forward. After that, what we need do is just to compare the values of $K(k)$ obtained by \textbf{Algorithm}~ \ref{alg-Kseries}, \textbf{Algorithm}~ \ref{alg-Kagm}, \textbf{Algorithm}~ \ref{alg-Kintgc} and \textbf{Algorithm}~ \ref{alg-Kintgl}.

\textbf{Table}~ \ref{tab-comparison-K-solvers} shows the difference of numerical solvers. It is easy to find that
\begin{itemize}
\item Our four numerical algorithms lead to the same output and the correctness can be verified by the $\ProcName{Kseries}$ since it is based on the expansion of formulae \eqref{eq-K-expansion} which is right definitely and can be handled manually.
\item The available funcitons \lstinline|ellipticK| in MATLAB and
\lstinline|EllipticK| in Mathematica have consistent numerical solutions, which implies that the algorithms adopted may be the same although the solutions are not acceptable.
\end{itemize}
\begin{table}[H]
\centering
\caption{A comparison of numerical solvers for $K(k)$}
\label{tab-comparison-K-solvers}
\begin{tabular}{cccc}
\hline
\makecell[c]{\textbf{Parameter} \\ $\quad$ \\ $k$ }  & \makecell[c]{\textbf{CEI-1 Solvers} \\ $\ProcName{Kseries/Kagm}$ \\ $\ProcName{Kintgc/Kintgl}$ } & \makecell[c]{\textbf{MATLAB}\\ function \\  \lstinline|ellipticK| } & \makecell[c]{\textbf{Mathematica} \\ function \\ \lstinline|EllipticK|} \\
\hline
$0.00$  &    1.5707963    &    1.5708     &  1.57080  \\
$0.10$  &    1.5747456    &    1.6124     &  1.61244  \\
$0.20$  &    1.5868678    &    1.6596     &  1.65962  \\
$0.30$  &    1.6080486    &    1.7139     &  1.71389  \\
$0.40$  &    1.6399999    &    1.7775     &  1.77752  \\
$0.50$  &    1.6857504    &    1.8541     &  1.85407  \\
\hline
\end{tabular}
\end{table}
The algorithms developed in this paper can be obtained at the GitHub site \url{https://github.com/GrAbsRD/CEI-1/tree/main}, where a long table with filename \lstinline|Kvalues.txt| for the values of $K(k)$ is provided and the reader can run the code to verify the algorithms and reuse the code according to his/her interests.

\begin{table*}[htbp]
\centering
\caption{Validation of CEI-1 via Precision of Computation}
\label{tab-comp-precision}
\begin{tabular}{p{2.5cm}p{3cm}p{8cm}}
\hline
\textbf{Type of Solver}  & \makecell[l]{\textbf{Algorithm} \\ \textsc{Procedure}} &   \makecell[l]{\textbf{Default Value of Precision}: Relative or Absolute Error \\ Configuration of Parameters for Numerical Integration}  \\
\hline \hline
IS-CEI-1 & \makecell[l]{\textbf{Algorithm}~ \ref{alg-Kseries} \\ $\ProcName{Kseries}(k,\varepsilon)$}   &   Relative error  $\varepsilon = 10^{-9}$ \\
\hline
AGM-CEI-1 & \makecell[l]{\textbf{Algorithm}~ \ref{alg-AGM} \\ $\ProcName{Kagm}(k,\varepsilon)$}
&  Absolute error $\varepsilon = 10^{-9}$ \\
\hline
GC-CEI-1  & \makecell[l]{\textbf{Algorithm}~ \ref{alg-Kintgc}  \\ $\ProcName{Kintgc}(k,n)$}    &  \makecell[l]{Absolute error: $\abs{\scru{\mathcal{E}}{gc}_n(\scrd{f}{gc},1,k)} < \varepsilon = 10^{-9} $  \\
 $(k,n) \in \set{(0.1, 4), (0.2, 5), (0.3, 6), (0.4, 7), (0.5, 8)}$ }   \\
\hline
GL-CEI-1  & \makecell[l]{\textbf{Algorithm}~ \ref{alg-Kintgl} \\ $\ProcName{Kintgl}(k,n)$}    &  \makecell[l]{Absolute error: $\abs{\scru{\mathcal{E}}{gl}_n(\scrd{f}{gl},0,\pi/2,k)} < \varepsilon = 10^{-9} $   \\  $(k,n) = (0.1, 2)$ }   \\
\hline
\end{tabular}
\end{table*}

We remark that the validation of the four methods for computing $K(k)$ should be noted because there are different parameters which control the precision of computation. As shown in \textbf{Table}~ \ref{tab-comp-precision}, it is not difficult to find the following features:
\begin{itemize}
\item For the IS-CEI-1 solver, the meaning of relative precision $\varepsilon$ is clear, and the absolute error is also applicable.
\item For the AGM-CEI-1 solver, the meaning of absolute error is clear, and the relative error could be adopted easily.
\item For the GC-CEI-1 solver, $n$ is an implicit parameter for control the precision. Given the absolute error $\varepsilon$ and the parameter $k$, we should estimate the integer $\scru{n}{gc}_f$ mentioned in Appendix \ref{appendix-ErrEstGC} such that
\begin{equation}
\abs{\scru{\mathcal{E}}{gc}_n(f,1,k)}<\varepsilon
\end{equation}
for $n > \scru{n}{gc}_f$.
\item For the GL-CEI-1 solver, $n$ is also an implicit parameter for control the precision. Given the absolute error $\varepsilon$ and the parameter $k$, we should estimate  the integer $\scru{n}{gl}_f$ mentioned in Appendix \ref{appendix-ErrEstGL} such that
\begin{equation}
\abs{\scru{\mathcal{E}}{gl}_n(f, 0, \pi/2,k)}<\varepsilon
\end{equation}
for $n > \scru{n}{gl}_f$.
\end{itemize}

Why do we use the implicit parameter $n$ instead of the
explicit parameter $\varepsilon$ to control the precision of computation in the GC-CEI-1 and GL-CEI-1 methods? The answer lies in the difficulty of estimating the upper bounds of $\abs{\scrd{f}{gc}^{(2n)}(\xi,k)}$ and  $\abs{\scrd{f}{gl}^{(2n)}(\xi,k)}$ for $\xi \in (-1,1)$ and $k\in [0,\sqrt{2}/2]$. Consequently, it is difficult for us to design algorithms to estimate the  $\scru{n}{gl}_f$ and $\scru{n}{gc}_f$ with the precision $\varepsilon$ directly. This feature gives us a good example to demonstrate the advantages and disadvantages of the methods and algorithms developed.
It is valuable in the sense of education although it is a pity in the sense of engineering. For the readers who cares the controllability of the iteration numbers $n$ according to the precision $\varepsilon$ in the MP problem, we suggest the Newton-Costes method in numerical integration.

\section{Conclusions} \label{sec-conclusions}

The numerical schemes for computing the CEI-1 is essential for its applications. The available numerical solutions obtained by MATLAB and Mathematica are not acceptable, which implies that  we should pay attention to the verification, validation and tesing stage  in research, development and STEM education in order to avoid unnecessary losses.

Theorec analysis shows that the correctness of the numerical solution can be verified by the analytic formulae in the form of infinite series. As alternative choices, we proposed four feasible numerical schemes and designed  the \ProcName{Kseries}, \ProcName{Kagm}, \ProcName{Kintgc} and \ProcName{Kintgl} solvers for CEI-1 to obtain consistent numerical results based on infinite series method, AGM method, Gauss-Chebyshev \& Gauss-Legendre numerical integrations. The key algorithms developed have been verified, validated and tested.

Although our direct purpose lies in provide correct and replacable numerical algorithms for the CEI-1 in MATLAB and Mathematica, the methods adopted can also be  used for the complete elliptic integrals of the second and third kinds. Furthermore, the key modules designed for the four solvers are designed for  more general problems so as to satisfy various applications as more as possible. Particularly, the iterative algorithms for generating orthogonal polynomials with iterative formulae $Y_n(x) = [A(n)x + B(n)]Y_{n-1}(x) - C(n) Y_{n-2}(x)$  and their derivatives can be taken to compute the  Legendre, Chebyshev, Laguerre and Hermite polynomials which have wide applications in mathematics, physics and engineering.


Cumulative probability for the sum of exponentially-distributed variables

Abstract: Exponential distributions appear in a wide range of applications including chemistry, nuclear physics, time series analyses, and stock market trends. There are conceivable circumstances in which one would be interested in the cumulative probability distribution of the sum of some number of exponential variables, with potentially differing constants in their exponents. In this article we present a pedagogical derivation of the cumulative distribution, which reproduces the known formula from power density analyses in the limit that all of the constants are equal, and which assumes no prior knowledge of combinatorics except for some of the properties of a class of symmetric polynomials in $n$ variables (Schur polynomials).

\section{Introduction}

In many circumstances, a system can be considered to have no ``memory", in the sense that, for example, the expected amount of time to the next radioactive decay, or chemical reaction, or failure of a machine part, does not depend on how much time has already elapsed.  The unique memoryless and continuous probability distribution is the exponential distribution; if a variable $P$ has an expected value $P_{\rm exp}$, then the normalized differential probability density is
\begin{equation}
{\rm prob}(P)={1\over{P_{\rm exp}}}e^{-P/P_{\rm exp}}
\end{equation}
and the probability that $P$ will be $P_0$ or larger is
\begin{equation}
{\rm prob}(P\geq P_0)=e^{-P_0/P_{\rm exp}}\; .
\end{equation}
Alternatively, the exponential distribution is the solution to the differential equation
\begin{equation}
{dy\over{dP}}=-y/P_{\rm exp}\; .
\end{equation}

There may be occasions in which one wishes to compute the probability distribution of the sum of several independently-sampled exponential variables, which could have different decay constants.  The sum of the waiting times for a decay from several different radioactive substances provides a perhaps artificial example of this type.

Thus we are faced with the following problem: if we combine the {\it statistically independent} measurements of a quantity $P$ for $n$ discrete variables, what is the probability distribution of the sum of the values of those quantities given that they are all exponentially distributed?  Put another way, if the expected constants for the $n$ variables are $P_{1,{\rm exp}}, P_{2,{\rm exp}},\ldots,P_{n,{\rm exp}}$, how probable is it in that model that the sum of the measured values will be at least $P_{\rm tot}$?

Motivated by this problem, we will proceed as follows. In Section \ref{sec:integral} we obtain by mathematical induction our general formula. This proof is completed by a basic lemma of long standing, presented in Section \ref{sec:lemma}, in which we use some properties of Schur polynomials. In Section \ref{sec:application} we apply our formula to the case where all exponential constants are the same, and recover the correct result, which is known in power density theory among other contexts. We present our final remarks in Section \ref{sec:final}.

\section{The general formula}
\label{sec:integral}

The probability that the sum of the values of $n$ measurements drawn from exponentials is greater than or equal to $P_{\rm tot}$, is one minus the probability that the sum is less than $P_{\rm tot}$:
\begin{equation}
\begin{array}{rl}
   {\rm prob}(P \geq P_{\rm tot})&=1-\int_0^{P_{\rm tot}} (1/P_{1,{\rm exp}})e^{-P_1/P_{1,{\rm exp}}} \\
                   &\times \biggl[\int_0^{P_{\rm tot}-P_1} (1/P_{2,{\rm exp}})e^{-P_2/P_{2,{\rm exp}}} \\
                   &\times \biggl[\int_0^{P_{\rm tot}-P_1-P_2} (1/P_{3,{\rm exp}})e^{-P_3/P_{3,{\rm exp}}}\times\ldots\times \\
                   &\times\biggl[\int_0^{P_{tot}-\sum_{i=1}^{n-1}P_i} (1/P_{n,{\rm exp}})e^{-P_n/P_{n,{\rm exp}}}dP_n\biggr]dP_{n-1}\biggr]\ldots\biggr]dP_1\; .
\end{array}
\label{eq:original}
\end{equation}
We claim that this expression evaluates to
\begin{equation}
{\rm prob}(P \geq P_{\rm tot})=\sum_{i=1}^n \left({P_{i,{\rm exp}}^{n-1}e^{-P_{\rm tot}/P_{i,{\rm exp}}}\over{\prod_{j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}\right)\; .
\label{eq:formula}
\end{equation}

We prove this by induction:

{\bf Step 1:} For $n=1$, the probability is
\begin{equation}
\begin{array}{rl}
{\rm prob}(P \geq P_{\rm tot})&=1-\int_0^{P_{\rm tot}}(1/P_{1,{\rm exp}})e^{-P_1/P_{1,{\rm exp}}}dP_1\\
&=1-(1-e^{-P_{\rm tot}/P_{1,{\rm exp}}})=e^{-P_{\rm tot}/P_{1,{\rm exp}}}\; .
\end{array}
\end{equation}
This is consistent with eq. (\ref{eq:formula}).

{\bf Step 2:} Assume that the formula is true for a given $n$. For $n+1$, insertion of the formula along with some relabeling gives us
\begin{eqnarray}
&&{\rm prob}(P \geq P_{\rm tot})=1-\int_0^{P_{\rm tot}}{1\over{P_{1,{\rm exp}}}}e^{-P_1/P_{1,{\rm exp}}}dP_1\times\nonumber\\
&\times&\left[1-\sum_{i=2}^{n+1}{P_{i,{\rm exp}}^{n-1}e^{-(P_{\rm tot}-P_1)/P_{i,{\rm exp}}}\over{\prod_{1<j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}\right]\; .
\end{eqnarray}
Multiplying through, we obtain
\begin{eqnarray}
&&1-\left[\int_0^{P_{\rm tot}}{1\over{P_{1,{\rm exp}}}}e^{-P_1/P_{1,{\rm exp}}}dP_1-\right.\nonumber\\
&-&\left.\int_0^{P_{\rm tot}}\sum_{i=2}^{n+1}{e^{-P_1(1/P_{1,{\rm exp}}-1/P_{i,{\rm exp}})}P_{i,{\rm exp}}^{n-1}e^{-P_{\rm tot}/P_{i,{\rm exp}}}\over{P_{1,{\rm exp}}\prod_{1<j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}dP_1\right]\; .
\end{eqnarray}
The first integral just evaluates to $1-e^{-P_{\rm tot}/P_{1,{\rm exp}}}$.  For the second integral, we note that the factor in the exponent multiplying $-P_1$ is
\begin{equation}
{1\over{P_{1,{\rm exp}}}}-{1\over{P_{i,{\rm exp}}}}={P_{i,{\rm exp}}-P_{1,{\rm exp}}\over{P_{1,{\rm exp}}P_{i,{\rm exp}}}}
\end{equation}
and thus the second integral becomes
\begin{eqnarray}
&-&\sum_{i=2}^{n+1}{P_{i,{\rm exp}}^ne^{-P_{\rm tot}/P_{i,{\rm exp}}}\over{P_{i,{\rm exp}}-P_{1,{\rm exp}}}}{1\over{\prod_{1<j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}\times\nonumber\\
&\times&\left[1-e^{-P_{\rm tot}/P_{1,{\rm exp}}}e^{P_{\rm tot}/P_{i,{\rm exp}}}\right]\; .
\end{eqnarray}
Subtracting the sum of the integrals from 1 gives
\begin{eqnarray}
&&{\rm prob}(P \geq P_{\rm tot})=\sum_{i=2}^{n+1}{P_{i,{\rm exp}}^ne^{-P_{\rm tot}/P_{i,{\rm exp}}}\over{\prod_{j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}+e^{-P_{\rm tot}/P_{1,{\rm exp}}}\times\nonumber\\
&\times&\left[1-\sum_{i=2}^{n+1}{P_{i,{\rm exp}}^n\over{\prod_{j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}\right]\; .
\end{eqnarray}
The first term has the required form for $i=2$ through $i=n+1$.  We will prove our formula if we can show that
\begin{equation}
1-\sum_{i=2}^{n+1}{P_{i,{\rm exp}}^n\over{\prod_{j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}={P_{1,{\rm exp}}^n\over{\prod_{j\neq 1}(P_{1,{\rm exp}}-P_{j,{\rm exp}})}}\; ,
\end{equation}
which is to say that we can prove our formula if we can show that
\begin{equation}
\sum_{i=1}^{n+1}{P_{i,{\rm exp}}^n\over{\prod_{j\neq i}(P_{i,{\rm exp}}-P_{j,{\rm exp}})}}=1\; .
\label{eq:lemma}
\end{equation}

\section{Statement and proof of the basic lemma}
\label{sec:lemma}

Now we proceed to prove eq. (\ref{eq:lemma}) in order to complete the proof by induction of our general formula given in eq. (\ref{eq:formula}). As this result will be used again in Section \ref{sec:application}, we present it in this Section as a separate lemma (which, as we discuss, already appeared in generalized form some centuries ago), which we state and prove below using techniques that do not require advanced mathematics. We give explicit examples with $n = 1,2$ and 3 in Appendix \ref{sec:ex-lemma}.

\begin{lemma}
\label{lemma1}
Let $\{x_i\}_{i \in \mathbb{N}}$ be a set of real positive numbers, $n$ a given natural number and $\{a_i\}_{i \in \mathbb{N}}$ be a real sequence given by
\begin{equation}
a_i = \frac{x_i^n}{\prod_{j\neq i}(x_i - x_j)}\,, \quad \rm{with} \quad j = 1,\ldots,i-1,i+1,\ldots,n+1\,.
\end{equation}
Then the sum $S_{n+1} = \sum_{i=1}^{n+1} a_i = 1$.
\end{lemma}
As we indicate above, generalizations of this formula have been applied to interpolation theory as early as \cite{Newton}, and there are significant connections to geometry (in evaluating integrals over projection space and in the context of flag manifolds; for several papers that clarify these connections see \cite{LS1,LS2,LS3,LS4}, and for a more recent review see \cite{Pragacz}).  In addition, when one interprets the exponential as a probability distribution, one can take advantage of the fact that the distribution of the sum of two probability densities is the convolution of the densities (for an application in this context, see, e.g., \cite{Akkouchi}).  Here, however, we present a proof that relies on the properties of certain classes of symmetric polynomials.

{\it Proof.} $S_{n+1}$ is a symmetric polynomial in the $x_i$ (in fact, it is a Schur polynomial as we will see below) because it can be written as $A_n/B_n$, where both $A_n$ and $B_n$ are alternating polynomials of degree $n$  in the $x_i$'s and are given by
\begin{eqnarray}
\label{eq:A_n}
A_n &=& \sum_{i=1}^{n+1}(-1)^{i+1}x_i^n\prod_{j < k; j,k \neq i}(x_j-x_k)\,,\\
B_n &=& \prod_{j < k}(x_j-x_k)\,.
\label{eq:B_n}
\end{eqnarray}
All alternating polynomials can be written as the product $V_n\cdot s$, where $V_n$ is the Vandermonde polynomial (\textit{i.e.}, the determinant of the Vandermonde matrix \cite{NumericalRecipes}) and $s$ is a symmetric polynomial. We recognize now that $B_n = V_n$, and therefore $S_{n+1}$ is a symmetric polynomial given by the ratio of the alternating polynomial $A_n$ over the Vandermonde polynomial. Thus, $S_{n+1}$ is called a Schur polynomial \cite{Schur}.

Therefore we can write $A_n = B_n\cdot s$. As $A_n$ and $B_n$ are polynomials of the same order, $s$ must be a zeroth-order polynomial: $s = C$, with $C = $ const. and $A_n = C\cdot B_n$. To show that $C = 1$, we compare the coefficients of the $x_1^n$ terms in $A_n$ and $B_n$, as given by eqs. (\ref{eq:A_n}) and (\ref{eq:B_n}). For both $A_n$ and $B_n$, the coefficient of $x_1^n$ is
\begin{equation}
\prod_{1< j < k}(x_j-x_k)\,,
\end{equation}
which demonstrates that $C = 1$. Therefore, $A_n = B_n$ and $S_{n+1} = A_n/B_n = 1$.

\section{An application: Reduction of the general formula in the case that all expected values are nearly equal}
\label{sec:application}

Our general formula given by eq. (\ref{eq:formula}) has, in its denominator, the products of differences of expected values.  If two or more of the $P_{i,{\rm exp}}$ approach each other, then the formula appears singular.  It is not, in fact, as the original integral given in eq. (\ref{eq:original}) is clearly nonsingular. We will demonstrate this below, and we give explicit examples for $n = 2,3$ in Appendix \ref{sec:ex-app}.

Let us assume that there are $n$ total measurements, and that all of them have expected values that are very close to each other. We will assume that $P_{2,{\rm exp}}=P_{1,{\rm exp}}+\epsilon_2$, $P_{3,{\rm exp}}=P_{1,{\rm exp}}+\epsilon_3$, $\ldots$, $P_{n,{\rm exp}}=P_{1,{\rm exp}}+\epsilon_n$, and take the limit of the resulting expression as $\epsilon_2\rightarrow 0$, $\epsilon_3\rightarrow 0,\ldots, \epsilon_m\rightarrow 0$:
\begin{eqnarray}
&&\lim_{P_{i,{\rm exp}}\to P_{1,{\rm exp}}}{\rm prob}(P \geq P_{\rm tot}) = \nonumber\\
&=&\lim_{\epsilon_i \to 0}\left(\frac{P_{1,{\rm exp}}^{n-1}e^{-P_{\rm tot}/P_{1,{\rm exp}}}}{\prod_{j>1}(-1)^{n-1}\epsilon_j}
+ \sum_{i=2}^n\frac{(P_{1,{\rm exp}}+\epsilon_i)^{n-1}e^{-P_{\rm tot}/(P_{1,{\rm exp}}+\epsilon_i)}}{\epsilon_i\prod_{j > 1; j \neq i}(\epsilon_i - \epsilon_j)}\right)
\end{eqnarray}
or
\begin{equation}
\lim_{\epsilon_i \to 0}\left(\frac{f(P_{1,{\rm exp}})}{\prod_{j>1}(-1)^{n-1}\epsilon_j}
+ \sum_{i=2}^n\frac{f(P_{1,{\rm exp}}+\epsilon_i)}{\epsilon_i\prod_{j > 1; j \neq i}(\epsilon_i - \epsilon_j)}\right)\,,
\label{eq:lim_f}
\end{equation}
where we used the auxiliary function
\begin{equation}
f(P) = P^{n-1}e^{-P_{\rm tot}/P}\,.
\label{eq:f}
\end{equation}
We will calculate this limit by expanding $f(P_{1,{\rm exp}}+\epsilon_i)$ in a Taylor series around $P_{1,{\rm exp}}$,
\begin{equation}
f(P_{1,{\rm exp}}+\epsilon_i) = \sum_{l=0}^{\infty}\frac{f^{(l)}(P_{1,{\rm exp}})}{l!}\epsilon_i^l\,,
\end{equation}
and substituting it in eq. (\ref{eq:lim_f}). We can now collect the terms proportional to $f(P_{1,{\rm exp}})$ and its  $l$-derivatives.

For $l=0$, we find the coefficient of $f(P_{1,{\rm exp}})$ and we can show that it is:
\begin{equation}
\frac{1}{\prod_{j>1}(-1)^{n-1}\epsilon_j}
+ \sum_{i=2}^n\frac{1}{\epsilon_i\prod_{j > 1;j \neq i}(\epsilon_i - \epsilon_j)} = 0\,,
\label{eq:k0}
\end{equation}
where, similarly to our proof of Lemma \ref{lemma1}, we can write the second term as
\begin{equation}
\frac{\sum_{i=2}^n(-1)^{i}\prod_{j \neq i}\epsilon_j\prod_{1<j<k;j,k \neq i}(\epsilon_j-\epsilon_k)}{\prod_{i>1}\epsilon_i\prod_{1<j < k}(\epsilon_j - \epsilon_k)} = \frac{(-1)^n}{\prod_{i>1}\epsilon_i}\,,
\end{equation}
after the cancellation of the alternating polynomials of degree $n-2$ in the $\epsilon_j$'s, leading to the result in (\ref{eq:k0}).

For each $l$ in the range $1< l < n-1$, we find that the coefficient of the l-derivative $f^{(l)}(P_{1,{\rm exp}})$ is:
\begin{equation}
\frac{1}{l!}\sum_{i=2}^n\frac{\epsilon_i^l}{\prod_{j \neq 1}\epsilon_i(\epsilon_i - \epsilon_j)} = 0\,,
\end{equation}
because the sum can be written in the form
\begin{equation}
\frac{\sum_{i=2}^n(-1)^{i}\epsilon_i^{l-1}\prod_{1<j<k;j,k \neq i}(\epsilon_j-\epsilon_k)}{\prod_{1<j < k}(\epsilon_j - \epsilon_k)}\; .
\end{equation}
From this we can see that the denominator is the Vandermonde determinant in the variables $\epsilon_i$ (with $i = 2, \ldots,n$) \cite{NumericalRecipes}, whereas the numerator is zero, because it is equal to the determinant of the modified Vandermonde matrix in which the line $\epsilon_i^{l-1}$ appears twice, where in the second occurrence it replaces the last line $\epsilon_i^{n-2}$.

For $l = n-1$, the coefficient of the l-derivative $f^{(l)}(P_{1,{\rm exp}})$ is
\begin{equation}
\frac{1}{(n-1)!}\sum_{i=2}^n\frac{\epsilon_i^{(n-1)}}{\prod_{j \neq 1}\epsilon_i(\epsilon_i - \epsilon_j)} = \frac{1}{(n-1)!}\,,
\end{equation}
where we can again use Lemma \ref{lemma1} to show that the sum equals 1.

For $l > n-1$, all coefficients of the $l$-derivatives $f^{(l)}(P_{1,{\rm exp}})$ go to zero when we take the limit $\epsilon_i \to 0$, as these coefficients will have higher order polynomials in $\epsilon_i$ in the numerator.

Thus, finally, we find that the desired result for the limit given in eq. (\ref{eq:lim_f}) is given by the only surviving term  $f^{(n-1)}(P_{1,{\rm exp}})/(n-1)!$ and, for the derivatives of our $f(P)$ given by eq. (\ref{eq:f}) we prove in Appendix \ref{sec:derivative} that
\begin{equation}
f^{(n-1)}(P_{1,{\rm exp}}) = (n-1)!\, e^{-P_{\rm tot}/P_{1,{\rm exp}}}\sum_{i=0}^{n-1}\frac{(P_{\rm tot}/P_{1,{\rm exp}})^i}{i!}\,,
\label{eq:df}
\end{equation}
so that we obtain
\begin{equation}
\lim_{P_{i,{\rm exp}}\to P_{1,{\rm exp}}}{\rm prob}(P \geq P_{\rm tot}) = e^{-P_{\rm tot}/P_{1,{\rm exp}}}\sum_{i=0}^{n-1}\frac{(P_{\rm tot}/P_{1,{\rm exp}})^i}{i!}\,.
\end{equation}
This is the result known from, for example, time series analysis\footnote{If we apply Leahy normalization, as is standard in astronomy, then $P_{\rm exp}=2$ and thus the probability is
$e^{-P_{\rm tot}/2}\sum_{i=0}^{n-1}{(P_{\rm tot}/2)^i\over{i!}}\,$.} in the context of an intrinsically steady source whose only power comes from Poisson fluctuations (see \cite{BlackmanTukey} and the limit $P_s\rightarrow 0$ of equation (16) from \cite{Groth75}).

\section{Final Remarks}
\label{sec:final}

We have presented here an application of basic properties of Schur polynomials (symmetric polynomials that can be written as the ratio between an alternating polynomial in the numerator and the Vandermonde polynomial in the denominator) motivated by the statistical problem of determining the cumulative distribution of the sum of exponentially-distributed variables. Our work led to the result given in Lemma \ref{lemma1}, for calculating the sums of  Schur polynomials that appeared in our analysis.

As an application of our analysis, we recovered the known expression for the probability that the power density of an intrinsically constant source, summed over some number of independent frequency bins, exceeds a given total. As part of our calculation, we found an interesting direct expression for the $(n-1)$th-derivative of our auxiliary function $f$.

\medskip
{\bf Acknowledgments}
We are very grateful to our colleagues Pedro Lauridsen Ribeiro and Harry Tamvakis, who read through an earlier version of this paper and provided invaluable context.  This work was supported in part by S{\~{a}}o Paulo Research Foundation (FAPESP) grant 2015/20433-4 and by joint research workshop award 2015/50421-8 from FAPESP and the University of Maryland, College Park.