如何在python中使用vectorized ='True'实现'solve_ivp'

时间:2019-11-29 03:44:43

标签: python scipy

我一直在尝试使用public class CustomerList { [JsonProperty("custlist")] public Customer[] Customers { get; set; } } public class Customer { [JsonProperty("cust_name")] public string Name { get; set; } [JsonProperty("cust_id")] public string Id { get; set; } } var sample = "{\"custlist\":[{\"cust_name\":\"Vincent\"},{\"cust_id\":\"klq206f3872d08m92t6\"},{\"cust_name\":\"Joyce\"},{\"cust_id\":\"125g1474grx2d03t9dld\"}]}"; var result = JsonConvert.DeserializeObject<CustomerList>(sample).Customers; // Or! var dictResult = JsonConvert.DeserializeObject<Dictionary<string, Customer[]>>(sample)["custlist"]; 求解一组微分方程。系统的雅可比矩阵为A,如下所示。我想启用选项solve_ivp,但是很不幸,我不知道如何修改当前代码以向量化Jacobian矩阵A。有人知道如何做到这一点吗?

vectorized='True'

1 个答案:

答案 0 :(得分:2)

请查看this answer,其解释很彻底。特别是对于您的代码,请参阅下面的更新的代码段和图。 vectorize并不能提供任何加速效果。但是,为关键字jac提供A会有所不同。但是我猜只有在A为常数的情况下才有效吗?

# imports
import numpy as np
import scipy.sparse as sp
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt  # noqa


def dc_dt(t, C):
    print(C.shape)
    if len(C.shape) == 1:
        return np.squeeze(A.dot(C)) + B
    else:
        return A.dot(C) + np.transpose(np.tile(B, (C.shape[1], 1)))
    # return np.squeeze(A.dot(C)) + B


# grid sizing
R = 0.05  # sphere radius
N = 1000  # number of points
D = 0.00002  # diffusion coefficient
k = 10  # Arrhenius
Cs = 1.0  # Boundary concentration
C0 = 0.0  # Initial concentration
time_constant = R**2.0 / D
dr = R / (N - 1)
# Algebra simplification
a = D / dr**2
Init_conc = np.repeat(0, N)
B = np.zeros(N)
B[-1] = Cs * (a + a / (N - 1))
e1 = np.ones(N)
e2 = np.ones(N)
e3 = np.ones(N)
e1[0] = -k - 6 * a
e1[1:] = -k - 2 * a
e2[1] = 6 * a
for i in range(2, N):
    e2[i] = a + a / (i - 1)
for i in range(0, N - 1):
    e3[i] = a - a / (i + 1)
A = sp.spdiags([e3, e1, e2], [-1, 0, 1], N, N, format="csc")
# Solving the system, I want to implement the same thing with vectorized='True'
OutputTimes = np.linspace(0, 0.2 * time_constant, 10000)
ans = solve_ivp(dc_dt, (0, 0.2 * time_constant), Init_conc,
                method='BDF', t_eval=OutputTimes, jac=A, vectorized=True)
plt.plot(np.arange(N), ans.y[:, 0])
plt.plot(np.arange(N), ans.y[:, 1])
plt.plot(np.arange(N), ans.y[:, 10])
plt.plot(np.arange(N), ans.y[:, 20])
plt.plot(np.arange(N), ans.y[:, 50])
plt.plot(np.arange(N), ans.y[:, -1])
plt.show()

enter image description here