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'
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])