-1

I am having problems with my code which is a Runge Kutta algorithm to numerically solve for a harmonic oscillator. Unfortunately, I am receiving an error that says I can't multiply sequence by non-int of type float. Considering this code is nearly verbatim from an educational text, I cannot see where the error lies. Could someone please help me? Thanks by your friendly neighborhood Spiderman.

import numpy as np
import matplotlib.pyplot as plt


#Variable Definitions

N = 500
x0 = 1.0
v0 = 0.0
dur = 10.0

dt = dur/float(N-1)

#creating the array

y = np.zeros([N,2])

y[0,0] = x0
y[0,1] = v0

#runge kutta algorithm

def rk4(y, time, dt, deriv)
    k1 = dt * deriv(y,time)
    k2 = dt * deriv(y + 0.5*k1,time + 0.5*dt)
    k3 = dt * deriv(y + 0.5*k2, time + 0.5*dt)
    k4 = dt * deriv(y + k3, time + dt)
    y_next = y + (k1 + 2*(k2+k3)+k4)/6
    return y_next


#Harmonic oscillator

def Harmonic(x,time):
    y0 = x[1]
    y1 = (-1)*x[0]
    return ([y0,y1])

#forming data points 
for i in range(N-1): 
    y[i+1] = rk4(y[i],0, dt, Harmonic)

 time  = np.linspace(0, dur, N)   

 #plotting

plt.plot(time,y[:,1])
plt.show()

The error is on line 33.

TypeError: can't multiply sequence by non-int of type 'float'

  • 2
    Which line does it say your error occurs on? – Loocid May 05 '15 at 05:29
  • 4
    `Harmonic` returns lists. What do you expect to happen when you multiply one of those lists by a float? – user2357112 May 05 '15 at 05:31
  • 1
    Post your actual exception (with traceback) in the question, don't just vaguely describe it. – abarnert May 05 '15 at 05:35
  • @user2357112: If he's a numerical programmer, he might be expecting that it returns a new list with each value multiplied by that float. (In which case he probably should be using NumPy arrays, rather than lists.) – abarnert May 05 '15 at 05:36
  • just out of curiosity, what's the textbook? – abcd May 05 '15 at 05:36
  • If it's taken "almost verbatim" from a textbook, in what ways does it differ from the verbatim code? If you type in the verbatim code, does it work? – abarnert May 05 '15 at 05:36
  • Well, I am trying to use the Runge Kutta algorithm to change both my initial values of the list. How would I tackle this problem. – user3461947 May 05 '15 at 05:42
  • This is the book: http://phys.csuchico.edu/ayars/312/Handouts/comp-phys-python.pdf – user3461947 May 05 '15 at 05:57

1 Answers1

3

I'm willing to bet the problem is that you're mixing up NumPy arrays and normal Python lists.


You're using NumPy arrays all over your code. These know how to do all kinds of cool things, like element-wise operations. For example:

>>> a = np.array([1, 2, 3, 4])
>>> a * 1.5
array([ 1.5,  3. ,  4.5,  6. ])

But Python lists don't know how to do that. (On the other hand, they know how to do other things that NumPy arrays don't, like append new values to the end, or make copies automatically when you slice instead of only when you explicitly tell them to.) Multiplying a Python list by a number just means to repeat the list that many times. It makes sense for an integer, but not for a float—and it's not what you want here even for an integer:

>>> a = [1, 2, 3, 4]
>>> a * 2
[1, 2, 3, 4, 1, 2, 3, 4]
>>> a * 1.5
TypeError: can't multiply sequence by non-int of type 'float'

Your Harmonic function is returning a list, not an array:

def Harmonic(x,time):
    y0 = x[1]
    y1 = (-1)*x[0]
    return ([y0,y1])

But you're trying to multiply the result of that function by a number. Which would make sense for an array, but not for a list.

So you probably just want to change that:

def Harmonic(x,time):
    y0 = x[1]
    y1 = (-1)*x[0]
    return np.array([y0,y1])
abarnert
  • 354,177
  • 51
  • 601
  • 671