0

Related to my previous question: Having much trouble with 'preallocating cell arrays' in Python

I implemented the suggestions and now have two codes - one running odeint in scipy, and one running vode. They both give me the same error that I don't know how to fix.

Here is my commented code:

import numpy as np
from scipy.integrate import odeint

#Constants and parameters
N = 2
K00 = np.logspace(0,3,101,10)
len1 = len(K00)
epsilon = 0.01
y0 = [0]*(3*N/2+3)
u1 = 0
u2 = 0
u3 = 0
Kplot = np.zeros((len1,1))
Pplot = np.zeros((len1,1))
S = [np.zeros((len1,1)) for kkkk in range(N/2+1)]
KS = [np.zeros((len1,1)) for kkkk in range(N/2+1)]
PS = [np.zeros((len1,1)) for kkkk in range(N/2+1)]
Splot = [np.zeros((len1,1)) for kkkk in range(N/2+1)]
KSplot = [np.zeros((len1,1)) for kkkk in range(N/2+1)]
PSplot = [np.zeros((len1,1)) for kkkk in range(N/2+1)]

for alpha in range(0,(N/2+1)):
    Splot[alpha] = np.zeros((len1,1))
for beta in range((N/2)+1,N+1):
    KSplot[beta-N/2-1] = np.zeros((len1,1))
for gamma in range(N+1,3*N/2+1):
    PSplot[gamma-N] = np.zeros((len1,1))

for series in range(0,len1):
    K0 = K00[series]
    Q = 10
    r1 = 0.0001
    r2 = 0.001
    a = 0.001
    d = 0.001
    k = 0.999
    S10 = 1e5
    P0 = 1
    tfvec = np.tile(1e10,(1,5))
    tf = tfvec[0,0]
    time = np.linspace(0,tf,len1)

    #Defining dy/dt's
    def f(t,y):
        for alpha in range(0,(N/2+1)):
            S[alpha] = y[alpha]
        for beta in range((N/2)+1,N+1):
            KS[beta-N/2-1] = y[beta]
        for gamma in range(N+1,3*N/2+1):
            PS[gamma-N] = y[gamma]
        K = y[3*N/2+1]
        P = y[3*N/2+2]

        # The model equations
        ydot = np.zeros((3*N/2+3,1))
        B = range((N/2)+1,N+1)
        G = range(N+1,3*N/2+1)
        runsumPS = 0
        runsum1 = 0
        runsumKS = 0 
        runsum2 = 0

        for m in range(0,N/2):
            runsumPS = runsumPS + PS[m+1]
            runsum1 = runsum1 + S[m+1]
            runsumKS = runsumKS + KS[m]
            runsum2 = runsum2 + S[m]    
            ydot[B[m]] = a*K*S[m]-(d+k+r1)*KS[m]

        for i in range(0,N/2-1):
            ydot[G[i]] = a*P*S[i+1]-(d+k+r1)*PS[i+1]

        for p in range(1,N/2):
            ydot[p] = -S[p]*(r1+a*K+a*P)+k*KS[p-1]+ \
                      d*(PS[p]+KS[p])

        ydot[0] = Q-(r1+a*K)*S[0]+d*KS[0]+k*runsumPS
        ydot[N/2] = k*KS[N/2-1]-(r2+a*P)*S[N/2]+ \
                    d*PS[N/2]
        ydot[G[N/2-1]] = a*P*S[N/2]-(d+k+r2)*PS[N/2]
        ydot[3*N/2+1] = (d+k+r1)*runsumKS-a*K*runsum2
        ydot[3*N/2+2] = (d+k+r1)*(runsumPS-PS[N/2])- \
                        a*P*runsum1+(d+k+r2)*PS[N/2]

        for j in range(0,3*N/2+3):
            return ydot[j] 

    # Initial conditions
    y0[0] = S10
    for i in range(1,3*N/2+1):
        y0[i] = 0
    y0[3*N/2+1] = K0
    y0[3*N/2+2] = P0

    # Solve the DEs
    soln = odeint(f,y0,time)
    for alpha in range(0,(N/2+1)):
        S[alpha] = soln[:,alpha]
    for beta in range((N/2)+1,N+1):
        KS[beta-N/2-1] = soln[:,beta]   
    for gamma in range(N+1,3*N/2+1):
        PS[gamma-N] = soln[:,gamma]

    for alpha in range(0,(N/2+1)):
        Splot[alpha][series] = soln[len1-1,alpha]
    for beta in range((N/2)+1,N+1):
        KSplot[beta-N/2-1][series] = soln[len1-1,beta]
    for gamma in range(N+1,3*N/2+1):
        PSplot[gamma-N][series] = soln[len1-1,gamma]

    for alpha in range(0,(N/2+1)):
        u1 = u1 + Splot[alpha]
    for beta in range((N/2)+1,N+1):
        u2 = u2 + KSplot[beta-N/2-1]
    for gamma in range(N+1,3*N/2+1):
        u3 = u3 + PSplot[gamma-N]

    K = soln[:,3*N/2+1]
    P = soln[:,3*N/2+2]
    Kplot[series] = soln[len1-1,3*N/2+1]
    Pplot[series] = soln[len1-1,3*N/2+2]
    utot = u1+u2+u3

The error message is below:

     45     def f(t,y):
     46         for alpha in range(0,(N/2+1)):
---> 47             S[alpha] = y[alpha]
     48         for beta in range((N/2)+1,N+1):
     49             KS[beta-N/2-1] = y[beta]

TypeError: 'float' object has no attribute '__getitem__' 

I need to assign each element of S, which is an array, to a location in the y array. How though?

Thanks in advance for any help.

4
  • 2
    Clearly one or both of S or y isn't an array; it's a float, per the error message. Commented Nov 5, 2015 at 12:10
  • 1
    If you preallocated S as an array of zeros (actually a list of arrays of zeros, looking at the code - that seems odd, but is probably not the problem), how would it become a float?! Far more likely is that the y argument is the float, but print type(S), type(y) would tell you for sure. Commented Nov 5, 2015 at 12:14
  • Got it, but type(y) gives me "NameError: name 'y' is not defined". Commented Nov 5, 2015 at 12:15
  • 2
    ...inside f? You can't find out the type of an object referenced by an identifier in scopes where that identifier doesn't exist! Commented Nov 5, 2015 at 12:16

1 Answer 1

1

Take another look at the documentation for odeint. The signature of the function that defines the system to be solved is func(y,t,...). You must change the definition of f to

def f(y, t):
    ...

Note that the order of y and t is the opposite of the order used with the ode class of scipy.integrate. See, for example, Interchanging between different scipy ode solvers.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.