UNIVERSITY INSTITUTE OF ENGINEERING
Subject Name – Numerical Methods and Optimization Using Python
Course Code- 21CSH-459b
Submitted To: Mohit Sir Submitted By: harsh patil
Faculty Name: Mohit Singh Bisht Name: Harsh Patil
UID: 21BCS1560
Section:
21bcs53
Group:
a
Department of Computer Science & Engineering
INDEX
Exp. List of Experiments Conduct Viva Record Total Remarks
No (M.M:12) (M.M:10) (M.M:8) (M.M:30)
A solar panel manufacturer
1. wants to optimize the
design of their solar panels
to maximize energy
production. They have
historical data on the
amount of energy produced
by solar panels with
different surface areas and
the cost of manufacturing
those panels. The
manufacturer wants to find
the optimal surface area
that maximizes the profit
function, which is the
difference between the
revenue and the cost. You
have been hired to develop
a program that uses the
Newton-Raphson Method to
find the optimal surface
area for the solar panels.
The Newton-Raphson
Method is a numerical
method used to find the root
of a function.
A small software company
2. has a list of employee ages:
34, 28, 45, 22, and 30.
They want to arrange these
ages in ascending order
using the bubble sort
algorithm to analyze the
age distribution efficiently.
Explain how bubble sort will
process this list to sort it,
describing the changes in
the list after each full pass
through the data. Also,
mention the total number of
swaps performed until the
list is completely sorted.
Experiment–I: Review of Python Basics, Data Types, Control Structures, and Functions in Python
AIM: Implement of Python Basics : Variable, Print Statement, Commands, Data Types : Numeric Types,
string , List and Tuple , Control Structures: If, For and While, Functios: Function
Definition,Function Call,Return Statement,Default Parameters
S/W Requirement: Python 3.11 (Install latest according to your system).
Introduction: understanding of Python basics, data types, control structures, and functions to build a
strong foundation for programming. Let's break down these concepts and provide a brief review for each.
1. Python Basics:
Variables: In Python, you can create variables to store and manipulate data. Variable names are case-
sensitive.
Print Statement: Use the print function to display output.
Comments: Add comments to your code using # for single-line comments or triple-quotes (''' or """) for
multi-line comments.
2. Data Types:
Numeric Types: Integers (int), floating-point numbers (float).
String: Sequence of characters.
13
List: Ordered, mutable collection.
Tuple: Ordered, immutable collection.
3. Control Structures:
If Statements:
Loops:
For Loop:
While Loop:
14
Functions in Python:
Function Definition:
Function Call:
Return Statement:
Default Parameters:
Experiment – II: Implementations of different Data Structures in python
AIM: Implementation of Stack, Queue and Linked List.
S/W Requirement: Python 3.11 (Install latest according to your system).
Stack:
Code:
class Stack:
def init (self):
self.items = []
def is_empty(self):
return len(self.items) == 0
def push(self, item):
self.items.append(item)
def pop(self):
if not self.is_empty():
return self.items.pop()
else:
raise IndexError("pop from an empty stack")
def peek(self):
if not self.is_empty():
return self.items[-1]
else:
raise IndexError("peek from an empty stack")
def size(self):
return len(self.items)
# Example usage:
stack = Stack()
stack.push(1)
1
stack.push(2)
stack.push(3)
print("Stack:", stack.items)
print("Pop:", stack.pop())
print("Peek:", stack.peek())
print("Stack size:", stack.size())
Queue:
Code:
from collections import deque
class Queue:
def init (self):
self.items = deque()
def is_empty(self):
return len(self.items) == 0
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
if not self.is_empty():
return self.items.popleft()
else:
raise IndexError("dequeue from an empty queue")
def size(self):
return len(self.items)
# Example usage:
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
2
print("Queue:", list(queue.items))
print("Dequeue:", queue.dequeue())
print("Queue size:", queue.size())
Linked List :
Code:
class Node:
def init (self, data):
self.data = data
self.next = None
class LinkedList:
def init (self):
self.head = None
def is_empty(self):
return self.head is None
def append(self, data):
new_node = Node(data)
if self.is_empty():
self.head = new_node
else:
current = self.head
while current.next:
current = current.next
current.next = new_node
def display(self):
elements = []
current = self.head
while current:
3
elements.append(current.data)
current = current.next
print("Linked List:", elements)
# Example usage:
linked_list = LinkedList()
linked_list.append(1)
linked_list.append(2)
linked_list.append(3)
linked_list.display()
Experiment–III: Implementing Root-finding Algorithms (Bisection method, Newton-Raphson
method) in Python
AIM: Implementing Root-finding Algorithms (Bisection method, Newton-Raphson method) in Python
S/W Requirement: Python 3.11 (Install latest version according to your system).
Bisection Method:
Code:
def bisection_method(func, a, b, tol=1e-6, max_iter=100):
if func(a) * func(b) > 0:
raise ValueError("The function values at the interval endpoints must have opposite
signs.") iteration = 0
while (b - a) / 2 > tol and iteration < max_iter:
c = (a + b) / 2
if func(c) == 0:
return c # Found exact root
elif func(c) * func(a) < 0:
b=c
else:
a=c
iteration += 1
return (a + b) / 2
# Example usage:
def quadratic_function(x):
return x**2 - 4
root = bisection_method(quadratic_function, 0, 3)
print("Bisection Method Root:", root)
Newton-Raphson Method:
Code:
def newton_raphson_method(func, func_derivative, initial_guess, tol=1e-6, max_iter=100):
x = initial_guess
iteration = 0
while abs(func(x)) > tol and iteration < max_iter:
x = x - func(x) / func_derivative(x)
iteration += 1
return x
# Example usage:
def cubic_function(x):
return x**3 - 6*x**2 + 11*x - 6
def cubic_derivative(x):
return 3*x**2 - 12*x + 11
initial_guess = 1.5
root_newton = newton_raphson_method(cubic_function, cubic_derivative, initial_guess)
print("Newton-Raphson Method Root:", root_newton)
Output
Experiment-IV: Implementing Secant Algorithms in Python
AIM: Implementing Secant Algorithms in Python
S/W Requirement: Python 3.11 (Install latest version according to your system)..
Introduction:
Secant method.
def secant_method(func, x0, x1, tol=1e-6, max_iter=100):
"""
Implements the Secant method to find the root of a function.
Parameters:
- func: The target function.
- x0: Initial guess for the root.
- x1: Another initial guess for the root.
- tol: Tolerance for stopping criterion (default is 1e-6).
- max_iter: Maximum number of iterations (default is 100).
Returns:
- root: Approximation of the root.
- iterations: Number of iterations performed.
"""
x_k_minus_1 =
x0 x_k = x1
for k in range(max_iter):
f_k_minus_1 = func(x_k_minus_1)
f_k = func(x_k)
x_k_plus_1 = x_k - f_k * (x_k - x_k_minus_1) / (f_k - f_k_minus_1)
if abs(x_k_plus_1 - x_k) < tol:
return x_k_plus_1, k + 1 # Return the root and the number of iterations
x_k_minus_1 = x_k
x_k = x_k_plus_1
raise ValueError("Secant method did not converge within the maximum number of
iterations.")
# Example usage:
if name == " main ":
# Define the function for finding the square root of a
number def target_function(x):
return x**2 - 4
25
# Initial guesses
x0 = 1.0
x1 = 3.0
# Call the Secant method function
root, iterations = secant_method(target_function, x0, x1)
print(f"Root found: {root}")
print(f"Iterations: {iterations}")
Output
Experiment-V: Hands-on interpolation exercises using Python libraries
AIM: To implement Hands-on interpolation exercises using Python libraries S/W
Requirement: Python 3.11 (Install latest version according to your system).
Introduction: Interpolation is a mathematical technique used to estimate values between
known data points. In Python, you can use various libraries such as NumPy and SciPy for
interpolation. Here's a hands-on interpolation exercise using these libraries.
Remember to install the required libraries if you haven't already:
Code:
import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
# Generate some sample data
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 8, 18, 32, 50])
# Plot the original data
plt.scatter(x, y, label='Original Data')
# Perform linear interpolation
linear_interp = interp1d(x, y, kind='linear')
x_interp_linear = np.linspace(min(x), max(x), 100)
y_interp_linear = linear_interp(x_interp_linear)
plt.plot(x_interp_linear, y_interp_linear, label='Linear Interpolation')
# Perform cubic spline interpolation
cubic_interp = interp1d(x, y, kind='cubic')
y_interp_cubic = cubic_interp(x_interp_linear)
plt.plot(x_interp_linear, y_interp_cubic, label='Cubic Spline Interpolation')
# Show the plot
plt.title('Interpolation Exercise')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.show()
In this example, we first generate some sample data with x and y arrays. We then use linear
and cubic spline interpolation with the help of interp1d from SciPy. The interpolated values
are then plotted alongside the original data using Matplotlib.
Feel free to experiment with different kinds of interpolation (e.g., quadratic, polynomial) by
changing the kind parameter in interp1d. You can also try using different sets of data to observe
how the interpolation behaves with various datasets.
Output
Experiment-VI: Implementing numerical integration algorithms.
AIM: implementing two common numerical integration algorithms, the trapezoidal rule and
Simpson's rule
S/W Requirement: Python 3.11 (Install latest version according to your system).
Numerical integration algorithms are used to approximate definite integrals when an analytical
solution is not feasible. Here's a hands-on experiment implementing two common numerical
integration algorithms, the trapezoidal rule and Simpson's rule, in Python:
Code:
import numpy as np
import matplotlib.pyplot as plt
# Function to
integrate def func(x):
return x**2
# Trapezoidal rule implementation
def trapezoidal_rule(func, a, b, n):
h = (b - a) / n
x = np.linspace(a, b, n + 1)
y = func(x)
integral = h * (np.sum(y) - 0.5 * (y[0] + y[-1]))
return integral
# Simpson's rule implementation
def simpsons_rule(func, a, b, n):
h = (b - a) / n
x = np.linspace(a, b, n + 1)
y = func(x)
integral = h / 3 * (y[0] + 4 * np.sum(y[1:-1:2]) + 2 * np.sum(y[2:-2:2]) + y[-
1]) return integral
# Define integration
bounds a, b = 0, 2
# True integral value for comparison (since we know the integral of x^2 from 0 to
2) true_value = 2.67 # Analytical solution
print(f'True Integral Value: {true_value}')
# Experiment with different values of n
n_values = [4, 8, 16, 32, 64]
# Perform integration and print
results for n in n_values:
trapezoidal_result = trapezoidal_rule(func, a, b,
n) simpsons_result = simpsons_rule(func, a, b, n)
print(f'n={n}: Trapezoidal Result={trapezoidal_result:.4f},
Simpsons Result={simpsons_result:.4f}')
# Plot the function and the area under the curve
x_values = np.linspace(a, b, 100)
plt.plot(x_values, func(x_values), label='$x^2$ function')
plt.fill_between(x_values, func(x_values), alpha=0.2, label='Area under the curve')
# Show the plot and legend
plt.title('Numerical Integration
Experiment') plt.xlabel('x')
plt.ylabel('f(x)')
plt.legend()
plt.show()
Output
Experiment-VII: Implementing numerical differentiation algorithms
AIM: hands-on experiment implementing numerical differentiation in Python.
S/W Requirement: Python 3.11 (Install latest version according to your system).
Introduction: Numerical differentiation involves approximating derivatives of a function
using numerical methods. One common method for numerical differentiation is the finite
difference method. Below is a hands-on experiment implementing numerical differentiation in
Python.
Code :
import numpy as np
import matplotlib.pyplot as plt
# Function to differentiate
def func(x):
return x**2
# True derivative for comparison (since we know the derivative of x^2 is
2x) def true_derivative(x):
return 2 * x
# Finite difference method for numerical differentiation (forward
difference) def forward_difference(func, x, h):
return (func(x + h) - func(x)) / h
# Define parameters
x_value = 2.0
h_values = [0.1, 0.01, 0.001]
# Calculate true derivative
true_derivative_value = true_derivative(x_value)
print(f'True Derivative Value: {true_derivative_value}')
# Experiment with different values of
h for h in h_values:
numerical_derivative = forward_difference(func, x_value, h)
print(f'h={h}: Numerical Derivative={numerical_derivative:.4f}')
# Plot the function and tangent line for visualization
x_values = np.linspace(0, 4, 100)
plt.plot(x_values, func(x_values), label='$x^2$ function')
plt.scatter(x_value, func(x_value), color='red', label='Point of Interest')
# Plot tangent lines for different h
values for h in h_values:
tangent_line = true_derivative_value * (x_values - x_value) + func(x_value)
plt.plot(x_values, tangent_line, label=f'Tangent (h={h})', linestyle='--')
# Show the plot and legend
plt.title('Numerical Differentiation Experiment')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.legend()
plt.show()
Output
Experiment-VIII: Write a program on Lagrange Multipliers in Python
AIM: To implement procedures of Lagrange Multipliers in Python.
S/W Requirement: Python 3.11 (Install latest version according to your system).
Introduction: simple Python program that demonstrates the use of Lagrange multipliers to
solve a constrained optimization problem. In this example, we'll consider a simple optimization
problem with equality constraints.
Code:
from scipy.optimize import minimize
# Objective function to minimize
def objective_function(x):
return x[0]**2 + x[1]**2
# Equality constraint function
def constraint_equation(x):
return x[0] + x[1] - 1
# Lagrangian function
def lagrangian(x, lambda_):
return objective_function(x) + lambda_ * constraint_equation(x)
# Wrapper function for
scipy.optimize.minimize def
optimize_with_lagrange(initial_guess):
result = minimize(lambda x: lagrangian(x, 1.0), initial_guess, constraints={'type': 'eq',
'fun': constraint_equation})
return result
# Initial guess
initial_guess = [0.5, 0.5]
# Optimize using Lagrange multipliers
result = optimize_with_lagrange(initial_guess)
# Display the results
print("Optimal solution:", result.x)
print("Optimal value:", result.fun)
print("Lagrange multiplier:", result.fun - objective_function(result.x))
Output
Experimen- IX: Write a program on Optimization with Equality and Inequality
Constraints Using Python.
AIM: on Optimization with Equality and Inequality Constraints Using Python.
S/W Requirement: Python 3.11 (Install latest version according to your system).
Introduction: Demonstrates optimization with both equality and inequality constraints using
the scipy.optimize module. In this example, we'll use the minimize function to solve a
constrained optimization problem:
from scipy.optimize import minimize
Code:
# Objective function to minimize
def objective_function(x):
return x[0]**2 + x[1]**2
# Equality constraint function
def equality_constraint(x):
return x[0] + x[1] - 1
# Inequality constraint function
def inequality_constraint(x):
return x[0] - x[1]
# Initial guess
initial_guess = [0.5, 0.5]
# Define constraints
constraints = [{'type': 'eq', 'fun': equality_constraint}, {'type': 'ineq', 'fun':
inequality_constraint}]
# Optimize with equality and inequality constraints
result = minimize(objective_function, initial_guess, constraints=constraints)
# Display the results
print("Optimal solution:", result.x)
print("Optimal value:", result.fun)
Output
Experiment -X: Write a program to Optimization of a Multidimensional Function Using
Particle Swarm Optimization in Python
AIM: To implement triggers
S/W Requirement: Python 3.11 (Install latest version according to your system).
Python program that uses the Particle Swarm Optimization (PSO) algorithm to optimize a
multidimensional function. In this example, I'll use the pyswarm library, which provides an
implementation of the PSO algorithm.
First, you'll need to install the pyswarm library if you haven't already:
Code:
import numpy as np
from pyswarm import pso
# Define the multidimensional objective function to
minimize def objective_function(x):
return np.sum(x**2)
# Set the search space bounds (example: 3-dimensional
space) lower_bound = [-5, -5, -5]
upper_bound = [5, 5, 5]
# Perform PSO optimization
best_solution, best_value = pso(objective_function, lower_bound, upper_bound)
# Display the results
print("Optimal solution:", best_solution)
print("Optimal value:", best_value)
Output