def solution(self, x): controls = self.unflatten(x) solution = RK2(self.seir, self.y0, self.t_total, self.parameters, controls) solution = self.grouping(solution) return solution[:, 5]
def forward(self, x): controls = self.unflatten(x) solution = RK2(self.seir, self.y0, self.t_total, self.parameters, controls) solution = self.grouping(solution) # u = np.append(np.log(solution[self.loc, 7]), np.log(np.diff(solution[self.loc, 7]))) u = np.log(solution[self.loc, 5]) return u
def initialization(configurations, parameters, controls): # initialize the optimization problem with controls terminate at the end of observation (today) y0, t_total, N_total, number_group, population_proportion, \ t_control, number_days_per_control_change, number_control_change_times, number_time_dependent_controls = configurations alpha, q, tau, HFR, kappa, beta, delta, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q = controls model = Model(configurations, parameters, controls) t0 = time.time() solution = RK2(model.seir, y0, t_total, parameters, controls) # np.savez(savefilename, t=t, solution=solution, controls=controls) print("solve time by RK2 method", time.time() - t0) solution_group = model.grouping(solution) print("# total infected = ", N_total - solution_group[-1, 0], "# total death = ", solution_group[-1, 7], "maximum # hospitalized = ", np.max(solution_group[:, 5])) simulation_first_confirmed = np.where(solution_group[:, 8] >= data_confirmed[0])[0][0] # simulation_first_confirmed = np.where(solution_group[:, 8] > data_confirmed[0]-1)[0][0] # simulation_first_confirmed = 40 print("day for first 100 confirmed = ", simulation_first_confirmed) # control frequency and time # number_days_per_control_change = 7 number_control_change_times = np.floor_divide((simulation_first_confirmed + len(data_confirmed)), number_days_per_control_change) number_control_days = number_days_per_control_change * number_control_change_times t_control = np.linspace(0, number_control_days, number_control_change_times) number_days = number_control_days t_total = np.linspace(0, number_days, 1 * number_days + 1) # t_control = np.linspace(25, 25 + (number_control_change_times - 1) * number_days_per_control_change, # number_control_change_times) alpha = np.array([0.0 for i in range(number_control_change_times)]) # S to E social distancing # q = np.array([0.0 for i in range(number_control_change_times)]) # S to Q quarantine # tau = np.array([0.1 for i in range(number_control_change_times)]) # E to I confirmation ratio # HFR = np.array([0.2 for i in range(number_control_change_times)]) # kappa = np.array([0.04 for i in range(number_control_change_times)]) controls = (alpha, q, tau, HFR, kappa, beta, delta, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q) # controls = alpha configurations = (y0, t_total, N_total, number_group, population_proportion, t_control, number_days_per_control_change, number_control_change_times, number_time_dependent_controls) return simulation_first_confirmed, configurations, parameters, controls
def initialization(self): # initialize the optimization problem with controls terminate at the end of observation (today) y0, t_total, N_total, number_group, population_proportion, \ t_control, number_days_per_control_change, number_control_change_times, number_time_dependent_controls = self.configurations alpha, q, tau, HFR, kappa, beta, delta, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q = self.controls t0 = time.time() solution = RK2(self.seir, self.y0, self.t_total, self.parameters, self.controls) # np.savez(savefilename, t=t, solution=solution, controls=controls) print("solve time by RK2 method", time.time() - t0) solution_group = self.grouping(solution) print("# total infected = ", self.N_total - solution_group[-1, 0], "# total death = ", solution_group[-1, 7], "maximum # hospitalized = ", np.max(solution_group[:, 5])) self.simulation_first_confirmed = np.where( solution_group[:, 8] >= self.data_confirmed[0])[0][0] # simulation_first_confirmed = np.where(solution_group[:, 8] > data_confirmed[0]-1)[0][0] # simulation_first_confirmed = 40 print("day for first 100 confirmed = ", self.simulation_first_confirmed) # control frequency and time # number_days_per_control_change = 7 day = self.simulation_first_confirmed + self.lag_hospitalized self.loc = np.arange(day, day + len(self.data_hospitalized)) # print("self.loc = ", self.loc) number_days = self.simulation_first_confirmed + len( self.data_confirmed) number_control_change_times = number_days t_total = np.linspace(0, number_days, number_days + 1) t_control = np.linspace(0, number_days, number_days + 1) self.t_total = t_total self.t_control = t_control self.dimension = len(self.t_control) alpha = 0.1 * np.ones(self.dimension) self.controls = (alpha, q, tau, HFR, kappa, beta, delta, sigma, eta_I, eta_Q, mu, gamma_I, gamma_A, gamma_H, gamma_Q) flat_args, self.unflatten = flatten(self.controls) self.configurations = (y0, t_total, N_total, number_group, population_proportion, t_control, number_days_per_control_change, number_control_change_times, number_time_dependent_controls)
def constraint(flat_args): # objective uses flattend arguments to facilitate autograd functionality controls = unflatten(flat_args) solution = RK2(model.model.seir, y0, t_total, parameters, controls) solution = model.grouping(solution) result = np.max(solution[:, 5]) * (1.E6 / N_total) # if number_group == 1: # # maximum number of hospitalized cases # result = np.max(solution[:, 5]) * (1.E6 / N_total) # else: # # maximum number of hospitalized cases # result = np.max(np.sum(solution[:, 5*number_group:6*number_group], axis=1)) * (1.E6/N_total) print("hospitalized cases per million = ", result) return result
def objective(flat_args): # objective uses flattend arguments to facilitate autograd functionality # unflatten, parameters, weights = args controls = unflatten(flat_args) solution = RK2(model.seir, y0, t_total, parameters, controls) solution = model.grouping(solution) ws, coeffs, kappas = weights day = simulation_first_confirmed simulation_confirmed = solution[day:day + len(data_confirmed), 8] # penalty_confirmed = np.sum(np.power(np.log(simulation_confirmed) - np.log(data_confirmed), 2)) penalty_confirmed = np.sum(np.power(np.log(np.diff(simulation_confirmed)) - np.log(np.diff(data_confirmed)), 2)) # penalty_confirmed = np.sum(np.log(1+np.power(simulation_confirmed - data_confirmed, 2))) # penalty_confirmed = np.sum(np.log(1+np.abs(simulation_confirmed - data_confirmed))) # penalty_confirmed = np.sum(np.power(simulation_confirmed - data_confirmed, 2)/data_confirmed[-1]**2) day = simulation_first_confirmed + lag_hospitalized simulation_hospitalized = solution[day:day + len(data_hospitalized), 5] penalty_hospitalized = np.sum(np.power(np.log(simulation_hospitalized) - np.log(data_hospitalized), 2)) # penalty_hospitalized = np.sum(np.log(1+np.power(simulation_hospitalized - data_hospitalized, 2))) # penalty_hospitalized = np.sum(np.log(1+np.abs(simulation_hospitalized - data_hospitalized))) # penalty_hospitalized = np.sum(np.power(simulation_hospitalized - data_hospitalized, 2)/data_hospitalized[-1]**2) day = simulation_first_confirmed + lag_deceased simulation_deceased = solution[day:day + len(data_deceased), 7] penalty_deceased = np.sum(np.power(np.log(simulation_deceased) - np.log(data_deceased), 2)) penalty_deceased = penalty_deceased + np.sum(np.power(np.log(np.diff(simulation_deceased)) - np.log(np.diff(data_deceased)), 2)) # penalty_deceased = np.sum(np.log(1+np.power(simulation_deceased - data_deceased, 2))) # penalty_deceased = np.sum(np.log(1+np.abs(simulation_deceased - data_deceased))) # penalty_deceased = np.sum(np.power(simulation_deceased - data_deceased, 2)/data_deceased[-1]**2) # if number_group == 1: # # simulation_first_confirmed = np.where(solution[:, 8] > 100)[0][0] # # day = simulation_first_confirmed # simulation_confirmed = solution[day:day + len(data_confirmed), 8] # penalty_confirmed = np.sum(np.power(np.log(simulation_confirmed) - np.log(data_confirmed), 2)) # # day = simulation_first_confirmed + lag_hospitalized # simulation_hospitalized = solution[day:day + len(data_hospitalized), 5] # penalty_hospitalized = np.sum(np.power(np.log(simulation_hospitalized) - np.log(data_hospitalized), 2)) # # day = simulation_first_confirmed + lag_deceased # simulation_deceased = solution[day:day + len(data_deceased), 7] # penalty_deceased = np.sum(np.power(np.log(simulation_deceased) - np.log(data_deceased), 2)) # # # infected = solution[day-20:day-20+len(data_deceased), 8] + solution[day-20:day-20+len(data_deceased), 9] # # # # penalty_deceased = penalty_deceased + np.sum(np.power(np.log(infected) - np.log(data_deceased) - np.log(100/0.65), 2)) # # else: # day = simulation_first_confirmed # simulation_confirmed = np.sum(solution[day:day + len(data_confirmed), 8*number_group:9*number_group], axis=1) # penalty_confirmed = np.sum(np.power(np.log(simulation_confirmed) - np.log(data_confirmed), 2)) # # day = simulation_first_confirmed + lag_hospitalized # simulation_hospitalized = np.sum(solution[day:day + len(data_hospitalized), 5*number_group:6*number_group], axis=1) # penalty_hospitalized = np.sum(np.power(np.log(simulation_hospitalized) - np.log(data_hospitalized), 2)) # # day = simulation_first_confirmed + lag_deceased # simulation_deceased = np.sum(solution[day:day + len(data_deceased), 7*number_group:8*number_group], axis=1) # penalty_deceased = np.sum(np.power(np.log(simulation_deceased) - np.log(data_deceased), 2)) # # # death = solution[day + len(data_deceased), 7*number_group:8*number_group] # # simulation_death_by_age = death[:9] + death[9:] # # simulation_death_by_age = simulation_death_by_age / np.sum(simulation_death_by_age) # # penalty_deceased_distribution = 100. * np.sum((simulation_death_by_age - death_by_age) ** 2) # # penalty_deceased = penalty_deceased + penalty_deceased_distribution # # # simulation_deaths = np.sum(solution[ten_death_day:ten_death_day + len(deaths), 7*number_group:8*number_group], axis=1) # # penalty_deceased = np.sum(np.power(np.log(simulation_deaths) - np.log(deaths), 2)) # # # # simulation_hospitalized = np.sum(solution[ten_death_day + lag:ten_death_day + lag + len(hospitalized), 5*number_group:6*number_group], axis=1) # # penalty_hospitalized = np.sum(np.power(np.log(simulation_hospitalized) - np.log(hospitalized), 2)) # # # # simulation_positive = np.sum(solution[ten_death_day:ten_death_day + len(deaths), 8*number_group:9*number_group], axis=1) # # penalty_positive = np.sum(np.power(np.log(simulation_positive) - np.log(positive), 2)) # penalization for control penalty_control = penalization(controls, coeffs, kappas) result = ws[0]*penalty_deceased + ws[1]*penalty_hospitalized + ws[2]*penalty_confirmed + ws[3]*penalty_control # print("alpha, q, g_I, g_A = ", controls) print("weights = ", ws, "deceased term = ", ws[0]*penalty_deceased, "hospitalized term = ", ws[1]*penalty_hospitalized, "confirmed term = ", ws[2]*penalty_confirmed, "control term = ", ws[3]*penalty_control) # "deceased distribution = ", penalty_deceased_distribution return result
print("time to compute hessian vector product by finite difference = ", time.time() - t0) # print("hessian vector product by finite difference = ", hvp_FD) print("relative error of hessian vector product by FD and AD = ", np.linalg.norm(hvp_AD-hvp_FD)/np.linalg.norm(hvp_AD)) if __name__ == "__main__": simulation_first_confirmed, configurations, parameters, controls = initialization(configurations, parameters, controls) y0, t_total, N_total, number_group, population_proportion, \ t_control, number_days_per_control_change, number_control_change_times, number_time_dependent_controls = configurations model = Model(configurations, parameters, controls) solution = RK2(model.seir, y0, t_total, parameters, controls) Rt = model.reproduction(t_total, parameters, controls, solution) # l-bfgs-b optimization # ws = [1., 1., 100.] # penalty parameters for deceased, hospitalized, confirmed, and control ws = [2., 0., 0., 100.] # penalty adjusted by population in each group # coeffs = [np.array( # [10. * population_proportion * (((i + 1) / number_control_change_times)+0.5) for i in range(number_control_change_times)]), # np.array( # [1. * population_proportion * (((i + 1) / number_control_change_times)+0.5) for i in range(number_control_change_times)]), # np.array( # [1. * population_proportion * (((i + 1) / number_control_change_times)+0.5) for i in range(number_control_change_times)]),
controls = (alpha, ) misfit = Misfit(configurations, parameters, controls, simulation_first_confirmed) # sigma = 10 * np.ones_like(x) prior = Laplacian(misfit.dimension, gamma=10, mean=alpha) # prior = Laplacian(misfit.dimension, gamma=10, regularization=False) model = Model(prior, misfit) if __name__ == "__main__": print(misfit.t_total) solution = RK2(misfit.seir, misfit.y0, misfit.t_total, misfit.parameters, misfit.controls) solution = misfit.grouping(solution) # compute growth rate at properly chosen time intervals t0, t1 = 10, 20 E0, E1 = solution[t0, 1], solution[t1, 1] print("exposed growth rate beta for exp(beta*t) = ", np.log(E1 / E0) / (t1 - t0), "doubling time = ", np.log(2) / (np.log(E1 / E0) / (t1 - t0))) t0, t1 = 20, 30 I0, I1 = solution[t0, 4], solution[t1, 4] print("symptomatic growth rate beta for exp(beta*t) = ", np.log(I1 / I0) / (t1 - t0), "doubling time = ", np.log(2) / (np.log(I1 / I0) / (t1 - t0))) t0, t1 = 30, 40 D0, D1 = solution[t0, 7], solution[t1, 7]