Search code examples
pythondifferential-equations

Using a list of floats for a loop


I'm trying to run a Runge-Kutta algorithm to approximate a differential equation. I want to go through a list of values for a constant variable, A, in the function and have the algorithm loop go through for each item in the list and produce a graph. I keep getting an error saying "list indices must be integers or slices but not a float". I tried to convert the numbers in the list to being integer fractions of each other but that didn't work either. I'm mostly unsure on how to circumvent this error as some fixes I found didn't work, here is my code:

import numpy as np
import matplotlib.pyplot as plt
from math import pi
from numpy import arange
from matplotlib.pyplot import plot,show

wo = 1
w = 2       #defining wo, w, g1, Amplitude and steps
h = 0.001
g1 = 0.2
A = [0.1,0.25,0.5,0.7,0.75,0.85,0.95,1.00,1.02,1.031,1.033,1.035,1.05]
for item in list(A):                #Converting list items into Float values
    [float(i) for i in A]

xpoints = arange(0,100,h)
tpoints = []
zpoints = []
t=0
x = 0
z = pi/2
for i in A:                               #Calls for items in Amplitude list to run algorighm
    def F(t, z, x):                             #Defining the differential equation
        return -g1 * z - (wo ** 2 + 2 * A[i] * np.cos(w * t)) * np.sin(x)
    for x in xpoints:
        tpoints.append(t)
        zpoints.append(z)
        m1 = z*h
        k1 = h*F(t,z,x)    #setting up the runge-kutta algorithm
        m2 = h*(z+(k1/2))
        k2 = h*F(t+0.5*m1,z+0.5*m1,x+0.5*h)
        m3 = h*(z+0.5*k2)
        k3 = h*F(t+0.5*m2,z+0.5*m2,x+0.5*h)
        m4 = h*(z+0.5*k3)
        k4 = h*F(t+0.5*m3,z+0.5*m3,x+0.5*h)
        t += (m1+2*m2+2*m3+m4)/6
        z += (k1+2*k2+2*k3+k4)/6
    A += 1
plot(xpoints,zpoints)

Solution

  • The problem isn't that the numbers themselves need to be converted. Note how you iterate with for i in A:. This means that i is the actual value and not the index. So where you use A[i], you're trying to go to the 0.1 index of A. Instead, just replace A[i] with i in the line at the bottom of this snippet.

    A = [0.1,0.25,0.5,0.7,0.75,0.85,0.95,1.00,1.02,1.031,1.033,1.035,1.05]
    ...
    for i in A:      
        def F(t, z, x):                             
            return -g1 * z - (wo ** 2 + 2 * A[i] * np.cos(w * t)) * np.sin(x)