NACP Group Project
NACP Group Project
1 Problem 9
Consider the logistic map x( n + 1) = Axn (1xn ) where xn is the nth iteration for 0x1. Here A is a
constant. Vary the value of A from 0.89 to 3.995 in an interval of 0.0125 in each step. 1) For each
value of A, note the values of xn for 15 < n < 200. Then make a plot of Xn versus A to show the
bifurcation and chaos. 2) For A = 4, choose two points x and x where x = x + 0.01 and iterate.
Plot log(|xn xn |/0.01) as a function of n. See if it is approaching a straight line.
1.1 Method
1. Firtsly, will define the range of A values from 0.89 to 3.995 with an interval of 0.0125.
2. Then initializing the parameters: n_min (start iteration), n_max (end iteration),
num_iterations (to stabilize the system), and num_points (number of data points for each
A).
3. Creating an array to store A values and x_n values.
4. For each A value:
• Initializing x with an arbitrary value (e.g., 0.5).
• Iterating for num_iterations to stabilize the system.
• Iterating from n_min to n_max, applying the logistic map equation to calculate x_n
values.
• Storing the A and x_n values in the respective arrays.
5. Creating a bifurcation diagram using matplotlib, where x_n is plotted against A.
6. Using a colormap to assign different colors based on the A values for visual distinction.
7. Displaying the bifurcation diagram to visualize the transition from order to chaos as A varies.
1.2 Program
[12]: import numpy as np
import matplotlib.pyplot as plt
# Defining parameters
A_values = np.arange(0.89, 4.0, 0.0125) # Values of A
n_min = 15 # Starting iteration at n = 15
n_max = 200 # Ending iteration at n = 200
num_iterations = 1000 # Number of iterations to stabilize the system
num_points = n_max - n_min # Number of data points for each A
1
# Creating a colormap for different A values
colormap = plt.cm.viridis
normalize = plt.Normalize(vmin=A_values.min(), vmax=A_values.max())
x_values = []
for n in range(n_min, n_max):
x = A * x * (1 - x)
x_values.append(x)
A_data.extend([A] * num_points)
x_data.extend(x_values)
2
[13]: import numpy as np
import matplotlib.pyplot as plt
for n in range(iterations):
x = logistic_map(x, A)
x_prime = logistic_map(x_prime, A)
log_diff = np.log(np.abs(x - x_prime) / 0.01)
log_differences.append(log_diff)
3
1.3 Result
The provided code generates a bifurcation diagram illustrating the behavior of the logistic map
for a range of A values from 0.89 to 3.995. Each point on the diagram represents the value of xn
(population) for a specific A value after a certain number of iterations. As A varies, the bifurcation
diagram reveals a transition from order to chaos, with the emergence of complex and unpredictable
patterns in the population dynamics. The use of different colors for each A value enhances the
visualization, making it easier to distinguish the different regimes of the logistic map.
In the bifurcation diagram of the logistic map, the transition from order to chaos is characterized
by distinct patterns of population behavior. Initially, as A increases, the system exhibits stable,
periodic oscillations with clear, well-defined values of xn . However, as A continues to rise, these
periodic orbits bifurcate, leading to a cascade of increasingly complex and unpredictable behavior.
Eventually, chaos emerges, marked by a seemingly random, aperiodic sequence of xn values. This
transition demonstrates how small variations in A can result in a dramatic shift from ordered, pre-
dictable dynamics to chaotic, highly sensitive behavior, a fundamental aspect of nonlinear systems.
4
2 Problem 5
It is late at night and a drunkard is walking along a very long street. The drunkard is not sure
which is the way home, so he randomly takes steps of length 1m forward or backward. He takes
one step every second continuously for 1 hour.
(a) Simulate the drunkard’s walk by using a random number generator.
(b) Generate 100 different realizations of the random sequence of steps by using a different seed
each time.
(c) Graphically show the random walks.
(d) Calculate the displacement of the drunkard for each realization, and show graphically how
these are distributed using a histogram.
(e) Calculate the mean and the root mean square (RMS) displacement of the drunkard after 1
hour.
(f) Increase the time (number of steps) and show that the mean displacement tends to 0 and the
RMS displacement scales as the square-root of the time.
2.1 Program
[17]: import random
# Example usage:
random_walk = drunkard_walk(3600) # 1 hour, 1 step per second
5
plt.xlabel('Time (seconds)')
plt.ylabel('Position')
plt.title('Random Walks')
plt.show()
# (e) Calculating the mean and the root mean square (RMS) displacement of the␣
,→drunkard after 1 hour.
import numpy as np
mean_displacement = np.mean(displacements)
rms_displacement = np.sqrt(np.mean([d ** 2 for d in displacements]))
6
7
Mean Displacement: 8.78
RMS Displacement: 61.2427954946539
2.2 Result
The code simulates a drunkard’s random walk, generating 100 different realizations of 1-hour walks
with one step per second. Graphically, these random walks are visualized, showcasing the diverse
paths taken. The displacement of the drunkard is calculated for each realization, and a histogram
illustrates the distribution of displacements. The mean displacement and root mean square (RMS)
displacement after 1 hour are computed, providing quantitative measures of the overall movement.
The code employs modular functions, promoting clarity and reusability, and matplotlib for visual-
izations, enhancing understanding. The results demonstrate the stochastic nature of the drunkard’s
walk, with statistical metrics characterizing the overall displacement.
3 Problem 2
The Fraunhofer diffraction pattern from an aperture can be described by theFourier transform of
the aperture function. Using this information, numeri-cally simulate the Fraunhoffer diffraction
pattern for the following slits:
1) Rectangular Slit
8
2) Square Slit
3) Circular Slit
3.1 Method
We will begin by defining essential parameters, including the number of sub-intervals and aperture
dimensions. Then will initialize a rectangular function in the spatial domain, representing the
aperture. Afterward, the frequency domain array is initialized, paving the way for the calculation
of the 2D Discrete Fourier Transform (DFT). The DFT captures the diffraction pattern resulting
from the rectangular aperture. Visualization is achieved through both 3D plots and 2D images,
offering insights into the spatial distribution of diffraction. The code will employ nested loops for
computations and rely on the matplotlib library for effective visual representation, contributing to
a comprehensive understanding of light diffraction phenomena.
3.2 Program
[12]: import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
# Defining parameters
N = 31 # Total sub-intervals
M = 31 # Total sub-intervals
a = 7 # Slit width = a
b = 6 # Slit height = b
dft[u, v] = add
9
x = np.linspace(0, N, N)
y = np.linspace(0, M, M)
xx, yy = np.meshgrid(x, y)
fig = plt.figure(1)
ax = fig.add_subplot(1, 2, 1, projection='3d')
p = ax.plot_surface(xx, yy, np.abs(dft) / np.max(np.abs(dft)), cmap='hot')
ax.set_yticklabels([])
ax.set_xticklabels([])
ax.set_zticklabels([])
im.set_interpolation('bilinear')
ax.set_yticklabels([])
ax.set_xticklabels([])
10
[1]: # (b) Square slit
# Defining parameters
N = 31 # Total sub-intervals
M = 31 # Total sub-intervals
a = 7 # Slit width = a
11
b = 7 # Slit height = b (making it a square slit)
dft[u, v] = add
im.set_interpolation('bilinear')
12
ax.set_yticklabels([])
ax.set_xticklabels([])
13
3.3 Result
The provided codes simulate the diffraction pattern produced by a rectangular slit and square slit
using the Discrete Fourier Transform (DFT). The spatial domain representation of a rectangular
aperture is created and transformed to the frequency domain using the 2D DFT. The resulting
diffraction pattern is visualized in 3D and as an image. Additionally, the code demonstrates the
transformation of a rectangular aperture and its diffraction pattern. Parameters such as the slit
width and height influence the diffraction pattern, which is crucial in understanding the behavior
of light when encountering obstacles. The code utilizes nested loops for computations and utilizes
the matplotlib library for 3D and 2D visualizations.
4 Problem 8
Numerically solve the Schroedinger’s equation for a simple harmonic poten-tial and the Lennard-
Jonnes potential. Plot the wave functions for the groundstate and first two excited states. For both
cases, compare the results with the analytical results.
4.1 Method
The provided code should numerically solve the Schrödinger equation for an anharmonic oscillator
with a quartic perturbation using a finite difference method. It initializes the potential and kinetic
energy matrices, constructs the Hamiltonian matrix, and employs NumPy’s eigenvalue solver to
find the eigenvalues and eigenvectors. The resulting normalized wavefunctions are then plotted.
User inputs define the domain limits and the number of grid points. The code’s modularity en-
hances clarity, with clearly defined functions for potential energy, grid creation, and Hamiltonian
construction.
4.2 Program
[16]: import numpy as np
import matplotlib.pyplot as plt
14
for j in range(N-2):
if i == j:
T[i, j] = -2
elif np.abs(i - j) == 1:
T[i, j] = 1
else:
T[i, j] = 0
# Hamiltonian matrix
H = -T / (2 * h**2) + V
plt.xlabel('x', size=14)
plt.ylabel('$\psi$(x)', size=14)
plt.legend()
plt.title('Normalized Wavefunctions for a Leonard Jones Potential', size=14)
plt.show()
15
[14]: import numpy as np
import matplotlib.pyplot as plt
16
T = np.zeros((N-2)**2).reshape(N-2, N-2)
for i in range(N-2):
for j in range(N-2):
if i == j:
T[i, j] = -2
elif np.abs(i - j) == 1:
T[i, j] = 1
else:
T[i, j] = 0
# Hamiltonian matrix
H = -T / (2 * h**2) + V
plt.xlabel('x', size=14)
plt.ylabel('$\psi$(x)', size=14)
plt.legend()
plt.title('Normalized Wavefunctions for an Harmonic Oscillator', size=14)
plt.show()
17
4.3 Results
From the graph (1), we can see that the wave functions obtained numerically by the finite differ-
ence method for the Lennard - Jones potential match perfectly with the wave functions calculated
analytically except the ground state wave function (which is inverted). The eigenvalues are also
consistent with the theoretical results. The GS wave function is inverted because we are doing an
eigenvalue problem and python, instead of taking the eigenvector v took -v fir this, so the wf got
inverted . To interpret these results, we just need to understand that the GS wf is inverted and all
other WF are perfectly good, because the procedure for solving for excited states doesn’t involve
any contribution from the prior ones after getting the eigenvalues .
From the graph (2), we can see that the wave functions obtained numerically by the finite difference
method for the harmonic oscillator match perfectly with the wave functions calculated analytically.
The eigenvalues are also consecutive odd integers .
18
1 Contribution of individual group members
1.1 Problem 9
Akshat Singh - 9) b)
Ankit Patel - 9) a)
1.2 Problem 5
Both of us contributed almost equally to the discussions and code writing .
1.3 Problem 2
Akshat Singh - Code
Ankit Patel - Code Modification and Discussions .
1.4 Problem 8
Akshat Singh - Finding out the standard results .
Ankit Patel - Code for finite difference Method and application of that to the
problems .