From 183c55c09e62c069d65b2f5d9f5d7c065ad16228 Mon Sep 17 00:00:00 2001 From: Christian Kolset Date: Wed, 3 Sep 2025 13:19:49 -0600 Subject: Updated entries --- tutorials/module_2/1_problem_solving_strategies.md | 54 ++++++++ tutorials/module_2/2_num_methods_1.md | 119 ++++++++++++++++++ tutorials/module_2/num_methods_1.md | 119 ------------------ tutorials/module_2/problem_solving_strategies.md | 54 -------- tutorials/module_3/0_numerical_methods.md | 46 +++++++ tutorials/module_3/1_numerical_differentiation.md | 67 ++++++++++ tutorials/module_3/2_roots_optimization.md | 12 ++ tutorials/module_3/3_system_of_equations.md | 11 ++ tutorials/module_3/4_numerical_integration.md | 129 +++++++++++++++++++ tutorials/module_3/5_ode.md | 10 ++ tutorials/module_3/numerical_differentiation.md | 67 ---------- tutorials/module_3/numerical_integration.md | 140 --------------------- tutorials/module_3/numerical_methods.md | 46 ------- tutorials/module_3/ode.md | 10 -- tutorials/module_3/roots_optimization.md | 12 -- tutorials/module_3/system_of_equations.md | 11 -- 16 files changed, 448 insertions(+), 459 deletions(-) create mode 100644 tutorials/module_2/1_problem_solving_strategies.md create mode 100644 tutorials/module_2/2_num_methods_1.md delete mode 100644 tutorials/module_2/num_methods_1.md delete mode 100644 tutorials/module_2/problem_solving_strategies.md create mode 100644 tutorials/module_3/0_numerical_methods.md create mode 100644 tutorials/module_3/1_numerical_differentiation.md create mode 100644 tutorials/module_3/2_roots_optimization.md create mode 100644 tutorials/module_3/3_system_of_equations.md create mode 100644 tutorials/module_3/4_numerical_integration.md create mode 100644 tutorials/module_3/5_ode.md delete mode 100644 tutorials/module_3/numerical_differentiation.md delete mode 100644 tutorials/module_3/numerical_integration.md delete mode 100644 tutorials/module_3/numerical_methods.md delete mode 100644 tutorials/module_3/ode.md delete mode 100644 tutorials/module_3/roots_optimization.md delete mode 100644 tutorials/module_3/system_of_equations.md diff --git a/tutorials/module_2/1_problem_solving_strategies.md b/tutorials/module_2/1_problem_solving_strategies.md new file mode 100644 index 0000000..4fa20e9 --- /dev/null +++ b/tutorials/module_2/1_problem_solving_strategies.md @@ -0,0 +1,54 @@ +# Algorithmic thinking + +^da584e + +In engineering, solving a problem begins long before we start coding or building models. Like any other engineering challenge, computational problems must first be clearly framed and understood. In this section, you will learn to **apply algorithmic thinking** to systematically approach engineering problems, **translate real-world situations into structured programming logic**, and **use computational tools to implement, test, and refine solutions**. + +Before diving into code, it's crucial to define the problem carefully, frame the problem so that logically so that a computer can understand then execute so that + + +## Define the Problem + +As any other engineering problem, we need to frame it before we can start working on it. So before jumping straight into coding or building models, clearly define the engineering problem. + +1. List your givens, this includes any constants or equations. What inputs do we know? +2. Find: List what you're trying to solve for. What outputs do we need to find? +3. Establish the assumptions based on your engineering knowledge that you deem to be appropriate to use for the problem. This determines what mathematical models we can apply to the problem (i.e. equations or formulas). +4. Solution: Show the works of the problem, this will include any code used together with documentation or any explanations of the code. +5. Comment: reflect and comment on your findings. + +## Think Algorithmically + +Since we are going to use computers to compute our calculate we first need to break the problem into logical steps that a computer can follow. This can be done with tools such as flowchart or psuedo-code. + +- **Define the inputs and outputs.** What variables will the program take in, and what results will it produce? +- **Break the problem into sub-tasks.** Identify steps such as data input, logic processing and output. +- **Outline the algorithm.** Write pseudo-code or flowcharts that describe the computational steps. +- **Identify patterns or formulas.** Can loops, conditionals, or equations be used to automate parts of the solution? + +### Flowchart for fixing lamp +![Lamp Flowchart](figures/LampFlowchart.png) + +### Psuedo-Code for processing and plotting stress-strain data: +1. Import force and displacement data from file. +2. Convert data from force and displacement to stress and strain. +3. Plot the stress-strain curve. +4. Identify the yield point or modulus. + +## Write & Execute the Code +When writing the code it is important to ask yourself whether you're using the right tools, libraries or method to solve the problem. **Check for any syntax and logic errors** then debug line-by-line using print statements or by using a debugging tool. + +## Verify and Validate +When writing code it is crucial to test and confirm your code. It is therefore important to ask yourself the following questions. Does the code do what you intended it to do? And, is the mathematical model used in the code valid for the current problem? +## Exercise: Rubrics Cube problem + + + +## Exercise: Design a derivative finding algorithm +Set up the problem and write pseudo-code to calculate the gradient of an unknown function. + +1. **Given:** +2. **Find: +3. **Assumptions:** +4. **Solution:** +5. **Comment:** \ No newline at end of file diff --git a/tutorials/module_2/2_num_methods_1.md b/tutorials/module_2/2_num_methods_1.md new file mode 100644 index 0000000..1ab4fa8 --- /dev/null +++ b/tutorials/module_2/2_num_methods_1.md @@ -0,0 +1,119 @@ +# Solving non-linear equations + +^ca27a3 + +## Introduction + + +## Prerequisites + +```python +import numpy +import scipy +import sympy +``` + + +## fsolve from SciPy + +```python +from scipy.optimize import fsolve + +def equations(vars): + x, y = vars + eq1 = x**2 + y**2 - 25 + eq2 = x**2 - y + return [eq1, eq2] + +initial_guess = [1, 1] +solution = fsolve(equations, initial_guess) +print("Solution:", solution) +``` + +## root from SciPy +```python +from scipy.optimize import root + +def equations(vars): + x, y = vars + eq1 = x**2 + y**2 - 25 + eq2 = x**2 - y + return [eq1, eq2] + +initial_guess = [1, 1] +solution = root(equations, initial_guess) +print("Solution:", solution.x) +``` + + +## minimize from SciPy +```python +from scipy.optimize import minimize + +# Define the equations +def equation1(x, y): + return x**2 + y**2 - 25 + +def equation2(x, y): + return x**2 - y + +# Define the objective function for optimization +def objective(xy): + x, y = xy + return equation1(x, y)**2 + equation2(x, y)**2 + +# Initial guess +initial_guess = [1, 1] + +# Perform optimization +result = minimize(objective, initial_guess) +solution_optimization = result.x + +print("Optimization Method Solution:", solution_optimization) + +``` + +## nsolve from SymPy +```python +from sympy import symbols, Eq, nsolve + +# Define the variables +x, y = symbols('x y') + +# Define the equations +eq1 = Eq(x**2 + y**2, 25) +eq2 = Eq(x - y, 0) + +# Initial guess for the solution +initial_guess = [1, 1] + +# Use nsolve to find the solution +solution = nsolve([eq1, eq2], [x, y], initial_guess) +print("Solution:", solution) +``` + +## newton_method from NumPy + +```python +import numpy as np + +def equations(vars): + x, y = vars + eq1 = x**2 + y**2 - 25 + eq2 = x**2 - y + return np.array([eq1, eq2]) + +def newton_method(initial_guess, tolerance=1e-6, max_iter=100): + vars = np.array(initial_guess, dtype=float) + for _ in range(max_iter): + J = np.array([[2 * vars[0], 2 * vars[1]], [2 * vars[0], -1]]) + F = equations(vars) + delta = np.linalg.solve(J, -F) + vars += delta + if np.linalg.norm(delta) < tolerance: + return vars + +initial_guess = [1, 1] +solution = newton_method(initial_guess) +print("Solution:", solution) +``` \ No newline at end of file diff --git a/tutorials/module_2/num_methods_1.md b/tutorials/module_2/num_methods_1.md deleted file mode 100644 index 1ab4fa8..0000000 --- a/tutorials/module_2/num_methods_1.md +++ /dev/null @@ -1,119 +0,0 @@ -# Solving non-linear equations - -^ca27a3 - -## Introduction - - -## Prerequisites - -```python -import numpy -import scipy -import sympy -``` - - -## fsolve from SciPy - -```python -from scipy.optimize import fsolve - -def equations(vars): - x, y = vars - eq1 = x**2 + y**2 - 25 - eq2 = x**2 - y - return [eq1, eq2] - -initial_guess = [1, 1] -solution = fsolve(equations, initial_guess) -print("Solution:", solution) -``` - -## root from SciPy -```python -from scipy.optimize import root - -def equations(vars): - x, y = vars - eq1 = x**2 + y**2 - 25 - eq2 = x**2 - y - return [eq1, eq2] - -initial_guess = [1, 1] -solution = root(equations, initial_guess) -print("Solution:", solution.x) -``` - - -## minimize from SciPy -```python -from scipy.optimize import minimize - -# Define the equations -def equation1(x, y): - return x**2 + y**2 - 25 - -def equation2(x, y): - return x**2 - y - -# Define the objective function for optimization -def objective(xy): - x, y = xy - return equation1(x, y)**2 + equation2(x, y)**2 - -# Initial guess -initial_guess = [1, 1] - -# Perform optimization -result = minimize(objective, initial_guess) -solution_optimization = result.x - -print("Optimization Method Solution:", solution_optimization) - -``` - -## nsolve from SymPy -```python -from sympy import symbols, Eq, nsolve - -# Define the variables -x, y = symbols('x y') - -# Define the equations -eq1 = Eq(x**2 + y**2, 25) -eq2 = Eq(x - y, 0) - -# Initial guess for the solution -initial_guess = [1, 1] - -# Use nsolve to find the solution -solution = nsolve([eq1, eq2], [x, y], initial_guess) -print("Solution:", solution) -``` - -## newton_method from NumPy - -```python -import numpy as np - -def equations(vars): - x, y = vars - eq1 = x**2 + y**2 - 25 - eq2 = x**2 - y - return np.array([eq1, eq2]) - -def newton_method(initial_guess, tolerance=1e-6, max_iter=100): - vars = np.array(initial_guess, dtype=float) - for _ in range(max_iter): - J = np.array([[2 * vars[0], 2 * vars[1]], [2 * vars[0], -1]]) - F = equations(vars) - delta = np.linalg.solve(J, -F) - vars += delta - if np.linalg.norm(delta) < tolerance: - return vars - -initial_guess = [1, 1] -solution = newton_method(initial_guess) -print("Solution:", solution) -``` \ No newline at end of file diff --git a/tutorials/module_2/problem_solving_strategies.md b/tutorials/module_2/problem_solving_strategies.md deleted file mode 100644 index 4fa20e9..0000000 --- a/tutorials/module_2/problem_solving_strategies.md +++ /dev/null @@ -1,54 +0,0 @@ -# Algorithmic thinking - -^da584e - -In engineering, solving a problem begins long before we start coding or building models. Like any other engineering challenge, computational problems must first be clearly framed and understood. In this section, you will learn to **apply algorithmic thinking** to systematically approach engineering problems, **translate real-world situations into structured programming logic**, and **use computational tools to implement, test, and refine solutions**. - -Before diving into code, it's crucial to define the problem carefully, frame the problem so that logically so that a computer can understand then execute so that - - -## Define the Problem - -As any other engineering problem, we need to frame it before we can start working on it. So before jumping straight into coding or building models, clearly define the engineering problem. - -1. List your givens, this includes any constants or equations. What inputs do we know? -2. Find: List what you're trying to solve for. What outputs do we need to find? -3. Establish the assumptions based on your engineering knowledge that you deem to be appropriate to use for the problem. This determines what mathematical models we can apply to the problem (i.e. equations or formulas). -4. Solution: Show the works of the problem, this will include any code used together with documentation or any explanations of the code. -5. Comment: reflect and comment on your findings. - -## Think Algorithmically - -Since we are going to use computers to compute our calculate we first need to break the problem into logical steps that a computer can follow. This can be done with tools such as flowchart or psuedo-code. - -- **Define the inputs and outputs.** What variables will the program take in, and what results will it produce? -- **Break the problem into sub-tasks.** Identify steps such as data input, logic processing and output. -- **Outline the algorithm.** Write pseudo-code or flowcharts that describe the computational steps. -- **Identify patterns or formulas.** Can loops, conditionals, or equations be used to automate parts of the solution? - -### Flowchart for fixing lamp -![Lamp Flowchart](figures/LampFlowchart.png) - -### Psuedo-Code for processing and plotting stress-strain data: -1. Import force and displacement data from file. -2. Convert data from force and displacement to stress and strain. -3. Plot the stress-strain curve. -4. Identify the yield point or modulus. - -## Write & Execute the Code -When writing the code it is important to ask yourself whether you're using the right tools, libraries or method to solve the problem. **Check for any syntax and logic errors** then debug line-by-line using print statements or by using a debugging tool. - -## Verify and Validate -When writing code it is crucial to test and confirm your code. It is therefore important to ask yourself the following questions. Does the code do what you intended it to do? And, is the mathematical model used in the code valid for the current problem? -## Exercise: Rubrics Cube problem - - - -## Exercise: Design a derivative finding algorithm -Set up the problem and write pseudo-code to calculate the gradient of an unknown function. - -1. **Given:** -2. **Find: -3. **Assumptions:** -4. **Solution:** -5. **Comment:** \ No newline at end of file diff --git a/tutorials/module_3/0_numerical_methods.md b/tutorials/module_3/0_numerical_methods.md new file mode 100644 index 0000000..449ece0 --- /dev/null +++ b/tutorials/module_3/0_numerical_methods.md @@ -0,0 +1,46 @@ +# Numerical Methods +Engineering + +## What is a numerical method? +Numerical methods are techniques that transform mathematical problems into forms that can be solved using arithmetic and logical operations. Because digital computers excel at these computations, numerical methods are often referred to as computer mathematics. + + +## Numerical Differentiation +Forwards difference +Backwards difference +Central Difference method +[Read More](https://pythonnumericalmethods.studentorg.berkeley.edu/notebooks/chapter20.00-Numerical-Differentiation.html) + +## Roots and Optimization +Incremental Search +Bisection +Modified Secant +Newton-Raphson + +## System of Equations +Guassian Method +LU Decomposition + +## Numerical Integration + +Midpoint +Trapezoidal +Romberg +Gaussian +Simpson's Rule + +[Read More](https://pythonnumericalmethods.studentorg.berkeley.edu/notebooks/chapter21.00-Numerical-Integration.html) + + +## Numerical Solutions of Ordinary Differential Equations + +Euler's Method +- Forward +- Backwards + +Runge-Kutte + +[ReadMore](https://pythonnumericalmethods.studentorg.berkeley.edu/notebooks/chapter22.00-ODE-Initial-Value-Problems.html) + + + diff --git a/tutorials/module_3/1_numerical_differentiation.md b/tutorials/module_3/1_numerical_differentiation.md new file mode 100644 index 0000000..b34b315 --- /dev/null +++ b/tutorials/module_3/1_numerical_differentiation.md @@ -0,0 +1,67 @@ +# Numerical Differentiation +Finding a derivative of tabular data can be done using a finite difference. Here we essentially pick two points on a function or a set of data points and calculate the slope from there. Let's imagine a domain $x$ as a vector such that $\vec{x}$ = $\pmatrix{x_0, x_1, x_2, ...}$. Then we can use the following methods to approximate derivatives + +## Forward Difference +Uses the point at which we want to find the derivative and a point forwards on the line. +$$ +f'(x_i) = \frac{f(x_{i+1})-f(x_i)}{x_{i+1}-x_i} +$$ +*Hint: Consider what happens at the last point.* + +```python +import numpy as np +import matplotlib.pyplot as plt + +# Initiate vectors +x = np.linspace(0, 2, 100) +y = 34 * np.exp(3 * x) + +dydx = (y[1:] - y[:-1]) / (x[1:] - x[:-1]) + +# Plot the function +plt.plot(x, y, label=r'$y(x)$') +plt.plot(x, dydx, label=b'$/frac{dy}{dx}$') +plt.xlabel('x') +plt.ylabel('y') +plt.title('Plot of $34e^{3x}$') +plt.grid(True) +plt.legend() +plt.show() +``` + + +## Backwards Difference +Uses the point at which we want to find +$$ +f'(x_i) = \frac{f(x_{i})-f(x_{i-1})}{x_i - x_{i-1}} +$$ + + +```python +import numpy as np +import matplotlib.pyplot as plt + +# Initiate vectors +x = np.linspace(0, 2, 100) +y = 34 * np.exp(3 * x) + +dydx = (y[1:] - y[:-1]) / (x[1:] - x[:-1]) + +# Plot the function +plt.plot(x, y, label=r'$y(x)$') +plt.plot(x, dydx, label=b'$/frac{dy}{dx}$') +plt.xlabel('x') +plt.ylabel('y') +plt.title('Plot of $34e^{3x}$') +plt.grid(True) +plt.legend() +plt.show() +``` +## Central Difference + +$$ +f'(x_i) = \frac{f(x_{i+1})-f(x_{i-1})}{x_{i+1}-x_{i-1}} +$$ + + + diff --git a/tutorials/module_3/2_roots_optimization.md b/tutorials/module_3/2_roots_optimization.md new file mode 100644 index 0000000..3a288cc --- /dev/null +++ b/tutorials/module_3/2_roots_optimization.md @@ -0,0 +1,12 @@ +# Root Finding Methods + +Root Finding Methods or non-linear equation solvers. + +## Incremental Search + +## Bisection + +## Modified Secant + +## Newton-Raphson + diff --git a/tutorials/module_3/3_system_of_equations.md b/tutorials/module_3/3_system_of_equations.md new file mode 100644 index 0000000..9830060 --- /dev/null +++ b/tutorials/module_3/3_system_of_equations.md @@ -0,0 +1,11 @@ +# Systems of Equations + + +## Naive Gauss Elimination + +## Forward Elimination + +## Back Substitution + +## LU Decomposition + diff --git a/tutorials/module_3/4_numerical_integration.md b/tutorials/module_3/4_numerical_integration.md new file mode 100644 index 0000000..c486825 --- /dev/null +++ b/tutorials/module_3/4_numerical_integration.md @@ -0,0 +1,129 @@ +## Midpoint Method + + +## Trapezoidal Method + + +## Romberg Integration + + +## Gaussian Integration + + +## Simpson's Rule + +### Simpsons 1/3 + +### Simpsons 3/8 + + + + +# Numerical Integration +## Why Numerical? +Integration is one of the fundamental tools in engineering analysis. Mechanical engineers frequently encounter integrals when computing work from force–displacement data, determining heat transfer from a time-dependent signal, or calculating lift and drag forces from pressure distributions over an airfoil. While some integrals can be evaluated analytically, most practical problems involve functions that are either too complex or are available only as experimental data. As engineering we choose numerical integration—also known as quadrature—provides a systematic approach to approximate the integral of a function over a finite interval. + +In this tutorial, we will study several standard methods of numerical integration, compare their accuracy, and implement them in Python. By the end, you will understand not only how to apply each method, but also when one method may be more suitable than another. + +--- + +## Numerical Methods +We wish to approximate a definite integral of the form: +$$ +I = \int_a^b f(x) \, dx +$$ +by a weighted sum of function values: +$$ +I \approx \sum_{i=0}^m w_i f(x_i). +$$ +Here, $x_i$ are the chosen evaluation points and $w_i$ are their associated weights. + +### Midpoint Rule +The midpoint rule divides the interval into $n$ subintervals of equal width $h = (b-a)/n$ and +evaluates the function at the midpoint of each subinterval: +$$ +I \approx \sum_{i=0}^{n-1} h \, f\!\left(x_i + \tfrac{h}{2}\right). +$$ +This method achieves second-order accuracy (error decreases with $h^2$). +### Trapezoidal Rule +The trapezoidal rule approximates the area under the curve as a series of trapezoids: +$$ +I \approx \frac{h}{2}\Big[f(x_0) + 2\sum_{i=1}^{n-1} f(x_i) + f(x_n)\Big]. +$$ +It is simple to implement and works especially well for tabulated data. Like the midpoint rule, +its accuracy is of order $O(h^2)$. + +### Simpson’s Rule +Simpson’s rules use polynomial interpolation to achieve higher accuracy. + +- **Simpson’s 1/3 Rule (order $O(h^4)$)** + Requires an even number of subintervals $n$: + $$ + I \approx \frac{h}{3}\Big[f(x_0) + 4\sum_{\text{odd } i} f(x_i) + + 2\sum_{\text{even } i