0

I am trying to run the following script, but get the error

IndexError: list index out of range

I have read that this is because when you create a list it is initially empty so you need to assign to it some value which I have done by doing the following

q.append(0)

but I still get the error. Can someone point out what I an doing wrong? Thank you!

import numpy
from numpy import *
import matplotlib.pyplot as plt

pfa = []                        #Create lists that will hold pf,qf values
qfa = []
pf = []
qf = []
p = []
q = []
pf.append(0)
qf.append(0)
p.append(0)
q.append(0)
q[0]  = -0.5         # initial p and q values
p[0]  = 0
h = 0.001
for i in range(10):

  k1 = -h*sin(q[i])
  j1 = h*(p[i])
  k2 = -h*sin(q[i]+(1/2)*j1)
  j2 = h*p[i]*(q[i]+(1/2)*k1)             
  k3 = -h*sin(q[i]+(1/2)*j2)
  j3 = h*p[i]*(q[i]+(1/2)*k2)
  k4 = -h*sin(q[i]+(1/2)*j3)
  j4 = h*p[i]*(q[i]+(1/2)*k3)
  pf[i+1] = p[i] +(h/6.0)*(k1+2*k2+2*k3+k4)
  qf[i+1] = q[i] +(h/6.0)*(j1+2*j2+2*j3+j4)
  pfa.append(pf)                   #append lists
  qfa.append(qf)

plt.plot(qfa,pfa)
plt.show()

the trace back and error

Traceback (most recent call last):
File "C:\Documents and Settings\My Documents\Symplectic Integrators\RK4_2.py", line  23, in <module>
j1 = h*(p[i])
IndexError: list index out of range
Stripers247
  • 2,265
  • 11
  • 38
  • 40
  • you are accessing `q[i]` with `i` being lager than `0` (which is your maximum index). What do you expected it do do? Just use `0` as a value? In that case you need to create a large enough list in the first place: `qf = [0,0,0,0,0,0,0,0,0,0]` or `qf = [0 for _ in range(10)]` (those are equivalent). You could also a `defaultdict(int)`, maybe. – Niklas B. Mar 03 '12 at 02:04
  • I put the ``p.append(0) q.append(0) pf.append(0) qf.append(0)`` in the loop now I don't get the error – Stripers247 Mar 03 '12 at 02:07
  • Yeah, but only because it fixes the error, it doesn't have to be the right way to do it. It'd be better to initialize the lists properly *before* the loop. – Niklas B. Mar 03 '12 at 02:18
  • @Niklas your right I will give it a try – Stripers247 Mar 03 '12 at 02:43
  • @NiklasB.your way works, but I now get the same error error at this line ``pf[i+1] = p[i] +(h/6.0)*(k1+2*k2+2*k3+k4) IndexError: list assignment index out of range`` I did as you suggested for the pf list as well. – Stripers247 Mar 03 '12 at 02:49
  • So make it one element more: `pf = [0 for _ in range(11)]`. You should really make yourself familiar with the concept of arrays, there's lots of resources about it. – Niklas B. Mar 03 '12 at 02:52
  • Will give it a try thank you. I am reading up on lists and arrays – Stripers247 Mar 03 '12 at 02:57

1 Answers1

2

Your lists contain only one element, and you are trying to access members at positions 0 to 9. Think about it:

>>> p = []
>>> p.append(0)
>>> p
[0]
>>> for i in range(2):
...     print "position {0}, value {1}".format(p[i], i)
... 
position 0, value 0
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range

When you do p[i], p must have at least i + 1 size.

And take a look about at your pf[i] == p[i], it is an expression, not an assignment.

Maybe what you need is something like:

pf = []
for i in range(10):
    ...
    # at this point pf.append() assigns to position i

    pf.append(p[i] + (h / 6.0) * (k1 + 2*k2 + 2*k3 + k4))
    ...

But be careful, because p needs to contain all the values you need before the for loop.

Hugo Lopes Tavares
  • 28,528
  • 5
  • 47
  • 45
  • @Hugo... Thank you for the feedback I put ``p.append(0) q.append(0) pf.append(0) qf.append(0)`` on the loop and it now runs error free. I did ``pf[i] == p[i]`` as an expression because when I tried it as an assignment I got an error. I also have edited that line it should have read ``pf[i+1] == p[i]``. – Stripers247 Mar 03 '12 at 02:13
  • @Surfcast23: An expression and an assignment do *not* do the same thing. In this case `==` is seeing if they are the same, but `=` would make `pf[i+1]` the value of `p[i] +(h/6.0)*(k1+2*k2+2*k3+k4)` -- in other words, the code you have now doesn't do anything useful with those two lines. – Ethan Furman Mar 03 '12 at 14:53