Complete Elliptic Integral of the First Kind: K(k)

Rationale

When dealing with transmission lines, specially when designing coplanar waveguides in a PCB with specific characteristic impedances, the K(k) tend to pop in an equation or two.

Usually, when dealing with characteristic impedances in coplanar waveguides, the equations depend mostly on the K(k) / K’(k) quotient, and a few fast approximations for this division can be found in a publication by Hilberg [1]. This topic will be covered in much more detail in a future blog post.

Without fast approximations, the K(k) isn’t easy to calculate by hand, as it depends on hypergeometric functions and the intermediate calculations will rapidly grow in complexity with very large numerical values — only with the aid of a computer, it becomes feasible to solve them. So let’s dig into some definitions first before we call Python into the scene.

Definitions

The Complete Elliptic Integral of the First Kind, K(k), is defined for 0 <= k < 1, by:

As described by G. D. Anderson, et al. [2], elliptical integrals of the first and second kind can be solved with the Gaussian hypergeometric function two-F-one, defined as:

Which depends on the Rising Factorial, defined as:

Still from [2], rewritting K(k) in terms of the hypergeometric function two-F-one, yields:

And putting everything together, we have:

Calculations

Using Python to solve K(k) is extremelly straightforward if depending on scipy or mpmath isn’t an issue:


from scipy import pi
from scipy.special import hyp2f1

# Alternatively, mpmath.hyp2f1 can be used
# from mpmath import pi
# from mpmath import hyp2f1

def K(k):
    return (pi / 2.) * hyp2f1(0.50.51, k ** 2)

But if you need an implementation without depending on scipy nor mpmath, then a simple version, yet limited in precision, can be written as:


# Author  : pah <a.t> ucodev <d.o.t> org
# Source  : https://www.ucodev.org/notes2self/complete-elliptic-integral-of-the-first-kind
# License : https://www.apache.org/licenses/LICENSE-2.0

from functools import reduce # reduce() required to be imported in Python3

def fact(x):
    return reduce(lambda a, b: a * b, range(1, x + 1or [1])

def fact_rising(x, n):
    return reduce(lambda a, b: a * b, [ x + i for i in range(n) or [1 - x]])

def hyp2f1(a, b, c, z):
    i = s = 0
    while True:
        _s = s + (((fact_rising(a, i) * fact_rising(b, i)) / fact_rising(c, i)) * ((z ** i) / fact(i)))

        if not (0. < (round(_s, 11) - round(s, 11)) < float('inf')): break
        s = _s
        i += 1

    return s

def K(k):
    return round(1.5707963267948966 * hyp2f1(0.50.51, k ** 2), 8)

The issue with the implementation above is that it will struggle to give precise results when k >= 0.92, given that there will not be enough precision in the double precision floating point variables to carry out the division of the very large rising factorial results as i increases. Although this implementation will most likely suffice for most uses, alternatively one can extend it by using numpy.float128, which will increase the precision and provide decent results up to k < 0.9911.

Considerations

All in all, if adding scipy or mpmath as a dependency is acceptable for your project, you should definetly go with it, given that creating an implementation for hypergeometric functions while not being dependent on floating point variables, will require all intermediate calculations to be performed with single digit array representations of all values, or some other technique to deal with very large, and very small, real numbers — and if not done properly, the performance of the custom implementation may end up being way worse than expected.

The addition of a solid dependency that greatly simplifies the implementation and improves the code quality and readability, should always be considered as an enhancement — unless there’s a very strong reason for not doing so.

References

[1] : “From Approximations to Exact Relations for Characteristic Impedances”, Wolfgang Hilberg, published in the “IEEE TRANSACTIONS ON MICROWAVE THEORY AND TECHNIQUES, VOL. MTT-17, NO. 5, MAY 1969”

[2] : “Hypergeometric Functions and Elliptic Integrals”, G. D. Anderson, M. K. Vamanamurthy, and M. Vuorinen, December 1992

Notes

This blog post is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The code examples in this blog post were written by, and are copyrighted by the author of this website (www.ucodev.org), and are licensed under the Apache License, version 2.0.

If there are any questions or suggestions related to this blog post, please check the website footer for the contact information of the author.

Previous
Previous

Characteristic Impedance of Coplanar Waveguides with Ground