Skip to content

Distributions (polykin.distributions)¤

reconstruct_Laguerre ¤

reconstruct_Laguerre(
    moments: FloatVectorLike,
) -> Callable[[FloatArrayLike], FloatArray]

Reconstruct a differential number distribution from a finite set of moments using a Laguerre-series approximation.

According to Bamford and Tompa, a number distribution \(P(n)\) can be expressed as an (infinite) expansion in Laguerre polynomials:

\[ P(n) = \frac{e^{-\rho}}{(DP_n)^2} \sum_{m=0}^{\infty} \gamma_m L_m(\rho) \]

with coefficients:

\[ \gamma_m = \sum_{i=0}^{m} \binom{m}{i} (-1)^{i} \frac{\lambda_i}{i!(DP_n)^{i-1}} \]

where \(L_m\) is the Laguerre polynomial of degree \(m\), \(\lambda_i\) is the \(i\)-th moment of the distribution, \(DP_n = \lambda_1/ \lambda_0\) is the number-average chain length, and \(\rho = n/DP_n\).

In principle, an infinite number of moments is required, but in certain well-behaved cases a modest (finite) number is sufficient.

Note

This method is mainly of historical interest. Its success depends strongly on the shape of the underlying distribution. It works well when the distribution is close to Flory-like, but may perform poorly for more complex shapes.

References

  • C.H. Bamford and H. Tompa, "The calculation of molecular weight distributions from kinetic schemes", Trans. Faraday Soc., 50, 1097 (1954).
PARAMETER DESCRIPTION
moments

Moments of \(P\), denoted \((\lambda_0, \lambda_1, \ldots)\).

TYPE: FloatVectorLike

RETURNS DESCRIPTION
Callable[[FloatArrayLike], FloatArray]

A function pdf(n) that evaluates the reconstructed number distribution \(P(n)\) at the supplied chain lengths n.

Source code in src/polykin/distributions/misc.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
def reconstruct_Laguerre(
    moments: FloatVectorLike,
) -> Callable[[FloatArrayLike], FloatArray]:
    r"""Reconstruct a differential number distribution from a finite set of
    moments using a Laguerre-series approximation.

    According to Bamford and Tompa, a number distribution $P(n)$ can be expressed
    as an (infinite) expansion in Laguerre polynomials:

    $$ P(n) = \frac{e^{-\rho}}{(DP_n)^2}
              \sum_{m=0}^{\infty} \gamma_m L_m(\rho) $$

    with coefficients:

    $$ \gamma_m = \sum_{i=0}^{m} \binom{m}{i} (-1)^{i}
                  \frac{\lambda_i}{i!(DP_n)^{i-1}} $$

    where $L_m$ is the Laguerre polynomial of degree $m$, $\lambda_i$ is the
    $i$-th moment of the distribution, $DP_n = \lambda_1/ \lambda_0$ is the
    number-average chain length, and $\rho = n/DP_n$.

    In principle, an infinite number of moments is required, but in certain
    well-behaved cases a modest (finite) number is sufficient.

    !!! note

        This method is mainly of historical interest. Its success depends
        strongly on the shape of the underlying distribution. It works well
        when the distribution is close to Flory-like, but may perform poorly
        for more complex shapes.

    **References**

    *   C.H. Bamford and H. Tompa, "The calculation of molecular weight
        distributions from kinetic schemes", Trans. Faraday Soc., 50, 1097 (1954).

    Parameters
    ----------
    moments : FloatVectorLike
        Moments of $P$, denoted $(\lambda_0, \lambda_1, \ldots)$.

    Returns
    -------
    Callable[[FloatArrayLike], FloatArray]
        A function `pdf(n)` that evaluates the reconstructed number distribution
        $P(n)$ at the supplied chain lengths `n`.
    """
    moments = np.asarray(moments, dtype=np.float64)
    DPn = moments[1] / moments[0]
    k = len(moments)

    # Series coefficients
    γ = np.empty(k, dtype=np.float64)
    for m in range(k):
        γ[m] = sum(
            comb(m, i) * (-1) ** i * moments[i] / DPn ** (i - 1) / factorial(i)
            for i in range(m + 1)
        )

    # Laguerre series γ0*L0 + γ1*L1 + ... + γm*Lm
    L = Laguerre(γ)

    # Bild pdf
    def pdf(n: FloatArrayLike) -> FloatArray:
        n = np.asarray(n, dtype=np.float64)
        ρ = n / DPn
        return np.exp(-ρ) / DPn**2 * L(ρ)

    return pdf