def _simulate(self, name, y0_dict): """ Simulate ODE models with setted parameter values. Args: name (str): phase series name y0_dict (dict): - key (str): variable name - value (float): initial value - dictionary of initial values or None - if model will be changed in the later phase, must be specified Returns: (tuple) (pandas.DataFrame): output of ODESimulator.dim() Index: reset index Columns: - Date (pd.TimeStamp): Observation date - Country (str): country/region name - Province (str): province/prefecture/state name - variables of the models (int): Confirmed (int) etc. (list[pd.TimeStamp]): list of start dates """ df = self.series_dict[name].summary() simulator = ODESimulator( self.country, province="-" if self.province is None else self.province) start_objects = list() for phase in df.index: model_name = df.loc[phase, self.ODE] model = self.model_dict[model_name] start_date = df.loc[phase, self.START] start_obj = self.date_obj(start_date) start_objects.append(start_obj) end_obj = self.date_obj(df.loc[phase, self.END]) phase_seconds = (end_obj - start_obj).total_seconds() + 1 step_n = round(phase_seconds / (60 * self.tau)) population = df.loc[phase, self.N] param_dict = df[model.PARAMETERS].to_dict(orient="index")[phase] if phase == self.num2str(1): # Calculate initial values ode_data = ODEData(self.clean_df, country=self.country, province=self.province) y0_dict_phase = ode_data.y0(model, population, start_date=start_date) else: y0_dict_phase = y0_dict.copy() if y0_dict is not None else None simulator.add(model, step_n, population, param_dict=param_dict, y0_dict=y0_dict_phase) simulator.run() first_date = df.loc[self.num2str(1), self.START] dim_df = simulator.dim(self.tau, first_date) return dim_df, start_objects
def simulate(self, step_n, param_dict): """ Simulate the values with the parameters. Args: step_n (int): number of iteration param_dict (dict): estimated parameter values - key (str): parameter name - value (int or float): parameter value Returns: (pandas.DataFrame): Index: reset index Columns: - t (int): Elapsed time divided by tau value [-] - columns with dimensionalized variables """ simulator = ODESimulator(country=self.country, province=self.province) simulator.add(model=self.model, step_n=step_n, population=self.population, param_dict=param_dict, y0_dict=self.y0_dict) simulator.run() return simulator.taufree()
def _simulate(self, name, y0_dict): """ Simulate ODE models with setted parameter values. @name <str>: phase series name @y0_dict <dict[str]=float>: - dictionary of initial values or None - if model will be changed in the later phase, must be specified @return <tuple(pd.DataFrame, list[pd.TimeStamp])>: - <pd.DataFrame>: output of ODESimulator.dim() - index <int>: reset index - Date <pd.TimeStamp>: Observation date - Country <str>: country/region name - Province <str>: province/prefecture/state name - variables of the models <int>: Confirmed <int> etc. - <list[pd.TimeStamp]>: list of start dates """ df = self.series_dict[name].summary() simulator = ODESimulator( self.country, province="-" if self.province is None else self.province) start_objects = list() for phase in df.index: model_name = df.loc[phase, self.ODE] model = self.model_dict[model_name] start_date = df.loc[phase, self.START] start_obj = self.date_obj(start_date) start_objects.append(start_obj) end_obj = self.date_obj(df.loc[phase, self.END]) phase_seconds = (end_obj - start_obj).total_seconds() + 1 step_n = round(phase_seconds / (60 * self.tau)) population = df.loc[phase, self.N] param_dict = df[model.PARAMETERS].to_dict(orient="index")[phase] if phase == self.num2str(1): # Calculate initial values ode_data = ODEData(self.clean_df, country=self.country, province=self.province) y0_dict_phase = ode_data.y0(model, population, start_date=start_date) else: try: y0_dict_phase = y0_dict.copy() except AttributeError: y0_dict_phase = None simulator.add(model, step_n, population, param_dict=param_dict, y0_dict=y0_dict_phase) simulator.run() first_date = df.loc[self.num2str(1), self.START] dim_df = simulator.dim(self.tau, first_date) return dim_df, start_objects
def simulate(self, step_n, param_dict): """ Simulate the values with the parameters. @step_n <int>: number of iteration @param_dict <dict[str]=int/float>: - estimated parameter values @return <pd.DataFrame>: - index: reset index - t <int>: Elapsed time divided by tau value [-] - columns with dimensionalized variables """ simulator = ODESimulator(country=self.country, province=self.province) simulator.add( model=self.model, step_n=step_n, population=self.population, param_dict=param_dict, y0_dict=self.y0_dict ) simulator.run() return simulator.taufree()
def simulate(self, step_n, param_dict): """ Simulate the values with the parameters. @step_n <int>: number of iteration @param_dict <dict[str]=int/float>: - estimated parameter values @return <pd.DataFrame>: - index: reseted index - t: time steps, 0, 1, 2, 3... - x, y, z, w etc. """ simulator = ODESimulator(country=self.country, province=self.province) simulator.add( model=self.model, step_n=step_n, population=self.population, param_dict=param_dict, y0_dict=self.y0_dict ) simulator.run() df = simulator.non_dim() return df
def simulate(self, name="Main", y0_dict=None, show_figure=True, filename=None): """ Simulate ODE models with setted parameter values. @name <str>: phase series name - if 'Main', main PhaseSeries will be used @y0_dict <doct[str]=float>: - dictionary of initial values or None - if model will be changed in the later phase, must be specified @show_figure <bool>: - if True, show the result as a figure. @filename <str>: filename of the figure, or None (show figure) @return <pd.DataFrame> - index <int>: reseted index - Date <str>: date, like 31Dec2020 - Country <str>: country/region name - Province <str>: province/prefecture/state name - variables of the models <int>: Confirmed <int> etc. """ # TODO: Refactoring, split this method name = self.MAIN if name == "Main" else name df = self.series_dict[name].summary() # Future must be added in advance if self.FUTURE not in df[self.TENSE].unique(): raise KeyError( f"Future phases of {name} scenario must be registered by Scenario.add_phase() in advance." ) simulator = ODESimulator( self.country, province="-" if self.province is None else self.province) start_dates = list() for phase in df.index: model_name = df.loc[phase, self.ODE] model = self.model_dict[model_name] start_obj = self.date_obj(df.loc[phase, self.START]) start_dates.append(start_obj) end_obj = self.date_obj(df.loc[phase, self.END]) phase_seconds = (end_obj - start_obj).total_seconds() + 1 step_n = round(phase_seconds / (60 * self.tau)) population = df.loc[phase, self.N] param_dict = df[model.PARAMETERS].to_dict(orient="index")[phase] if phase == self.num2str(1): # Calculate intial values nondim_data = NondimData(self.clean_df, country=self.country, province=self.province) nondim_df = nondim_data.make(model, population) init_index = [ date_obj for (date_obj, _) in self.series_dict[name].phase_dict.items() if date_obj == start_obj ][0] y0_dict_phase = { v: nondim_df.loc[init_index, v] for v in model.VARIABLES } else: try: y0_dict_phase = y0_dict.copy() except AttributeError: y0_dict_phase = None simulator.add(model, step_n, population, param_dict=param_dict, y0_dict=y0_dict_phase) simulator.run() dim_df = simulator.dim(self.tau, df.loc[self.num2str(1), self.START]) dim_df = dim_df.set_index(self.DATE).resample("D").mean() # TODO: smoothing the values dim_df = dim_df.astype(np.int64) fig_df = dim_df.copy() dim_df[self.DATE] = dim_df.index.strftime(self.DATE_FORMAT) dim_df = dim_df.reset_index(drop=True) dim_df = dim_df.loc[:, [self.DATE, *dim_df.columns.tolist()[:-1]]] if not show_figure: return dim_df # Show figure fig_cols_set = set(fig_df.columns) & set(self.FIG_COLUMNS) fig_cols = [col for col in self.FIG_COLUMNS if col in fig_cols_set] # TODO: add vertical lines to line-plot with tau and step_n line_plot(fig_df[fig_cols], title=f"{self.area}: Predicted number of cases", filename=filename, y_integer=True, v=start_dates[1:]) return dim_df