Special Functions

This example demonstrates special mathematical functions including Bessel functions and their applications.

Overview

Special functions are fundamental to many engineering applications:

  • Signal processing: Filter design and analysis

  • Electromagnetics: Waveguide mode calculations

  • Acoustics: Circular membrane vibrations

  • Optics: Diffraction patterns

Bessel Functions

First Kind (J_n)
  • Solutions to Bessel’s differential equation

  • Finite at the origin

  • Oscillatory behavior for positive arguments

Second Kind (Y_n)
  • Also called Neumann functions

  • Singular at the origin

  • Independent solution to Bessel’s equation

Key Properties
  • J_0(0) = 1, J_n(0) = 0 for n > 0

  • Recurrence relations connect different orders

  • Zeros are important for boundary value problems

Applications

Circular Drum Vibrations
  • Bessel function zeros determine mode frequencies

  • J_0 zeros: fundamental modes

  • Higher orders: more complex patterns

Cylindrical Waveguides
  • TE and TM mode cutoff frequencies

  • Field patterns in circular cross-section

  • Microwave and optical applications

Bessel Filters
  • Maximally flat group delay

  • Linear phase response

  • Named after Bessel functions

Boundary Value Problems
  • Heat conduction in cylinders

  • Electromagnetic fields

  • Quantum mechanics (spherical wells)

Bessel Zeros

The zeros of Bessel functions are critical values:

  • J_0 zeros: 2.405, 5.520, 8.654, 11.792, …

  • Used in filter design and mode analysis

  • Computed with bessel_zeros()

Code Highlights

The example demonstrates:

  • Bessel function evaluation with besselj() and bessely()

  • Multiple orders (J_0 through J_4)

  • Zero finding with bessel_zeros()

  • Visualization of function behavior

Source Code

  1"""
  2Demonstration of special functions and mathematical operations.
  3
  4This example shows:
  5- Bessel function computation and visualization
  6- Special function properties and characteristics
  7- Performance characteristics
  8"""
  9
 10import os
 11from pathlib import Path
 12
 13import numpy as np
 14import plotly.graph_objects as go
 15from plotly.subplots import make_subplots
 16
 17from pytcl.mathematical_functions.special_functions import (
 18    bessel_zeros,
 19    besselj,
 20    bessely,
 21)
 22
 23SHOW_PLOTS = os.environ.get("PYTCL_SHOW_PLOTS", "1") != "0"
 24OUTPUT_DIR = Path("docs/_static/images/examples")
 25OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
 26
 27
 28def demo_bessel_functions() -> None:
 29    """Demonstrate Bessel functions of the first and second kind."""
 30    print("\n" + "=" * 60)
 31    print("Bessel Functions Demonstration")
 32    print("=" * 60)
 33
 34    # Compute Bessel functions over a range
 35    x = np.linspace(0.1, 10, 100)
 36
 37    # First kind - J_0 and J_1
 38    j0 = besselj(0, x)
 39    j1 = besselj(1, x)
 40
 41    # Second kind - Y_0 and Y_1
 42    y0 = bessely(0, x)
 43    y1 = bessely(1, x)
 44
 45    print(f"\nBessel Functions J_n and Y_n:")
 46    print(f"  J_0(1) = {besselj(0, 1.0):.6f}")
 47    print(f"  J_1(1) = {besselj(1, 1.0):.6f}")
 48    print(f"  Y_0(1) = {bessely(0, 1.0):.6f}")
 49    print(f"  Y_1(1) = {bessely(1, 1.0):.6f}")
 50
 51    fig = make_subplots(
 52        rows=1,
 53        cols=2,
 54        subplot_titles=(
 55            "Bessel Functions (First Kind)",
 56            "Bessel Functions (Second Kind)",
 57        ),
 58    )
 59
 60    # First kind
 61    fig.add_trace(
 62        go.Scatter(
 63            x=x,
 64            y=j0,
 65            mode="lines",
 66            name="J₀(x)",
 67            line=dict(color="blue", width=2),
 68            hovertemplate="<b>J₀(x)</b><br>x: %{x:.3f}<br>J₀(x): %{y:.6f}<extra></extra>",
 69        ),
 70        row=1,
 71        col=1,
 72    )
 73    fig.add_trace(
 74        go.Scatter(
 75            x=x,
 76            y=j1,
 77            mode="lines",
 78            name="J₁(x)",
 79            line=dict(color="red", width=2),
 80            hovertemplate="<b>J₁(x)</b><br>x: %{x:.3f}<br>J₁(x): %{y:.6f}<extra></extra>",
 81        ),
 82        row=1,
 83        col=1,
 84    )
 85
 86    # Second kind
 87    fig.add_trace(
 88        go.Scatter(
 89            x=x,
 90            y=y0,
 91            mode="lines",
 92            name="Y₀(x)",
 93            line=dict(color="blue", width=2),
 94            hovertemplate="<b>Y₀(x)</b><br>x: %{x:.3f}<br>Y₀(x): %{y:.6f}<extra></extra>",
 95        ),
 96        row=1,
 97        col=2,
 98    )
 99    fig.add_trace(
100        go.Scatter(
101            x=x,
102            y=y1,
103            mode="lines",
104            name="Y₁(x)",
105            line=dict(color="red", width=2),
106            hovertemplate="<b>Y₁(x)</b><br>x: %{x:.3f}<br>Y₁(x): %{y:.6f}<extra></extra>",
107        ),
108        row=1,
109        col=2,
110    )
111
112    fig.update_xaxes(title_text="x", row=1, col=1)
113    fig.update_yaxes(title_text="Function Value", row=1, col=1)
114    fig.update_xaxes(title_text="x", row=1, col=2)
115    fig.update_yaxes(title_text="Function Value", row=1, col=2)
116
117    fig.update_layout(
118        height=500,
119        title_text="Bessel Functions of the First and Second Kind",
120        hovermode="x unified",
121        plot_bgcolor="rgba(240,240,240,0.5)",
122        showlegend=True,
123        legend=dict(x=0.02, y=0.98),
124    )
125
126    if SHOW_PLOTS:
127        fig.show()
128    else:
129        fig.write_html(
130            str(OUTPUT_DIR / "special_functions_demo.html"),
131            include_plotlyjs="cdn",
132            div_id="special_functions_demo",
133        )
134
135
136def demo_higher_order_bessel() -> None:
137    """Demonstrate higher order Bessel functions."""
138    print("\n" + "=" * 60)
139    print("Higher Order Bessel Functions")
140    print("=" * 60)
141
142    x = np.linspace(0.1, 10, 100)
143    x_val = 5.0
144
145    print(f"\nBessel functions at x={x_val}:")
146    for n in range(5):
147        j_n = besselj(n, x_val)
148        y_n = bessely(n, x_val)
149        print(f"  J_{n}({x_val}) = {j_n:.6f}, Y_{n}({x_val}) = {y_n:.6f}")
150
151    # Plot multiple orders
152    fig = go.Figure()
153
154    colors = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd"]
155    for n in range(5):
156        jn_vals = besselj(n, x)
157        fig.add_trace(
158            go.Scatter(
159                x=x,
160                y=jn_vals,
161                mode="lines",
162                name=f"J_{n}(x)",
163                line=dict(width=2.5, color=colors[n]),
164                hovertemplate=f"<b>J_{n}(x)</b><br>x: %{{x:.3f}}<br>J_{n}(x): %{{y:.6f}}<extra></extra>",
165            )
166        )
167
168    fig.update_layout(
169        title="Bessel Functions of Different Orders",
170        xaxis_title="x",
171        yaxis_title="J_n(x)",
172        height=500,
173        hovermode="x unified",
174        plot_bgcolor="rgba(240,240,240,0.5)",
175        showlegend=True,
176        legend=dict(x=0.65, y=0.95),
177    )
178
179    if SHOW_PLOTS:
180        fig.show()
181    else:
182        fig.write_html(
183            str(OUTPUT_DIR / "special_functions_demo_higher_order.html"),
184            include_plotlyjs="cdn",
185            div_id="special_functions_demo_higher_order",
186        )
187
188
189def demo_bessel_zeros() -> None:
190    """Demonstrate Bessel function zeros and roots."""
191    print("\n" + "=" * 60)
192    print("Bessel Function Zeros")
193    print("=" * 60)
194
195    print(f"\nZeros of Bessel functions are important for:")
196    print(f"  - Circular drum vibrations")
197    print(f"  - Cylindrical waveguides")
198    print(f"  - Bessel filter design")
199    print(f"  - Boundary value problems")
200
201    # Get zeros of J_0
202    zeros = bessel_zeros(0, 5)
203    print(f"\nFirst 5 zeros of J_0(x): {zeros}")
204
205
206def main() -> None:
207    """Run all demonstrations."""
208    print("\n" + "=" * 60)
209    print("Mathematical Special Functions Demonstration")
210    print("=" * 60)
211
212    demo_bessel_functions()
213    demo_higher_order_bessel()
214    demo_bessel_zeros()
215
216    print("\n" + "=" * 60)
217    print("Demonstration Complete")
218    print("=" * 60)
219
220
221if __name__ == "__main__":
222    main()
223
224OUTPUT_DIR = Path("docs/_static/images/examples")
225OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
226
227SHOW_PLOTS = True

Running the Example

python examples/special_functions_demo.py

See Also