Skip to content

Commit 6b6c29f

Browse files
Merge pull request #1 from Venkat11Thadi/Venkat11Thadi-patch-1
added wronskian_second_order_de.py
2 parents 788d95b + d218dd1 commit 6b6c29f

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

maths/wronskian_second_order_de.py

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
"""
2+
Module to analyze homogeneous linear differential equations.
3+
4+
It supports:
5+
- Second-order equations: a*y'' + b*y' + c*y = 0
6+
- First-order equations: b*y' + c*y = 0 (when a = 0)
7+
8+
Features:
9+
- Computes characteristic roots (for second-order)
10+
- Derives fundamental solutions
11+
- Calculates first derivatives
12+
- Evaluates the Wronskian determinant
13+
- Tests for linear independence
14+
15+
References:
16+
https://en.wikipedia.org/wiki/Linear_differential_equation
17+
"""
18+
19+
import cmath
20+
from sympy import symbols, exp, cos, sin, diff, simplify
21+
22+
23+
def compute_characteristic_roots(
24+
coefficient_a: float, coefficient_b: float, coefficient_c: float
25+
) -> tuple[complex, complex]:
26+
"""
27+
Compute roots of the characteristic equation:
28+
a*r^2 + b*r + c = 0
29+
30+
>>> compute_characteristic_roots(1, -2, 1)
31+
((1+0j), (1+0j))
32+
>>> compute_characteristic_roots(1, 0, 1)
33+
((0+1j), (0-1j))
34+
"""
35+
discriminant = coefficient_b**2 - 4 * coefficient_a * coefficient_c
36+
sqrt_discriminant = cmath.sqrt(discriminant)
37+
root_1 = (-coefficient_b + sqrt_discriminant) / (2 * coefficient_a)
38+
root_2 = (-coefficient_b - sqrt_discriminant) / (2 * coefficient_a)
39+
return root_1, root_2
40+
41+
42+
def construct_fundamental_solutions(root_1: complex, root_2: complex):
43+
"""
44+
Construct fundamental solutions (y1, y2) of a 2nd-order ODE.
45+
46+
>>> from sympy import symbols, exp
47+
>>> x = symbols('x')
48+
>>> r1, r2 = 1, 1
49+
>>> construct_fundamental_solutions(r1, r2)
50+
(exp(x), x*exp(x))
51+
"""
52+
variable_x = symbols("x")
53+
54+
# Case 1: Real and equal roots
55+
if root_1 == root_2 and root_1.imag == 0:
56+
solution_1 = exp(root_1.real * variable_x)
57+
solution_2 = variable_x * exp(root_1.real * variable_x)
58+
59+
# Case 2: Real and distinct roots
60+
elif root_1.imag == 0 and root_2.imag == 0:
61+
solution_1 = exp(root_1.real * variable_x)
62+
solution_2 = exp(root_2.real * variable_x)
63+
64+
# Case 3: Complex conjugate roots (α ± iβ)
65+
else:
66+
alpha = root_1.real
67+
beta = abs(root_1.imag)
68+
solution_1 = exp(alpha * variable_x) * cos(beta * variable_x)
69+
solution_2 = exp(alpha * variable_x) * sin(beta * variable_x)
70+
71+
return solution_1, solution_2
72+
73+
74+
def compute_wronskian(function_1, function_2):
75+
"""
76+
Compute the Wronskian determinant of two functions.
77+
78+
>>> from sympy import symbols, exp
79+
>>> x = symbols('x')
80+
>>> f1, f2 = exp(x), x*exp(x)
81+
>>> compute_wronskian(f1, f2)
82+
exp(2*x)
83+
"""
84+
variable_x = symbols("x")
85+
derivative_1 = diff(function_1, variable_x)
86+
derivative_2 = diff(function_2, variable_x)
87+
wronskian = simplify(function_1 * derivative_2 - function_2 * derivative_1)
88+
return wronskian
89+
90+
91+
def solve_first_order_equation(coefficient_b: float, coefficient_c: float) -> None:
92+
"""
93+
Solve the first-order ODE: b*y' + c*y = 0
94+
and display its general solution and Wronskian.
95+
96+
>>> solve_first_order_equation(2, 4)
97+
"""
98+
variable_x = symbols("x")
99+
if coefficient_b == 0:
100+
print("Error: Both a and b cannot be zero. Not a valid differential equation.")
101+
return
102+
103+
# Simplified form: y' + (c/b)*y = 0
104+
constant_k = coefficient_c / coefficient_b
105+
solution = exp(-constant_k * variable_x)
106+
107+
derivative_solution = diff(solution, variable_x)
108+
wronskian = simplify(solution * derivative_solution)
109+
110+
print("\n--- First-Order Differential Equation ---")
111+
print(f"Equation: {coefficient_b}*y' + {coefficient_c}*y = 0")
112+
print(f"Solution: y = C * e^(-({coefficient_c}/{coefficient_b}) * x)")
113+
print(f"y'(x) = {derivative_solution}")
114+
print(f"Wronskian (single function): {wronskian}")
115+
print("Linear independence: Trivial (only one solution).")
116+
117+
118+
def analyze_differential_equation(
119+
coefficient_a: float, coefficient_b: float, coefficient_c: float
120+
) -> None:
121+
"""
122+
Determine the type of equation and analyze it accordingly.
123+
"""
124+
# Case 1: Not a valid DE
125+
if coefficient_a == 0 and coefficient_b == 0:
126+
print("Error: Both 'a' and 'b' cannot be zero. Not a valid differential equation.")
127+
return
128+
129+
# Case 2: First-order DE
130+
if coefficient_a == 0:
131+
solve_first_order_equation(coefficient_b, coefficient_c)
132+
return
133+
134+
# Case 3: Second-order DE
135+
print("\n--- Second-Order Differential Equation ---")
136+
root_1, root_2 = compute_characteristic_roots(
137+
coefficient_a, coefficient_b, coefficient_c
138+
)
139+
140+
print(f"Characteristic roots: r1 = {root_1}, r2 = {root_2}")
141+
142+
function_1, function_2 = construct_fundamental_solutions(root_1, root_2)
143+
144+
variable_x = symbols("x")
145+
derivative_1 = diff(function_1, variable_x)
146+
derivative_2 = diff(function_2, variable_x)
147+
wronskian = compute_wronskian(function_1, function_2)
148+
149+
print(f"y₁(x) = {function_1}")
150+
print(f"y₂(x) = {function_2}")
151+
print(f"y₁'(x) = {derivative_1}")
152+
print(f"y₂'(x) = {derivative_2}")
153+
print(f"Wronskian: {wronskian}")
154+
155+
if wronskian == 0:
156+
print("The functions are linearly dependent.")
157+
else:
158+
print("The functions are linearly independent.")
159+
160+
161+
def main() -> None:
162+
"""
163+
Entry point of the program.
164+
"""
165+
print("Enter coefficients for the equation a*y'' + b*y' + c*y = 0")
166+
try:
167+
coefficient_a = float(input("a = ").strip())
168+
coefficient_b = float(input("b = ").strip())
169+
coefficient_c = float(input("c = ").strip())
170+
except ValueError:
171+
print("Invalid input. Please enter numeric values for coefficients.")
172+
return
173+
174+
analyze_differential_equation(coefficient_a, coefficient_b, coefficient_c)
175+
176+
177+
if __name__ == "__main__":
178+
main()

0 commit comments

Comments
 (0)