diff --git a/.gitignore b/.gitignore index 31d355f..e16628e 100644 --- a/.gitignore +++ b/.gitignore @@ -157,5 +157,11 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +.idea/ /data1/ + +# Local folders and files +execution_time/ +test_distribution/ +cache.json +local_tests.py \ No newline at end of file diff --git a/critical_value.py b/critical_value.py deleted file mode 100644 index 146184e..0000000 --- a/critical_value.py +++ /dev/null @@ -1,45 +0,0 @@ -import numpy as np -from scipy.stats import kstest - -from stattest.experiment.configuration.configuration import AbstractHypothesis -from stattest.test import AbstractTestStatistic, KSWeibullTest -import scipy.stats as scipy_stats -import multiprocessing - - -def get_value(test1: AbstractTestStatistic, hypothesis: AbstractHypothesis, size): - x = hypothesis.generate(size=size) - return test1.execute_statistic(x) - - -def calculate_critical_value1(test1: AbstractTestStatistic, hypothesis: AbstractHypothesis, size: int, alpha: float, - count) -> (float, [float]): - # Calculate critical value - tests = count*[test1] - hypothesis = count*[hypothesis] - sizes = count*[size] - - with multiprocessing.Pool(multiprocessing.cpu_count()) as pool: - distribution = pool.starmap(get_value, zip(tests, hypothesis, sizes)) - - distribution.sort() - - ecdf = scipy_stats.ecdf(distribution) - critical_value = float(np.quantile(ecdf.cdf.quantiles, q=1 - alpha)) - return critical_value, distribution - - -if __name__ == '__main__': - test = KSWeibullTest() - rvs = np.sort(rvs) - cdf_vals = generate_weibull_cdf(rvs, l=self.l, k=self.k) - kstest() - '''start = timeit.default_timer() - value = calculate_critical_value(test, StandardNormalHypothesis(), 30, 0.05, 1_000_000) - end = timeit.default_timer() - print(end - start, value) - - start = timeit.default_timer() - value1, _ = calculate_critical_value1(test, StandardNormalHypothesis(), 30, 0.05, 1_000_000) - end = timeit.default_timer() - print(end - start, value1)''' diff --git a/example.py b/example.py deleted file mode 100644 index e95b9b9..0000000 --- a/example.py +++ /dev/null @@ -1,88 +0,0 @@ -from stattest.execution.report_generator import ReportGenerator, TopTestTableReportBlockGenerator -from stattest.test.generator import BetaRVSGenerator, CauchyRVSGenerator, LaplaceRVSGenerator, LogisticRVSGenerator, \ - TRVSGenerator, TukeyRVSGenerator, Chi2Generator, GammaGenerator, GumbelGenerator, LognormGenerator, \ - WeibullGenerator, TruncnormGenerator, LoConNormGenerator, ScConNormGenerator, MixConNormGenerator -from stattest.test.normal import AbstractNormalityTestStatistic - -sizes = [30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000] - -symmetric_generators = [BetaRVSGenerator(a=0.5, b=0.5), BetaRVSGenerator(a=1, b=1), BetaRVSGenerator(a=2, b=2), - CauchyRVSGenerator(t=0, s=0.5), CauchyRVSGenerator(t=0, s=1), CauchyRVSGenerator(t=0, s=2), - LaplaceRVSGenerator(t=0, s=1), LogisticRVSGenerator(t=2, s=2), - TRVSGenerator(df=1), TRVSGenerator(df=2), TRVSGenerator(df=4), TRVSGenerator(df=10), - TukeyRVSGenerator(lam=0.14), TukeyRVSGenerator(lam=0.5), TukeyRVSGenerator(lam=2), - TukeyRVSGenerator(lam=5), TukeyRVSGenerator(lam=10)] -asymmetric_generators = [BetaRVSGenerator(a=2, b=1), BetaRVSGenerator(a=2, b=5), BetaRVSGenerator(a=4, b=0.5), - BetaRVSGenerator(a=5, b=1), - Chi2Generator(df=1), Chi2Generator(df=2), Chi2Generator(df=4), Chi2Generator(df=10), - GammaGenerator(alfa=2, beta=2), GammaGenerator(alfa=3, beta=2), GammaGenerator(alfa=5, beta=1), - GammaGenerator(alfa=9, beta=1), GammaGenerator(alfa=15, beta=1), - GammaGenerator(alfa=100, beta=1), GumbelGenerator(mu=1, beta=2), LognormGenerator(s=1, mu=0), - WeibullGenerator(l=0.5, k=1), WeibullGenerator(l=1, k=2), WeibullGenerator(l=2, k=3.4), - WeibullGenerator(l=3, k=4)] -modified_generators = [TruncnormGenerator(a=-1, b=1), TruncnormGenerator(a=-2, b=2), TruncnormGenerator(a=-3, b=3), - TruncnormGenerator(a=-3, b=1), TruncnormGenerator(a=-3, b=2), - LoConNormGenerator(p=0.3, a=1), LoConNormGenerator(p=0.4, a=1), LoConNormGenerator(p=0.5, a=1), - LoConNormGenerator(p=0.3, a=3), LoConNormGenerator(p=0.4, a=3), LoConNormGenerator(p=0.5, a=3), - LoConNormGenerator(p=0.3, a=5), LoConNormGenerator(p=0.4, a=5), LoConNormGenerator(p=0.5, a=5), - ScConNormGenerator(p=0.05, b=0.25), ScConNormGenerator(p=0.10, b=0.25), - ScConNormGenerator(p=0.20, b=0.25), ScConNormGenerator(p=0.05, b=2), - ScConNormGenerator(p=0.10, b=2), - ScConNormGenerator(p=0.20, b=2), ScConNormGenerator(p=0.05, b=4), - ScConNormGenerator(p=0.10, b=4), - ScConNormGenerator(p=0.20, b=4), - MixConNormGenerator(p=0.3, a=1, b=0.25), MixConNormGenerator(p=0.4, a=1, b=0.25), - MixConNormGenerator(p=0.5, a=1, b=0.25), MixConNormGenerator(p=0.3, a=3, b=0.25), - MixConNormGenerator(p=0.4, a=3, b=0.25), MixConNormGenerator(p=0.5, a=3, b=0.25), - MixConNormGenerator(p=0.3, a=1, b=4), MixConNormGenerator(p=0.4, a=1, b=4), - MixConNormGenerator(p=0.5, a=1, b=4), MixConNormGenerator(p=0.3, a=3, b=4), - MixConNormGenerator(p=0.4, a=3, b=4), MixConNormGenerator(p=0.5, a=3, b=4)] - - -def run(tests_to_run: [AbstractNormalityTestStatistic], sizes): - for test in tests_to_run: - for size in sizes: - print('Calculating...', test.code(), size) - test.calculate_critical_value(size, 0.05, 1000) - print('Critical value calculated', test.code(), size) - - -if __name__ == '__main__': - cpu_count = 2 # multiprocessing.cpu_count() - """ - # Generate data - rvs_generators = symmetric_generators + asymmetric_generators + modified_generators - print('RVS generators count: ', len(rvs_generators)) - sizes_chunks = np.array_split(np.array(sizes), cpu_count) - start = timeit.default_timer() - with multiprocessing.Pool(cpu_count) as pool: - pool.starmap(prepare_rvs_data, zip(repeat(rvs_generators), sizes_chunks)) - # prepare_rvs_data(rvs_generators, sizes) - stop = timeit.default_timer() - print('Time: ', stop - start) - - cache = MonteCarloCacheService() - tests = [CoinTest()] - alpha = [0.05, 0.1, 0.01] - start = timeit.default_timer() - execute_powers(tests, alpha) - stop = timeit.default_timer() - print('Power calculation time: ', stop - start) - """ - - """ - manager = multiprocessing.Manager() - lock = manager.Lock() - cache = ThreadSafeMonteCarloCacheService(lock=lock) - tests = [EPTest(cache=cache)] - tests_chunks = np.array_split(np.array(tests), cpu_count) - with multiprocessing.Pool(cpu_count) as pool: - pool.starmap(run, zip(tests_chunks, repeat(sizes))) - """ - symmetric = [x.code() for x in symmetric_generators] - asymmetric = [x.code() for x in asymmetric_generators] - modified = [x.code() for x in modified_generators] - print(len(symmetric + asymmetric + modified)) - report_generator = ReportGenerator([TopTestTableReportBlockGenerator()]) - report_generator.generate() - diff --git a/generators/gen.py b/generators/gen.py index b78d848..d5dfe47 100644 --- a/generators/gen.py +++ b/generators/gen.py @@ -12,4 +12,4 @@ def code(self): return super()._convert_to_code(['beta', self.a, self.b]) def generate(self, size): - return generate_beta(size=size, a=self.a, b=self.b) \ No newline at end of file + return generate_beta(size=size, a=self.a, b=self.b) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..bc8cc72 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[project] +name = "stattest" +version = "0.0.1" +authors = [ + { name="Example Author", email="author@example.com" }, +] +description = "Stattest Project" +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] + +[project.urls] +Homepage = "https://github.com/alex98247/statistic-test" +Issues = "https://github.com/alex98247/statistic-test/issues" + +# TODO: fill stub from official documentation \ No newline at end of file diff --git a/stattest/constants.py b/stattest/constants.py index de8832d..5c18826 100644 --- a/stattest/constants.py +++ b/stattest/constants.py @@ -3,4 +3,4 @@ Config = dict[str, Any] USERPATH_GENERATORS = "generators" -USERPATH_HYPOTHESIS = "hypothesis" \ No newline at end of file +USERPATH_HYPOTHESIS = "hypothesis" diff --git a/stattest/core/distribution/expon.py b/stattest/core/distribution/expon.py index 9ec96d6..f3ed653 100644 --- a/stattest/core/distribution/expon.py +++ b/stattest/core/distribution/expon.py @@ -1,11 +1,11 @@ from scipy.stats import expon -def generate_expon(size, l=1): - scale = 1 / l +def generate_expon(size, lam=1): # TODO: refactor structure with inheritance?? + scale = 1 / lam return expon.rvs(size=size, scale=scale) -def cdf_expon(rvs, l=1): - scale = 1 / l +def cdf_expon(rvs, lam=1): + scale = 1 / lam return expon.cdf(rvs, scale=scale) diff --git a/stattest/core/distribution/sample.py b/stattest/core/distribution/sample.py index 1d1d168..678b9cd 100644 --- a/stattest/core/distribution/sample.py +++ b/stattest/core/distribution/sample.py @@ -2,9 +2,9 @@ import numpy as np -def moment(a, moment=1, center=None): - scipy_moment(a=a, moment=moment, center=center) +def moment(a, mom=1, center=None): + scipy_moment(a=a, moment=mom, center=center) -def central_moment(a, moment=1): - return scipy_moment(a=a, moment=moment, center=np.mean(a, axis=0)) +def central_moment(a, mom=1): + return scipy_moment(a=a, moment=mom, center=np.mean(a, axis=0)) diff --git a/stattest/exceptions.py b/stattest/exceptions.py index 5b53593..a427d09 100644 --- a/stattest/exceptions.py +++ b/stattest/exceptions.py @@ -11,7 +11,8 @@ class OperationalException(PySatlException): Most of the time, this is caused by an invalid Configuration. """ + class ConfigurationError(OperationalException): """ Configuration error. Usually caused by invalid configuration. - """ \ No newline at end of file + """ diff --git a/stattest/experiment/__init__.py b/stattest/experiment/__init__.py index 1b40f5a..ab897c6 100644 --- a/stattest/experiment/__init__.py +++ b/stattest/experiment/__init__.py @@ -1,3 +1,3 @@ from stattest.experiment.experiment import Experiment -from stattest.experiment.configuration.configuration import ExperimentConfiguration, ReportConfiguration, ReportBuilder, \ - AlternativeConfiguration +from stattest.experiment.configuration.configuration import (ExperimentConfiguration, ReportConfiguration, + ReportBuilder, AlternativeConfiguration) diff --git a/stattest/experiment/configuration/config_validation.py b/stattest/experiment/configuration/config_validation.py index d69aff9..c58a629 100644 --- a/stattest/experiment/configuration/config_validation.py +++ b/stattest/experiment/configuration/config_validation.py @@ -12,7 +12,7 @@ def _extend_validator(validator_class): """ Extended validator for the Freqtrade configuration JSON Schema. - Currently it only handles defaults for subschemas. + Currently, it only handles defaults for subschemas. """ validate_properties = validator_class.VALIDATORS["properties"] @@ -29,7 +29,7 @@ def set_defaults(validator, properties, instance, schema): FreqtradeValidator = _extend_validator(Draft4Validator) -def validate_config_schema(conf: dict[str, Any], preliminary: bool = False) -> dict[str, Any]: +def validate_config_schema(conf: dict[str, Any], preliminagiry: bool = False) -> dict[str, Any]: """ Validate the configuration follow the Config Schema :param conf: Config in JSON format @@ -47,7 +47,7 @@ def validate_config_schema(conf: dict[str, Any], preliminary: bool = False) -> d def validate_config_consistency(conf: dict[str, Any], *, preliminary: bool = False) -> None: """ Validate the configuration consistency. - Should be ran after loading both configuration and strategy, + Should be run after loading both configuration and strategy, since strategies can set certain configuration settings too. :param conf: Config in JSON format :return: Returns None if everything is ok, otherwise throw an ConfigurationError diff --git a/stattest/experiment/configuration/load_config.py b/stattest/experiment/configuration/load_config.py index 40f552e..ba17058 100644 --- a/stattest/experiment/configuration/load_config.py +++ b/stattest/experiment/configuration/load_config.py @@ -87,7 +87,7 @@ def load_from_files( return load_config_file(filename) file = Path(filename) if base_path: - # Prepend basepath to allow for relative assignments + # Prepend base path to allow for relative assignments file = base_path / file config_tmp = load_config_file(str(file)) diff --git a/stattest/experiment/experiment.py b/stattest/experiment/experiment.py index d1de113..7913619 100644 --- a/stattest/experiment/experiment.py +++ b/stattest/experiment/experiment.py @@ -4,7 +4,6 @@ from stattest.experiment.test.test_step import execute_test_step - class Experiment: def __init__(self, configuration: ExperimentConfiguration or str): self.__configuration = configuration @@ -25,4 +24,4 @@ def execute(self): execute_test_step(self.__configuration.test_configuration, rvs_store) # Generate reports - execute_report_step(self.__configuration.report_configuration) \ No newline at end of file + execute_report_step(self.__configuration.report_configuration) diff --git a/stattest/experiment/generator/generator_step.py b/stattest/experiment/generator/generator_step.py index 064ee8c..0a1a185 100644 --- a/stattest/experiment/generator/generator_step.py +++ b/stattest/experiment/generator/generator_step.py @@ -4,7 +4,7 @@ from multiprocessing import freeze_support, RLock import numpy as np -from tqdm import tqdm, trange +from tqdm import tqdm from stattest.experiment.configuration.configuration import AlternativeConfiguration from stattest.experiment.generator import AbstractRVSGenerator diff --git a/stattest/experiment/report/model.py b/stattest/experiment/report/model.py index 8d7e9eb..c66baf1 100644 --- a/stattest/experiment/report/model.py +++ b/stattest/experiment/report/model.py @@ -2,11 +2,10 @@ from matplotlib import pyplot as plt from stattest.experiment import ReportBuilder -from stattest.experiment.test.worker import PowerWorkerResult, BenchmarkWorkerResult +from stattest.experiment.test.worker import PowerWorkerResult from stattest.persistence.models import IBenchmarkResultStore -from stattest.persistence.sql_lite_store.power_result_store import PowerResultSqLiteStore - +""" class ChartBenchmarkMeanReportBuilder(ReportBuilder): def __init__(self): self.data = {} @@ -45,6 +44,7 @@ def build(self): @staticmethod def __build_path(result: BenchmarkWorkerResult): return '_'.join([result.test_code, str(result.size)]) +""" class ChartPowerReportBuilder(ReportBuilder): @@ -93,7 +93,7 @@ def build(self): class PowerResultReader: - def __init__(self, power_result_store: PowerResultSqLiteStore, batch_size=100): + def __init__(self, power_result_store, batch_size=100): self.power_result_store = power_result_store self.batch_size = batch_size self.offset = 0 diff --git a/stattest/persistence/file_store/critical_value_store.py b/stattest/persistence/file_store/critical_value_store.py index b874495..f5f83a1 100644 --- a/stattest/persistence/file_store/critical_value_store.py +++ b/stattest/persistence/file_store/critical_value_store.py @@ -5,7 +5,7 @@ from typing_extensions import override from stattest.persistence import ICriticalValueStore -from stattest.persistence.file_store.store import FastJsonStoreService, write_json, read_json +from stattest.persistence.file_store.store import write_json, read_json class CriticalValueFileStore(ICriticalValueStore): diff --git a/stattest/persistence/file_store/store.py b/stattest/persistence/file_store/store.py index 7c31560..ac45b5c 100644 --- a/stattest/persistence/file_store/store.py +++ b/stattest/persistence/file_store/store.py @@ -18,16 +18,16 @@ def get(self, key: str): """ Get cached value if exists, else return None. - :param key: cache key + :param key: cache_services key """ raise NotImplementedError("Method is not implemented") def put(self, key: str, value): """ - Put object to cache. + Put object to cache_services. - :param key: cache key - :param value: cache value + :param key: cache_services key + :param value: cache_services value """ raise NotImplementedError("Method is not implemented") @@ -44,7 +44,7 @@ def get(self, key: str): """ Get cached value if exists, else return None. - :param key: cache key + :param key: cache_services key """ if key not in self.cache.keys(): @@ -64,10 +64,10 @@ def get_with_level(self, keys: [str]): def put(self, key: str, value): """ - Put object to cache. + Put object to cache_services. - :param key: cache key - :param value: cache value + :param key: cache_services key + :param value: cache_services value """ self.cache[key] = value @@ -90,7 +90,7 @@ def _create_key(self, keys: [str]): class JsonStoreService(InMemoryStoreService): def __init__(self, filename='cache.json', separator='.'): - super().__init__(separator) + super().__init__(separator=separator) mem_cache = {} if os.path.isfile(filename): mem_cache = read_json(filename) @@ -100,10 +100,10 @@ def __init__(self, filename='cache.json', separator='.'): def put(self, key: str, value): """ - Put object to cache. + Put object to cache_services. - :param key: cache key - :param value: cache value + :param key: cache_services key + :param value: cache_services value """ super().put(key, value) write_json(self.filename, self.cache) @@ -132,7 +132,7 @@ def flush(self): class FastJsonStoreService(FastStoreService): def __init__(self, filename='cache.json', separator='.'): - super().__init__(separator) + super().__init__(separator=separator) mem_cache = {} if os.path.isfile(filename): mem_cache = read_json(filename) diff --git a/stattest/persistence/models.py b/stattest/persistence/models.py index 9b15d69..4d77958 100644 --- a/stattest/persistence/models.py +++ b/stattest/persistence/models.py @@ -143,7 +143,7 @@ def get_power(self, sl: float, size: int, test_code: str, alternative_code: str) :param test_code: test code :param alternative_code: alternative code - :return power on None + :return: power on None """ pass @@ -154,7 +154,7 @@ def get_powers(self, offset: int, limit: int): # -> [PowerResultModel]: :param offset: offset :param limit: limit - :return list of PowerResultModel + :return: list of PowerResultModel """ pass @@ -176,7 +176,7 @@ def get_benchmark(self, test_code: str, size: int) -> [float]: :param test_code: test code - :return benchmark on None + :return: benchmark on None """ pass @@ -187,6 +187,6 @@ def get_benchmarks(self, offset: int, limit: int): # -> [PowerResultModel]: :param offset: offset :param limit: limit - :return list of PowerResultModel + :return: list of PowerResultModel """ pass diff --git a/stattest/persistence/sql_lite_store/base.py b/stattest/persistence/sql_lite_store/base.py index 2704a5a..97a43b6 100644 --- a/stattest/persistence/sql_lite_store/base.py +++ b/stattest/persistence/sql_lite_store/base.py @@ -4,4 +4,4 @@ class ModelBase(DeclarativeBase): - pass \ No newline at end of file + pass diff --git a/stattest/persistence/sql_lite_store/benchmark_result_store.py b/stattest/persistence/sql_lite_store/benchmark_result_store.py index 943ede3..2af4434 100644 --- a/stattest/persistence/sql_lite_store/benchmark_result_store.py +++ b/stattest/persistence/sql_lite_store/benchmark_result_store.py @@ -56,7 +56,7 @@ def get_benchmark(self, test_code: str, size: int) -> [float]: :param test_code: test code - :return benchmark on None + :return: benchmark on None """ result = BenchmarkResultSqLiteStore.session.query(BenchmarkResultModel).filter( BenchmarkResultModel.test_code == test_code, @@ -75,7 +75,7 @@ def get_benchmarks(self, offset: int, limit: int): # -> [PowerResultModel]: :param offset: offset :param limit: limit - :return list of PowerResultModel + :return: list of PowerResultModel """ result = (BenchmarkResultSqLiteStore.session.query(BenchmarkResultModel) .order_by(BenchmarkResultModel.id).offset(offset).limit(limit)).all() diff --git a/stattest/persistence/sql_lite_store/db_init.py b/stattest/persistence/sql_lite_store/db_init.py index 81ccfef..af5eafc 100644 --- a/stattest/persistence/sql_lite_store/db_init.py +++ b/stattest/persistence/sql_lite_store/db_init.py @@ -78,5 +78,5 @@ def init_db(db_url: str) -> None: return engine # previous_tables = inspect(engine).get_table_names() - #ModelBase.metadata.create_all(engine) + # ModelBase.metadata.create_all(engine) # check_migrate(engine, decl_base=ModelBase, previous_tables=previous_tables) diff --git a/stattest/persistence/sql_lite_store/key_value_store.py b/stattest/persistence/sql_lite_store/key_value_store.py index 9dd9de7..7c0b5ec 100644 --- a/stattest/persistence/sql_lite_store/key_value_store.py +++ b/stattest/persistence/sql_lite_store/key_value_store.py @@ -10,6 +10,7 @@ ValueTypes = Union[str, datetime, float, int] + class ValueTypesEnum(str, Enum): STRING = "str" DATETIME = "datetime" @@ -183,4 +184,4 @@ def get_int_value(key: str) -> Optional[int]: ) if kv is None: return None - return kv.int_value \ No newline at end of file + return kv.int_value diff --git a/stattest/resolvers/hypothesis_resolver.py b/stattest/resolvers/hypothesis_resolver.py index 656822d..b0e7419 100644 --- a/stattest/resolvers/hypothesis_resolver.py +++ b/stattest/resolvers/hypothesis_resolver.py @@ -64,8 +64,8 @@ def _load_hypothesis( extra_dirs.append(extra_dir) abs_paths = HypothesisResolver.build_search_paths(user_data_dir=None, - user_subdir=USERPATH_GENERATORS, - extra_dirs=extra_dirs) + user_subdir=USERPATH_GENERATORS, + extra_dirs=extra_dirs) hypothesis = HypothesisResolver._load_object( paths=abs_paths, diff --git a/stattest/resolvers/iresolver.py b/stattest/resolvers/iresolver.py index 2b6d99d..ba51006 100644 --- a/stattest/resolvers/iresolver.py +++ b/stattest/resolvers/iresolver.py @@ -39,7 +39,7 @@ class IResolver: This class contains all the logic to load custom classes """ - # Childclasses need to override this + # Child classes need to override this object_type: type[Any] object_type_str: str user_subdir: Optional[str] = None @@ -155,8 +155,8 @@ def _search_object( obj[0].__file__ = str(entry) if add_source: obj[0].__source__ = obj[1] - return (obj[0], module_path) - return (None, None) + return obj[0], module_path + return None, None @classmethod def _load_object( diff --git a/stattest/test/common.py b/stattest/test/common.py index 6c0ae41..a4eaab7 100644 --- a/stattest/test/common.py +++ b/stattest/test/common.py @@ -1,4 +1,5 @@ import numpy as np +from abc import ABC import scipy.stats as scipy_stats from scipy import special from typing_extensions import override @@ -6,7 +7,7 @@ from stattest.test.models import AbstractTestStatistic -class KSTestStatistic(AbstractTestStatistic): +class KSTestStatistic(AbstractTestStatistic, ABC): def __init__(self, alternative='two-sided', mode='auto'): self.alternative = alternative @@ -14,10 +15,7 @@ def __init__(self, alternative='two-sided', mode='auto'): mode = 'exact' self.mode = mode - @staticmethod - def code(): - raise NotImplementedError("Method is not implemented") - + @override def execute_statistic(self, rvs, cdf_vals=None): """ Title: The Kolmogorov-Smirnov statistic for the Laplace distribution Ref. (book or article): Puig, @@ -36,6 +34,10 @@ def execute_statistic(self, rvs, cdf_vals=None): * 'asymp': uses asymptotic distribution of test statistic :param rvs: unsorted vector :return: + + Parameters + ---------- + cdf_vals """ # rvs = np.sort(rvs) n = len(rvs) @@ -71,6 +73,7 @@ def execute_statistic(self, rvs, cdf_vals=None): prob = np.clip(prob, 0, 1) return D + @override def calculate_critical_value(self, rvs_size, sl): return scipy_stats.distributions.kstwo.ppf(1 - sl, rvs_size) @@ -94,9 +97,11 @@ def __compute_dminus(cdf_vals, rvs): class ADTestStatistic(AbstractTestStatistic): @staticmethod + @override def code(): raise NotImplementedError("Method is not implemented") + @override def execute_statistic(self, rvs, log_cdf=None, log_sf=None, w=None): """ Title: The Anderson-Darling test Ref. (book or article): See package nortest and also Table 4.9 p. 127 in M. @@ -113,17 +118,17 @@ def execute_statistic(self, rvs, log_cdf=None, log_sf=None, w=None): return A2 -class LillieforsTest(KSTestStatistic): - - @staticmethod - def code(): - raise NotImplementedError("Method is not implemented") +class LillieforsTest(KSTestStatistic, ABC): + alternative = 'two-sided' + mode = 'auto' + @override def execute_statistic(self, z, cdf_vals=None): return super().execute_statistic(z, cdf_vals) -class CrammerVonMisesTestStatistic(AbstractTestStatistic): +class CrammerVonMisesTestStatistic(AbstractTestStatistic, ABC): + @override def execute_statistic(self, rvs, cdf_vals): n = len(rvs) @@ -133,7 +138,7 @@ def execute_statistic(self, rvs, cdf_vals): return w -class Chi2TestStatistic(AbstractTestStatistic): +class Chi2TestStatistic(AbstractTestStatistic, ABC): @staticmethod def _m_sum(a, *, axis, preserve_mask, xp): @@ -142,6 +147,7 @@ def _m_sum(a, *, axis, preserve_mask, xp): return sum if preserve_mask else np.asarray(sum) return xp.sum(a, axis=axis) + @override def execute_statistic(self, f_obs, f_exp, lambda_): # `terms` is the array of terms that are summed along `axis` to create # the test statistic. We use some specialized code for a few special @@ -163,11 +169,12 @@ def execute_statistic(self, f_obs, f_exp, lambda_): return terms.sum() + @override def calculate_critical_value(self, rvs_size, sl): return scipy_stats.distributions.chi2.ppf(1 - sl, rvs_size - 1) -class MinToshiyukiTestStatistic(AbstractTestStatistic): +class MinToshiyukiTestStatistic(AbstractTestStatistic, ABC): @override def execute_statistic(self, cdf_vals): @@ -180,3 +187,5 @@ def execute_statistic(self, cdf_vals): s = np.sum(d * np.sqrt(fi)) return s / np.sqrt(n) + +# TODO: fix signatures diff --git a/stattest/test/exponent.py b/stattest/test/exponent.py index e69de29..3132071 100644 --- a/stattest/test/exponent.py +++ b/stattest/test/exponent.py @@ -0,0 +1,829 @@ +import math +from typing_extensions import override +from abc import ABC + +from stattest.core.distribution import expon +import numpy as np +import scipy.special as scipy_special + +from stattest.test.goodness_of_fit import AbstractGoodnessOfFitTestStatistic + + +class AbstractExponentialityTestStatistic(AbstractGoodnessOfFitTestStatistic, ABC): + + def __init__(self, lam=1): + self.lam = lam + + @staticmethod + @override + def code(): + return 'EXPONENTIALITY' + '_' + super(AbstractGoodnessOfFitTestStatistic, + AbstractGoodnessOfFitTestStatistic).code() + + @override + def _generate(self, size): + return expon.generate_expon(size, self.lam) + + +class EPTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'EP' + '_' + super(EPTestExp, EPTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Epps and Pulley test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + ep : float + The test statistic. + """ + + n = len(rvs) + y = rvs / np.mean(rvs) + ep = np.sqrt(48 * n) * np.sum(np.exp(-y) - 1 / 2) / n + + return ep + + +class KSTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'KS' + '_' + super(KSTestExp, KSTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Kolmogorov and Smirnov test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + ks : float + The test statistic. + """ + + n = len(rvs) + y = rvs / np.mean(rvs) + z = np.sort(1 - np.exp(-y)) + j1 = np.arange(1, n + 1) / n + m1 = np.max(j1 - z) + j2 = (np.arange(0, n) + 1) / n + m2 = np.max(z - j2) + ks = max(m1, m2) # TODO: fix mistype + + return ks + + +class AHSTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'AHS' + '_' + super(AHSTestExp, AHSTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Statistic of the exponentiality test based on Ahsanullah characterization. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + a : float + The test statistic. + :param rvs: + """ + + n = len(rvs) + h = 0 + g = 0 + for k in range(n): + for i in range(n): + for j in range(n): + if abs(rvs[i] - rvs[j]) < rvs[k]: + h += 1 + if 2 * min(rvs[i], rvs[j]) < rvs[k]: + g += 1 + a = (h - g) / (n ** 3) + + return a + + +class ATKTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'ATK' + '_' + super(ATKTestExp, ATKTestExp).code() + + @override + def execute_statistic(self, rvs, p=0.99): + """ + Atkinson test statistic for exponentiality. + + Parameters + ---------- + p : float + Statistic parameter. + rvs : array_like + Array of sample data. + + Returns + ------- + atk : float + The test statistic. + """ + + n = len(rvs) + y = np.mean(rvs) + m = np.mean(np.power(rvs, p)) + r = (m ** (1 / p)) / y + atk = np.sqrt(n) * np.abs(r - scipy_special.gamma(1 + p) ** (1 / p)) + + return atk + + +class COTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'CO' + '_' + super(COTestExp, COTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Cox and Oakes test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + co : float + The test statistic. + :param rvs: + """ + + n = len(rvs) + y = rvs / np.mean(rvs) + y = np.log(y) * (1 - y) + co = np.sum(y) + n + + return co + + +class CVMTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'CVM' + '_' + super(CVMTestExp, CVMTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Cramer-von Mises test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + cvm : float + The test statistic. + """ + + n = len(rvs) + y = rvs / np.mean(rvs) + z = np.sort(1 - np.exp(-y)) + c = (2 * np.arange(1, n + 1) - 1) / (2 * n) + z = (z - c) ** 2 + cvm = 1 / (12 * n) + np.sum(z) + + return cvm + + +class DSPTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'DSP' + '_' + super(DSPTestExp, DSPTestExp).code() + + @override + def execute_statistic(self, rvs, b=0.44): + """ + Deshpande test statistic for exponentiality. + + Parameters + ---------- + b : float + Statistic parameter. + rvs : array_like + Array of sample data. + + Returns + ------- + des : float + The test statistic. + """ + + n = len(rvs) + des = 0 + for i in range(n): + for k in range(n): + if (i != k) and (rvs[i] > b * rvs[k]): + des += 1 + des /= (n * (n - 1)) + + return des + + +class EPSTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'EPS' + '_' + super(EPSTestExp, EPSTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Epstein test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + eps : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + x = np.concatenate(([0], rvs)) + d = (np.arange(n, 0, -1)) * (x[1:n + 1] - x[0:n]) + eps = 2 * n * (np.log(np.sum(d) / n) - (np.sum(np.log(d))) / n) / (1 + (n + 1) / (6 * n)) + + return eps + + +class FZTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'FZ' + '_' + super(FZTestExp, FZTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Frozini test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + froz : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + rvs = np.array(rvs) + y = np.mean(rvs) + froz = (1 / np.sqrt(n)) * np.sum(np.abs(1 - np.exp(-rvs / y) - (np.arange(1, n + 1) - 0.5) / n)) + + return froz + + +class GiniTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'Gini' + '_' + super(GiniTestExp, GiniTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Gini test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + gini : float + The test statistic. + """ + + n = len(rvs) + a = np.arange(1, n) + b = np.arange(n - 1, 0, -1) + a = a * b + x = np.sort(rvs) + k = x[1:] - x[:-1] + gini = np.sum(k * a) / ((n - 1) * np.sum(x)) + + return gini + + +class GDTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'GD' + '_' + super(GDTestExp, GDTestExp).code() + + @override + def execute_statistic(self, rvs, r=None): + """ + Gnedenko F-test statistic for exponentiality. + + Parameters + ---------- + r : float + Statistic parameter. + rvs : array_like + Array of sample data. + + Returns + ------- + gd : float + The test statistic. + """ + + if r is None: + r = round(len(rvs) / 2) + n = len(rvs) + x = np.sort(np.concatenate(([0], rvs))) + d = (np.arange(n, 0, -1)) * (x[1:n + 1] - x[0:n]) + gd = (sum(d[:r]) / r) / (sum(d[r:]) / (n - r)) + + return gd + + +class HMTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'HM' + '_' + super(HMTestExp, HMTestExp).code() + + @override + def execute_statistic(self, rvs, r=None): + """ + Harris' modification of Gnedenko F-test. + + Parameters + ---------- + r : float + Statistic parameter. + rvs : array_like + Array of sample data. + + Returns + ------- + hm : float + The test statistic. + """ + + if r is None: + r = round(len(rvs) / 4) + n = len(rvs) + x = np.sort(np.concatenate(([0], rvs))) + d = (np.arange(n, 0, -1)) * (x[1:n + 1] - x[:n]) + hm = ((np.sum(d[:r]) + np.sum(d[-r:])) / (2 * r)) / ((np.sum(d[r:-r])) / (n - 2 * r)) + + return hm + + +class HG1TestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'HG1' + '_' + super(HG1TestExp, HG1TestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Hegazy-Green 1 test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + hg : float + The test statistic. + """ + + n = len(rvs) + x = np.sort(rvs) + b = -np.log(1 - np.arange(1, n + 1) / (n + 1)) + hg = (n ** (-1)) * np.sum(np.abs(x - b)) + + return hg + + +class HPTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'HP' + '_' + super(HPTestExp, HPTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Hollander-Proshan test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + hp : float + The test statistic. + """ + + n = len(rvs) + t = 0 + for i in range(n): + for j in range(n): + for k in range(n): + if (i != j) and (i != k) and (j < k) and (rvs[i] > rvs[j] + rvs[k]): + t += 1 + hp = (2 / (n * (n - 1) * (n - 2))) * t + + return hp + + +class KMTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'KM' + '_' + super(KMTestExp, KMTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Kimber-Michael test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + km : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + y = np.mean(rvs) + s = (2 / np.pi) * np.arcsin(np.sqrt(1 - np.exp(-(rvs / y)))) + r = (2 / np.pi) * np.arcsin(np.sqrt((np.arange(1, n + 1) - 0.5) / n)) + km = max(abs(r - s)) + + return km + + +class KCTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'KC' + '_' + super(KCTestExp, KCTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Kochar test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + kc : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + u = np.array([(i + 1) / (n + 1) for i in range(n)]) + j = 2 * (1 - u) * (1 - np.log(1 - u)) - 1 + kc = np.sqrt(108 * n / 17) * (np.sum(j * rvs)) / np.sum(rvs) + + return kc + + +class LZTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'LZ' + '_' + super(LZTestExp, LZTestExp).code() + + @override + def execute_statistic(self, rvs, p=0.5): + """ + Lorenz test statistic for exponentiality. + + Parameters + ---------- + p : float + Statistic parameter. + rvs : array_like + Array of sample data. + + Returns + ------- + lz : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + lz = sum(rvs[:int(n * p)]) / sum(rvs) + + return lz + + +class MNTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'MN' + '_' + super(MNTestExp, MNTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Moran test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + mn : float + The test statistic. + """ + + # n = len(rvs) + y = np.mean(rvs) + mn = -scipy_special.digamma(1) + np.mean(np.log(rvs / y)) + + return mn + + +class PTTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'PT' + '_' + super(PTTestExp, PTTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Pietra test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + pt : float + The test statistic. + """ + + n = len(rvs) + xm = np.mean(rvs) + pt = np.sum(np.abs(rvs - xm)) / (2 * n * xm) + + return pt + + +class SWTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'SW' + '_' + super(SWTestExp, SWTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Shapiro-Wilk test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + sw : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + y = np.mean(rvs) + sw = n * (y - rvs[0]) ** 2 / ((n - 1) * np.sum((rvs - y) ** 2)) + + return sw + + +class RSTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'RS' + '_' + super(RSTestExp, RSTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Statistic of the exponentiality test based on Rossberg characterization. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + rs : float + The test statistic. + """ + + n = len(rvs) + sh = 0 + sg = 0 + for m in range(n): + h = 0 + for i in range(n - 2): + for j in range(i + 1, n - 1): + for k in range(j + 1, n): + if (rvs[i] + rvs[j] + rvs[k] - 2 * min(rvs[i], rvs[j], rvs[k]) - max(rvs[i], rvs[j], rvs[k]) < + rvs[m]): + h += 1 + h = ((6 * math.factorial(n - 3)) / math.factorial(n)) * h + sh += h + for m in range(n): + g = 0 + for i in range(n - 1): + for j in range(i + 1, n): + if min(rvs[i], rvs[j]) < rvs[m]: + g += 1 + g = ((2 * math.factorial(n - 2)) / math.factorial(n)) * g + sg += g + rs = sh - sg + rs /= n + + return rs + + +class WETestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'WE' + '_' + super(WETestExp, WETestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + WE test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + we : float + The test statistic. + """ + + n = len(rvs) + m = np.mean(rvs) + v = np.var(rvs) + we = (n - 1) * v / (n ** 2 * m ** 2) + + return we + + +class WWTestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'WW' + '_' + super(WWTestExp, WWTestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Wong and Wong test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + ww : float + The test statistic. + """ + + # n = len(rvs) + ww = max(rvs) / min(rvs) + + return ww + + +class HG2TestExp(AbstractExponentialityTestStatistic): + + @staticmethod + @override + def code(): + return 'HG2' + '_' + super(HG2TestExp, HG2TestExp).code() + + @override + def execute_statistic(self, rvs, **kwargs): + """ + Hegazy-Green 2 test statistic for exponentiality. + + Parameters + ---------- + rvs : array_like + Array of sample data. + + Returns + ------- + hg : float + The test statistic. + """ + + n = len(rvs) + rvs.sort() + b = -np.log(1 - np.arange(1, n + 1) / (n + 1)) + hg = (n ** (-1)) * np.sum((rvs - b) ** 2) + + return hg + +# TODO: check all mistype warnings diff --git a/stattest/test/goodness_of_fit.py b/stattest/test/goodness_of_fit.py new file mode 100644 index 0000000..3625957 --- /dev/null +++ b/stattest/test/goodness_of_fit.py @@ -0,0 +1,21 @@ +from typing_extensions import override + +from stattest.test.models import AbstractTestStatistic +from abc import ABC + + +class AbstractGoodnessOfFitTestStatistic(AbstractTestStatistic, ABC): + + @staticmethod + @override + def code(): + return 'GOODNESS_OF_FIT' + + def _generate(self, size): + raise NotImplementedError("Method is not implemented") + + def test(self, rvs, alpha): # TODO: separate abstract class for testing? + x_cr = self.calculate_critical_value(len(rvs), alpha) + statistic = self.execute_statistic(rvs) + + return False if statistic > x_cr else True diff --git a/stattest/test/models.py b/stattest/test/models.py index 1e1aabf..3865164 100644 --- a/stattest/test/models.py +++ b/stattest/test/models.py @@ -1,15 +1,18 @@ from numpy import float64 from typing_extensions import Optional +from abc import ABC, abstractmethod -class AbstractTestStatistic: +class AbstractTestStatistic(ABC): @staticmethod + @abstractmethod def code() -> str: """ Generate code for test statistic. """ raise NotImplementedError("Method is not implemented") + @abstractmethod def execute_statistic(self, rvs, **kwargs) -> float or float64: """ Execute test statistic and return calculated statistic value. diff --git a/stattest/test/normal.py b/stattest/test/normal.py index 702f3ad..f566ebe 100644 --- a/stattest/test/normal.py +++ b/stattest/test/normal.py @@ -1,104 +1,79 @@ import math +from typing_extensions import override from stattest.core.distribution import norm import numpy as np import scipy.stats as scipy_stats import pandas as pd -from stattest.test import AbstractTestStatistic -from stattest.persistence.file_store.critical_value_store import CriticalValueFileStore +from stattest.test.goodness_of_fit import AbstractGoodnessOfFitTestStatistic from stattest.test.common import KSTestStatistic, ADTestStatistic, LillieforsTest +from abc import ABC -class AbstractNormalityTestStatistic(AbstractTestStatistic): +class AbstractNormalityTestStatistic(AbstractGoodnessOfFitTestStatistic, ABC): + @override + def __init__(self, mean=0, var=1): + self.mean = mean + self.var = var - def __init__(self, cache=CriticalValueFileStore()): - self.mean = 0 - self.var = 1 - self.cache = cache - - def calculate_critical_value(self, rvs_size, sl, count=1_000_000): - keys_cr = [self.code(), str(rvs_size), str(sl)] - x_cr = self.cache.get_with_level(keys_cr) - if x_cr is not None: - return x_cr - - d = self.cache.get_distribution(self.code(), rvs_size) - if d is not None: - ecdf = scipy_stats.ecdf(d) - x_cr = np.quantile(ecdf.cdf.quantiles, q=1 - sl) - self.cache.put_with_level(keys_cr, x_cr) - self.cache.flush() - return x_cr - - result = np.zeros(count) - - for i in range(count): - x = self.generate(size=rvs_size, mean=self.mean, var=self.var) - result[i] = self.execute_statistic(x) - - result.sort() - - ecdf = scipy_stats.ecdf(result) - x_cr = np.quantile(ecdf.cdf.quantiles, q=1 - sl) - self.cache.put_with_level(keys_cr, x_cr) - self.cache.put_distribution(self.code(), rvs_size, result) - self.cache.flush() - return x_cr - - def test(self, rvs, alpha): - x_cr = self.calculate_critical_value(len(rvs), alpha) - statistic = self.execute_statistic(rvs) - - return False if statistic > x_cr else True + @staticmethod + @override + def code(): + return 'NORMALITY' + '_' + super(AbstractGoodnessOfFitTestStatistic, AbstractGoodnessOfFitTestStatistic).code() - def generate(self, size, mean=0, var=1): - return norm.generate_norm(size, mean, var) +class KSNormalityTest(AbstractNormalityTestStatistic, KSTestStatistic): + @override + def __init__(self, alternative='two-sided', mode='auto', mean=0, var=1): + AbstractNormalityTestStatistic.__init__(self) + KSTestStatistic.__init__(self, alternative, mode) -class KSNormalityTest(KSTestStatistic): + self.mean = mean + self.var = var @staticmethod + @override def code(): - return 'KS_NORMALITY' + return 'KS' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): rvs = np.sort(rvs) cdf_vals = scipy_stats.norm.cdf(rvs) - return super().execute_statistic(rvs, cdf_vals) + return KSTestStatistic.execute_statistic(self, rvs, cdf_vals) # TODO: should test it """"" -class ChiSquareTest(AbstractNormalityTest): +class ChiSquareTest(AbstractNormalityTestStatistic): # TODO: check test correctness @staticmethod + @override def code(): - return 'CHI2' + return 'CHI2' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): rvs = np.sort(rvs) f_obs = np.asanyarray(rvs) f_obs_float = f_obs.astype(np.float64) - f_exp = pdf_norm(rvs) - scipy_stats.chi2_contingency() + f_exp = pdf_norm(rvs) # TODO: remove link to ext package + scipy_stats.chi2_contingency() # TODO: fix warning!! terms = (f_obs_float - f_exp) ** 2 / f_exp return terms.sum(axis=0) """"" -# Values from Stephens, M A, "EDF Statistics for Goodness of Fit and -# Some Comparisons", Journal of the American Statistical -# Association, Vol. 69, Issue 347, Sept. 1974, pp 730-737 -_Avals_norm = np.array([0.576, 0.656, 0.787, 0.918, 1.092]) - -class ADNormalityTest(ADTestStatistic): +class ADNormalityTest(AbstractNormalityTestStatistic, ADTestStatistic): @staticmethod + @override def code(): - return 'AD_NORMALITY' + return 'AD' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): s = np.std(rvs, ddof=1, axis=0) y = np.sort(rvs) xbar = np.mean(rvs, axis=0) @@ -107,23 +82,24 @@ def execute_statistic(self, rvs): logsf = scipy_stats.distributions.norm.logsf return super().execute_statistic(rvs, log_cdf=logcdf, log_sf=logsf, w=w) - -""" - def calculate_critical_value(self, rvs_size, alpha, count=500_000): + @override + def calculate_critical_value(self, rvs_size, sl, count=500_000): # TODO: check test correctness # sig = [0.15, 0.10, 0.05, 0.025, 0.01].index(alpha) # critical = np.around(_Avals_norm / (1.0 + 4.0 / rvs_size - 25.0 / rvs_size / rvs_size), 3) # print(critical[sig]) - return super().calculate_critical_value(rvs_size, alpha) -""" + # return super().calculate_critical_value(rvs_size, alpha) + raise NotImplementedError("Not implemented") -class SWTest(AbstractNormalityTestStatistic): +class SWNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'SW' + return 'SW' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): f_obs = np.asanyarray(rvs) f_obs_sorted = np.sort(f_obs) x_mean = np.mean(f_obs) @@ -152,7 +128,8 @@ def ordered_statistic(n): u = 1 / np.sqrt(n) wn = np.polyval(p1, u) - # wn = np.array([p1[0] * (u ** 5), p1[1] * (u ** 4), p1[2] * (u ** 3), p1[3] * (u ** 2), p1[4] * (u ** 1), p1[5]]).sum() + # wn = np.array([p1[0] * (u ** 5), p1[1] * (u ** 4), p1[2] * (u ** 3), p1[3] * (u ** 2), + # p1[4] * (u ** 1), p1[5]]).sum() w1 = -wn if n == 4 or n == 5: @@ -172,13 +149,15 @@ def ordered_statistic(n): return np.concatenate([[w1, w2], result, [wn1, wn]]) -class CVMTest(AbstractNormalityTestStatistic): +class CVMNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'CVM' + return 'CVM' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) rvs = np.sort(rvs) @@ -186,32 +165,35 @@ def execute_statistic(self, rvs): cdf_vals = scipy_stats.norm.cdf(vals) u = (2 * np.arange(1, n + 1) - 1) / (2 * n) - CM = 1 / (12 * n) + np.sum((u - cdf_vals) ** 2) - return CM + cm = 1 / (12 * n) + np.sum((u - cdf_vals) ** 2) + return cm -class LillieforsNormalityTest(LillieforsTest): +class LillieforsNormalityTest(AbstractNormalityTestStatistic, LillieforsTest): @staticmethod + @override def code(): - return 'LILLIE_NORMALITY' + return 'LILLIE' + '_' + super(AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): x = np.asarray(rvs) z = (x - x.mean()) / x.std(ddof=1) cdf_vals = scipy_stats.norm.cdf(np.sort(z)) - return super().execute_statistic(rvs, cdf_vals) + return super(LillieforsTest, self).execute_statistic(rvs, cdf_vals) -# TODO: What is it """ -class DATest(AbstractNormalityTest): +class DANormalityTest(AbstractNormalityTestStatistic): # TODO: check for correctness @staticmethod + @override def code(): - return 'DA' + return 'DA' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): x = np.asanyarray(rvs) y = np.sort(x) n = len(x) @@ -226,13 +208,14 @@ def execute_statistic(self, rvs): """ -class JBTest(AbstractNormalityTestStatistic): - +class JBNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'JB' + return 'JB' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): x = np.asarray(rvs) x = x.ravel() axis = 0 @@ -249,13 +232,14 @@ def execute_statistic(self, rvs): return statistic -class SkewTest(AbstractNormalityTestStatistic): - +class SkewNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'SKEW' + return 'SKEW' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): x = np.asanyarray(rvs) y = np.sort(x) @@ -272,22 +256,23 @@ def skew_test(a): y = b2 * math.sqrt(((n + 1) * (n + 3)) / (6.0 * (n - 2))) beta2 = (3.0 * (n ** 2 + 27 * n - 70) * (n + 1) * (n + 3) / ((n - 2.0) * (n + 5) * (n + 7) * (n + 9))) - W2 = -1 + math.sqrt(2 * (beta2 - 1)) - delta = 1 / math.sqrt(0.5 * math.log(W2)) - alpha = math.sqrt(2.0 / (W2 - 1)) + w2 = -1 + math.sqrt(2 * (beta2 - 1)) + delta = 1 / math.sqrt(0.5 * math.log(w2)) + alpha = math.sqrt(2.0 / (w2 - 1)) y = np.where(y == 0, 1, y) - Z = delta * np.log(y / alpha + np.sqrt((y / alpha) ** 2 + 1)) - - return Z + z = delta * np.log(y / alpha + np.sqrt((y / alpha) ** 2 + 1)) + return z -class KurtosisTest(AbstractNormalityTestStatistic): +class KurtosisNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'KURTOSIS' + return 'KURTOSIS' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): x = np.asanyarray(rvs) y = np.sort(x) @@ -306,35 +291,36 @@ def kurtosis_test(a): # stacklevel=2) b2 = scipy_stats.kurtosis(a, axis=0, fisher=False) - E = 3.0 * (n - 1) / (n + 1) - varb2 = 24.0 * n * (n - 2) * (n - 3) / ((n + 1) * (n + 1.) * (n + 3) * (n + 5)) # [1]_ Eq. 1 - x = (b2 - E) / np.sqrt(varb2) # [1]_ Eq. 4 + e = 3.0 * (n - 1) / (n + 1) + var_b2 = 24.0 * n * (n - 2) * (n - 3) / ((n + 1) * (n + 1.) * (n + 3) * (n + 5)) # [1]_ Eq. 1 + x = (b2 - e) / np.sqrt(var_b2) # [1]_ Eq. 4 # [1]_ Eq. 2: - sqrtbeta1 = 6.0 * (n * n - 5 * n + 2) / ((n + 7) * (n + 9)) * np.sqrt((6.0 * (n + 3) * (n + 5)) / - (n * (n - 2) * (n - 3))) + sqrt_beta1 = 6.0 * (n * n - 5 * n + 2) / ((n + 7) * (n + 9)) * np.sqrt((6.0 * (n + 3) * (n + 5)) / + (n * (n - 2) * (n - 3))) # [1]_ Eq. 3: - A = 6.0 + 8.0 / sqrtbeta1 * (2.0 / sqrtbeta1 + np.sqrt(1 + 4.0 / (sqrtbeta1 ** 2))) - term1 = 1 - 2 / (9.0 * A) - denom = 1 + x * np.sqrt(2 / (A - 4.0)) + a = 6.0 + 8.0 / sqrt_beta1 * (2.0 / sqrt_beta1 + np.sqrt(1 + 4.0 / (sqrt_beta1 ** 2))) + term1 = 1 - 2 / (9.0 * a) + denom = 1 + x * np.sqrt(2 / (a - 4.0)) term2 = np.sign(denom) * np.where(denom == 0.0, np.nan, - np.power((1 - 2.0 / A) / np.abs(denom), 1 / 3.0)) + np.power((1 - 2.0 / a) / np.abs(denom), 1 / 3.0)) # if np.any(denom == 0): # msg = ("Test statistic not defined in some cases due to division by " # "zero. Return nan in that case...") # warnings.warn(msg, RuntimeWarning, stacklevel=2) - Z = (term1 - term2) / np.sqrt(2 / (9.0 * A)) # [1]_ Eq. 5 - - return Z + z = (term1 - term2) / np.sqrt(2 / (9.0 * a)) # [1]_ Eq. 5 + return z -class DAPTest(SkewTest, KurtosisTest): +class DAPNormalityTest(SkewNormalityTest, KurtosisNormalityTest): @staticmethod + @override def code(): - return 'DAP' + return 'DAP' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): x = np.asanyarray(rvs) y = np.sort(x) @@ -345,13 +331,14 @@ def execute_statistic(self, rvs): # https://github.com/puzzle-in-a-mug/normtest -class FilliTest(AbstractNormalityTestStatistic): - +class FilliNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'Filli' + return 'Filli' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): uniform_order = self._uniform_order_medians(len(rvs)) zi = self._normal_order_medians(uniform_order) x_data = np.sort(rvs) @@ -379,13 +366,14 @@ def _statistic(x_data, zi): # https://github.com/puzzle-in-a-mug/normtest -class LooneyGulledgeTest(AbstractNormalityTestStatistic): - +class LooneyGulledgeNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'LG' + return 'LG' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): # ordering x_data = np.sort(rvs) @@ -407,13 +395,13 @@ def _normal_order_statistic(x_data, weighted=False): df = pd.DataFrame({"x_data": x_data}) # getting mi values df["Rank"] = np.arange(1, df.shape[0] + 1) - df["Ui"] = LooneyGulledgeTest._order_statistic( + df["Ui"] = LooneyGulledgeNormalityTest._order_statistic( sample_size=x_data.size, ) df["Mi"] = df.groupby(["x_data"])["Ui"].transform("mean") normal_ordered = scipy_stats.norm.ppf(df["Mi"]) else: - ordered = LooneyGulledgeTest._order_statistic( + ordered = LooneyGulledgeNormalityTest._order_statistic( sample_size=x_data.size, ) normal_ordered = scipy_stats.norm.ppf(ordered) @@ -433,17 +421,20 @@ def _order_statistic(sample_size): # https://github.com/puzzle-in-a-mug/normtest -class RyanJoinerTest(AbstractNormalityTestStatistic): +class RyanJoinerNormalityTest(AbstractNormalityTestStatistic): + @override def __init__(self, weighted=False, cte_alpha="3/8"): - super().__init__() + super(AbstractNormalityTestStatistic).__init__() self.weighted = weighted self.cte_alpha = cte_alpha @staticmethod + @override def code(): - return 'RJ' + return 'RJ' + '_' + super(AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): # ordering x_data = np.sort(rvs) @@ -497,13 +488,14 @@ def _order_statistic(sample_size, cte_alpha="3/8"): return (i - cte_alpha) / (sample_size - 2 * cte_alpha + 1) -class SFTest(AbstractNormalityTestStatistic): - +class SFNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'SF' + return 'SF' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) rvs = np.sort(rvs) @@ -517,70 +509,72 @@ def execute_statistic(self, rvs): # https://habr.com/ru/articles/685582/ -class EPTest(AbstractNormalityTestStatistic): - +class EPNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'EP' + return 'EP' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) - X = np.sort(rvs) - X_mean = np.mean(X) - m2 = np.var(X, ddof=0) + x = np.sort(rvs) + x_mean = np.mean(x) + m2 = np.var(x, ddof=0) - A = np.sqrt(2) * np.sum([np.exp(-(X[i] - X_mean) ** 2 / (4 * m2)) for i in range(n)]) - B = 0 + a = np.sqrt(2) * np.sum([np.exp(-(x[i] - x_mean) ** 2 / (4 * m2)) for i in range(n)]) + b = 0 for k in range(1, n): - B = B + np.sum(np.exp(-(X[:k] - X[k]) ** 2 / (2 * m2))) - B = 2 / n * B - t = 1 + n / np.sqrt(3) + B - A + b = b + np.sum(np.exp(-(x[:k] - x[k]) ** 2 / (2 * m2))) + b = 2 / n * b + t = 1 + n / np.sqrt(3) + b - a return t -class Hosking2Test(AbstractNormalityTestStatistic): - +class Hosking2NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'HOSKING2' + return 'HOSKING2' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: - - xtmp = [0] * n + x_tmp = [0] * n l21, l31, l41 = 0.0, 0.0, 0.0 - mutau41, vtau31, vtau41 = 0.0, 0.0, 0.0 + mu_tau41, v_tau31, v_tau41 = 0.0, 0.0, 0.0 for i in range(n): - xtmp[i] = rvs[i] - xtmp = np.sort(xtmp) + x_tmp[i] = rvs[i] + x_tmp = np.sort(x_tmp) for i in range(2, n): - l21 += xtmp[i - 1] * self.pstarmod1(2, n, i) - l31 += xtmp[i - 1] * self.pstarmod1(3, n, i) - l41 += xtmp[i - 1] * self.pstarmod1(4, n, i) + l21 += x_tmp[i - 1] * self.pstarmod1(2, n, i) + l31 += x_tmp[i - 1] * self.pstarmod1(3, n, i) + l41 += x_tmp[i - 1] * self.pstarmod1(4, n, i) l21 = l21 / (2.0 * math.comb(n, 4)) l31 = l31 / (3.0 * math.comb(n, 5)) l41 = l41 / (4.0 * math.comb(n, 6)) tau31 = l31 / l21 tau41 = l41 / l21 if 1 <= n <= 25: - mutau41 = 0.067077 - vtau31 = 0.0081391 - vtau41 = 0.0042752 + mu_tau41 = 0.067077 + v_tau31 = 0.0081391 + v_tau41 = 0.0042752 if 25 < n <= 50: - mutau41 = 0.064456 - vtau31 = 0.0034657 - vtau41 = 0.0015699 + mu_tau41 = 0.064456 + v_tau31 = 0.0034657 + v_tau41 = 0.0015699 if 50 < n: - mutau41 = 0.063424 - vtau31 = 0.0016064 - vtau41 = 0.00068100 - return pow(tau31, 2.0) / vtau31 + pow(tau41 - mutau41, 2.0) / vtau41 + mu_tau41 = 0.063424 + v_tau31 = 0.0016064 + v_tau41 = 0.00068100 + return pow(tau31, 2.0) / v_tau31 + pow(tau41 - mu_tau41, 2.0) / v_tau41 return 0 - def pstarmod1(self, r, n, i): + @staticmethod + def pstarmod1(r, n, i): res = 0.0 for k in range(r): res = res + (-1.0) ** k * math.comb(r - 1, k) * math.comb(i - 1, r + 1 - 1 - k) * math.comb(n - i, 1 + k) @@ -588,28 +582,30 @@ def pstarmod1(self, r, n, i): return res -class Hosking1Test(AbstractNormalityTestStatistic): - +class Hosking1NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'HOSKING1' + return 'HOSKING1' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat10(rvs) - def stat10(self, x): + @staticmethod + def stat10(x): n = len(x) if n > 3: - xtmp = x[:n].copy() - xtmp.sort() + x_tmp = x[:n].copy() + x_tmp.sort() tmp1 = n * (n - 1) tmp2 = tmp1 * (n - 2) tmp3 = tmp2 * (n - 3) - b0 = sum(xtmp[:3]) + sum(xtmp[3:]) - b1 = 1.0 * xtmp[1] + 2.0 * xtmp[2] + sum(i * xtmp[i] for i in range(3, n)) - b2 = 2.0 * xtmp[2] + sum((i * (i - 1)) * xtmp[i] for i in range(3, n)) - b3 = sum((i * (i - 1) * (i - 2)) * xtmp[i] for i in range(3, n)) + b0 = sum(x_tmp[:3]) + sum(x_tmp[3:]) + b1 = 1.0 * x_tmp[1] + 2.0 * x_tmp[2] + sum(i * x_tmp[i] for i in range(3, n)) + b2 = 2.0 * x_tmp[2] + sum((i * (i - 1)) * x_tmp[i] for i in range(3, n)) + b3 = sum((i * (i - 1) * (i - 2)) * x_tmp[i] for i in range(3, n)) b0 /= n b1 /= tmp1 b2 /= tmp2 @@ -621,44 +617,45 @@ def stat10(self, x): tau4 = l4 / l2 if 1 <= n <= 25: - mutau4 = 0.12383 - vtau3 = 0.0088038 - vtau4 = 0.0049295 + mu_tau4 = 0.12383 + v_tau3 = 0.0088038 + v_tau4 = 0.0049295 elif 25 < n <= 50: - mutau4 = 0.12321 - vtau3 = 0.0040493 - vtau4 = 0.0020802 + mu_tau4 = 0.12321 + v_tau3 = 0.0040493 + v_tau4 = 0.0020802 else: - mutau4 = 0.12291 - vtau3 = 0.0019434 - vtau4 = 0.00095785 + mu_tau4 = 0.12291 + v_tau3 = 0.0019434 + v_tau4 = 0.00095785 - statTLmom = (tau3 ** 2) / vtau3 + (tau4 - mutau4) ** 2 / vtau4 - return statTLmom + stat_tl_mom = (tau3 ** 2) / v_tau3 + (tau4 - mu_tau4) ** 2 / v_tau4 + return stat_tl_mom -class Hosking3Test(AbstractNormalityTestStatistic): - +class Hosking3NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'HOSKING3' + return 'HOSKING3' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat12(rvs) def stat12(self, x): n = len(x) if n > 3: - xtmp = x[:n] - xtmp.sort() + x_tmp = x[:n] + x_tmp.sort() l22 = 0.0 l32 = 0.0 l42 = 0.0 for i in range(2, n): - l22 += xtmp[i - 1] * self.pstarmod2(2, n, i) - l32 += xtmp[i - 1] * self.pstarmod2(3, n, i) - l42 += xtmp[i - 1] * self.pstarmod2(4, n, i) + l22 += x_tmp[i - 1] * self.pstarmod2(2, n, i) + l32 += x_tmp[i - 1] * self.pstarmod2(3, n, i) + l42 += x_tmp[i - 1] * self.pstarmod2(4, n, i) l22 /= 2.0 * math.comb(n, 6) l32 /= 3.0 * math.comb(n, 7) l42 /= 4.0 * math.comb(n, 8) @@ -666,50 +663,52 @@ def stat12(self, x): tau42 = l42 / l22 if 1 <= n <= 25: - mutau42 = 0.044174 - vtau32 = 0.0086570 - vtau42 = 0.0042066 + mu_tau42 = 0.044174 + v_tau32 = 0.0086570 + v_tau42 = 0.0042066 elif 25 < n <= 50: - mutau42 = 0.040389 - vtau32 = 0.0033818 - vtau42 = 0.0013301 + mu_tau42 = 0.040389 + v_tau32 = 0.0033818 + v_tau42 = 0.0013301 else: - mutau42 = 0.039030 - vtau32 = 0.0015120 - vtau42 = 0.00054207 + mu_tau42 = 0.039030 + v_tau32 = 0.0015120 + v_tau42 = 0.00054207 - statTLmom2 = (tau32 ** 2) / vtau32 + (tau42 - mutau42) ** 2 / vtau42 - return statTLmom2 + stat_tl_mom2 = (tau32 ** 2) / v_tau32 + (tau42 - mu_tau42) ** 2 / v_tau42 + return stat_tl_mom2 - def pstarmod2(self, r, n, i): + @staticmethod + def pstarmod2(r, n, i): res = 0.0 for k in range(r): res += (-1) ** k * math.comb(r - 1, k) * math.comb(i - 1, r + 2 - 1 - k) * math.comb(n - i, 2 + k) return res -class Hosking4Test(AbstractNormalityTestStatistic): - +class Hosking4NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'HOSKING4' + return 'HOSKING4' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat13(rvs) def stat13(self, x): n = len(x) if n > 3: - xtmp = x[:n] - xtmp.sort() + x_tmp = x[:n] + x_tmp.sort() l23 = 0.0 l33 = 0.0 l43 = 0.0 for i in range(2, n): - l23 += xtmp[i - 1] * self.pstarmod3(2, n, i) - l33 += xtmp[i - 1] * self.pstarmod3(3, n, i) - l43 += xtmp[i - 1] * self.pstarmod3(4, n, i) + l23 += x_tmp[i - 1] * self.pstarmod3(2, n, i) + l33 += x_tmp[i - 1] * self.pstarmod3(3, n, i) + l43 += x_tmp[i - 1] * self.pstarmod3(4, n, i) l23 /= 2.0 * math.comb(n, 8) l33 /= 3.0 * math.comb(n, 9) l43 /= 4.0 * math.comb(n, 10) @@ -717,109 +716,114 @@ def stat13(self, x): tau43 = l43 / l23 if 1 <= n <= 25: - mutau43 = 0.033180 - vtau33 = 0.0095765 - vtau43 = 0.0044609 + mu_tau43 = 0.033180 + v_tau33 = 0.0095765 + v_tau43 = 0.0044609 elif 25 < n <= 50: - mutau43 = 0.028224 - vtau33 = 0.0033813 - vtau43 = 0.0011823 + mu_tau43 = 0.028224 + v_tau33 = 0.0033813 + v_tau43 = 0.0011823 else: - mutau43 = 0.026645 - vtau33 = 0.0014547 - vtau43 = 0.00045107 + mu_tau43 = 0.026645 + v_tau33 = 0.0014547 + v_tau43 = 0.00045107 - statTLmom3 = (tau33 ** 2) / vtau33 + (tau43 - mutau43) ** 2 / vtau43 - return statTLmom3 + stat_tl_mom3 = (tau33 ** 2) / v_tau33 + (tau43 - mu_tau43) ** 2 / v_tau43 + return stat_tl_mom3 - def pstarmod3(self, r, n, i): + @staticmethod + def pstarmod3(r, n, i): res = 0.0 for k in range(r): res += (-1) ** k * math.comb(r - 1, k) * math.comb(i - 1, r + 3 - 1 - k) * math.comb(n - i, 3 + k) return res -class ZhangWuCTest(AbstractNormalityTestStatistic): - +class ZhangWuCNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'ZWC' + return 'ZWC' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: - Phiz = np.zeros(n) - meanX = np.mean(rvs) - varX = np.var(rvs, ddof=1) - sdX = np.sqrt(varX) + phiz = np.zeros(n) + mean_x = np.mean(rvs) + var_x = np.var(rvs, ddof=1) + sd_x = np.sqrt(var_x) for i in range(n): - Phiz[i] = scipy_stats.norm.cdf((rvs[i] - meanX) / sdX) - Phiz.sort() - statZC = 0.0 + phiz[i] = scipy_stats.norm.cdf((rvs[i] - mean_x) / sd_x) + phiz.sort() + stat_zc = 0.0 for i in range(1, n + 1): - statZC += np.log((1.0 / Phiz[i - 1] - 1.0) / ((n - 0.5) / (i - 0.75) - 1.0)) ** 2 - return statZC + stat_zc += np.log((1.0 / phiz[i - 1] - 1.0) / ((n - 0.5) / (i - 0.75) - 1.0)) ** 2 + return stat_zc -class ZhangWuATest(AbstractNormalityTestStatistic): - +class ZhangWuANormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'ZWA' + return 'ZWA' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: - Phiz = np.zeros(n) - meanX = np.mean(rvs) - varX = np.var(rvs) - sdX = np.sqrt(varX) + phiz = np.zeros(n) + mean_x = np.mean(rvs) + var_x = np.var(rvs) + sd_x = np.sqrt(var_x) for i in range(n): - Phiz[i] = scipy_stats.norm.cdf((rvs[i] - meanX) / sdX) - Phiz.sort() - statZA = 0.0 + phiz[i] = scipy_stats.norm.cdf((rvs[i] - mean_x) / sd_x) + phiz.sort() + stat_za = 0.0 for i in range(1, n + 1): - statZA += np.log(Phiz[i - 1]) / ((n - i) + 0.5) + np.log(1.0 - Phiz[i - 1]) / ((i - 0.5)) - statZA = -statZA - statZA = 10.0 * statZA - 32.0 - return statZA - + stat_za += np.log(phiz[i - 1]) / ((n - i) + 0.5) + np.log(1.0 - phiz[i - 1]) / (i - 0.5) + stat_za = -stat_za + stat_za = 10.0 * stat_za - 32.0 + return stat_za -class GlenLeemisBarrTest(AbstractNormalityTestStatistic): +class GlenLeemisBarrNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'GLB' + return 'GLB' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: - Phiz = np.zeros(n) - meanX = np.mean(rvs) - varX = np.var(rvs, ddof=1) - sdX = np.sqrt(varX) + phiz = np.zeros(n) + mean_x = np.mean(rvs) + var_x = np.var(rvs, ddof=1) + sd_x = np.sqrt(var_x) for i in range(n): - Phiz[i] = scipy_stats.norm.cdf((rvs[i] - meanX) / sdX) - Phiz.sort() + phiz[i] = scipy_stats.norm.cdf((rvs[i] - mean_x) / sd_x) + phiz.sort() for i in range(1, n + 1): - Phiz[i - 1] = scipy_stats.beta.cdf(Phiz[i - 1], i, n - i + 1) - Phiz.sort() - statPS = 0 + phiz[i - 1] = scipy_stats.beta.cdf(phiz[i - 1], i, n - i + 1) + phiz.sort() + stat_ps = 0 for i in range(1, n + 1): - statPS += (2 * n + 1 - 2 * i) * np.log(Phiz[i - 1]) + (2 * i - 1) * np.log(1 - Phiz[i - 1]) - return -n - statPS / n + stat_ps += (2 * n + 1 - 2 * i) * np.log(phiz[i - 1]) + (2 * i - 1) * np.log(1 - phiz[i - 1]) + return -n - stat_ps / n -class DoornikHansenTest(AbstractNormalityTestStatistic): - +class DoornikHansenNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'DH' + return 'DH' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.doornik_hansen(rvs) def doornik_hansen(self, x): @@ -837,7 +841,8 @@ def doornik_hansen(self, x): stat = z1 ** 2 + z2 ** 2 return stat - def skewness_to_z1(self, skew, n): + @staticmethod + def skewness_to_z1(skew, n): b = 3 * ((n ** 2) + 27 * n - 70) * (n + 1) * (n + 3) / ((n - 2) * (n + 5) * (n + 7) * (n + 9)) w2 = -1 + math.sqrt(2 * (b - 1)) d = 1 / math.sqrt(math.log(math.sqrt(w2))) @@ -846,7 +851,8 @@ def skewness_to_z1(self, skew, n): z = d * math.log((y / a) + math.sqrt((y / a) ** 2 + 1)) return z - def kurtosis_to_z2(self, skew, kurt, n): + @staticmethod + def kurtosis_to_z2(skew, kurt, n): n2 = n ** 2 n3 = n ** 3 p1 = n2 + 15 * n - 4 @@ -864,295 +870,314 @@ def kurtosis_to_z2(self, skew, kurt, n): return z -class RobustJarqueBeraTest(AbstractNormalityTestStatistic): - +class RobustJarqueBeraNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'RJB' + return 'RJB' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): y = np.sort(rvs) n = len(rvs) - M = np.median(y) + m = np.median(y) c = np.sqrt(math.pi / 2) - J = (c / n) * np.sum(np.abs(rvs - M)) + j = (c / n) * np.sum(np.abs(rvs - m)) m_3 = scipy_stats.moment(y, moment=3) m_4 = scipy_stats.moment(y, moment=4) - RJB = (n / 6) * (m_3 / J ** 3) ** 2 + (n / 64) * (m_4 / J ** 4 - 3) ** 2 - return RJB - + rjb = (n / 6) * (m_3 / j ** 3) ** 2 + (n / 64) * (m_4 / j ** 4 - 3) ** 2 + return rjb -class BontempsMeddahi1Test(AbstractNormalityTestStatistic): +class BontempsMeddahi1NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'BM1' + return 'BM1' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: z = [0.0] * n - varX = 0.0 - meanX = 0.0 + var_x = 0.0 + mean_x = 0.0 tmp3 = 0.0 tmp4 = 0.0 for i in range(n): - meanX += rvs[i] - meanX /= n + mean_x += rvs[i] + mean_x /= n for i in range(n): - varX += rvs[i] ** 2 - varX = (n * (varX / n - meanX ** 2)) / (n - 1) - sdX = math.sqrt(varX) + var_x += rvs[i] ** 2 + var_x = (n * (var_x / n - mean_x ** 2)) / (n - 1) + sd_x = math.sqrt(var_x) for i in range(n): - z[i] = (rvs[i] - meanX) / sdX + z[i] = (rvs[i] - mean_x) / sd_x for i in range(n): tmp3 += (z[i] ** 3 - 3 * z[i]) / math.sqrt(6) tmp4 += (z[i] ** 4 - 6 * z[i] ** 2 + 3) / (2 * math.sqrt(6)) - statBM34 = (tmp3 ** 2 + tmp4 ** 2) / n - return statBM34 + stat_bm34 = (tmp3 ** 2 + tmp4 ** 2) / n + return stat_bm34 -class BontempsMeddahi2Test(AbstractNormalityTestStatistic): - +class BontempsMeddahi2NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'BM2' + return 'BM2' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat15(rvs) - def stat15(self, x): + @staticmethod + def stat15(x): n = len(x) if n > 3: z = np.zeros(n) - meanX = np.mean(x) - varX = np.var(x, ddof=1) - sdX = np.sqrt(varX) + mean_x = np.mean(x) + var_x = np.var(x, ddof=1) + sd_x = np.sqrt(var_x) for i in range(n): - z[i] = (x[i] - meanX) / sdX + z[i] = (x[i] - mean_x) / sd_x tmp3 = np.sum((z ** 3 - 3 * z) / np.sqrt(6)) tmp4 = np.sum((z ** 4 - 6 * z ** 2 + 3) / (2 * np.sqrt(6))) tmp5 = np.sum((z ** 5 - 10 * z ** 3 + 15 * z) / (2 * np.sqrt(30))) tmp6 = np.sum((z ** 6 - 15 * z ** 4 + 45 * z ** 2 - 15) / (12 * np.sqrt(5))) - statBM36 = (tmp3 ** 2 + tmp4 ** 2 + tmp5 ** 2 + tmp6 ** 2) / n - return statBM36 + stat_bm36 = (tmp3 ** 2 + tmp4 ** 2 + tmp5 ** 2 + tmp6 ** 2) / n + return stat_bm36 -class BonettSeierTest(AbstractNormalityTestStatistic): - +class BonettSeierNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'BS' + return 'BS' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat17(rvs) - def stat17(self, x): + @staticmethod + def stat17(x): n = len(x) if n > 3: m2 = 0.0 - meanX = 0.0 + mean_x = 0.0 term = 0.0 for i in range(n): - meanX += x[i] + mean_x += x[i] - meanX = meanX / float(n) + mean_x = mean_x / float(n) for i in range(n): - m2 += (x[i] - meanX) ** 2 - term += abs(x[i] - meanX) + m2 += (x[i] - mean_x) ** 2 + term += abs(x[i] - mean_x) m2 = m2 / float(n) term = term / float(n) omega = 13.29 * (math.log(math.sqrt(m2)) - math.log(term)) - statTw = math.sqrt(float(n + 2)) * (omega - 3.0) / 3.54 - return statTw - + stat_tw = math.sqrt(float(n + 2)) * (omega - 3.0) / 3.54 + return stat_tw -class MartinezIglewiczTest(AbstractNormalityTestStatistic): +class MartinezIglewiczNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'MI' + return 'MI' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat32(rvs) - def stat32(self, x): + @staticmethod + def stat32(x): n = len(x) if n > 3: - xtmp = np.copy(x) - xtmp.sort() + x_tmp = np.copy(x) + x_tmp.sort() if n % 2 == 0: - M = (xtmp[n // 2] + xtmp[n // 2 - 1]) / 2.0 + m = (x_tmp[n // 2] + x_tmp[n // 2 - 1]) / 2.0 else: - M = xtmp[n // 2] + m = x_tmp[n // 2] - aux1 = x - M - xtmp = np.abs(aux1) - xtmp.sort() + aux1 = x - m + x_tmp = np.abs(aux1) + x_tmp.sort() if n % 2 == 0: - A = (xtmp[n // 2] + xtmp[n // 2 - 1]) / 2.0 + a = (x_tmp[n // 2] + x_tmp[n // 2 - 1]) / 2.0 else: - A = xtmp[n // 2] - A = 9.0 * A + a = x_tmp[n // 2] + a = 9.0 * a - z = aux1 / A + z = aux1 / a term1 = np.sum(aux1 ** 2 * (1 - z ** 2) ** 4) term2 = np.sum((1 - z ** 2) * (1 - 5 * z ** 2)) term3 = np.sum(aux1 ** 2) - Sb2 = (n * term1) / term2 ** 2 - statIn = (term3 / (n - 1)) / Sb2 - return statIn - + sb2 = (n * term1) / term2 ** 2 + stat_in = (term3 / (n - 1)) / sb2 + return stat_in -class CabanaCabana1Test(AbstractNormalityTestStatistic): +class CabanaCabana1NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'CC1' + return 'CC1' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat19(rvs) - def stat19(self, x): + @staticmethod + def stat19(x): n = len(x) if n > 3: - zdata = (x - np.mean(x)) / np.std(x, ddof=1) - meanH3 = np.sum(zdata ** 3 - 3 * zdata) / (np.sqrt(6) * np.sqrt(n)) - meanH4 = np.sum(zdata ** 4 - 6 * zdata ** 2 + 3) / (2 * np.sqrt(6) * np.sqrt(n)) - meanH5 = np.sum(zdata ** 5 - 10 * zdata ** 3 + 15 * zdata) / (2 * np.sqrt(30) * np.sqrt(n)) - meanH6 = np.sum(zdata ** 6 - 15 * zdata ** 4 + 45 * zdata ** 2 - 15) / (12 * np.sqrt(5) * np.sqrt(n)) - meanH7 = np.sum(zdata ** 7 - 21 * zdata ** 5 + 105 * zdata ** 3 - 105 * zdata) / ( + z_data = (x - np.mean(x)) / np.std(x, ddof=1) + mean_h3 = np.sum(z_data ** 3 - 3 * z_data) / (np.sqrt(6) * np.sqrt(n)) + mean_h4 = np.sum(z_data ** 4 - 6 * z_data ** 2 + 3) / (2 * np.sqrt(6) * np.sqrt(n)) + mean_h5 = np.sum(z_data ** 5 - 10 * z_data ** 3 + 15 * z_data) / (2 * np.sqrt(30) * np.sqrt(n)) + mean_h6 = np.sum(z_data ** 6 - 15 * z_data ** 4 + 45 * z_data ** 2 - 15) / (12 * np.sqrt(5) * np.sqrt(n)) + mean_h7 = np.sum(z_data ** 7 - 21 * z_data ** 5 + 105 * z_data ** 3 - 105 * z_data) / ( 12 * np.sqrt(35) * np.sqrt(n)) - meanH8 = np.sum(zdata ** 8 - 28 * zdata ** 6 + 210 * zdata ** 4 - 420 * zdata ** 2 + 105) / ( + mean_h8 = np.sum(z_data ** 8 - 28 * z_data ** 6 + 210 * z_data ** 4 - 420 * z_data ** 2 + 105) / ( 24 * np.sqrt(70) * np.sqrt(n)) - vectoraux1 = meanH4 + meanH5 * zdata / np.sqrt(2) + meanH6 * (zdata ** 2 - 1) / np.sqrt(6) + meanH7 * ( - zdata ** 3 - 3 * zdata) / (2 * np.sqrt(6)) + meanH8 * (zdata ** 4 - 6 * zdata ** 2 + 3) / ( - 2 * np.sqrt(30)) - statTSl = np.max(np.abs(scipy_stats.norm.cdf(zdata) * meanH3 - scipy_stats.norm.pdf(zdata) * vectoraux1)) - return statTSl - + vector_aux1 = (mean_h4 + mean_h5 * z_data / np.sqrt(2) + + mean_h6 * (z_data ** 2 - 1) / np.sqrt(6) + mean_h7 * (z_data ** 3 - 3 * z_data) + / (2 * np.sqrt(6)) + mean_h8 * (z_data ** 4 - 6 * z_data ** 2 + 3) / ( + 2 * np.sqrt(30))) + stat_tsl = np.max(np.abs(scipy_stats.norm.cdf(z_data) * mean_h3 + - scipy_stats.norm.pdf(z_data) * vector_aux1)) + return stat_tsl -class CabanaCabana2Test(AbstractNormalityTestStatistic): +class CabanaCabana2NormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'CC2' + return 'CC2' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat20(rvs) - def stat20(self, x): + @staticmethod + def stat20(x): n = len(x) if n > 3: # TODO: Move variance calculation - varX = n * np.var(x) / (n - 1) - sdX = np.sqrt(varX) - z = (x - np.mean(x)) / sdX - H0 = np.zeros(n) - H1 = np.zeros(n) - H2 = np.zeros(n) - H3 = np.zeros(n) - H4 = np.zeros(n) - H5 = np.zeros(n) - H6 = np.zeros(n) - H7 = np.zeros(n) - H8 = np.zeros(n) - - H3tilde = 0 - H4tilde = 0 - H5tilde = 0 - H6tilde = 0 - H7tilde = 0 - H8tilde = 0 + + var_x = n * np.var(x) / (n - 1) + sd_x = np.sqrt(var_x) + z = (x - np.mean(x)) / sd_x + h0 = np.zeros(n) + h1 = np.zeros(n) + h2 = np.zeros(n) + h3 = np.zeros(n) + h4 = np.zeros(n) + h5 = np.zeros(n) + h6 = np.zeros(n) + h7 = np.zeros(n) + h8 = np.zeros(n) + + h3_tilde = 0 + h4_tilde = 0 + h5_tilde = 0 + h6_tilde = 0 + h7_tilde = 0 + h8_tilde = 0 for i in range(n): - H0[i] = 1 - H1[i] = z[i] - H2[i] = (math.pow(z[i], 2.0) - 1.0) / np.sqrt(2.0) - H3[i] = (math.pow(z[i], 3.0) - 3.0 * z[i]) / np.sqrt(6.0) - H4[i] = (math.pow(z[i], 4.0) - 6.0 * math.pow(z[i], 2.0) + 3.0) / (2.0 * np.sqrt(6.0)) - H5[i] = (math.pow(z[i], 5.0) - 10.0 * math.pow(z[i], 3.0) + 15.0 * z[i]) / (2.0 * np.sqrt(30.0)) - H6[i] = (math.pow(z[i], 6.0) - 15.0 * math.pow(z[i], 4.0) + 45.0 * math.pow(z[i], 2.0) - 15.0) / ( + h0[i] = 1 + h1[i] = z[i] + h2[i] = (math.pow(z[i], 2.0) - 1.0) / np.sqrt(2.0) + h3[i] = (math.pow(z[i], 3.0) - 3.0 * z[i]) / np.sqrt(6.0) + h4[i] = (math.pow(z[i], 4.0) - 6.0 * math.pow(z[i], 2.0) + 3.0) / (2.0 * np.sqrt(6.0)) + h5[i] = (math.pow(z[i], 5.0) - 10.0 * math.pow(z[i], 3.0) + 15.0 * z[i]) / (2.0 * np.sqrt(30.0)) + h6[i] = (math.pow(z[i], 6.0) - 15.0 * math.pow(z[i], 4.0) + 45.0 * math.pow(z[i], 2.0) - 15.0) / ( 12.0 * np.sqrt(5.0)) - H7[i] = (math.pow(z[i], 7.0) - 21.0 * math.pow(z[i], 5.0) + 105.0 * math.pow(z[i], 3.0) - 105.0 * z[ + h7[i] = (math.pow(z[i], 7.0) - 21.0 * math.pow(z[i], 5.0) + 105.0 * math.pow(z[i], 3.0) - 105.0 * z[ i]) / ( 12.0 * np.sqrt(35.0)) - H8[i] = (math.pow(z[i], 8.0) - 28.0 * math.pow(z[i], 6.0) + 210.0 * math.pow(z[i], + h8[i] = (math.pow(z[i], 8.0) - 28.0 * math.pow(z[i], 6.0) + 210.0 * math.pow(z[i], 4.0) - 420.0 * math.pow( z[i], 2.0) + 105.0) / ( 24.0 * np.sqrt(70.0)) - H3tilde = H3tilde + H3[i] - H4tilde = H4tilde + H4[i] - H5tilde = H5tilde + H5[i] - H6tilde = H6tilde + H6[i] - H7tilde = H7tilde + H7[i] - H8tilde = H8tilde + H8[i] - - H3tilde = H3tilde / np.sqrt(n) - H4tilde = H4tilde / np.sqrt(n) - H5tilde = H5tilde / np.sqrt(n) - H6tilde = H6tilde / np.sqrt(n) - H7tilde = H7tilde / np.sqrt(n) - H8tilde = H8tilde / np.sqrt(n) - - vectoraux2 = (np.sqrt(2) * H0 + H2) * H5tilde + (np.sqrt(3 / 2) * H1 + H3) * H6tilde + ( - np.sqrt(4 / 3) * H2 + H4) * H7tilde + (np.sqrt(5 / 4) * H3 + H5) * H8tilde + ( - np.sqrt(5 / 4) * H3 + H5) * H8tilde - statTKl = np.max(np.abs(-scipy_stats.norm.pdf(z) * H3tilde + ( - scipy_stats.norm.cdf(z) - z * scipy_stats.norm.pdf(z)) * H4tilde - scipy_stats.norm.pdf( - z) * vectoraux2)) - return statTKl - - -class ChenShapiroTest(AbstractNormalityTestStatistic): - + h3_tilde = h3_tilde + h3[i] + h4_tilde = h4_tilde + h4[i] + h5_tilde = h5_tilde + h5[i] + h6_tilde = h6_tilde + h6[i] + h7_tilde = h7_tilde + h7[i] + h8_tilde = h8_tilde + h8[i] + + h3_tilde = h3_tilde / np.sqrt(n) + h4_tilde = h4_tilde / np.sqrt(n) + h5_tilde = h5_tilde / np.sqrt(n) + h6_tilde = h6_tilde / np.sqrt(n) + h7_tilde = h7_tilde / np.sqrt(n) + h8_tilde = h8_tilde / np.sqrt(n) + + vector_aux2 = (np.sqrt(2) * h0 + h2) * h5_tilde + (np.sqrt(3 / 2) * h1 + h3) * h6_tilde + ( + np.sqrt(4 / 3) * h2 + h4) * h7_tilde + (np.sqrt(5 / 4) * h3 + h5) * h8_tilde + ( + np.sqrt(5 / 4) * h3 + h5) * h8_tilde + stat_tkl = np.max(np.abs(-scipy_stats.norm.pdf(z) * h3_tilde + ( + scipy_stats.norm.cdf(z) - z * scipy_stats.norm.pdf(z)) * h4_tilde - scipy_stats.norm.pdf( + z) * vector_aux2)) + return stat_tkl + + +class ChenShapiroNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'CS' + return 'CS' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat26(rvs) - def stat26(self, x): + @staticmethod + def stat26(x): n = len(x) if n > 3: xs = np.sort(x) - meanX = np.mean(x) - varX = np.var(x, ddof=1) - M = scipy_stats.norm.ppf(np.arange(1, n + 1) / (n + 0.25) - 0.375 / (n + 0.25)) - statCS = np.sum((xs[1:] - xs[:-1]) / (M[1:] - M[:-1])) / ((n - 1) * np.sqrt(varX)) - statCS = np.sqrt(n) * (1.0 - statCS) - return statCS - + # mean_x = np.mean(x) + var_x = np.var(x, ddof=1) + m = scipy_stats.norm.ppf(np.arange(1, n + 1) / (n + 0.25) - 0.375 / (n + 0.25)) + stat_cs = np.sum((xs[1:] - xs[:-1]) / (m[1:] - m[:-1])) / ((n - 1) * np.sqrt(var_x)) + stat_cs = np.sqrt(n) * (1.0 - stat_cs) + return stat_cs -class ZhangQTest(AbstractNormalityTestStatistic): +class ZhangQNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'ZQ' + return 'ZQ' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat27(rvs) - def stat27(self, x): + @staticmethod + def stat27(x): n = len(x) if n > 3: @@ -1177,17 +1202,18 @@ def stat27(self, x): b[i - 1] = (1.0 / (u[i - 1] - u[i + 3]) - 1.0 / (u[i - 5] - u[i - 1])) / (n - 4) q1 = np.dot(a, xs) q2 = np.dot(b, xs) - statQ = np.log(q1 / q2) - return statQ + stat_q = np.log(q1 / q2) + return stat_q -class CoinTest(AbstractNormalityTestStatistic): - +class CoinNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'COIN' + return 'COIN' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat30(rvs) def stat30(self, x): @@ -1195,11 +1221,11 @@ def stat30(self, x): if n > 3: z = [0] * n - M = [n // 2] - sp = [0] * M[0] + m = [n // 2] + sp = [0] * m[0] a = [0] * n - varX = 0.0 - meanX = 0.0 + var_x = 0.0 + mean_x = 0.0 term1 = 0.0 term2 = 0.0 term3 = 0.0 @@ -1207,19 +1233,19 @@ def stat30(self, x): term6 = 0.0 for i in range(n): - meanX += x[i] - meanX /= n + mean_x += x[i] + mean_x /= n for i in range(n): - varX += x[i] ** 2 - varX = (n * (varX / n - meanX ** 2)) / (n - 1) - sdX = math.sqrt(varX) + var_x += x[i] ** 2 + var_x = (n * (var_x / n - mean_x ** 2)) / (n - 1) + sd_x = math.sqrt(var_x) for i in range(n): - z[i] = (x[i] - meanX) / sdX + z[i] = (x[i] - mean_x) / sd_x z.sort() - self.nscor2(sp, n, M) + self.nscor2(sp, n, m) if n % 2 == 0: for i in range(n // 2): @@ -1240,10 +1266,11 @@ def stat30(self, x): term4 += a[i] ** 3 * z[i] term6 += a[i] ** 6 - statbeta32 = ((term1 * term2 - term3 * term4) / (term1 * term1 - term3 * term6)) ** 2 - return statbeta32 + stat_beta32 = ((term1 * term2 - term3 * term4) / (term1 * term1 - term3 * term6)) ** 2 + return stat_beta32 - def correc(self, i, n): + @staticmethod + def correc(i, n): c1 = [9.5, 28.7, 1.9, 0., -7., -6.2, -1.6] c2 = [-6195., -9569., -6728., -17614., -8278., -3570., 1075.] c3 = [93380., 175160., 410400., 2157600., 2.376e6, 2.065e6, 2.065e6] @@ -1308,32 +1335,34 @@ def nscor2(self, s, n, n2): return -class DagostinoTest(AbstractNormalityTestStatistic): - +class DagostinoNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'D' + return 'D' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: xs = np.sort(rvs) # We sort the data - meanX = sum(xs) / n - varX = sum(x_i ** 2 for x_i in xs) / n - meanX ** 2 - T = sum((i - 0.5 * (n + 1)) * xs[i - 1] for i in range(1, n + 1)) - D = T / ((n ** 2) * math.sqrt(varX)) - statDa = math.sqrt(n) * (D - 0.28209479) / 0.02998598 - - return statDa # Here is the test statistic value + mean_x = sum(xs) / n + var_x = sum(x_i ** 2 for x_i in xs) / n - mean_x ** 2 + t = sum((i - 0.5 * (n + 1)) * xs[i - 1] for i in range(1, n + 1)) + d = t / ((n ** 2) * math.sqrt(var_x)) + stat_da = math.sqrt(n) * (d - 0.28209479) / 0.02998598 + return stat_da # Here is the test statistic value -class ZhangQStarTest(AbstractNormalityTestStatistic): +class ZhangQStarNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'ZQS' + return 'ZQS' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: @@ -1357,24 +1386,27 @@ def execute_statistic(self, rvs): for i in range(4, n - 4): b[i] = (1 / (u[i] - u[i + 4]) - 1 / (u[i - 4] - u[i])) / (n - 4) - q1star = -np.dot(a, xs[::-1]) - q2star = -np.dot(b, xs[::-1]) + q1_star = -np.dot(a, xs[::-1]) + q2_star = -np.dot(b, xs[::-1]) - Qstar = np.log(q1star / q2star) - return Qstar + q_star = np.log(q1_star / q2_star) + return q_star """ -class ZhangQQStarTest(AbstractNormalityTest): +class ZhangQQStarNormalityTest(AbstractNormalityTestStatistic): # TODO: check for correctness @staticmethod + @override def code(): - return 'ZQQ' + return 'ZQQ' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat28(rvs) - def stat28(self, x): + @staticmethod + def stat28(x): n = len(x) if n > 3: @@ -1385,36 +1417,37 @@ def stat27(x): def stat34(x): pass - pvalue27 = [1.0] - pvalue34 = [1.0] + p_value27 = [1.0] + p_value34 = [1.0] stat27(x) # stat Q de Zhang - if pvalue27[0] > 0.5: - pval1 = 1.0 - pvalue27[0] + if p_value27[0] > 0.5: + p_val1 = 1.0 - p_value27[0] else: - pval1 = pvalue27[0] + p_val1 = p_value27[0] stat34(x) # stat Q* de Zhang - if pvalue34[0] > 0.5: - pval2 = 1.0 - pvalue34[0] + if p_value34[0] > 0.5: + p_val2 = 1.0 - p_value34[0] else: - pval2 = pvalue34[0] + p_val2 = p_value34[0] - stat = -2.0 * (np.log(pval1) + np.log(pval2)) # Combinaison des valeurs-p (Fisher, 1932) + stat = -2.0 * (np.log(p_val1) + np.log(p_val2)) # Combinaison des valeurs-p (Fisher, 1932) return stat # Here is the test statistic value """ -class SWRGTest(AbstractNormalityTestStatistic): - +class SWRGNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'SWRG' + return 'SWRG' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) if n > 3: @@ -1425,68 +1458,70 @@ def execute_statistic(self, rvs): aux1 = np.concatenate(([0], mi[:-1] * fi[:-1])) aux3 = np.concatenate((mi[1:] * fi[1:], [0])) aux4 = aux1 - aux2 + aux3 - aistar = -((n + 1) * (n + 2)) * fi * aux4 - norm2 = np.sum(aistar ** 2) - ai = aistar / np.sqrt(norm2) + ai_star = -((n + 1) * (n + 2)) * fi * aux4 + norm2 = np.sum(ai_star ** 2) + ai = ai_star / np.sqrt(norm2) xs = np.sort(rvs) - meanX = np.mean(xs) - aux6 = np.sum((xs - meanX) ** 2) - statWRG = np.sum(ai * xs) ** 2 / aux6 - - return statWRG # Here is the test statistic value + mean_x = np.mean(xs) + aux6 = np.sum((xs - mean_x) ** 2) + stat_wrg = np.sum(ai * xs) ** 2 / aux6 + return stat_wrg # Here is the test statistic value -class GMGTest(AbstractNormalityTestStatistic): +class GMGNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'GMG' + return 'GMG' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat33(rvs) - def stat33(self, x): + @staticmethod + def stat33(x): n = len(x) if n > 3: import math - xtmp = [0] * n - varX = 0.0 - meanX = 0.0 - Jn = 0.0 + x_tmp = [0] * n + var_x = 0.0 + mean_x = 0.0 + jn = 0.0 pi = 4.0 * math.atan(1.0) # or use pi = M_PI, where M_PI is defined in math.h # calculate sample mean for i in range(n): - meanX += x[i] - meanX = meanX / n + mean_x += x[i] + mean_x = mean_x / n # calculate sample var and standard deviation for i in range(n): - varX += (x[i] - meanX) ** 2 - varX = varX / n - sdX = math.sqrt(varX) + var_x += (x[i] - mean_x) ** 2 + var_x = var_x / n + sd_x = math.sqrt(var_x) # calculate sample median for i in range(n): - xtmp[i] = x[i] + x_tmp[i] = x[i] - xtmp = np.sort(xtmp) # We sort the data + x_tmp = np.sort(x_tmp) # We sort the data if n % 2 == 0: - M = (xtmp[n // 2] + xtmp[n // 2 - 1]) / 2.0 + m = (x_tmp[n // 2] + x_tmp[n // 2 - 1]) / 2.0 else: - M = xtmp[n // 2] # sample median + m = x_tmp[n // 2] # sample median # calculate statRsJ for i in range(n): - Jn += abs(x[i] - M) - Jn = math.sqrt(pi / 2.0) * Jn / n + jn += abs(x[i] - m) + jn = math.sqrt(pi / 2.0) * jn / n - statRsJ = sdX / Jn + stat_rsj = sd_x / jn - return statRsJ # Here is the test statistic value + return stat_rsj # Here is the test statistic value """ Title: Statistique de test de Brys-Hubert-Struyf MC-LR @@ -1495,13 +1530,14 @@ def stat33(self, x): """ -class BHSTest(AbstractNormalityTestStatistic): - +class BHSNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'BHS' + return 'BHS' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat16(rvs) def stat16(self, x): @@ -1518,100 +1554,100 @@ def stat16(self, x): x2 = x_sorted[(n // 2) + 1:] eps = [2.220446e-16, 2.225074e-308] - iter = [1000, 0] + iter_ = [1000, 0] print('ssss') - w1 = self.mc_C_d(x, eps, iter) + w1 = self.mc_c_d(x, eps, iter_) print('ssss1') - w2 = self.mc_C_d(x1, eps, iter) - w3 = self.mc_C_d(x2, eps, iter) + w2 = self.mc_c_d(x1, eps, iter_) + w3 = self.mc_c_d(x2, eps, iter_) omega = [0.0, 0.198828, 0.198828] vec = [w1 - omega[0], -w2 - omega[1], w3 - omega[2]] - invV = np.array([ + inv_v = np.array([ [0.8571890822945882, -0.1051268907484579, 0.1051268907484580], [-0.1051268907484579, 0.3944817329840534, -0.01109532299714422], [0.1051268907484579, -0.01109532299714422, 0.3944817329840535] ]) - statTMCLR = n * np.dot(vec, np.dot(invV, vec)) - return statTMCLR # Here is the test statistic value + stat_tmclr = n * np.dot(vec, np.dot(inv_v, vec)) + return stat_tmclr # Here is the test statistic value - def mc_C_d(self, z, eps, iter): + def mc_c_d(self, z, eps, iter_): """ NOTE: eps = [eps1, eps2] - iter = [maxit, trace_lev] as input + iter = [max_it, trace_lev] as input = [it, converged] as output """ - trace_lev = iter[1] + trace_lev = iter_[1] it = 0 converged = True - medc = None # "the" result - # DBL_MAX = 1.7976931348623158e+308 - DBL_MAX = 1.7976931348623158e+308 - Large = DBL_MAX / 4. + med_c = None # "the" result + # dbl_max = 1.7976931348623158e+308 + dbl_max = 1.7976931348623158e+308 + large = dbl_max / 4. n = len(z) if n < 3: - medc = 0. - iter[0] = it # to return - iter[1] = converged - return medc + med_c = 0. + iter_[0] = it # to return + iter_[1] = converged + return med_c # copy data before sort()ing in place, also reflecting it -- dealing with +-Inf. # NOTE: x[0] "empty" so we can use 1-indexing below x = [0.0] * (n + 1) for i in range(n): zi = z[i] - x[i + 1] = -((Large if zi == float('inf') else (-Large if zi == -float('inf') else zi))) + x[i + 1] = -(large if zi == float('inf') else (-large if zi == -float('inf') else zi)) x[1:] = sorted(x[1:]) # full sort - # xmed := median(x[1:n]) = -median(z[0:(n-1)]) + # x_med := median(x[1:n]) = -median(z[0:(n-1)]) if n % 2: # n even - xmed = x[(n // 2) + 1] + x_med = x[(n // 2) + 1] else: # n odd ind = (n // 2) - xmed = (x[ind] + x[ind + 1]) / 2.0 - - if abs(x[1] - xmed) < eps[0] * (eps[0] + abs(xmed)): - medc = -1. - iter[0] = it # to return - iter[1] = converged - return medc - elif abs(x[n] - xmed) < eps[0] * (eps[0] + abs(xmed)): - medc = 1. - iter[0] = it # to return - iter[1] = converged - return medc + x_med = (x[ind] + x[ind + 1]) / 2.0 + + if abs(x[1] - x_med) < eps[0] * (eps[0] + abs(x_med)): + med_c = -1. + iter_[0] = it # to return + iter_[1] = converged + return med_c + elif abs(x[n] - x_med) < eps[0] * (eps[0] + abs(x_med)): + med_c = 1. + iter_[0] = it # to return + iter_[1] = converged + return med_c # else: median is not at the border if trace_lev: - print(f"mc_C_d(z[1:{n}], trace_lev={trace_lev}): Median = {-xmed} (not at the border)") + print(f"mc_C_d(z[1:{n}], trace_lev={trace_lev}): Median = {-x_med} (not at the border)") # center x[] wrt median --> such that then median(x[1:n]) == 0 for i in range(1, n + 1): - x[i] -= xmed + x[i] -= x_med # Now scale to inside [-0.5, 0.5] and flip sign such that afterwards # x[1] >= x[2] >= ... >= x[n] - xden = -2 * max(-x[1], x[n]) + x_den = -2 * max(-x[1], x[n]) for i in range(1, n + 1): - x[i] /= xden - xmed /= xden + x[i] /= x_den + x_med /= x_den if trace_lev >= 2: - print(f" x[] has been rescaled (* 1/s) with s = {-xden}") + print(f" x[] has been rescaled (* 1/s) with s = {-x_den}") j = 1 - x_eps = eps[0] * (eps[0] + abs(xmed)) - while j <= n and x[j] > x_eps: # test relative to xmed + x_eps = eps[0] * (eps[0] + abs(x_med)) + while j <= n and x[j] > x_eps: # test relative to x_med j += 1 if trace_lev >= 2: print(f" x1[] := {{x | x_j > x_eps = {x_eps}}} has {j - 1} (='j-1') entries") i = 1 x2 = x[j - 1:] # pointer -- corresponding to x2[i] = x[j] - while j <= n and x[j] > -x_eps: # test relative to xmed + while j <= n and x[j] > -x_eps: # test relative to x_med j += 1 i += 1 # now x1[] := {x | x_j > -eps} also includes the median (0) @@ -1619,12 +1655,12 @@ def mc_C_d(self, z, eps, iter): print(f"'median-x' {{x | -eps < x_i <= eps}} has {i - 1} (= 'k') entries") h1 = j - 1 # == size of x1[] == the sum of those two sizes above # conceptually, x2[] := {x | x_j <= eps} (which includes the median 0) - h2 = i + (n - j) # == size of x2[] == maximal size of whimed() arrays + h2 = i + (n - j) # == size of x2[] == maximal size of whi_med() arrays if trace_lev: print(f" now allocating 2+5 work arrays of size (1+) h2={h2} each:") - # work arrays for whimed_i() - acand = [0.0] * h2 + # work arrays for whi_med_i() + a_cand = [0.0] * h2 a_srt = [0.0] * h2 iw_cand = [0] * h2 # work arrays for the fast-median-of-table algorithm: currently still with 1-indexing @@ -1641,7 +1677,7 @@ def mc_C_d(self, z, eps, iter): trial = -2. # -Wall work = [0.0] * n iwt = [0] * n - IsFound = False + is_found = False nl = 0 neq = 0 # MK: 'neq' counts the number of observations in the inside the tolerance range, @@ -1650,7 +1686,7 @@ def mc_C_d(self, z, eps, iter): # left might be larger than right + 1 since we are only testing with accuracy eps_trial # and therefore there might be more than one observation in the `tolerance range` # between < and <=. - while not IsFound and (nr - nl + neq > n) and it < iter[0]: + while not is_found and (nr - nl + neq > n) and it < iter_[0]: print(it) it += 1 j = 0 @@ -1661,7 +1697,7 @@ def mc_C_d(self, z, eps, iter): work[j] = self.h_kern(x[k], x2[i - 1], k, i, h1 + 1, eps[1]) j += 1 if trace_lev >= 4: - print(" before whimed(): work and iwt, each [0:({})]".format(j - 1)) + print(" before whi_med(): work and iwt, each [0:({})]".format(j - 1)) if j >= 100: for i in range(90): print(f" {work[i]:8g}", end="") @@ -1682,10 +1718,10 @@ def mc_C_d(self, z, eps, iter): for i in range(j): print(f" {iwt[i]:8d}", end="") print("\n", end="") - trial = self.whimed_i(work, iwt, j, acand, a_srt, iw_cand) + trial = self.whi_med_i(work, iwt, j, a_cand, a_srt, iw_cand) eps_trial = eps[0] * (eps[0] + abs(trial)) if trace_lev >= 3: - print(f"{' ':2s} it={it:2d}, whimed(*, n={j:6d})= {trial:8g} ", end="") + print(f"{' ':2s} it={it:2d}, whi_med(*, n={j:6d})= {trial:8g} ", end="") j = 1 for i in range(h2, 0, -1): @@ -1732,12 +1768,12 @@ def mc_C_d(self, z, eps, iter): neq += left[i] - right[i] - 1 nr = sum_p else: # knew > sum_p - IsFound = (knew <= sum_q) # i.e. sum_p < knew <= sum_q + is_found = (knew <= sum_q) # i.e. sum_p < knew <= sum_q if trace_lev >= 3: - print("; s_p < kn ?<=? s_q: {}".format("TRUE" if IsFound else "no")) - if IsFound: - medc = trial + print("; s_p < kn ?<=? s_q: {}".format("TRUE" if is_found else "no")) + if is_found: + med_c = trial else: # knew > sum_q for i in range(1, h2 + 1): left[i] = q[i] @@ -1745,13 +1781,13 @@ def mc_C_d(self, z, eps, iter): neq += left[i] - right[i] - 1 nl = sum_q - converged = IsFound or (nr - nl + neq <= n) + converged = is_found or (nr - nl + neq <= n) if not converged: - print(f"maximal number of iterations ({iter[0]} =? {it}) reached prematurely") + print(f"maximal number of iterations ({iter_[0]} =? {it}) reached prematurely") # still: - medc = trial + med_c = trial - if converged and not IsFound: # e.g., for mc(1:4) + if converged and not is_found: # e.g., for mc(1:4) j = 0 for i in range(1, h2 + 1): if left[i] <= right[i]: @@ -1762,72 +1798,76 @@ def mc_C_d(self, z, eps, iter): print(f" not found [it={it}, (nr,nl) = ({nr},{nl})], -> (knew-nl, j) = ({knew - nl},{j})") # using rPsort(work, n,k), since we don't need work[] anymore work[:(knew - nl)] = sorted(work[:(knew - nl)]) - medc = -work[knew - nl - 1] + med_c = -work[knew - nl - 1] if converged and trace_lev >= 2: print(f"converged in {it} iterations") - iter[0] = it # to return - iter[1] = converged + iter_[0] = it # to return + iter_[1] = converged - return medc + return med_c - def h_kern(self, a, b, ai, bi, ab, eps): + @staticmethod + def h_kern(a, b, ai, bi, ab, eps): if np.abs(a - b) < 2.0 * eps or b > 0: return np.sign(ab - (ai + bi)) else: return (a + b) / (a - b) - def whimed_i(self, a, w, n, a_cand, a_srt, w_cand): + @staticmethod + def whi_med_i(a, w, n, a_cand, a_srt, w_cand): w_tot = sum(w) - wrest = 0 + w_rest = 0 while True: a_srt[:] = sorted(a) n2 = n // 2 trial = a_srt[n2] - wleft = sum(w[i] for i in range(n) if a[i] < trial) - wmid = sum(w[i] for i in range(n) if a[i] == trial) - wright = sum(w[i] for i in range(n) if a[i] > trial) + w_left = sum(w[i] for i in range(n) if a[i] < trial) + w_mid = sum(w[i] for i in range(n) if a[i] == trial) + # w_right = sum(w[i] for i in range(n) if a[i] > trial) - kcand = 0 - if 2 * (wrest + wleft) > w_tot: + k_cand = 0 + if 2 * (w_rest + w_left) > w_tot: for i in range(n): if a[i] < trial: - a_cand[kcand] = a[i] - w_cand[kcand] = w[i] - kcand += 1 - elif 2 * (wrest + wleft + wmid) <= w_tot: + a_cand[k_cand] = a[i] + w_cand[k_cand] = w[i] + k_cand += 1 + elif 2 * (w_rest + w_left + w_mid) <= w_tot: for i in range(n): if a[i] > trial: - a_cand[kcand] = a[i] - w_cand[kcand] = w[i] - kcand += 1 - wrest += wleft + wmid + a_cand[k_cand] = a[i] + w_cand[k_cand] = w[i] + k_cand += 1 + w_rest += w_left + w_mid else: return trial - n = kcand + n = k_cand for i in range(n): a[i] = a_cand[i] w[i] = w_cand[i] -class SpiegelhalterTest(AbstractNormalityTestStatistic): - +class SpiegelhalterNormalityTest(AbstractNormalityTestStatistic): @staticmethod + @override def code(): - return 'SH' + return 'SH' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat41(rvs) - def stat41(self, x): + @staticmethod + def stat41(x): n = len(x) if n > 3: - statSp, varX, mean = 0.0, 0.0, 0.0 + stat_sp, var_x, mean = 0.0, 0.0, 0.0 max_val, min_val = x[0], x[0] for i in range(1, n): if x[i] > max_val: @@ -1838,9 +1878,9 @@ def stat41(self, x): mean += x[i] mean /= n for i in range(n): - varX += (x[i] - mean) ** 2 - varX /= (n - 1) - sd = math.sqrt(varX) + var_x += (x[i] - mean) ** 2 + var_x /= (n - 1) + sd = math.sqrt(var_x) u = (max_val - min_val) / sd g = 0.0 for i in range(n): @@ -1852,38 +1892,39 @@ def stat41(self, x): cn = (2 * math.pi) ** (1 / (2 * (n - 1))) * ((n * math.sqrt(n)) / math.e) ** (1 / (n - 1)) / ( 2 * math.e) # Stirling approximation - statSp = ((cn * u) ** (-(n - 1)) + g ** (-(n - 1))) ** (1 / (n - 1)) - - return statSp # Here is the test statistic value + stat_sp = ((cn * u) ** (-(n - 1)) + g ** (-(n - 1))) ** (1 / (n - 1)) + return stat_sp # Here is the test statistic value -class DesgagneLafayeTest(AbstractNormalityTestStatistic): +class DesgagneLafayeNormalityTest(AbstractNormalityTestStatistic): @staticmethod def code(): - return 'DLDMZEPD' + return 'DLDMZEPD' + '_' + super(AbstractNormalityTestStatistic, AbstractNormalityTestStatistic).code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): return self.stat35(rvs) - def stat35(self, x): + @staticmethod + def stat35(x): n = len(x) if n > 3: # Computation of the value of the test statistic y = np.zeros(n) - varpopX = 0.0 - meanX = np.mean(x) + varpop_x = 0.0 + mean_x = np.mean(x) r1 = 0.0 r2 = 0.0 r3 = 0.0 for i in range(n): - varpopX += x[i] ** 2 - varpopX = varpopX / n - meanX ** 2 - sdX = np.sqrt(varpopX) + varpop_x += x[i] ** 2 + varpop_x = varpop_x / n - mean_x ** 2 + sd_x = np.sqrt(varpop_x) for i in range(n): - y[i] = (x[i] - meanX) / sdX + y[i] = (x[i] - mean_x) / sd_x # Formulas given in our paper p. 169 for i in range(n): @@ -1895,8 +1936,11 @@ def stat35(self, x): r3 = 0.20981558 - r3 / n # Formula given in our paper p. 170 - Rn = n * ((r1 * 1259.04213344 - r2 * 32040.69569026 + r3 * 85065.77739473) * r1 + ( + rn = n * ((r1 * 1259.04213344 - r2 * 32040.69569026 + r3 * 85065.77739473) * r1 + ( -r1 * 32040.6956903 + r2 * 918649.9005906 - r3 * 2425883.3443201) * r2 + ( r1 * 85065.7773947 - r2 * 2425883.3443201 + r3 * 6407749.8211208) * r3) - return Rn # Here is the test statistic value + return rn # Here is the test statistic value + +# TODO: fix all weak warnings +# TODO: check tests diff --git a/stattest/test/weibull.py b/stattest/test/weibull.py index a595138..fc38e56 100644 --- a/stattest/test/weibull.py +++ b/stattest/test/weibull.py @@ -1,93 +1,87 @@ -import math +from abc import abstractmethod, ABC +import numpy as np from numpy import histogram +from scipy.optimize import minimize_scalar from scipy.stats import distributions from typing_extensions import override -from stattest.core.distribution.weibull import generate_weibull_cdf, generate_weibull_logcdf, generate_weibull_logsf -import numpy as np -from scipy.optimize import minimize_scalar -from stattest.test.models import AbstractTestStatistic +from stattest.core.distribution.weibull import generate_weibull_cdf + from stattest.test.common import KSTestStatistic, ADTestStatistic, LillieforsTest, CrammerVonMisesTestStatistic, \ Chi2TestStatistic, MinToshiyukiTestStatistic +from stattest.test.models import AbstractTestStatistic -class MinToshiyukiWeibullTestStatistic(MinToshiyukiTestStatistic): +class AbstractWeibullTestStatistic(AbstractTestStatistic, ABC): def __init__(self, l=1, k=5): - super().__init__() self.l = l self.k = k @staticmethod + @override def code(): - return 'MT_WEIBULL' + return 'WEIBULL' + +class MinToshiyukiWeibullTestStatistic(AbstractWeibullTestStatistic, MinToshiyukiTestStatistic): + @staticmethod @override - def execute_statistic(self, rvs): + def code(): + return 'MT' + '_' + AbstractWeibullTestStatistic.code() + + @override + def execute_statistic(self, rvs, **kwargs): rvs = np.sort(rvs) cdf_vals = generate_weibull_cdf(rvs, l=self.l, k=self.k) - return super().execute_statistic(cdf_vals) - + return MinToshiyukiTestStatistic.execute_statistic(self, cdf_vals) -class Chi2PearsonWiebullTest(Chi2TestStatistic): - def __init__(self, l=1, k=5): - super().__init__() - self.l = l - self.k = k +class Chi2PearsonWiebullTest(AbstractWeibullTestStatistic, Chi2TestStatistic): @staticmethod + @override def code(): - return 'CHI2_PEARSON_WEIBULL' + return 'CHI2_PEARSON' + '_' + AbstractWeibullTestStatistic.code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): rvs_sorted = np.sort(rvs) n = len(rvs) (observed, bin_edges) = histogram(rvs_sorted, bins=int(np.ceil(np.sqrt(n)))) observed = observed / n expected = generate_weibull_cdf(bin_edges, l=self.l, k=self.k) expected = np.diff(expected) - return super().execute_statistic(observed, expected, 1) - + return Chi2TestStatistic.execute_statistic(self, observed, expected, 1) -class LillieforsWiebullTest(LillieforsTest): - def __init__(self, l=1, k=5): - super().__init__() - self.l = l - self.k = k +class LillieforsWiebullTest(AbstractWeibullTestStatistic, LillieforsTest): @staticmethod + @override def code(): - return 'LILLIE_WEIBULL' + return 'LILLIE' + '_' + AbstractWeibullTestStatistic.code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): rvs_sorted = np.sort(rvs) cdf_vals = generate_weibull_cdf(rvs_sorted, l=self.l, k=self.k) - return super().execute_statistic(rvs, cdf_vals) - + return LillieforsTest.execute_statistic(rvs, cdf_vals) -class CrammerVonMisesWeibullTest(CrammerVonMisesTestStatistic): - def __init__(self, l=1, k=5): - super().__init__() - self.l = l - self.k = k +class CrammerVonMisesWeibullTest(AbstractWeibullTestStatistic, CrammerVonMisesTestStatistic): def execute_statistic(self, rvs, cdf_vals): rvs_sorted = np.sort(rvs) cdf_vals = generate_weibull_cdf(rvs_sorted, l=self.l, k=self.k) - return super().execute_statistic(rvs, cdf_vals) + return CrammerVonMisesTestStatistic.execute_statistic(rvs, cdf_vals) -class ADWeibullTest(ADTestStatistic): - def __init__(self, l=1, k=5): - super().__init__() - self.l = l - self.k = k - +class ADWeibullTest(AbstractWeibullTestStatistic, ADTestStatistic): @staticmethod + @override def code(): - return 'AD_WEIBULL' + return 'AD' + '_' + AbstractWeibullTestStatistic.code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): rvs = np.log(rvs) y = np.sort(rvs) xbar, s = distributions.gumbel_l.fit(y) @@ -95,34 +89,39 @@ def execute_statistic(self, rvs): logcdf = distributions.gumbel_l.logcdf(w) logsf = distributions.gumbel_l.logsf(w) - return super().execute_statistic(rvs, log_cdf=logcdf, log_sf=logsf, w=w) - + return ADTestStatistic.execute_statistic(rvs, log_cdf=logcdf, log_sf=logsf, w=w) -class KSWeibullTest(KSTestStatistic): +class KSWeibullTest(AbstractWeibullTestStatistic, KSTestStatistic): + @override def __init__(self, alternative='two-sided', mode='auto', l=1, k=5): - super().__init__(alternative, mode) + AbstractWeibullTestStatistic.__init__(self, None) + KSTestStatistic.__init__(self, alternative, mode) + self.l = l self.k = k @staticmethod + @override def code(): - return 'KS_WEIBULL' + return 'KS' + '_' + AbstractWeibullTestStatistic.code() - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): rvs = np.sort(rvs) cdf_vals = generate_weibull_cdf(rvs, l=self.l, k=self.k) - return super().execute_statistic(rvs, cdf_vals) - + return KSTestStatistic.execute_statistic(self, rvs, cdf_vals) -class SBTestStatistic(AbstractTestStatistic): +class SBTestStatistic(AbstractWeibullTestStatistic): @staticmethod + @override def code(): - return 'SB' + return 'SB' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Shapiro Wilk - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) lv = np.log(rvs) y = np.sort(lv) @@ -142,14 +141,15 @@ def execute_statistic(self, rvs): return WPP_statistic -class ST2TestStatistic(AbstractTestStatistic): - +class ST2TestStatistic(AbstractWeibullTestStatistic): @staticmethod + @override def code(): - return 'ST2' + return 'ST2' + '_' + AbstractWeibullTestStatistic.code() # Smooth test statistic based on the kurtosis - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) lv = np.log(rvs) y = np.sort(lv) @@ -164,14 +164,15 @@ def execute_statistic(self, rvs): return WPP_statistic -class ST1TestStatistic(AbstractTestStatistic): - +class ST1TestStatistic(AbstractWeibullTestStatistic): @staticmethod + @override def code(): - return 'ST1' + return 'ST1' + '_' + AbstractWeibullTestStatistic.code() # Smooth test statistic based on the skewness - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, *kwargs): n = len(rvs) lv = np.log(rvs) y = np.sort(lv) @@ -185,14 +186,16 @@ def execute_statistic(self, rvs): return WPP_statistic -class REJGTestStatistic(AbstractTestStatistic): +class REJGTestStatistic(AbstractWeibullTestStatistic): @staticmethod + @override def code(): - return 'REJG' + return 'REJG' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Evans, Johnson and Green based on probability plot - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) lv = np.log(rvs) y = np.sort(lv) @@ -230,14 +233,16 @@ def f1(toto, vect): return (np.exp(-ksi), t, y) -class RSBTestStatistic(AbstractTestStatistic): +class RSBTestStatistic(AbstractWeibullTestStatistic): @staticmethod + @override def code(): - return 'RSB' + return 'RSB' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Smith and Bain based on probability plot - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): n = len(rvs) I = np.arange(1, n + 1) @@ -253,7 +258,7 @@ def execute_statistic(self, rvs): return WPP_statistic -class WeibullNormalizeSpaceTestStatistic(AbstractTestStatistic): +class WeibullNormalizeSpaceTestStatistic(AbstractWeibullTestStatistic): @staticmethod def GoFNS(t, n, m): @@ -271,6 +276,7 @@ def GoFNS(t, n, m): res[i] += q_r * p_r / ((n + 2) * (n + 2)) * (1 / 3 * (q_r - p_r) * d3_Q_r + 1 / 8 * p_r * q_r * d4_Q_r) return res + @override def execute_statistic(self, rvs, type_): m = len(rvs) s = 0 # can be defined @@ -320,17 +326,23 @@ def execute_statistic(self, rvs, type_): class TSWeibullTestStatistic(WeibullNormalizeSpaceTestStatistic): @staticmethod + @override def code(): - return 'TS' + return 'TS' + '_' + AbstractWeibullTestStatistic.code() # Tiku-Singh test statistic - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): """ Tiku M.L. and Singh M., Testing the two-parameter Weibull distribution, Communications in Statistics, 10, 907-918, 1981. :param rvs: :return: + + Parameters + ---------- + **kwargs """ return super().execute_statistic(rvs, 'TS') @@ -338,17 +350,23 @@ def execute_statistic(self, rvs): class LOSWeibullTestStatistic(WeibullNormalizeSpaceTestStatistic): @staticmethod + @override def code(): - return 'LOS' + return 'LOS' + '_' + AbstractWeibullTestStatistic.code() # Lockhart-O'Reilly-Stephens test statistic - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): """ Lockhart R.A., O'Reilly F. and Stephens M.A., Tests for the extreme-value and Weibull distributions based on normalized spacings, Naval Research Logistics Quarterly, 33, 413-421, 1986. :param rvs: :return: + + Parameters + ---------- + **kwargs """ return super().execute_statistic(rvs, 'LOS') @@ -357,22 +375,29 @@ def execute_statistic(self, rvs): class MSFWeibullTestStatistic(WeibullNormalizeSpaceTestStatistic): @staticmethod + @override def code(): - return 'MSF' + return 'MSF' + '_' + AbstractWeibullTestStatistic.code() # Lockhart-O'Reilly-Stephens test statistic - def execute_statistic(self, rvs): + @override + def execute_statistic(self, rvs, **kwargs): """ Mann N.R., Scheuer E.M. and Fertig K.W., A new goodness-of-fit test for the two-parameter Weibull or extreme-value distribution, Communications in Statistics, 2, 383-400, 1973. :param rvs: :return: + + Parameters + ---------- + **kwargs """ return super().execute_statistic(rvs, 'MSF') -class WPPWeibullTestStatistic(AbstractTestStatistic): + +class WPPWeibullTestStatistic(AbstractWeibullTestStatistic): @staticmethod def MLEst(x): if np.min(x) <= 0: @@ -398,8 +423,9 @@ def f1(toto, vect): y = -(y - ksi) * t return {'eta': np.exp(-ksi), 'beta': t, 'y': y} - ##Family of the test statistics based on the probability plot and shapiro-Wilk type tests + # Family of the test statistics based on the probability plot and shapiro-Wilk type tests @staticmethod + @override def execute_statistic(x, type_): n = len(x) lv = np.log(x) @@ -429,7 +455,7 @@ def execute_statistic(x, type_): a = 0.4228 * n - np.sum(Wn) Wn = np.concatenate((Wn, [a])) b = (0.6079 * np.sum(Wn * y) - 0.2570 * np.sum(Wi * y)) / n - WPP_statistic = n * b ** 2/S2 + WPP_statistic = n * b ** 2 / S2 elif type_ == "RSB": m = I / (n + 1) @@ -470,13 +496,16 @@ def execute_statistic(x, type_): return WPP_statistic + class OKWeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'OK' + return 'OK' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Ozturk and Korukoglu + @override def execute_statistic(self, rvs): """ On the W Test for the Extreme Value Distribution @@ -490,62 +519,82 @@ def execute_statistic(self, rvs): return super().execute_statistic(rvs, 'OK') + class SBWeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'SB' + return 'SB' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Shapiro Wilk + @override def execute_statistic(self, rvs): return super().execute_statistic(rvs, 'SB') + class RSBWeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'RSB' + return 'RSB' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Smith and Bain based on probability plot + @override def execute_statistic(self, rvs): return super().execute_statistic(rvs, 'RSB') + class ST2WeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'ST2' + return 'ST2' + '_' + AbstractWeibullTestStatistic.code() # Smooth test statistic based on the kurtosis + @override def execute_statistic(self, rvs): return super().execute_statistic(rvs, 'ST2') + class ST1WeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'ST1' + return 'ST1' + '_' + AbstractWeibullTestStatistic.code() # Smooth test statistic based on the skewness + @override def execute_statistic(self, rvs): return super().execute_statistic(rvs, 'ST1') + class REJGWeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'REJG' + return 'REJG' + '_' + AbstractWeibullTestStatistic.code() # Test statistic of Evans, Johnson and Green based on probability plot + @override def execute_statistic(self, rvs): return super().execute_statistic(rvs, 'REJG') + class SPPWeibullTestStatistic(WPPWeibullTestStatistic): @staticmethod + @override def code(): - return 'SPP' + return 'SPP' + '_' + AbstractWeibullTestStatistic.code() # Test statistic based on stabilized probability plot + @override def execute_statistic(self, rvs): - return super().execute_statistic(rvs, 'SPP') \ No newline at end of file + return super().execute_statistic(rvs, 'SPP') + +# TODO: fix signatures diff --git a/tests/AbstractTestCase.py b/tests/AbstractTestCase.py deleted file mode 100644 index 841a4c0..0000000 --- a/tests/AbstractTestCase.py +++ /dev/null @@ -1,8 +0,0 @@ -import pytest - - -class AbstractTestCase: - - def test_execute_statistic(self, data, result, statistic_test): - statistic = statistic_test.execute_statistic(data) - assert result == pytest.approx(statistic, 0.00001) diff --git a/tests/abstract_test_case.py b/tests/abstract_test_case.py new file mode 100644 index 0000000..865ced1 --- /dev/null +++ b/tests/abstract_test_case.py @@ -0,0 +1,4 @@ +class AbstractTestCase: + @staticmethod + def test_execute_statistic(data, result, statistic_test): # TODO: add generics? + raise "Not implemented" diff --git a/tests/distribution/distribution_test.py b/tests/distribution/distribution_test.py index 0d651df..ab34a6e 100644 --- a/tests/distribution/distribution_test.py +++ b/tests/distribution/distribution_test.py @@ -24,6 +24,7 @@ @pytest.mark.skip(reason="no way of currently testing this") class TestDistribution: + size = 10000 @pytest.mark.parametrize( ("mean", "a", "b"), @@ -34,7 +35,7 @@ class TestDistribution: ], ) def test_generate_uniform(self, mean, a, b): - uniform = generate_uniform(1000, a=a, b=b) + uniform = generate_uniform(self.size / 10, a=a, b=b) e_mean = np.mean(uniform) assert e_mean == pytest.approx(mean, abs=0.2) @@ -47,7 +48,7 @@ def test_generate_uniform(self, mean, a, b): ], ) def test_generate_norm(self, mean, var, a, b): - rvs = generate_norm(10000, mean=a, var=b) + rvs = generate_norm(self.size, mean=a, var=b) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -61,7 +62,7 @@ def test_generate_norm(self, mean, var, a, b): ], ) def test_generate_beta(self, mean, var, a, b): - rvs = generate_beta(10000, a=a, b=b) + rvs = generate_beta(self.size, a=a, b=b) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -74,20 +75,20 @@ def test_generate_beta(self, mean, var, a, b): ], ) def test_generate_cauchy(self, mean, t, s): - rvs = generate_cauchy(10000, t=t, s=s) + rvs = generate_cauchy(self.size, t=t, s=s) e_mean = np.mean(rvs) # cauchy has no mean assert e_mean == pytest.approx(mean, abs=1) @pytest.mark.parametrize( - ("mean", "var", "l"), + ("mean", "var", "lam"), [ (1, 1, 1), (0.25, 1 / 16, 4), ], ) - def test_generate_expon(self, mean, var, l): - rvs = generate_expon(10000, l=l) + def test_generate_expon(self, mean, var, lam): + rvs = generate_expon(self.size, lam) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -101,7 +102,7 @@ def test_generate_expon(self, mean, var, l): ], ) def test_generate_gamma(self, mean, var, alfa, beta): - rvs = generate_gamma(10000, alfa=alfa, beta=beta) + rvs = generate_gamma(self.size, alfa=alfa, beta=beta) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -115,7 +116,7 @@ def test_generate_gamma(self, mean, var, alfa, beta): ], ) def test_generate_gumbel(self, mean, var, mu, beta): - rvs = generate_gumbel(10000, mu=mu, beta=beta) + rvs = generate_gumbel(self.size, mu=mu, beta=beta) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.3) @@ -129,7 +130,7 @@ def test_generate_gumbel(self, mean, var, mu, beta): ], ) def test_generate_laplace(self, mean, var, t, s): - rvs = generate_laplace(10000, t=t, s=s) + rvs = generate_laplace(self.size, t=t, s=s) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -159,7 +160,7 @@ def test_generate_logistic(self, mean, var, t, s): ], ) def test_generate_lognorm(self, mean, var, mu, s): - rvs = generate_lognorm(10000, mu=mu, s=s) + rvs = generate_lognorm(self.size, mu=mu, s=s) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.5) @@ -173,7 +174,7 @@ def test_generate_lognorm(self, mean, var, mu, s): ], ) def test_generate_t(self, mean, var, df): - rvs = generate_t(10000, df=df) + rvs = generate_t(self.size, df=df) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -188,7 +189,7 @@ def test_generate_t(self, mean, var, df): ], ) def test_generate_chi2(self, mean, var, df): - rvs = generate_chi2(10000, df=df) + rvs = generate_chi2(self.size, df=df) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -202,7 +203,7 @@ def test_generate_chi2(self, mean, var, df): ], ) def test_generate_truncnorm(self, mean, var, m, v, a, b): - rvs = generate_truncnorm(10000, mean=m, var=v, a=a, b=b) + rvs = generate_truncnorm(self.size, mean=m, var=v, a=a, b=b) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -216,22 +217,22 @@ def test_generate_truncnorm(self, mean, var, m, v, a, b): ], ) def test_generate_tukey(self, mean, var, lam): - rvs = generate_tukey(10000, lam=lam) + rvs = generate_tukey(self.size, lam=lam) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) assert e_var == pytest.approx(var, abs=0.2) @pytest.mark.parametrize( - ("mean", "var", "k", "l"), + ("mean", "var", "k", "lam"), [ (1, 1, 1, 1), (4, 16, 1, 4), (0.9064, 0.0646614750404533, 4, 1), ], ) - def test_generate_weibull(self, mean, var, k, l): - rvs = generate_weibull(10000, k=k, l=l) + def test_generate_weibull(self, mean, var, k, lam): + rvs = generate_weibull(self.size, k=k, lam=lam) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -245,7 +246,7 @@ def test_generate_weibull(self, mean, var, k, l): ], ) def test_generate_lo_con_norm(self, mean, var, p, a): - rvs = generate_lo_con_norm(10000, p=p, a=a) + rvs = generate_lo_con_norm(self.size, p=p, a=a) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -259,7 +260,7 @@ def test_generate_lo_con_norm(self, mean, var, p, a): ], ) def test_generate_scale_con_norm(self, mean, var, p, b): - rvs = generate_scale_con_norm(10000, p=p, b=b) + rvs = generate_scale_con_norm(self.size, p=p, b=b) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) @@ -273,7 +274,7 @@ def test_generate_scale_con_norm(self, mean, var, p, b): ], ) def test_generate_mix_con_norm(self, mean, var, p, a, b): - rvs = generate_mix_con_norm(10000, p=p, a=a, b=b) + rvs = generate_mix_con_norm(self.size, p=p, a=a, b=b) e_mean = np.mean(rvs) e_var = np.var(rvs) assert e_mean == pytest.approx(mean, abs=0.2) diff --git a/tests/exponentiality/__init__.py b/tests/exponentiality/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/exponentiality/abstract_exponentiality_test_case.py b/tests/exponentiality/abstract_exponentiality_test_case.py new file mode 100644 index 0000000..b7bc076 --- /dev/null +++ b/tests/exponentiality/abstract_exponentiality_test_case.py @@ -0,0 +1,15 @@ +from typing_extensions import override + +import pytest + +from tests.abstract_test_case import AbstractTestCase +from stattest.test.exponent import AbstractExponentialityTestStatistic + + +class AbstractExponentialityTestCase(AbstractTestCase): + + @staticmethod + @override + def test_execute_statistic(data, result, statistic_test: AbstractExponentialityTestStatistic): + statistic = statistic_test.execute_statistic(data) + assert result == pytest.approx(statistic, 0.00001) diff --git a/tests/exponentiality/ahs_exp_test.py b/tests/exponentiality/ahs_exp_test.py new file mode 100644 index 0000000..c2f2e9a --- /dev/null +++ b/tests/exponentiality/ahs_exp_test.py @@ -0,0 +1,20 @@ +import pytest as pytest + +from stattest.test.exponent import AHSTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +# TODO: actual test (7; 10) +@pytest.mark.parametrize( + ("data", "result"), + [ + ([-0.5, 1.7, 1.2, 2.2, 0, -3.2768, 0.42], -0.37900874635568516), + ([1.5, 2.7, -3.8, 4.6, -0.5, -0.6, 0.7, 0.8, -0.9, 10], -0.41), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseAHSExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return AHSTestExp() diff --git a/tests/exponentiality/atk_exp_test.py b/tests/exponentiality/atk_exp_test.py new file mode 100644 index 0000000..c8641aa --- /dev/null +++ b/tests/exponentiality/atk_exp_test.py @@ -0,0 +1,20 @@ +import pytest as pytest + +from stattest.test.exponent import ATKTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +# TODO: actual test (7; 10) +@pytest.mark.parametrize( + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.007564336567134994), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.00858038457884382), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseATKExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return ATKTestExp() diff --git a/tests/exponentiality/co_exp_test.py b/tests/exponentiality/co_exp_test.py new file mode 100644 index 0000000..e823079 --- /dev/null +++ b/tests/exponentiality/co_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import COTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseCOExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return COTestExp() diff --git a/tests/exponentiality/cvm_exp_test.py b/tests/exponentiality/cvm_exp_test.py new file mode 100644 index 0000000..a188434 --- /dev/null +++ b/tests/exponentiality/cvm_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import CVMTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseCVMExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return CVMTestExp() diff --git a/tests/exponentiality/dsp_exp_test.py b/tests/exponentiality/dsp_exp_test.py new file mode 100644 index 0000000..faa11e8 --- /dev/null +++ b/tests/exponentiality/dsp_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import DSPTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseDSPExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return DSPTestExp() diff --git a/tests/exponentiality/ep_exp_test.py b/tests/exponentiality/ep_exp_test.py new file mode 100644 index 0000000..3ff9078 --- /dev/null +++ b/tests/exponentiality/ep_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import EPTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], -1.5476370552787166), + ([1, 2, -3, 4, -5, -6, 7, 8, -9, 10], 50597.27324595228), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseEPExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return EPTestExp() diff --git a/tests/exponentiality/eps_exp_test.py b/tests/exponentiality/eps_exp_test.py new file mode 100644 index 0000000..4c7ee2f --- /dev/null +++ b/tests/exponentiality/eps_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import EPSTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseEPSExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return EPSTestExp() diff --git a/tests/exponentiality/fz_exp_test.py b/tests/exponentiality/fz_exp_test.py new file mode 100644 index 0000000..b74fe91 --- /dev/null +++ b/tests/exponentiality/fz_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import FZTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseFZExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return FZTestExp() diff --git a/tests/exponentiality/gd_exp_test.py b/tests/exponentiality/gd_exp_test.py new file mode 100644 index 0000000..324fc04 --- /dev/null +++ b/tests/exponentiality/gd_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import GDTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseGDExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return GDTestExp() diff --git a/tests/exponentiality/gini_exp_test.py b/tests/exponentiality/gini_exp_test.py new file mode 100644 index 0000000..b8c89bf --- /dev/null +++ b/tests/exponentiality/gini_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import GiniTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseGiniExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return GiniTestExp() diff --git a/tests/exponentiality/hg1_exp_test.py b/tests/exponentiality/hg1_exp_test.py new file mode 100644 index 0000000..ab3cc7c --- /dev/null +++ b/tests/exponentiality/hg1_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import HG1TestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseHG1ExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return HG1TestExp() diff --git a/tests/exponentiality/hg2_exp_test.py b/tests/exponentiality/hg2_exp_test.py new file mode 100644 index 0000000..6024303 --- /dev/null +++ b/tests/exponentiality/hg2_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import HG2TestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseHG2ExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return HG2TestExp() diff --git a/tests/exponentiality/hm_exp_test.py b/tests/exponentiality/hm_exp_test.py new file mode 100644 index 0000000..87e89b3 --- /dev/null +++ b/tests/exponentiality/hm_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import HMTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseHMExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return HMTestExp() diff --git a/tests/exponentiality/hp_exp_test.py b/tests/exponentiality/hp_exp_test.py new file mode 100644 index 0000000..fa0ede1 --- /dev/null +++ b/tests/exponentiality/hp_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import HPTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseHPExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return HPTestExp() diff --git a/tests/exponentiality/kc_exp_test.py b/tests/exponentiality/kc_exp_test.py new file mode 100644 index 0000000..d7811b9 --- /dev/null +++ b/tests/exponentiality/kc_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import KCTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseKCExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return KCTestExp() diff --git a/tests/exponentiality/km_exp_test.py b/tests/exponentiality/km_exp_test.py new file mode 100644 index 0000000..3785ae8 --- /dev/null +++ b/tests/exponentiality/km_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import KMTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17378394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16282061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseKMExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return KMTestExp() diff --git a/tests/exponentiality/ks_exp_test.py b/tests/exponentiality/ks_exp_test.py new file mode 100644 index 0000000..0cd9d3d --- /dev/null +++ b/tests/exponentiality/ks_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import KSTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseKSExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return KSTestExp() diff --git a/tests/exponentiality/lz_exp_test.py b/tests/exponentiality/lz_exp_test.py new file mode 100644 index 0000000..acb827b --- /dev/null +++ b/tests/exponentiality/lz_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import LZTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseLZExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return LZTestExp() diff --git a/tests/exponentiality/mn_exp_test.py b/tests/exponentiality/mn_exp_test.py new file mode 100644 index 0000000..2e12296 --- /dev/null +++ b/tests/exponentiality/mn_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import MNTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseMNExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return MNTestExp() diff --git a/tests/exponentiality/pt_exp_test.py b/tests/exponentiality/pt_exp_test.py new file mode 100644 index 0000000..721f68f --- /dev/null +++ b/tests/exponentiality/pt_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import PTTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCasePTExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return PTTestExp() diff --git a/tests/exponentiality/rs_exp_test.py b/tests/exponentiality/rs_exp_test.py new file mode 100644 index 0000000..872fdd1 --- /dev/null +++ b/tests/exponentiality/rs_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import RSTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseRSExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return RSTestExp() diff --git a/tests/exponentiality/sw_exp_test.py b/tests/exponentiality/sw_exp_test.py new file mode 100644 index 0000000..50ebf3a --- /dev/null +++ b/tests/exponentiality/sw_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import SWTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseSWExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return SWTestExp() diff --git a/tests/exponentiality/we_exp_test.py b/tests/exponentiality/we_exp_test.py new file mode 100644 index 0000000..7f5ffa3 --- /dev/null +++ b/tests/exponentiality/we_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import WETestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseWEExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return WETestExp() diff --git a/tests/exponentiality/ww_exp_test.py b/tests/exponentiality/ww_exp_test.py new file mode 100644 index 0000000..6a07097 --- /dev/null +++ b/tests/exponentiality/ww_exp_test.py @@ -0,0 +1,19 @@ +import pytest as pytest + +from stattest.test.exponent import WWTestExp +from tests.exponentiality.abstract_exponentiality_test_case import AbstractExponentialityTestCase + + +@pytest.mark.parametrize( # TODO: actual test (7; 10) + ("data", "result"), + [ + ([1, 2, 3, 4, 5, 6, 7], 0.17377394345044517), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.16232061118184815), + ], +) +@pytest.mark.skip(reason="fix test and check") +class TestCaseWWExponentialityTest(AbstractExponentialityTestCase): + + @pytest.fixture + def statistic_test(self): + return WWTestExp() diff --git a/tests/normality/abstract_normality_test_case.py b/tests/normality/abstract_normality_test_case.py new file mode 100644 index 0000000..0fed2db --- /dev/null +++ b/tests/normality/abstract_normality_test_case.py @@ -0,0 +1,16 @@ +from typing_extensions import override + +import pytest + +from tests.abstract_test_case import AbstractTestCase +from stattest.test.normal import AbstractNormalityTestStatistic +from abc import ABC + + +class AbstractNormalityTestCase(AbstractTestCase, ABC): + + @staticmethod + @override + def test_execute_statistic(data, result, statistic_test: AbstractNormalityTestStatistic): + statistic = statistic_test.execute_statistic(data) + assert result == pytest.approx(statistic, 0.00001) diff --git a/tests/normality/ad_test.py b/tests/normality/ad_test.py index d761e64..a6ee36f 100644 --- a/tests/normality/ad_test.py +++ b/tests/normality/ad_test.py @@ -1,7 +1,7 @@ import pytest as pytest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase from stattest.test.normal import ADTestStatistic -from tests.AbstractTestCase import AbstractTestCase @pytest.mark.parametrize( @@ -15,7 +15,7 @@ ], ) @pytest.mark.skip(reason="no way of currently testing this") -class TestCaseADTest(AbstractTestCase): +class TestCaseADNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): diff --git a/tests/normality/bhs_test.py b/tests/normality/bhs_test.py index 6a4d7d1..8897d4a 100644 --- a/tests/normality/bhs_test.py +++ b/tests/normality/bhs_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import BHSTest -from tests.AbstractTestCase import AbstractTestCase +from stattest.test.normal import BHSNormalityTest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase @pytest.mark.parametrize( @@ -14,8 +14,8 @@ ) # TODO: remove skip @pytest.mark.skip(reason="no way of currently testing this") -class TestCaseBHSTest(AbstractTestCase): +class TestCaseBHSNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return BHSTest() + return BHSNormalityTest() diff --git a/tests/normality/bonett_seier_test.py b/tests/normality/bonett_seier_test.py index 7ebee1c..97ed608 100644 --- a/tests/normality/bonett_seier_test.py +++ b/tests/normality/bonett_seier_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import BonettSeierTest -from tests.AbstractTestCase import AbstractTestCase +from stattest.test.normal import BonettSeierNormalityTest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase @pytest.mark.parametrize( @@ -13,8 +13,8 @@ ], ) -class TestCaseBonettSeierTest(AbstractTestCase): +class TestCaseBonettSeierNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return BonettSeierTest() + return BonettSeierNormalityTest() diff --git a/tests/normality/botemps_meddahi1_test.py b/tests/normality/botemps_meddahi1_test.py index ed73c3b..731c577 100644 --- a/tests/normality/botemps_meddahi1_test.py +++ b/tests/normality/botemps_meddahi1_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import BontempsMeddahi1Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import BontempsMeddahi1NormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.79256755, 0.36811349, -0.56170844, 3.15364608], 4.814269), ], ) -class TestCaseZhangWuCTest(AbstractTestCase): +class TestCaseZhangWuCNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return BontempsMeddahi1Test() + return BontempsMeddahi1NormalityTest() diff --git a/tests/normality/botemps_meddahi2_test.py b/tests/normality/botemps_meddahi2_test.py index e57f176..8ac09ad 100644 --- a/tests/normality/botemps_meddahi2_test.py +++ b/tests/normality/botemps_meddahi2_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import BontempsMeddahi2Test -from tests.AbstractTestCase import AbstractTestCase +from stattest.test.normal import BontempsMeddahi2NormalityTest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.4190111, 0.6978357], 1.170676), ], ) -class TestCaseZhangWuCTest(AbstractTestCase): +class TestCaseZhangWuCNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return BontempsMeddahi2Test() + return BontempsMeddahi2NormalityTest() diff --git a/tests/normality/cabana_cabana1_test.py b/tests/normality/cabana_cabana1_test.py index 6a5fe07..f987c1e 100644 --- a/tests/normality/cabana_cabana1_test.py +++ b/tests/normality/cabana_cabana1_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import CabanaCabana1Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import CabanaCabana1NormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.99395022, -0.28167969, 0.11683112, 0.68954236], 0.5265257), ], ) -class TestCaseCabanaCabana1Test(AbstractTestCase): +class TestCaseCabanaCabana1NormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return CabanaCabana1Test() + return CabanaCabana1NormalityTest() diff --git a/tests/normality/cabana_cabana2_test.py b/tests/normality/cabana_cabana2_test.py index f02a427..d75bbf7 100644 --- a/tests/normality/cabana_cabana2_test.py +++ b/tests/normality/cabana_cabana2_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import CabanaCabana2Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import CabanaCabana2NormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.99395022, -0.28167969, 0.11683112, 0.68954236], 0.1238103), ], ) -class TestCaseCabanaCabana2Test(AbstractTestCase): +class TestCaseCabanaCabana2NormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return CabanaCabana2Test() + return CabanaCabana2NormalityTest() diff --git a/tests/normality/chen_shapiro_test.py b/tests/normality/chen_shapiro_test.py index 18d9b27..fd87635 100644 --- a/tests/normality/chen_shapiro_test.py +++ b/tests/normality/chen_shapiro_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import ChenShapiroTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import ChenShapiroNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -0.7751734, -1.8370833], -0.1217789), ], ) -class TestCaseZhangWuCTest(AbstractTestCase): +class TestCaseZhangWuCNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return ChenShapiroTest() + return ChenShapiroNormalityTest() diff --git a/tests/normality/coin_test.py b/tests/normality/coin_test.py index b3ca5ba..add6fa8 100644 --- a/tests/normality/coin_test.py +++ b/tests/normality/coin_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import CoinTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import CoinNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.28462605, 0.22804695, -0.29829152], 0.0009059856), ], ) -class TestCaseCoinTest(AbstractTestCase): +class TestCaseCoinNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return CoinTest() + return CoinNormalityTest() diff --git a/tests/normality/da_test.py b/tests/normality/da_test.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/normality/dagostino_test.py b/tests/normality/dagostino_test.py index 5a4a916..8e25183 100644 --- a/tests/normality/dagostino_test.py +++ b/tests/normality/dagostino_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import DagostinoTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import DagostinoNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -1.47549650, 0.42478574, 0.91713384, 0.24491208], -0.7608445), ], ) -class TestCaseDagostinoTest(AbstractTestCase): +class TestCaseDagostinoNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return DagostinoTest() + return DagostinoNormalityTest() diff --git a/tests/normality/dap_test.py b/tests/normality/dap_test.py index 58f3402..45243f1 100644 --- a/tests/normality/dap_test.py +++ b/tests/normality/dap_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import DAPTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import DAPNormalityTest @pytest.mark.parametrize( @@ -11,8 +11,8 @@ ([16, 18, 16, 14, 12, 12, 16, 18, 16, 14, 12, 12], 2.5224), ], ) -class TestCaseDAPTest(AbstractTestCase): +class TestCaseDAPNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return DAPTest() + return DAPNormalityTest() diff --git a/tests/normality/desgagne_lafaye_test.py b/tests/normality/desgagne_lafaye_test.py index e9fc2be..aba8133 100644 --- a/tests/normality/desgagne_lafaye_test.py +++ b/tests/normality/desgagne_lafaye_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import DesgagneLafayeTest -from tests.AbstractTestCase import AbstractTestCase +from stattest.test.normal import DesgagneLafayeNormalityTest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -0.03375564, 1.30610658], 0.8639117) ] ) -class TestDesgagneLafayeTest(AbstractTestCase): +class TestDesgagneLafayeTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return DesgagneLafayeTest() + return DesgagneLafayeNormalityTest() diff --git a/tests/normality/doornik_hasen_test.py b/tests/normality/doornik_hasen_test.py index a42acd0..3552349 100644 --- a/tests/normality/doornik_hasen_test.py +++ b/tests/normality/doornik_hasen_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import DoornikHansenTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import DoornikHansenNormalityTest @pytest.mark.parametrize( @@ -13,8 +13,8 @@ 1.50767670, -0.08592902, -0.46234996, 0.29561229, 0.32708351], 2.145117), ], ) -class TestCaseDoornikHasenTest(AbstractTestCase): +class TestCaseDoornikHasenNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return DoornikHansenTest() + return DoornikHansenNormalityTest() diff --git a/tests/normality/ep_test.py b/tests/normality/ep_test.py index 5eb1da3..0ec8e9a 100644 --- a/tests/normality/ep_test.py +++ b/tests/normality/ep_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import EPTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import EPNormalityTest @pytest.mark.parametrize( @@ -14,8 +14,8 @@ ], 0.05191694742233466), ], ) -class TestCaseEPTest(AbstractTestCase): +class TestCaseEPNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return EPTest() + return EPNormalityTest() diff --git a/tests/normality/filli_test.py b/tests/normality/filli_test.py index 78c4e1c..b036905 100644 --- a/tests/normality/filli_test.py +++ b/tests/normality/filli_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import FilliTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import FilliNormalityTest @pytest.mark.parametrize( @@ -10,8 +10,8 @@ ([-4, -2, 0, 1, 5, 6, 8], 0.9854095718708367), ], ) -class TestCaseFilliTest(AbstractTestCase): +class TestCaseFilliNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return FilliTest() + return FilliNormalityTest() diff --git a/tests/normality/glen_leemis_barr_test.py b/tests/normality/glen_leemis_barr_test.py index d6dd33d..a02386c 100644 --- a/tests/normality/glen_leemis_barr_test.py +++ b/tests/normality/glen_leemis_barr_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import GlenLeemisBarrTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import GlenLeemisBarrNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -0.45549464], 12.54511), ], ) -class TestCaseGlenLeemisBarrTest(AbstractTestCase): +class TestCaseGlenLeemisBarrNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return GlenLeemisBarrTest() + return GlenLeemisBarrNormalityTest() diff --git a/tests/normality/gmg_test.py b/tests/normality/gmg_test.py index 248acc3..dfbae9b 100644 --- a/tests/normality/gmg_test.py +++ b/tests/normality/gmg_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import GMGTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import GMGNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.07543129, -0.03098110, -0.72435341, -0.90046224], 1.066354), ], ) -class TestCaseGMGTest(AbstractTestCase): +class TestCaseGMGNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return GMGTest() + return GMGNormalityTest() diff --git a/tests/normality/hosking1_test.py b/tests/normality/hosking1_test.py index e1b9f80..e8a6b92 100644 --- a/tests/normality/hosking1_test.py +++ b/tests/normality/hosking1_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import Hosking1Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import Hosking1NormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -0.18712276, 0.12134652, 0.25866486], 3.347533), ], ) -class TestCaseHosking1Test(AbstractTestCase): +class TestCaseHosking1NormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return Hosking1Test() + return Hosking1NormalityTest() diff --git a/tests/normality/hosking2_test.py b/tests/normality/hosking2_test.py index ba73508..c2fb09d 100644 --- a/tests/normality/hosking2_test.py +++ b/tests/normality/hosking2_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import Hosking2Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import Hosking2NormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -0.8224675], 1.693243), ], ) -class TestCaseHosking2Test(AbstractTestCase): +class TestCaseHosking2NormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return Hosking2Test() + return Hosking2NormalityTest() diff --git a/tests/normality/hosking3_t.py b/tests/normality/hosking3_t.py index 6340eea..08220f7 100644 --- a/tests/normality/hosking3_t.py +++ b/tests/normality/hosking3_t.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import Hosking3Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import Hosking3NormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.5032659, 0.3810323, 0.8924223, 1.8037073], 117.5835), ], ) -class TestCaseHosking3Test(AbstractTestCase): +class TestCaseHosking3NormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return Hosking3Test() + return Hosking3NormalityTest() diff --git a/tests/normality/hosking4_test.py b/tests/normality/hosking4_test.py index f70135d..bd7881d 100644 --- a/tests/normality/hosking4_test.py +++ b/tests/normality/hosking4_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import Hosking4Test -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import Hosking4NormalityTest @pytest.mark.parametrize( @@ -13,8 +13,8 @@ 1.57505463, -0.34043549], 3.111041), ], ) -class TestCaseHosking4Test(AbstractTestCase): +class TestCaseHosking4NormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return Hosking4Test() + return Hosking4NormalityTest() diff --git a/tests/normality/jb_test.py b/tests/normality/jb_test.py index 410d574..a5b6eeb 100644 --- a/tests/normality/jb_test.py +++ b/tests/normality/jb_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import JBTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import JBNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.83445286, 0.72505429, 1.25012578, -1.11276931], 0.44334632590843914), ], ) -class TestCaseJBTest(AbstractTestCase): +class TestCaseJBNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return JBTest() + return JBNormalityTest() diff --git a/tests/normality/ks_test.py b/tests/normality/ks_test.py index aab54b1..4916cda 100644 --- a/tests/normality/ks_test.py +++ b/tests/normality/ks_test.py @@ -1,7 +1,7 @@ import pytest as pytest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase from stattest.test.normal import KSNormalityTest -from tests.AbstractTestCase import AbstractTestCase @pytest.mark.parametrize( @@ -21,7 +21,7 @@ 0.95253258, -1.17323879], 0.12958652448618313) ], ) -class TestCaseKSTest(AbstractTestCase): +class TestCaseKSNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): diff --git a/tests/normality/kurtosis_test.py b/tests/normality/kurtosis_test.py index 9c1201f..f370678 100644 --- a/tests/normality/kurtosis_test.py +++ b/tests/normality/kurtosis_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import KurtosisTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import KurtosisNormalityTest @pytest.mark.parametrize( @@ -10,8 +10,8 @@ ([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236], 2.3048235214240873), ], ) -class TestCaseKurtosisTest(AbstractTestCase): +class TestCaseKurtosisNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return KurtosisTest() + return KurtosisNormalityTest() diff --git a/tests/normality/lg_test.py b/tests/normality/lg_test.py index 5a47e3b..16b1326 100644 --- a/tests/normality/lg_test.py +++ b/tests/normality/lg_test.py @@ -1,8 +1,7 @@ import pytest as pytest -from stattest.test.normal import LooneyGulledgeTest -from tests.AbstractTestCase import AbstractTestCase - +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import LooneyGulledgeNormalityTest @pytest.mark.parametrize( ("data", "result"), @@ -10,8 +9,8 @@ ([148, 154, 158, 160, 161, 162, 166, 170, 170, 182, 195], 0.956524208286), ], ) -class TestCaseLGTest(AbstractTestCase): +class TestCaseLGNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return LooneyGulledgeTest() + return LooneyGulledgeNormalityTest() diff --git a/tests/normality/lilliefors_test.py b/tests/normality/lilliefors_test.py index 12180f7..d67b971 100644 --- a/tests/normality/lilliefors_test.py +++ b/tests/normality/lilliefors_test.py @@ -1,7 +1,7 @@ import pytest as pytest +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase from stattest.test.normal import LillieforsNormalityTest -from tests.AbstractTestCase import AbstractTestCase @pytest.mark.parametrize( @@ -13,7 +13,7 @@ 1.25378956, -0.64296653, 0.25356762, 0.23345769], 0.1695222), ], ) -class TestCaseLillieforsTest(AbstractTestCase): +class TestCaseLillieforsTestNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): diff --git a/tests/normality/martinez_iglewicz_test.py b/tests/normality/martinez_iglewicz_test.py index a9604f5..5a9a13e 100644 --- a/tests/normality/martinez_iglewicz_test.py +++ b/tests/normality/martinez_iglewicz_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import MartinezIglewiczTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import MartinezIglewiczNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.3070847, -1.6807102, -1.7846244, -0.3949447], 1.020476), ], ) -class TestCaseMartinezIglewiczTest(AbstractTestCase): +class TestCaseMartinezIglewiczNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return MartinezIglewiczTest() + return MartinezIglewiczNormalityTest() diff --git a/tests/normality/rj_test.py b/tests/normality/rj_test.py index 0eccf98..1f5648f 100644 --- a/tests/normality/rj_test.py +++ b/tests/normality/rj_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import RyanJoinerTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import RyanJoinerNormalityTest @pytest.mark.parametrize( @@ -11,8 +11,8 @@ ([6, 1, -4, 8, -2, 5, 0], 0.9844829186140105), ], ) -class TestCaseRJTest(AbstractTestCase): +class TestCaseRJNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return RyanJoinerTest() + return RyanJoinerNormalityTest() diff --git a/tests/normality/robust_jarque_bera_test.py b/tests/normality/robust_jarque_bera_test.py index 0756b1c..d22eaf9 100644 --- a/tests/normality/robust_jarque_bera_test.py +++ b/tests/normality/robust_jarque_bera_test.py @@ -1,8 +1,8 @@ import pytest as pytest -from stattest.test.normal import RobustJarqueBeraTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import RobustJarqueBeraNormalityTest @pytest.mark.parametrize( ("data", "result"), @@ -13,8 +13,8 @@ ], ) -class TestCaseRobustJarqueBeraTest(AbstractTestCase): +class TestCaseRobustJarqueBeraNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return RobustJarqueBeraTest() + return RobustJarqueBeraNormalityTest() diff --git a/tests/normality/sf_test.py b/tests/normality/sf_test.py index de41518..30c6620 100644 --- a/tests/normality/sf_test.py +++ b/tests/normality/sf_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import SFTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import SFNormalityTest @pytest.mark.parametrize( @@ -11,8 +11,8 @@ 0.8756286], 0.93569), ], ) -class TestCaseSFTest(AbstractTestCase): +class TestCaseSFNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return SFTest() + return SFNormalityTest() diff --git a/tests/normality/skew_test.py b/tests/normality/skew_test.py index 95c0b33..bff6375 100644 --- a/tests/normality/skew_test.py +++ b/tests/normality/skew_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import SkewTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import SkewNormalityTest @pytest.mark.parametrize( @@ -10,8 +10,8 @@ ([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236], 2.7788579769903414), ], ) -class TestCaseSkewTest(AbstractTestCase): +class TestCaseSkewNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return SkewTest() + return SkewNormalityTest() diff --git a/tests/normality/spiegelhalter_test.py b/tests/normality/spiegelhalter_test.py index cfdcfcc..3376eb5 100644 --- a/tests/normality/spiegelhalter_test.py +++ b/tests/normality/spiegelhalter_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import SpiegelhalterTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import SpiegelhalterNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 1.3267088, -0.3299987, -0.5767829, -1.4114579], 1.374628), ], ) -class TestCaseSpiegelhalterTest(AbstractTestCase): +class TestCaseSpiegelhalterNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return SpiegelhalterTest() + return SpiegelhalterNormalityTest() diff --git a/tests/normality/sw_test.py b/tests/normality/sw_test.py index b66db3f..7a549a4 100644 --- a/tests/normality/sw_test.py +++ b/tests/normality/sw_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import SWTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import SWNormalityTest @pytest.mark.parametrize( @@ -13,8 +13,8 @@ ([38.7, 41.5, 43.8, 44.5, 45.5, 46.0, 47.7, 58.0], 0.872973), ], ) -class TestCaseSWTest(AbstractTestCase): +class TestCaseSWNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return SWTest() + return SWNormalityTest() diff --git a/tests/normality/swm_test.py b/tests/normality/swm_test.py new file mode 100644 index 0000000..3ddc093 --- /dev/null +++ b/tests/normality/swm_test.py @@ -0,0 +1,23 @@ + +""" # TODO: check this test +import pytest as pytest + +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import SWMNormalityTest + + +@pytest.mark.parametrize( + ("data", "result"), + [ + ([12, 12, 12, 12, 14, 14, 16, 16, 16, 16, 18], 3.66666666), + ([18, 16, 16, 16, 16, 14, 14, 12, 12, 12, 12], 3.66666666), + ([-1.71228079, -0.86710019, 0.29950617, 1.18632683, -0.13929811, -1.47008114, + -1.29073683, 1.18998087, 0.80807576, 0.45558552], 0.07474902435493411), + ], +) +class TestCaseSWMNormalityTest(AbstractNormalityTestCase): + + @pytest.fixture + def statistic_test(self): + return SWMNormalityTest() +""" \ No newline at end of file diff --git a/tests/normality/swrg_test.py b/tests/normality/swrg_test.py index 60561be..2319a4b 100644 --- a/tests/normality/swrg_test.py +++ b/tests/normality/swrg_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import SWRGTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import SWRGNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ 0.35588475, -0.44262575, 0.28699128, -0.66855218], 0.9092612), ], ) -class TestCaseZhangWuCTest(AbstractTestCase): +class TestCaseZhangWuCNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return SWRGTest() + return SWRGNormalityTest() diff --git a/tests/normality/zhang_q_test.py b/tests/normality/zhang_q_test.py index 5cac684..2240438 100644 --- a/tests/normality/zhang_q_test.py +++ b/tests/normality/zhang_q_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import ZhangQTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import ZhangQNormalityTest @pytest.mark.parametrize( @@ -13,8 +13,8 @@ 2.25757863, -0.83696957, 0.01074617, -0.34492908], -0.2811746), ], ) -class TestCaseZhangQTest(AbstractTestCase): +class TestCaseZhangQNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return ZhangQTest() + return ZhangQNormalityTest() diff --git a/tests/normality/zhang_qstar_test.py b/tests/normality/zhang_qstar_test.py index 5fcd68b..da474a3 100644 --- a/tests/normality/zhang_qstar_test.py +++ b/tests/normality/zhang_qstar_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import ZhangQStarTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import ZhangQStarNormalityTest @pytest.mark.parametrize( @@ -13,8 +13,8 @@ 1.0786708, -0.1585859, -1.0140335, 1.0448026], -0.5880094), ], ) -class TestCaseZhangQStarTest(AbstractTestCase): +class TestCaseZhangQStarNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return ZhangQStarTest() + return ZhangQStarNormalityTest() diff --git a/tests/normality/zhang_wu_a_test.py b/tests/normality/zhang_wu_a_test.py index 3daf49e..266c926 100644 --- a/tests/normality/zhang_wu_a_test.py +++ b/tests/normality/zhang_wu_a_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import ZhangWuATest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import ZhangWuANormalityTest @pytest.mark.parametrize( @@ -13,12 +13,8 @@ ], ) @pytest.mark.skip(reason="no way of currently testing this") -class TestCaseZhangWuATest(AbstractTestCase): - - def test_execute_statistic(self, data, result, statistic_test): - statistic = statistic_test.execute_statistic(data) - assert result == pytest.approx(statistic, 0.1) +class TestCaseZhangWuCNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return ZhangWuATest() + return ZhangWuANormalityTest() diff --git a/tests/normality/zhang_wu_c_test.py b/tests/normality/zhang_wu_c_test.py index 4339498..54f0aa4 100644 --- a/tests/normality/zhang_wu_c_test.py +++ b/tests/normality/zhang_wu_c_test.py @@ -1,7 +1,7 @@ import pytest as pytest -from stattest.test.normal import ZhangWuCTest -from tests.AbstractTestCase import AbstractTestCase +from tests.normality.abstract_normality_test_case import AbstractNormalityTestCase +from stattest.test.normal import ZhangWuCNormalityTest @pytest.mark.parametrize( @@ -12,8 +12,8 @@ -0.70401541, 1.16743393], 5.607312), ], ) -class TestCaseZhangWuCTest(AbstractTestCase): +class TestCaseZhangWuCNormalityTest(AbstractNormalityTestCase): @pytest.fixture def statistic_test(self): - return ZhangWuCTest() + return ZhangWuCNormalityTest() diff --git a/weibull_experiment.py b/weibull_experiment.py index 8ccfa65..b8629bb 100644 --- a/weibull_experiment.py +++ b/weibull_experiment.py @@ -5,9 +5,8 @@ from stattest.experiment.configuration.configuration import TestConfiguration from stattest.experiment.report.model import PdfPowerReportBuilder, PowerResultReader from stattest.experiment.test.worker import PowerCalculationWorker -from stattest.persistence.sql_lite_store.critical_value_store import CriticalValueSqlLiteStore +from stattest.persistence.sql_lite_store import CriticalValueSqLiteStore, RvsSqLiteStore from stattest.persistence.sql_lite_store.power_result_store import PowerResultSqlLiteStore -from stattest.persistence.sql_lite_store.rvs_store import RvsSqlLiteStore from stattest.test import KSWeibullTest if __name__ == '__main__': @@ -25,7 +24,7 @@ listeners=listeners) tests = [KSWeibullTest()] - critical_value_store = CriticalValueSqlLiteStore() + critical_value_store = CriticalValueSqLiteStore() power_result_store = PowerResultSqlLiteStore() power_calculation_worker = PowerCalculationWorker(0.05, 1_000_000, power_result_store, critical_value_store, hypothesis=WeibullHypothesis()) @@ -37,12 +36,12 @@ reader = PowerResultReader(power_result_store) report_configuration = ReportConfiguration(report_builder, reader) - rvs_store = RvsSqlLiteStore() + rvs_store = RvsSqLiteStore() experiment_configuration = ExperimentConfiguration(alternatives_configuration, test_configuration, report_configuration, rvs_store=rvs_store, - critical_value_store=CriticalValueSqlLiteStore()) + critical_value_store=CriticalValueSqLiteStore()) experiment = Experiment(experiment_configuration) # Execute experiment