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() simulator.add(model=self.model, step_n=step_n, population=self.population, param_dict=param_dict, y0_dict=self.y0_dict) return simulator.taufree()
def simulate(self, y0_dict=None): """ Perform simulation with the set/estimated parameter values. Args: y0_dict (dict or None): dictionary of initial values or None - key (str): variable name - value (float): initial value Returns: pandas.DataFrame Index reset index Columns - Date (pd.Timestamp): Observation date - Confirmed (int): the number of confirmed cases - Infected (int): the number of currently infected cases - Fatal (int): the number of fatal cases - Recovered (int): the number of recovered cases - Variables of the model (int): Confirmed etc. Note: Simulation starts at the start date of the phase. Simulation end at the next date of the end date of the phase. """ self._model_is_registered() # Initial values y0_dict = y0_dict or {} y0_dict.update(self.y0_dict) diff_set = set(self._model.VARIABLES) - y0_dict.keys() y0_dict.update({var: 0 for var in diff_set}) # Conditions param_dict = self._ode_dict.copy() if None in param_dict.values(): raise UnExecutedError("PhaseUnit.set_ode()") tau = param_dict.pop(self.TAU) last_date = self.tomorrow(self._end_date) # Simulation simulator = ODESimulator() simulator.add( model=self._model, step_n=self.steps(self._start_date, last_date, tau), population=self._population, param_dict=param_dict, y0_dict=y0_dict ) # Dimensionalized values df = simulator.dim(tau=tau, start_date=self._start_date) df = self._model.restore(df) # Return day-level data df = df.set_index(self.DATE).resample("D").first() df = df.loc[df.index <= self._ensure_date(last_date), :] return df.reset_index().loc[:, self.NLOC_COLUMNS]
def add(self, model, country=None, province=None, **kwargs): """ Add example data. If the country has been registered, the start date will be the next data of the registered records. Args: model (subclass of cs.ModelBase): the first ODE model country (str): country name province (str): province name kwargs: the other keyword arguments of ODESimulator.add() Notes: If country is None, the name of the model will be used. If province is None, '-' will be used. """ # Arguments model = self.validate_subclass(model, ModelBase, name="model") arg_dict = model.EXAMPLE.copy() arg_dict.update(kwargs) country = country or model.NAME province = province or self.UNKNOWN try: population = arg_dict["population"] except KeyError: raise KeyError("@population must be specified.") # Start date and y0 values df = self._cleaned_df.copy() df = df.loc[ (df[self.COUNTRY] == country) & (df[self.PROVINCE] == province) ] if df.empty: start_date = self.start_date else: start_date = df.loc[df.index[-1], self.DATE] df = model.tau_free(df, population, tau=None) arg_dict["y0_dict"] = { k: df.loc[df.index[0], k] for k in model.VARIABLES } # Simulation simulator = ODESimulator(country=country, province=province) simulator.add(model=model, **arg_dict) simulator.run() # Add the simulated records to self dim_df = simulator.dim(tau=self.tau, start_date=start_date) restored_df = model.restore(dim_df) restored_df[self.COUNTRY] = country restored_df[self.PROVINCE] = province selected_df = restored_df.loc[:, self.COLUMNS] self._cleaned_df = pd.concat( [self._cleaned_df, selected_df], axis=0, ignore_index=True ) # Set non-dimensional data if country not in self.nondim_dict.keys(): self.nondim_dict[country] = dict() nondim_df = simulator.non_dim() if province in self.nondim_dict[country].keys(): nondim_df_old = self.nondim_dict[country][province].copy() nondim_df = pd.concat([nondim_df_old, nondim_df], axis=0) self.nondim_dict[country][province] = nondim_df.copy()
def _simulate(self, step_n, param_dict): """ Simulate the values with the parameters. Args: step_n (int): number of iteration dict[str, int or float]: dictionary of parameter values Returns: pandas.DataFrame: Index reset index Columns - t (int): Elapsed time divided by tau value [-] - columns with dimensionalized variables """ simulator = ODESimulator() simulator.add(model=self.model, step_n=step_n, population=self.population, param_dict=param_dict, y0_dict=self.y0_dict) return simulator.taufree()
def _simulate(self, name, y0_dict): """ Simulate ODE models with set 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 """ phase_series = copy.deepcopy(self.series_dict[name]) # Dates and the number of steps last_object = phase_series.last_object() start_objects = phase_series.start_objects() step_n_list = phase_series.number_of_steps(start_objects, last_object, self.tau) first_date = start_objects[0].strftime(self.DATE_FORMAT) # Information of models models = [self.model_dict[name] for name in phase_series.model_names()] # Population values population_values = phase_series.population_values() # Create simulator simulator = ODESimulator(self.country, province=self.province) # Add phases to the simulator df = phase_series.summary() zip_iter = zip(df.index, models, step_n_list, population_values) for (phase, model, step_n, population) in zip_iter: param_dict = df[model.PARAMETERS].to_dict(orient="index")[phase] if phase == self.num2str(1): # Calculate initial values subset_df = self.jhu_data.subset(country=self.country, province=self.province, start_date=first_date) subset_df = model.tau_free(subset_df, population, tau=None) y0_dict_phase = { k: subset_df.loc[subset_df.index[0], k] for k in model.VARIABLES } else: if y0_dict is None: y0_dict_phase = None else: y0_dict_phase = y0_dict.copy() simulator.add(model, step_n, population, param_dict=param_dict, y0_dict=y0_dict_phase) # Run simulation simulator.run() dim_df = simulator.dim(self.tau, first_date) return dim_df, start_objects
def add(self, model, country=None, province=None, **kwargs): """ Add example data. If the country has been registered, the start date will be the next data of the registered records. Args: model (cs.ModelBase): the first ODE model country (str or None): country name province (str or None): province name kwargs: the other keyword arguments of ODESimulator.add() Note: If country is None, the name of the model will be used. If province is None, '-' will be used. """ # Arguments model = self._ensure_subclass(model, ModelBase, name="model") arg_dict = model.EXAMPLE.copy() arg_dict.update(kwargs) population = arg_dict["population"] # Area country, province = self._model_to_area( model=model, country=country, province=province) # Start date and y0 values df = self._cleaned_df.copy() df = df.loc[ (df[self.COUNTRY] == country) & (df[self.PROVINCE] == province), : ] if df.empty: start_date = self.start_date else: start_date = df.loc[ df.index[-1], self.DATE].strftime(self.DATE_FORMAT) df = model.tau_free(df, population, tau=None) arg_dict[self.Y0_DICT] = { k: df.loc[df.index[0], k] for k in model.VARIABLES } # Simulation simulator = ODESimulator(country=country, province=province) simulator.add(model=model, **arg_dict) # Specialized records dim_df = simulator.dim(tau=self.tau, start_date=start_date) if country not in self._specialized_dict: self._specialized_dict[country] = {} self._specialized_dict[country][province] = dim_df.copy() # JHU-type records restored_df = model.restore(dim_df) restored_df[self.COUNTRY] = country restored_df[self.PROVINCE] = province selected_df = restored_df.loc[:, self.COLUMNS] self._cleaned_df = pd.concat( [self._cleaned_df, selected_df], axis=0, ignore_index=True ) # Set non-dimensional data if country not in self.nondim_dict: self.nondim_dict[country] = {} nondim_df = simulator.non_dim() if province in self.nondim_dict[country]: nondim_df_old = self.nondim_dict[country][province].copy() nondim_df = pd.concat([nondim_df_old, nondim_df], axis=0) self.nondim_dict[country][province] = nondim_df.copy()