How to Correctly Simulate an Infinite Well in Python?

Click For Summary

Discussion Overview

The discussion revolves around simulating an infinite potential well using Python, specifically focusing on obtaining the eigenfunctions and eigenvalues associated with the system. Participants are addressing issues related to the implementation of the Laplacian operator, the normalization of eigenfunctions, and the accuracy of computed eigenvalues compared to analytical solutions.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant shares their code for calculating eigenfunctions and eigenvalues but notes discrepancies between computed results and analytical solutions.
  • Another participant questions a potential typo in the code, suggesting a modification to the matrix assignment in the Laplacian function.
  • A later reply clarifies that the two versions of the loop in the Laplacian function perform the same operation, but raises concerns about possible off-by-one errors in matrix indexing.
  • One participant asks for clarification on the purpose of a specific part of the code that sets matrix entries, indicating a need for deeper understanding.
  • Another participant suggests multiplying the kinetic energy matrix by a large number to see if it aligns the computed solutions with analytical results, recalling a similar experience.
  • A different participant advises against using wildcard imports in Python and discusses properties of the finite graph Laplacian, suggesting additional checks to confirm the matrix's characteristics.

Areas of Agreement / Disagreement

Participants express differing views on the correctness of the code and the potential issues affecting the results. No consensus is reached regarding the specific problems or solutions, indicating ongoing uncertainty and exploration of the topic.

Contextual Notes

Participants highlight potential issues such as off-by-one errors in matrix indexing and the implications of using wildcard imports in Python. There are also discussions about the properties of the Laplacian matrix that may not be fully addressed in the current implementation.

Who May Find This Useful

This discussion may be useful for individuals interested in computational physics, numerical methods for solving differential equations, or those learning about quantum mechanics simulations.

svletana
Messages
20
Reaction score
1
I'm trying to get the eigenfunctions and eigenvalues (energies) of an infinite well in Python, but I have a few things I can't seem to fix or don't understand...
Here's the code I have:
Python:
from numpy import *
from numpy.linalg import eigh
import matplotlib.pyplot as plt
from __future__ import division

def Laplacian(x):
    h = x[1]-x[0] # assume uniformly spaced points
    n = len(x)
    M = -2*identity(n,'d')
    for i in range(1,n):
           M[i,i-1] = M[i-1,i] = 1
    return M/h**2

L = 6
x = linspace(0, L, 100)
T = -0.5*Laplacian(x)
H = T
E,U = eigh(H)

n = 1 # change to see another state
plt.plot(x,U[:,n-1],'o')
plt.plot(x, sqrt(2/L)*sin(n*pi*x/L),'o')
plt.show()

First of all, the eigenfunctions U[:,i] appear to be normalized if I check, but they don't match the analytic solution. Also, the eigenvalues don't match the values of energy for the infinite well 0.5(πn/L)2.

What could I be missing? The math seems to be fine.
Would it make it better to use scipy.linalg instead of numpy's?

Thanks!
 
Technology news on Phys.org
Python:
def Laplacian(x):
    h = x[1]-x[0] # assume uniformly spaced points
    n = len(x)
    M = -2*identity(n,'d')
    for i in range(1,n):
           M[i,i-1] = M[i-1,i] = 1
    return M/h**2
Is that a typo in the next to last line? Should it instead be M[i, i-1] = M[i-1, i] + 1?

BTW, do you have a typo in your user name? svetlana is a name I've seen often, not svletana. If you've made a mistake, I can change it.
 
  • Like
Likes   Reactions: svletana
Mark44 said:
Python:
def Laplacian(x):
    h = x[1]-x[0] # assume uniformly spaced points
    n = len(x)
    M = -2*identity(n,'d')
    for i in range(1,n):
           M[i,i-1] = M[i-1,i] = 1
    return M/h**2
Is that a typo in the next to last line? Should it instead be M[i, i-1] = M[i-1, i] + 1?

BTW, do you have a typo in your user name? svetlana is a name I've seen often, not svletana. If you've made a mistake, I can change it.

The code should be

Python:
    for i in range(1,n):
            M[i,i-1] = 1
            M[i-1,i] = 1
    return M/h**2

And my username is not a typo, I normally write it like this because svetlana is most likely taken :)
 
Now that I understand that part of your code, your two for loop versions do the same thing. What the loop seems to be doing is putting 1's on the diagonals next to the main diagonal of your identity matrix. The only thing that comes to mind that could be causing a problem is a possible off-by-one error. Keep in mind that range(1, n) consists of the numbers 1, 2, 3, ..., n-1, but doesn't include n. Make sure that your loop is setting all of the entries in the matrix that you want to have set.

Other than that, I don't see anything.
 
can you explain me what this part does?
Python:
    for i in range(1,n):
            M[i,i-1] = 1
            M[i-1,i] = 1
I mean what is the array you produce?
 
I remember encountering a similar problem when doing this... Try to multiply the kinetic energy matrix T with some relatively large number, like 100, and see if the solutions then match the analytical ones (something like this worked, if I remember correctly).
 
A couple things:

it's preferable to use "import numpy as np" -- importing * is generally frowned on. (For instance if you use "sum" after importing *, are you using np.sum() or python's built in sum)?

Second, the (finite) graph Laplacian is well understood to be symmetric positive semi-definite with a minimum eigenvalue ##\lambda_n = 0##. That is ##\mathbf L \mathbf 1 = \lambda_n \mathbf 1 = \mathbf 0##, and since real symmetric, ##\mathbf 1^T \mathbf L = \lambda_n \mathbf 1^T = \mathbf 0^T##.

Just before your return statement in your Laplacian function, try adding the following two lines of code
Python:
ones_v = ones(M.shape[0])
print dot(ones_v,M)
# if importing numpy as np:
# ones_v = np.ones(M.shape[0])
# print np.dot(ones_v, M)

but this doesn't return the zero vector, which is very strong hint as to what's wrong here

--- alternatively, you could insert similar code just below your assignment to T. Either way the ones vector is not in the nullspace of your Laplacian which means it is not a Laplacian
 

Similar threads

  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 21 ·
Replies
21
Views
6K
Replies
4
Views
5K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 10 ·
Replies
10
Views
3K