Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #98375

Scipy odeint (LSODA) gives inaccurate results; same code fine in MATLAB ode15s/ode23s

X-Received by 10.66.102.65 with SMTP id fm1mr8760951pab.20.1446847269045; Fri, 06 Nov 2015 14:01:09 -0800 (PST)
X-Received by 10.50.6.40 with SMTP id x8mr314103igx.0.1446847269004; Fri, 06 Nov 2015 14:01:09 -0800 (PST)
Path csiph.com!au2pb.net!usenet.blueworldhosting.com!feeder01.blueworldhosting.com!peer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!i2no508411igv.0!news-out.google.com!fs1ni1058igb.0!nntp.google.com!i2no508394igv.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
Newsgroups comp.lang.python
Date Fri, 6 Nov 2015 14:01:08 -0800 (PST)
Complaints-To groups-abuse@google.com
Injection-Info glegroupsg2000goo.googlegroups.com; posting-host=129.237.108.11; posting-account=lO2z8woAAADplnjgj1WnWhHZZkr5y45P
NNTP-Posting-Host 129.237.108.11
User-Agent G2/1.0
MIME-Version 1.0
Message-ID <942d2bd0-6322-4733-a6dd-ceeed40368cb@googlegroups.com> (permalink)
Subject Scipy odeint (LSODA) gives inaccurate results; same code fine in MATLAB ode15s/ode23s
From Abhishek <abhishek.mallela@gmail.com>
Injection-Date Fri, 06 Nov 2015 22:01:09 +0000
Content-Type text/plain; charset=ISO-8859-1
Content-Transfer-Encoding quoted-printable
Lines 137
X-Received-Bytes 6037
X-Received-Body-CRC 1361481398
Xref csiph.com comp.lang.python:98375

Show key headers only | View raw


I have code that runs perfectly well in MATLAB (using ode15s or ode23s) but falters with Scipy odeint. The MATLAB code is for a specific case of the generalized Python code. Here I have tried to reproduce the specific case in Python. The logic in the code is airtight and the algorithm is sound. I have also specified small rtol and atol values, as well as a large mxstep. 

My code is below:

    import numpy as np
    import matplotlib.pyplot as plt
    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 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(y,t):
            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]
    
            ydot_new = []
            for j in range(0,3*N/2+3):
                ydot_new.extend(ydot[j])
            return ydot_new
            
        # 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,rtol = 1e-12, atol = 1e-14, mxstep = 50000000)
        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
    
    #Plot
    plt.plot(np.log10(K00),utot[:,0])
    plt.show()

Why am I getting a "stiff-looking" graph in Python (http://i.stack.imgur.com/UGWSH.png), when MATLAB gives me a proper one (http://i.stack.imgur.com/F2jzd.jpg)? I would like to understand where the problem lies and how to solve it.

Thanks in advance for any help.

Back to comp.lang.python | Previous | NextNext in thread | Find similar | Unroll thread


Thread

Scipy odeint (LSODA) gives inaccurate results; same code fine in MATLAB ode15s/ode23s Abhishek <abhishek.mallela@gmail.com> - 2015-11-06 14:01 -0800
  Re: Scipy odeint (LSODA) gives inaccurate results; same code fine in MATLAB ode15s/ode23s Christian Gollwitzer <auriocus@gmx.de> - 2015-11-07 07:54 +0100
    Re: Scipy odeint (LSODA) gives inaccurate results; same code fine in MATLAB ode15s/ode23s Michael Torrie <torriem@gmail.com> - 2015-11-07 08:47 -0700

csiph-web