简体   繁体   中英

How to solve Kuznets curve growth model for the given differential equation?

Context:

Using the Maddison project real GDP per capita dataset, I derived the following equation using least squares: 0.012406 + 0.005132 ln(g) - 0.006304 ln(g)**2

As I am trying to predict the GDP per capita until 2050 for different economic groups, I referenced this paper's methodology "Tilman et al. 10.1073/pnas.1116437108" as to how they tried solving the same as a differential equation: dG/dt = G(-0.6284 + 0.157lnG - 0.0093ln(G)^2

I transformed my least squares the same way: -0.012406 g + g 0.005132 math.log(g) - g 0.006304*math.log(g)**2

I am trying to solve the ODE in python for several initial values to get the Kuznets curve and estimate for 2050. I used the below code, but I am unable to solve the same.

Python Code:

import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
from scipy.integrate import odeint
from scipy.integrate import solve_ivp 
import math

def solveit(y0):
    def gdp(g, t):
        y = g
        dgdt = [-0.012406*g  + g*0.005132*math.log(g) - g*0.006304*math.log(g)**2]
        return dgdt

#initial conditions
    #y0 = [785.60] 
    t = np.linspace(0, 60000, 1000)
#call integrator
    sol = odeint(gdp, y0, t)
    m = sol[:]
    plt.plot(t,m)
    plt.show()


ys= [[785.60],[1860],[7800]]

fig = plt.figure()
for y_ in ys:
    solveit(y_)

plt.legend(loc='best')
plt.grid()
plt.show()

Error message:

RuntimeError: The array return by func must be one-dimensional, but got ndim=2.

Directions regarding the same would be helpful.

When odeint calls the func parameter provided by the user, it will pass in an array for the state vector y . Even when the system is a single scalar equation, y will be passed in as a 1-d array with length 1. In your case, that means g will be a 1-d with length 1. You have this in gdp :

    dgdt = [-0.012406*g  + g*0.005132*math.log(g) - g*0.006304*math.log(g)**2]
    return dgdt

The problem is the extra brackets in the expression for dgdt . g is already a 1-d array, and therefore so is -0.012406*g . It turns out that math.log(g) actually returns a scalar, but a scalar plus a 1-d NumPy with length 1 does what you would expect, so in this case it doesn't cause a problem. So the result of the full expression -0.012406*g + g*0.005132*math.log(g) - g*0.006304*math.log(g)**2 is also a 1-d NumPy array (with length 1). When you wrap that result in brackets, you increase the "depth" of the data structure. In effect, you create a 2-d array (with trivial shape (1, 1)). For example, in the following, w is a 1-d array with length 1:

In [23]: w = np.array([1.0])

In [24]: np.shape(w)
Out[24]: (1,)

In [25]: np.shape([w])
Out[25]: (1, 1)

Note that [w] has shape (1, 1) , ie it is a 2-d array. odeint expects a 1-d array to be returned by the user's function, but it gets a 2-d array from your function and raises an error.

The fix is simple: remove those brackets:

    def gdp(g, t):
        dgdt = -0.012406*g  + g*0.005132*math.log(g) - g*0.006304*math.log(g)**2
        return dgdt

(Note that I removed the line y = g , which served no purpose.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM