diff --git a/extreme_estimator/R_fit/gev_fit/gev_mle_fit.py b/extreme_estimator/R_fit/gev_fit/gev_mle_fit.py index b6f05736b9d18fc9734f46fc1b9286b2d3a0d3dd..5bfe53f38905c32542fccdc55d8597a6d246d4fe 100644 --- a/extreme_estimator/R_fit/gev_fit/gev_mle_fit.py +++ b/extreme_estimator/R_fit/gev_fit/gev_mle_fit.py @@ -16,7 +16,7 @@ def mle_gev(x_gev: np.ndarray, start_loc=0, start_scale=1, start_shape=0): x_gev = rpyn.numpy2ri(x_gev) r.assign('x_gev', x_gev) r.assign('python_wrapping', True) - r.source(file="/home/erwan/Documents/projects/spatiotemporalextremes/R/gev_fit/gev_fit.R") + r.source(file="/home/erwan/Documents/projects/spatiotemporalextremes/extreme_estimator/gev_fit/gev_fit.extreme_estimator") res = r.mle_gev(loc=start_loc, scale=start_scale, shape=start_shape) mle_params = dict(r.attr(res, 'coef').items()) return mle_params diff --git a/extreme_estimator/R_fit/max_stable_fit/abstract_max_stable_model.py b/extreme_estimator/R_fit/max_stable_fit/abstract_max_stable_model.py new file mode 100644 index 0000000000000000000000000000000000000000..75a4c3cccb823ee14ffb1472277d3226fd6dfd65 --- /dev/null +++ b/extreme_estimator/R_fit/max_stable_fit/abstract_max_stable_model.py @@ -0,0 +1,87 @@ +from enum import Enum + +from rpy2.robjects import ListVector +from extreme_estimator.R_fit.utils import get_loaded_r +import numpy as np + + +class AbstractMaxStableModel(object): + + def __init__(self, params_start_fit=None, params_sample=None): + self.cov_mod = None + self.default_params_start_fit = None + self.default_params_sample = None + self.user_params_start_fit = params_start_fit + self.user_params_sample = params_sample + self.r = get_loaded_r() + + def fitmaxstab(self, maxima: np.ndarray, coord: np.ndarray, ): + # todo: find how to specify a startign point, understand how is it set by default + # res = None + # tries = 5 + # nb_tries = 0 + # while res is None and nb_tries < tries: + # try: + # res = self.r.fitmaxstab(maxima, coord, **self.cov_mod_param) # type: ListVector + # except rpy2.rinterface.RRuntimeError: + # pass + # nb_tries += 1 + # print(nb_tries) + res = self.r.fitmaxstab(np.transpose(maxima), coord, **self.cov_mod_param) # type: ListVector + fitted_values = res.rx2('fitted.values') + fitted_values = {key: fitted_values.rx2(key)[0] for key in fitted_values.names} + return fitted_values + + def rmaxstab(self, nb_obs: int, coord: np.ndarray, ) -> np.ndarray: + """ + Return an numpy of maxima. With rows being the stations and columns being the years of maxima + """ + maxima = np.array(self.r.rmaxstab(nb_obs, coord, **self.cov_mod_param, **self.params_sample)) + return np.transpose(maxima) + + @property + def cov_mod_param(self): + return {'cov.mod': self.cov_mod} + + @property + def params_start_fit(self): + return self.merge_params(default_params=self.default_params_start_fit, input_params=self.user_params_start_fit) + + @property + def params_sample(self): + return self.merge_params(default_params=self.default_params_sample, input_params=self.user_params_sample) + + @staticmethod + def merge_params(default_params, input_params): + merged_params = default_params.copy() + if input_params is not None: + assert isinstance(default_params, dict) and isinstance(input_params, dict) + assert set(input_params.keys()).issubset(set(default_params.keys())) + merged_params.update(input_params) + return merged_params + + +class CovarianceFunction(Enum): + whitmat = 0 + cauchy = 1 + powexp = 2 + bessel = 3 + + +class AbstractMaxStableModelWithCovarianceFunction(AbstractMaxStableModel): + + def __init__(self, params_start_fit=None, params_sample=None, covariance_function: CovarianceFunction = None): + super().__init__(params_start_fit, params_sample) + assert covariance_function is not None + self.covariance_function = covariance_function + self.default_params_sample = { + 'range': 3, + 'smooth': 0.5, + 'nugget': 0.5 + } + + +if __name__ == '__main__': + print([c.name for c in CovarianceFunction]) + for covariance_function in CovarianceFunction: + print(covariance_function) \ No newline at end of file diff --git a/extreme_estimator/R_fit/max_stable_fit/max_stable_fit.R b/extreme_estimator/R_fit/max_stable_fit/max_stable_fit.R index b51112f7a53e36f9236df8eedd0e0057a7cb0513..287a186b83a731c2ff6b5aea44975952bc1b9dd9 100644 --- a/extreme_estimator/R_fit/max_stable_fit/max_stable_fit.R +++ b/extreme_estimator/R_fit/max_stable_fit/max_stable_fit.R @@ -13,11 +13,14 @@ if (call_main) { print(coord) # Generate the data # data <- rmaxstab(n.obs, coord, "gauss", cov11 = 100, cov12 = 25, cov22 = 220) - data <- rmaxstab(n.obs, coord, "brown", range = 3, smooth = 0.5) + # data <- rmaxstab(n.obs, coord, "brown", range = 3, smooth = 0.5) + # data <- rmaxstab(n.obs, coord, "whitmat", nugget = 0.0, range = 3, smooth = 0.5) + data <- rmaxstab(n.obs, coord, "cauchy", ) # Fit back the data print(data) # res = fitmaxstab(data, coord, "gauss", fit.marge=FALSE, ) - res = fitmaxstab(data, coord, "brown") + # res = fitmaxstab(data, coord, "brown") + res = fitmaxstab(data, coord, "cauchy") # res = fitmaxstab(data, coord, "gauss", start=list(0,0,0)) print(res) print(class(res)) diff --git a/extreme_estimator/R_fit/max_stable_fit/max_stable_models.py b/extreme_estimator/R_fit/max_stable_fit/max_stable_models.py index 3aaaa7dd0e66fb2b9cf47a8aae23922ea663d0b0..2c77573f200a818e725e7c56147c0cea4d04e3d9 100644 --- a/extreme_estimator/R_fit/max_stable_fit/max_stable_models.py +++ b/extreme_estimator/R_fit/max_stable_fit/max_stable_models.py @@ -1,72 +1,10 @@ -import rpy2 +from enum import Enum -from rpy2.robjects import ListVector +from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import AbstractMaxStableModel, \ + AbstractMaxStableModelWithCovarianceFunction, CovarianceFunction -from extreme_estimator.R_fit.utils import get_loaded_r -import numpy as np - -def optimize_fit(max_stable_model_list, params_start_fit_list): - pass - - -class MaxStableModel(object): - - def __init__(self, params_start_fit=None, params_sample=None): - self.cov_mod = None - self.default_params_start_fit = None - self.default_params_sample = None - self.user_params_start_fit = params_start_fit - self.user_params_sample = params_sample - self.r = get_loaded_r() - - def fitmaxstab(self, maxima: np.ndarray, coord: np.ndarray, ): - # todo: find how to specify a startign point, understand how is it set by default - # res = None - # tries = 5 - # nb_tries = 0 - # while res is None and nb_tries < tries: - # try: - # res = self.r.fitmaxstab(maxima, coord, **self.cov_mod_param) # type: ListVector - # except rpy2.rinterface.RRuntimeError: - # pass - # nb_tries += 1 - # print(nb_tries) - res = self.r.fitmaxstab(np.transpose(maxima), coord, **self.cov_mod_param) # type: ListVector - fitted_values = res.rx2('fitted.values') - fitted_values = {key: fitted_values.rx2(key)[0] for key in fitted_values.names} - return fitted_values - - def rmaxstab(self, nb_obs: int, coord: np.ndarray, ) -> np.ndarray: - """ - Return an numpy of maxima. With rows being the stations and columns being the years of maxima - """ - maxima = np.array(self.r.rmaxstab(nb_obs, coord, **self.cov_mod_param, **self.params_sample)) - return np.transpose(maxima) - - @property - def cov_mod_param(self): - return {'cov.mod': self.cov_mod} - - @property - def params_start_fit(self): - return self.merge_params(default_params=self.default_params_start_fit, input_params=self.user_params_start_fit) - - @property - def params_sample(self): - return self.merge_params(default_params=self.default_params_sample, input_params=self.user_params_sample) - - @staticmethod - def merge_params(default_params, input_params): - merged_params = default_params.copy() - if input_params is not None: - assert isinstance(default_params, dict) and isinstance(input_params, dict) - assert set(input_params.keys()).issubset(set(default_params.keys())) - merged_params.update(input_params) - return merged_params - - -class GaussianMSP(MaxStableModel): +class Smith(AbstractMaxStableModel): def __init__(self, params_start_fit=None, params_sample=None): super().__init__(params_start_fit=params_start_fit, params_sample=params_sample) @@ -79,17 +17,45 @@ class GaussianMSP(MaxStableModel): } -class BrownResick(MaxStableModel): +class BrownResnick(AbstractMaxStableModel): def __init__(self, params_start_fit=None, params_sample=None): super().__init__(params_start_fit=params_start_fit, params_sample=params_sample) self.cov_mod = 'brown' self.default_params_start_fit = {} self.default_params_sample = { - "range": 3, - "smooth": 0.5, + 'range': 3, + 'smooth': 0.5, } -class ExtremalT(MaxStableModel): - pass +class Schlather(AbstractMaxStableModelWithCovarianceFunction): + + def __init__(self, params_start_fit=None, params_sample=None, covariance_function: CovarianceFunction = None): + super().__init__(params_start_fit, params_sample, covariance_function) + self.cov_mod = self.covariance_function.name + self.default_params_sample.update({}) + + +class Geometric(AbstractMaxStableModelWithCovarianceFunction): + + def __init__(self, params_start_fit=None, params_sample=None, covariance_function: CovarianceFunction = None): + super().__init__(params_start_fit, params_sample, covariance_function) + self.cov_mod = 'g' + self.covariance_function.name + self.default_params_sample .update({'sigma2': 0.5}) + + +class ExtremalT(AbstractMaxStableModelWithCovarianceFunction): + + def __init__(self, params_start_fit=None, params_sample=None, covariance_function: CovarianceFunction = None): + super().__init__(params_start_fit, params_sample, covariance_function) + self.cov_mod = 't' + self.covariance_function.name + self.default_params_sample .update({'DoF': 2}) + + +class ISchlather(AbstractMaxStableModelWithCovarianceFunction): + + def __init__(self, params_start_fit=None, params_sample=None, covariance_function: CovarianceFunction = None): + super().__init__(params_start_fit, params_sample, covariance_function) + self.cov_mod = 'i' + self.covariance_function.name + self.default_params_sample .update({'alpha': 0.5}) diff --git a/extreme_estimator/estimator/msp_estimator.py b/extreme_estimator/estimator/msp_estimator.py index 03c2f502a5afb33a7f4bf953e00c2a2f0ea8c84c..bb467d09985dc2d850480cc0e9990dcef47d7686 100644 --- a/extreme_estimator/estimator/msp_estimator.py +++ b/extreme_estimator/estimator/msp_estimator.py @@ -1,12 +1,12 @@ from extreme_estimator.estimator.abstract_estimator import AbstractEstimator -from extreme_estimator.R_fit.max_stable_fit.max_stable_models import MaxStableModel +from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import AbstractMaxStableModel from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset import numpy as np class MaxStableEstimator(AbstractEstimator): - def __init__(self, dataset: AbstractDataset, max_stable_model: MaxStableModel): + def __init__(self, dataset: AbstractDataset, max_stable_model: AbstractMaxStableModel): self.dataset = dataset self.max_stable_model = max_stable_model self.max_stable_params_fitted = None diff --git a/extreme_estimator/robustness_plot/abstract_robustness.py b/extreme_estimator/robustness_plot/abstract_robustness.py index b40f9bd2dc28932a0e8a1933305d0d0b8d485de9..4925440748052f919a3268c57ecbc822bd3f090b 100644 --- a/extreme_estimator/robustness_plot/abstract_robustness.py +++ b/extreme_estimator/robustness_plot/abstract_robustness.py @@ -1,7 +1,7 @@ from typing import List from extreme_estimator.estimator.msp_estimator import MaxStableEstimator -from extreme_estimator.R_fit.max_stable_fit.max_stable_models import GaussianMSP, MaxStableModel +from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import GaussianMSP, AbstractMaxStableModel from itertools import product from spatio_temporal_dataset.dataset.simulation_dataset import SimulatedDataset diff --git a/extreme_estimator/robustness_plot/spatial_robustness.py b/extreme_estimator/robustness_plot/spatial_robustness.py index 3d872cd2a0ac2522038d6ac2734853c34973d665..937a66b7c51d500a495c0614ea9c09519a60b516 100644 --- a/extreme_estimator/robustness_plot/spatial_robustness.py +++ b/extreme_estimator/robustness_plot/spatial_robustness.py @@ -1,4 +1,3 @@ -from extreme_estimator.R_fit.max_stable_fit.max_stable_models import GaussianMSP, BrownResick from extreme_estimator.robustness_plot.abstract_robustness import DisplayItem, AbstractRobustnessPlot, \ SpatialCoordinateClassItem, NbObservationItem, NbStationItem, MaxStableModelItem, SpatialParamsItem from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import CircleCoordinates diff --git a/spatio_temporal_dataset/dataset/simulation_dataset.py b/spatio_temporal_dataset/dataset/simulation_dataset.py index bc6a2860532661a69ccda797f76e3ec36882bcc0..7312acc945598a29658bef1d76b0fb421b5cd608 100644 --- a/spatio_temporal_dataset/dataset/simulation_dataset.py +++ b/spatio_temporal_dataset/dataset/simulation_dataset.py @@ -1,4 +1,4 @@ -from extreme_estimator.R_fit.max_stable_fit.max_stable_models import MaxStableModel, GaussianMSP +from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import AbstractMaxStableModel import pandas as pd from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset from spatio_temporal_dataset.temporal_maxima.temporal_maxima import TemporalMaxima @@ -9,24 +9,18 @@ from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import Ci class SimulatedDataset(AbstractDataset): def __init__(self, temporal_maxima: TemporalMaxima, spatial_coordinates: AbstractSpatialCoordinates, - max_stable_model: MaxStableModel): + max_stable_model: AbstractMaxStableModel): super().__init__(temporal_maxima, spatial_coordinates) self.max_stable_model = max_stable_model @classmethod - def from_max_stable_sampling(cls, nb_obs: int, max_stable_model:MaxStableModel, spatial_coordinates: AbstractSpatialCoordinates): + def from_max_stable_sampling(cls, nb_obs: int, max_stable_model:AbstractMaxStableModel, spatial_coordinates: AbstractSpatialCoordinates): maxima = max_stable_model.rmaxstab(nb_obs=nb_obs, coord=spatial_coordinates.coord) df_maxima = pd.DataFrame(data=maxima, index=spatial_coordinates.index) temporal_maxima = TemporalMaxima(df_maxima=df_maxima) return cls(temporal_maxima=temporal_maxima, spatial_coordinates=spatial_coordinates, max_stable_model=max_stable_model) -if __name__ == '__main__': - coord = CircleCoordinates.from_nb_points(nb_points=5, max_radius=1) - max_stable_model = GaussianMSP() - dataset = SimulatedDataset.from_max_stable_sampling(nb_obs=50, max_stable_model=max_stable_model, spatial_coordinates=coord) - print(dataset.df_dataset) - diff --git a/test/R/test_gev_fit.py b/test/extreme_estimator/test_gev_fit.py similarity index 90% rename from test/R/test_gev_fit.py rename to test/extreme_estimator/test_gev_fit.py index c2f4b9551ee74ac39a6ecb41a9ade20be14716a2..17b963658bfe5e560ae0b5ddfd20b50599e335c9 100644 --- a/test/R/test_gev_fit.py +++ b/test/extreme_estimator/test_gev_fit.py @@ -1,10 +1,9 @@ import unittest - -from R.gev_fit.gev_marginal import frechet_unitary_transformation -from R.gev_fit.gev_mle_fit import GevMleFit import rpy2.robjects as ro import numpy as np +from extreme_estimator.R_fit.gev_fit.gev_mle_fit import GevMleFit + class TestGevFit(unittest.TestCase): diff --git a/test/extreme_estimator/test_max_stable_fit.py b/test/extreme_estimator/test_max_stable_fit.py new file mode 100644 index 0000000000000000000000000000000000000000..cca832bfa3e1454d063df35c13550882867cd5ca --- /dev/null +++ b/test/extreme_estimator/test_max_stable_fit.py @@ -0,0 +1,37 @@ +import unittest + +from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import \ + AbstractMaxStableModelWithCovarianceFunction, CovarianceFunction +from extreme_estimator.R_fit.max_stable_fit.max_stable_models import Smith, BrownResnick, Schlather, \ + Geometric, ExtremalT, ISchlather +from spatio_temporal_dataset.dataset.simulation_dataset import SimulatedDataset +from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import CircleCoordinates + + +class TestMaxStableFit(unittest.TestCase): + MAX_STABLE_CLASSES = [Smith, BrownResnick, Schlather, Geometric, ExtremalT, ISchlather] + + def setUp(self): + super().setUp() + self.spatial_coord = CircleCoordinates.from_nb_points(nb_points=5, max_radius=1) + self.max_stable_models = [] + for max_stable_class in self.MAX_STABLE_CLASSES: + print(max_stable_class) + if issubclass(max_stable_class, AbstractMaxStableModelWithCovarianceFunction): + self.max_stable_models.extend([max_stable_class(covariance_function=covariance_function) + for covariance_function in CovarianceFunction]) + else: + self.max_stable_models.append(max_stable_class()) + + def test_sampling_fit_with_models(self, display=False): + for max_stable_model in self.max_stable_models: + dataset = SimulatedDataset.from_max_stable_sampling(nb_obs=10, max_stable_model=max_stable_model, + spatial_coordinates=self.spatial_coord) + if display: + print(dataset.head()) + max_stable_model.fitmaxstab(maxima=dataset.maxima, coord=dataset.coord) + self.assertTrue(True) + + +if __name__ == '__main__': + unittest.main()