Hi all,
I got the output described in the title when I executed the following code.
I do not know why the ode function outputs NaN this time.
Also, if you know of a solution to prevent this, could you please let me know?
I would be thankful if you could help me with this question.
import os
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import arviz as az
import pymc as pm
import pytensor
import pytensor.tensor as pt
# Initialize random number generator
RANDOM_SEED = 8927
rng = np.random.default_rng(RANDOM_SEED)
az.style.use("arviz-darkgrid")
time = 600
steps_per_second = 1000
n_steps = time * steps_per_second
dt =1 / steps_per_second
def ode_update_func(A, B, C, k1, k2, am, bm):
A_new = A + (-k1*pt.power(A, am))*dt
B_new = B + (k1*pt.power(A, am) - k2*pt.power(B, bm))*dt
C_new = C + (k2*pt.power(B, bm))*dt
return A_new, B_new, C_new
k1_true = 0.1
k2_true = 0.01
am_true = 1.0
bm_true = 1.0
A_init = np.array(1.0, dtype=np.float64)
B_init = np.array(0.0, dtype=np.float64)
C_init = np.array(0.0, dtype=np.float64)
results, updates = pytensor.scan(
fn=ode_update_func,
outputs_info=[A_init, B_init, C_init],
non_sequences=[k1_true, k2_true, am_true, bm_true],
n_steps=n_steps,
strict=True
)
results_true = np.concatenate((np.array([[A_init, B_init, C_init]]), np.stack([result.eval() for result in results]).T))
plt.plot(np.arange(n_steps+1)/steps_per_second, results_true[:, 0], label="A_true")
plt.plot(np.arange(n_steps+1)/steps_per_second, results_true[:, 1], label="B_true")
plt.plot(np.arange(n_steps+1)/steps_per_second, results_true[:, 2], label="C_true")
plt.legend()
plt.show()
with pm.Model() as model:
k1 = pm.TruncatedNormal("k1", mu=0.3, sigma=0.2, lower=0)
k2 = pm.TruncatedNormal("k2", mu=0.03, sigma=0.02, lower=0)
am = pm.TruncatedNormal("am", mu=1.0, sigma=0.2, lower=0)
bm = pm.TruncatedNormal("bm", mu=1.0, sigma=0.2, lower=0)
sigma = pm.InverseGamma("sigma", alpha=5, beta=0.2)
A_init = np.array(1.0, dtype=np.float64)
B_init = np.array(0.0, dtype=np.float64)
C_init = np.array(0.0, dtype=np.float64)
results, updates = pytensor.scan(
fn=ode_update_func,
outputs_info=[A_init, B_init, C_init],
non_sequences=[k1, k2, am, bm],
n_steps=n_steps,
strict=True
)
pm.Deterministic("result", pm.math.stack([results[0], results[1], results[2]]))
with model:
idata_prior = pm.sample_prior_predictive(5, random_seed=rng)
print(idata_prior.prior.result)
for i in range(5):
plt.plot(np.arange(1, n_steps+1)/steps_per_second, idata_prior.prior.result[0, i, 0, :], label="A_prior")
plt.plot(np.arange(1, n_steps+1)/steps_per_second, idata_prior.prior.result[0, i, 1, :], label="B_prior")
plt.plot(np.arange(1, n_steps+1)/steps_per_second, idata_prior.prior.result[0, i, 2, :], label="C_prior")