<jupyter_start><jupyter_text>Notebook DescriptionThis notebook helps find the solution to an initial value problem of a linear ODE of arbitrary order. The user must provide: * ODE definition * Particular solution (for non-homogeneous ODES) * A set of solutions to the associated homogeneous ODE * Initial conditionsThis document will: * automate display * calculating the Wronskian determinant to determine if the solutions form a fundamental set * fit the general solution to the initial conditions  Environment Setup<jupyter_code>from sympy import *
from IPython.display import display, Markdown
from utils import fit_to_initial_conditions, fit_undetermined_coefficients, wronskian_matrix
from utils import constant_coeff_characteristic_roots, roots_to_homogenous_solutions

init_printing(use_latex = True)<jupyter_output><empty_output><jupyter_text>Problem Specification<jupyter_code># Define independent variable, by default t
t = symbols('t')

# define solution symbol, by default y. Y symbol is used for
# display and denotation, while y will hold the solution values
y_symbol = symbols('y')
y_func = Function(y_symbol)(t)

# TODO: Define ODE
ode = diff(y_func, t, 3) - 2*diff(y_func, t, 2) + 2*diff(y_func, t) - y_func

# TODO: Define f(t) for non-homoegeneous ODEs, i.e. the e^x in y''+2y'+y=e^x
f = 0

# TODO: define the initial conditions. Like ode coefficients, the index
# indicates the derivative order
t0 = 0
y0 = [0 ,1 ,2]<jupyter_output><empty_output><jupyter_text>Problem SummaryA linear ODE defined as<jupyter_code>display(ode)<jupyter_output><empty_output><jupyter_text>has constant coefficients, so we can find homogenous solutions using the characteristic equation:<jupyter_code>root_list = constant_coeff_characteristic_roots(ode, t, y_func)
yh_solutions = roots_to_homogenous_solutions(root_list, t)<jupyter_output><empty_output><jupyter_text>These solutions form a fundamental set if their wronskian is not identical to 0:<jupyter_code># Display
w_symbol = symbols("W")
display(Markdown("The wronskian determinant " + latex(w_symbol, mode = "inline") + " is calculated as:"))

w_matrix = wronskian_matrix(t, *yh_solutions)
display(Eq(w_symbol, Determinant(w_matrix), evaluate = False))
w = wronskian(yh_solutions, t)
display(Eq(w_symbol, w, evaluate = False))<jupyter_output><empty_output><jupyter_text>Since the wronskian is not zero, we have a fundamental set and can write our solution in the form<jupyter_code>c_symbols = [symbols("c_%i" % (i+1)) for i in range(len(yh_solutions))]
y = sum([c_symbols[i]*yh_solutions[i] for i in range(len(yh_solutions))])
display(Eq(y_symbol, y, evaluate = False))<jupyter_output><empty_output><jupyter_text>Since we know our initial conditions, we can determine the values of our constants:<jupyter_code>c_values = fit_to_initial_conditions(y, t, c_symbols, t0, y0)<jupyter_output><empty_output><jupyter_text>We can substitute these values into our equation to find our solution:<jupyter_code>y = sum([c_values[i]*yh_solutions[i] for i in range(len(yh_solutions))])
display(Eq(y_symbol, y, evaluate = False))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0928732666881651, 'fraction_numerical': 0.0051596259271202835, 'mean_word_length': 7.545454545454546, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '644702', 'license': 'MIT', 'n_tokens_mistral': 1046, 'n_tokens_neox': 1019, 'n_words': 302, 'path': 'LinearODE.ipynb', 'repo_name': 'EganJ/MathHomeworkNotebooks', 'size': '3101'}