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()andbessely()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
Signal Processing - Signal processing applications
Transforms - Mathematical transforms