ezsnake 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. ezsnake-0.1.0/.gitignore +10 -0
  2. ezsnake-0.1.0/.python-version +1 -0
  3. ezsnake-0.1.0/PKG-INFO +131 -0
  4. ezsnake-0.1.0/README.md +116 -0
  5. ezsnake-0.1.0/licence.md +21 -0
  6. ezsnake-0.1.0/pyproject.toml +30 -0
  7. ezsnake-0.1.0/src/ezsnake/__init__.py +2 -0
  8. ezsnake-0.1.0/src/ezsnake/matlab/__init__.py +42 -0
  9. ezsnake-0.1.0/src/ezsnake/matlab/betacdf.py +43 -0
  10. ezsnake-0.1.0/src/ezsnake/matlab/betafit.py +132 -0
  11. ezsnake-0.1.0/src/ezsnake/matlab/betainv.py +76 -0
  12. ezsnake-0.1.0/src/ezsnake/matlab/betalike.py +147 -0
  13. ezsnake-0.1.0/src/ezsnake/matlab/betapdf.py +45 -0
  14. ezsnake-0.1.0/src/ezsnake/matlab/datenum_converter.py +71 -0
  15. ezsnake-0.1.0/src/ezsnake/matlab/distchck.py +39 -0
  16. ezsnake-0.1.0/src/ezsnake/matlab/hist.py +30 -0
  17. ezsnake-0.1.0/src/ezsnake/matlab/logncdf.py +45 -0
  18. ezsnake-0.1.0/src/ezsnake/matlab/lognfit.py +48 -0
  19. ezsnake-0.1.0/src/ezsnake/matlab/logninv.py +38 -0
  20. ezsnake-0.1.0/src/ezsnake/matlab/lognlike.py +54 -0
  21. ezsnake-0.1.0/src/ezsnake/matlab/lognpdf.py +36 -0
  22. ezsnake-0.1.0/src/ezsnake/matlab/lognrnd.py +34 -0
  23. ezsnake-0.1.0/src/ezsnake/matlab/lognstat.py +35 -0
  24. ezsnake-0.1.0/src/ezsnake/matlab/matlab.py +0 -0
  25. ezsnake-0.1.0/src/ezsnake/matlab/normcdf.py +66 -0
  26. ezsnake-0.1.0/src/ezsnake/matlab/normfit.py +58 -0
  27. ezsnake-0.1.0/src/ezsnake/matlab/norminv.py +25 -0
  28. ezsnake-0.1.0/src/ezsnake/matlab/normlike.py +49 -0
  29. ezsnake-0.1.0/src/ezsnake/matlab/normpdf.py +29 -0
  30. ezsnake-0.1.0/src/ezsnake/netcdf/__init__.py +4 -0
  31. ezsnake-0.1.0/src/ezsnake/netcdf/netcdf.py +170 -0
  32. ezsnake-0.1.0/src/ezsnake/netcdf/netcdf_schema.py +30 -0
  33. ezsnake-0.1.0/src/ezsnake/utils/__init__.py +25 -0
  34. ezsnake-0.1.0/src/ezsnake/utils/coords_converter.py +129 -0
  35. ezsnake-0.1.0/src/ezsnake/utils/utils.py +232 -0
  36. ezsnake-0.1.0/src/ezsnake/word_template_writer/README.md +886 -0
  37. ezsnake-0.1.0/src/ezsnake/word_template_writer/__init__.py +111 -0
  38. ezsnake-0.1.0/src/ezsnake/word_template_writer/_document_helpers.py +223 -0
  39. ezsnake-0.1.0/src/ezsnake/word_template_writer/_figure_helpers.py +352 -0
  40. ezsnake-0.1.0/src/ezsnake/word_template_writer/_table_helpers.py +455 -0
  41. ezsnake-0.1.0/src/ezsnake/word_template_writer/_table_styling.py +207 -0
  42. ezsnake-0.1.0/src/ezsnake/word_template_writer/_text_helpers.py +103 -0
  43. ezsnake-0.1.0/src/ezsnake/word_template_writer/api.py +471 -0
  44. ezsnake-0.1.0/src/ezsnake/word_template_writer/ejemplo_de_constructor_de_datos.py +120 -0
  45. ezsnake-0.1.0/src/ezsnake/word_template_writer/schemas_helpers.py +595 -0
  46. ezsnake-0.1.0/src/ezsnake/word_template_writer/utils.py +51 -0
  47. ezsnake-0.1.0/tests/test_dict2nc.py +69 -0
  48. ezsnake-0.1.0/uv.lock +573 -0
@@ -0,0 +1,10 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
@@ -0,0 +1 @@
1
+ 3.14.3
ezsnake-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,131 @@
1
+ Metadata-Version: 2.4
2
+ Name: ezsnake
3
+ Version: 0.1.0
4
+ Summary: ezsnake is a Python package for working with NetCDF files, a framework for working with python-docx, openpyxl, and also MATLAB datenum conversions into pandas Datetime format, providing an easy-to-use interface for data manipulation and analysis.
5
+ Author-email: "Fernando Bello Fuentes (BelloDev)" <fernandojbf123@gmail.com>
6
+ License-File: licence.md
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: netcdf4>=1.7.4
9
+ Requires-Dist: numpy>=2.0
10
+ Requires-Dist: openpyxl>=3.1
11
+ Requires-Dist: pandas>=2.0
12
+ Requires-Dist: python-docx>=1.1
13
+ Requires-Dist: scipy>=1.17.1
14
+ Description-Content-Type: text/markdown
15
+
16
+
17
+ # ezsnake
18
+
19
+ Librer铆a de utilidades cient铆ficas en Python para NetCDF, manipulaci贸n avanzada de Word, utilidades geogr谩ficas y funciones tipo MATLAB.
20
+
21
+ ---
22
+
23
+ ## 馃摝 M贸dulos principales
24
+
25
+ ### 1. NetCDF (`ezsnake.netcdf`)
26
+ Lectura, exploraci贸n y escritura de archivos NetCDF usando netCDF4.
27
+
28
+ **Funciones principales:**
29
+ - `load_nc(ruta, variable=None)`
30
+ - `view_att(ruta, variable=None)`
31
+ - `dict2nc(ruta, data)`
32
+
33
+ ### 2. Word Template Writer (`ezsnake.word_template_writer`)
34
+ Automatizaci贸n avanzada de plantillas Word (.docx): inserci贸n de figuras, referencias cruzadas, reemplazo de variables, tablas y documentos externos.
35
+
36
+ **API p煤blica:**
37
+ - `insertar_figuras_en_plantilla(doc, diccionario_de_reemplazos)`
38
+ - `insertar_referencias_cruzadas_en_plantilla(doc, diccionario_de_reemplazos)`
39
+ - `reemplazar_texto_en_plantilla(doc, diccionario_de_reemplazos)`
40
+ - `insertar_documento_externo_en_plantilla(doc, diccionario_de_reemplazos)`
41
+ - `rellenar_tablas_en_plantilla(doc, diccionario_de_reemplazos)`
42
+ - `reemplazar_variables_en_tablas(doc, diccionario_de_reemplazos)`
43
+
44
+ ### 3. MATLAB-like (`ezsnake.matlab`)
45
+ Funciones cient铆ficas compatibles con MATLAB para estad铆stica, distribuciones y conversi贸n de fechas:
46
+
47
+ **Funciones principales:**
48
+ - `betacdf`, `betafit`, `betainv`, `betalike`, `betapdf`, `betaln`
49
+ - `datenum_to_datetime`, `datenum_to_pd_datetime`
50
+ - `distchck`, `hist`
51
+ - `logncdf`, `lognfit`, `lognlike`, `lognpdf`, `lognrnd`, `lognstat`
52
+ - `normcdf`, `normfit`, `normlike`, `normpdf`, `norminv`
53
+
54
+ ### 4. Utilidades (`ezsnake.utils`)
55
+ Funciones para c谩lculos geogr谩ficos, manipulaci贸n de datos y utilidades varias:
56
+
57
+ **Funciones principales:**
58
+ - `uv2polar(u, v)`
59
+ - `polar2uv(dir_deg, spd)`
60
+ - `grados_a_km_lat(delta_lat)`
61
+ - `grados_a_km_lon(delta_lon, latitud)`
62
+ - `distancia_entre_dos_puntos(lon2, lat2, lon1, lat1, unidad='km')`
63
+ - `calcular_tiempo_de_viaje(lon2, lon1, lat2, lat1, velocidad, unidad='km')`
64
+ - `timestamp_a_texto_espanol(fecha, mes_y_anio)`
65
+ - `get_excel_variables_name(df_datos_documento)`
66
+ - `get_excel_variable_values(df_datos_documento, nombre_variable)`
67
+
68
+ ---
69
+
70
+ ## 馃殌 Instalaci贸n
71
+
72
+ Desde PyPI:
73
+ ```bash
74
+ pip install ezsnake
75
+ ```
76
+
77
+ Desde el repositorio (editable):
78
+ ```bash
79
+ pip install -e .
80
+ ```
81
+
82
+ ---
83
+
84
+ ## 馃搵 Requerimientos
85
+
86
+ - Python >= 3.11
87
+ - netcdf4 >= 1.7.4
88
+ - numpy >= 2.0
89
+ - openpyxl >= 3.1
90
+ - pandas >= 2.0
91
+ - python-docx >= 1.1
92
+ - scipy >= 1.17.1
93
+
94
+ ---
95
+
96
+ ## 馃摑 Ejemplo de uso
97
+
98
+ ```python
99
+ from ezsnake.netcdf import load_nc, view_att, dict2nc
100
+
101
+ # Cargar todas las variables de un archivo NetCDF
102
+ data = load_nc('archivo.nc')
103
+
104
+ # Cargar una variable espec铆fica
105
+ temperatura = load_nc('archivo.nc', 'temperature')
106
+
107
+ # Ver atributos de una variable
108
+ attrs = view_att('archivo.nc', 'temperature')
109
+
110
+ # Crear un archivo NetCDF desde un diccionario
111
+ data_dict = {
112
+ 'global_atributes': {'title': 'Mi archivo NetCDF'},
113
+ 'temperature': {
114
+ 'value': np.array([[1, 2], [3, 4]]),
115
+ 'dims': ['time', 'lat'],
116
+ 'units': 'Celsius'
117
+ }
118
+ }
119
+ dict2nc('nuevo_archivo.nc', data_dict)
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 馃懁 Autor y cr茅ditos
125
+
126
+ ***********
127
+ by BelloDev
128
+ agregado 2026/05/25
129
+ ultima revision 2026/05/25
130
+ ***********
131
+
@@ -0,0 +1,116 @@
1
+
2
+ # ezsnake
3
+
4
+ Librer铆a de utilidades cient铆ficas en Python para NetCDF, manipulaci贸n avanzada de Word, utilidades geogr谩ficas y funciones tipo MATLAB.
5
+
6
+ ---
7
+
8
+ ## 馃摝 M贸dulos principales
9
+
10
+ ### 1. NetCDF (`ezsnake.netcdf`)
11
+ Lectura, exploraci贸n y escritura de archivos NetCDF usando netCDF4.
12
+
13
+ **Funciones principales:**
14
+ - `load_nc(ruta, variable=None)`
15
+ - `view_att(ruta, variable=None)`
16
+ - `dict2nc(ruta, data)`
17
+
18
+ ### 2. Word Template Writer (`ezsnake.word_template_writer`)
19
+ Automatizaci贸n avanzada de plantillas Word (.docx): inserci贸n de figuras, referencias cruzadas, reemplazo de variables, tablas y documentos externos.
20
+
21
+ **API p煤blica:**
22
+ - `insertar_figuras_en_plantilla(doc, diccionario_de_reemplazos)`
23
+ - `insertar_referencias_cruzadas_en_plantilla(doc, diccionario_de_reemplazos)`
24
+ - `reemplazar_texto_en_plantilla(doc, diccionario_de_reemplazos)`
25
+ - `insertar_documento_externo_en_plantilla(doc, diccionario_de_reemplazos)`
26
+ - `rellenar_tablas_en_plantilla(doc, diccionario_de_reemplazos)`
27
+ - `reemplazar_variables_en_tablas(doc, diccionario_de_reemplazos)`
28
+
29
+ ### 3. MATLAB-like (`ezsnake.matlab`)
30
+ Funciones cient铆ficas compatibles con MATLAB para estad铆stica, distribuciones y conversi贸n de fechas:
31
+
32
+ **Funciones principales:**
33
+ - `betacdf`, `betafit`, `betainv`, `betalike`, `betapdf`, `betaln`
34
+ - `datenum_to_datetime`, `datenum_to_pd_datetime`
35
+ - `distchck`, `hist`
36
+ - `logncdf`, `lognfit`, `lognlike`, `lognpdf`, `lognrnd`, `lognstat`
37
+ - `normcdf`, `normfit`, `normlike`, `normpdf`, `norminv`
38
+
39
+ ### 4. Utilidades (`ezsnake.utils`)
40
+ Funciones para c谩lculos geogr谩ficos, manipulaci贸n de datos y utilidades varias:
41
+
42
+ **Funciones principales:**
43
+ - `uv2polar(u, v)`
44
+ - `polar2uv(dir_deg, spd)`
45
+ - `grados_a_km_lat(delta_lat)`
46
+ - `grados_a_km_lon(delta_lon, latitud)`
47
+ - `distancia_entre_dos_puntos(lon2, lat2, lon1, lat1, unidad='km')`
48
+ - `calcular_tiempo_de_viaje(lon2, lon1, lat2, lat1, velocidad, unidad='km')`
49
+ - `timestamp_a_texto_espanol(fecha, mes_y_anio)`
50
+ - `get_excel_variables_name(df_datos_documento)`
51
+ - `get_excel_variable_values(df_datos_documento, nombre_variable)`
52
+
53
+ ---
54
+
55
+ ## 馃殌 Instalaci贸n
56
+
57
+ Desde PyPI:
58
+ ```bash
59
+ pip install ezsnake
60
+ ```
61
+
62
+ Desde el repositorio (editable):
63
+ ```bash
64
+ pip install -e .
65
+ ```
66
+
67
+ ---
68
+
69
+ ## 馃搵 Requerimientos
70
+
71
+ - Python >= 3.11
72
+ - netcdf4 >= 1.7.4
73
+ - numpy >= 2.0
74
+ - openpyxl >= 3.1
75
+ - pandas >= 2.0
76
+ - python-docx >= 1.1
77
+ - scipy >= 1.17.1
78
+
79
+ ---
80
+
81
+ ## 馃摑 Ejemplo de uso
82
+
83
+ ```python
84
+ from ezsnake.netcdf import load_nc, view_att, dict2nc
85
+
86
+ # Cargar todas las variables de un archivo NetCDF
87
+ data = load_nc('archivo.nc')
88
+
89
+ # Cargar una variable espec铆fica
90
+ temperatura = load_nc('archivo.nc', 'temperature')
91
+
92
+ # Ver atributos de una variable
93
+ attrs = view_att('archivo.nc', 'temperature')
94
+
95
+ # Crear un archivo NetCDF desde un diccionario
96
+ data_dict = {
97
+ 'global_atributes': {'title': 'Mi archivo NetCDF'},
98
+ 'temperature': {
99
+ 'value': np.array([[1, 2], [3, 4]]),
100
+ 'dims': ['time', 'lat'],
101
+ 'units': 'Celsius'
102
+ }
103
+ }
104
+ dict2nc('nuevo_archivo.nc', data_dict)
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 馃懁 Autor y cr茅ditos
110
+
111
+ ***********
112
+ by BelloDev
113
+ agregado 2026/05/25
114
+ ultima revision 2026/05/25
115
+ ***********
116
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BelloDev [PhD. Fernando Bello Fuentes]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [tool.hatch.build.targets.wheel]
6
+ packages = ["src/ezsnake"]
7
+
8
+ [project]
9
+ name = "ezsnake"
10
+ version = "0.1.0"
11
+ description = "ezsnake is a Python package for working with NetCDF files, a framework for working with python-docx, openpyxl, and also MATLAB datenum conversions into pandas Datetime format, providing an easy-to-use interface for data manipulation and analysis."
12
+ readme = "README.md"
13
+ requires-python = ">=3.11"
14
+ dependencies = [
15
+ "netcdf4>=1.7.4",
16
+ "numpy>=2.0",
17
+ "openpyxl>=3.1",
18
+ "pandas>=2.0",
19
+ "python-docx>=1.1",
20
+ "scipy>=1.17.1",
21
+ ]
22
+
23
+ authors = [
24
+ { name = "Fernando Bello Fuentes (BelloDev)", email = "fernandojbf123@gmail.com" },
25
+ ]
26
+
27
+ [dependency-groups]
28
+ dev = [
29
+ "pytest>=9.0",
30
+ ]
@@ -0,0 +1,2 @@
1
+ __version__ = "0.1.0"
2
+ __author__ = "BelloDev"
@@ -0,0 +1,42 @@
1
+ from .betacdf import betacdf
2
+ from .betafit import betafit
3
+ from .betainv import betainv
4
+ from .betalike import betalike
5
+ from .betapdf import betapdf
6
+ from .datenum_converter import (datenum_to_datetime, datenum_to_pd_datetime)
7
+ from .distchck import distchck
8
+ from .hist import hist
9
+ from .logncdf import logncdf
10
+ from .lognfit import lognfit
11
+ from .lognlike import lognlike
12
+ from .lognpdf import lognpdf
13
+ from .lognrnd import lognrnd
14
+ from .lognstat import lognstat
15
+ from .normcdf import normcdf
16
+ from .normfit import normfit
17
+ from .normlike import normlike
18
+ from .normpdf import normpdf
19
+
20
+ __all__ = [
21
+ "betacdf",
22
+ "betafit",
23
+ "betainv",
24
+ "betalike",
25
+ "betapdf",
26
+ "datenum_converter",
27
+ "datenum_to_pd_datetime",
28
+ "distchck",
29
+ "hist",
30
+ "logncdf",
31
+ "lognfit",
32
+ "lognlike",
33
+ "lognpdf",
34
+ "lognrnd",
35
+ "lognstat",
36
+ "normcdf",
37
+ "normfit",
38
+ "normlike",
39
+ "normpdf"
40
+ ]
41
+
42
+ __author__ = "BelloDev"
@@ -0,0 +1,43 @@
1
+ import numpy as np
2
+ from scipy.stats import beta
3
+
4
+ def betacdf(x, a, b, tail='lower'):
5
+ """
6
+ BETACDF Beta cumulative distribution function.
7
+ P = BETACDF(X,A,B) returns the beta cumulative distribution
8
+ function with parameters A and B at the values in X.
9
+
10
+ The size of P is the common size of the input arguments. A scalar input
11
+ functions as a constant matrix of the same size as the other inputs.
12
+
13
+ BETAINC does the computational work.
14
+
15
+ P = BETACDF(X,A,B,'upper') returns the upper tail probability of the beta
16
+ distribution function with parameters A and B at the values in X.
17
+
18
+ See also BETAFIT, BETAINV, BETALIKE, BETAPDF, BETARND, BETASTAT, CDF,
19
+ BETAINC.
20
+
21
+ Reference:
22
+ [1] M. Abramowitz and I. A. Stegun, "Handbook of Mathematical
23
+ Functions", Government Printing Office, 1964, 26.5.
24
+ """
25
+ x = np.asarray(x)
26
+ a = np.asarray(a)
27
+ b = np.asarray(b)
28
+ # Broadcast to common shape
29
+ x, a, b = np.broadcast_arrays(x, a, b)
30
+ p = np.full_like(x, np.nan, dtype=float)
31
+ okAB = (0 < a) & (a < np.inf) & (0 < b) & (b < np.inf)
32
+ k = okAB & (0 <= x) & (x <= 1)
33
+ if tail == 'upper':
34
+ p[okAB & (x <= 0)] = 1.0
35
+ p[okAB & (x >= 1)] = 0.0
36
+ if np.any(k):
37
+ p[k] = beta.sf(x[k], a[k], b[k])
38
+ else:
39
+ p[okAB & (x < 0)] = 0.0
40
+ p[okAB & (x > 1)] = 1.0
41
+ if np.any(k):
42
+ p[k] = beta.cdf(x[k], a[k], b[k])
43
+ return p
@@ -0,0 +1,132 @@
1
+ import numpy as np
2
+ from scipy import stats, optimize
3
+ from scipy.special import gammaln, psi, logsumexp
4
+ from .betalike import betalike
5
+ from .norminv import norminv
6
+
7
+ def betafit(x, alpha=0.05):
8
+ """
9
+ BETAFIT Parameter estimates and confidence intervals for beta distributed data.
10
+ BETAFIT(X) Returns the maximum likelihood estimates of the parameters
11
+ of the beta distribution given the data in the vector, X.
12
+
13
+ [PHAT, PCI] = BETAFIT(X,ALPHA) gives MLEs and 100(1-ALPHA) percent
14
+ confidence intervals given the data. By default, the optional parameter
15
+ ALPHA = 0.05 corresponding to 95% confidence intervals.
16
+
17
+ The beta distribution is defined on the open interval (0,1). However, it
18
+ is sometimes also necessary to fit a beta distribution to data that
19
+ include exact zeros or ones. For such data, the beta likelihood function
20
+ is unbounded, and standard maximum likelihood estimation is not possible.
21
+ In that case, BETAFIT maximizes a modified likelihood that incorporates
22
+ the zeros or ones by treating them as if they were values that have been
23
+ left-censored at SQRT(REALMIN) or right-censored at 1-EPS/2, respectively.
24
+
25
+ See also BETACDF, BETAINV, BETALIKE, BETAPDF, BETARND, BETASTAT, MLE.
26
+
27
+ Reference:
28
+ (1994) Hahn, Gerald J., and Shapiro, Samuel, S. "Statistical Models in
29
+ Engineering", Wiley Classics Library, John Wiley & Sons, p. 95.
30
+ """
31
+
32
+ alpha = float(alpha)
33
+
34
+ if len(x) == 0:
35
+ phat = np.array([np.nan, np.nan])
36
+ pci = np.array([[np.nan, np.nan], [np.nan, np.nan]])
37
+ return phat, pci
38
+
39
+ x = np.asarray(x).flatten()
40
+
41
+ # Remove missing values from the data
42
+ x = x[~np.isnan(x)]
43
+
44
+ # Cannot fit data outside of the closed interval [0,1], or constant data
45
+ xmin = np.min(x)
46
+ xmax = np.max(x)
47
+
48
+ if (xmin < 0) or (xmax > 1) or not np.all(np.isreal(x)):
49
+ raise ValueError('X must be real values in the interval [0,1]')
50
+
51
+ if abs(xmin - xmax) <= 2 * np.finfo(float).eps * xmax:
52
+ raise ValueError('X must contain distinct values')
53
+
54
+ # Initial parameter estimates
55
+ n = len(x)
56
+ sumlogx = np.sum(np.log(x))
57
+ sumlog1mx = np.sum(np.log1p(-x))
58
+ tmp1 = np.exp(sumlog1mx / n)
59
+ tmp2 = np.exp(sumlogx / n)
60
+
61
+ tmp3 = (1 - tmp1 - tmp2)
62
+ ahat = 0.5 * (1 - tmp1) / tmp3
63
+ bhat = 0.5 * (1 - tmp2) / tmp3
64
+ pstart = np.array([ahat, bhat])
65
+
66
+ # If all values are strictly within the interval (0,1), use
67
+ # maximum likelihood with the usual continuous log-likelihood
68
+ xl = np.sqrt(np.finfo(float).tiny) # some tolerance above zero
69
+ xu = 1 - np.finfo(float).eps / 2
70
+
71
+ if (xl <= xmin) and (xmax <= xu):
72
+ def negloglike_cts(p):
73
+ p = np.exp(p) # remove log transform
74
+ return n * betaln(p[0], p[1]) - (p[0] - 1) * sumlogx - (p[1] - 1) * sumlog1mx
75
+
76
+ negloglike = negloglike_cts
77
+ else:
78
+ # If some values are zero or one, maximize a mixed likelihood that
79
+ # includes discrete probabilities for those values
80
+ x0 = (x < xl)
81
+ n0 = np.sum(x0)
82
+ x1 = (x > xu)
83
+ n1 = np.sum(x1)
84
+ x2 = x[~x0 & ~x1]
85
+ n2 = len(x2)
86
+ sumlogx2 = np.sum(np.log(x2))
87
+ sumlog1mx2 = np.sum(np.log1p(-x2))
88
+
89
+ def negloglike_mixed(p):
90
+ p = np.exp(p) # remove log transform
91
+ nll = n2 * betaln(p[0], p[1]) - (p[0] - 1) * sumlogx2 - (p[1] - 1) * sumlog1mx2
92
+
93
+ # Include F(xl) = Pr(X <= xl) for data that are zeros
94
+ if n0 > 0:
95
+ nll = nll - n0 * np.log(stats.beta.cdf(xl, p[0], p[1]))
96
+
97
+ # Include 1-F(xu) = Pr(X >= xu) for data that are ones
98
+ if n1 > 0:
99
+ nll = nll - n1 * np.log(1 - stats.beta.cdf(xu, p[0], p[1]))
100
+
101
+ return nll
102
+
103
+ negloglike = negloglike_mixed
104
+
105
+ # Maximize the likelihood using a log transform for the parameters, to ensure
106
+ # the parameters are positive
107
+ pstart = np.log(pstart)
108
+ result = optimize.minimize(negloglike, pstart, method='Nelder-Mead',
109
+ options={'xatol': 1e-7, 'fatol': 1e-7})
110
+ phat = np.exp(result.x)
111
+
112
+ if alpha is not None:
113
+
114
+ # Compute CIs on the log scale for both params
115
+ _, acov = betalike(phat, x)
116
+ logphat = np.log(phat)
117
+ selog = np.sqrt(np.diag(acov)) / phat
118
+
119
+ p_int = np.array([alpha / 2, 1 - alpha / 2])
120
+ pci = np.exp(norminv(np.column_stack([p_int, p_int]),
121
+ np.row_stack([logphat, logphat]),
122
+ np.row_stack([selog, selog])))
123
+ return phat, pci
124
+ else:
125
+ return phat
126
+
127
+
128
+ def betaln(a, b):
129
+ """
130
+ Beta function logarithm - equivalent to MATLAB's betaln function
131
+ """
132
+ return gammaln(a) + gammaln(b) - gammaln(a + b)
@@ -0,0 +1,76 @@
1
+ import numpy as np
2
+ import warnings
3
+ from scipy.special import betaincinv, betainc
4
+ from .distchck import distchck
5
+ from .betacdf import betacdf
6
+
7
+ def betainv(p, a, b):
8
+ """
9
+ BETAINV Inverse of the beta cumulative distribution function (cdf).
10
+ X = BETAINV(P,A,B) returns the inverse of the beta cdf with
11
+ parameters A and B at the values in P.
12
+
13
+ The size of X is the common size of the input arguments. A scalar input
14
+ functions as a constant matrix of the same size as the other inputs.
15
+
16
+ BETAINV uses Newton's method to converge to the solution (en MATLAB).
17
+ En Python, se usa scipy.special.betaincinv.
18
+
19
+ See also BETACDF, BETAFIT, BETALIKE, BETAPDF, BETARND, BETASTAT, ICDF.
20
+ """
21
+ if a is None or b is None:
22
+ raise ValueError('Too few inputs')
23
+ errorcode, (p, a, b) = distchck(3, p, a, b)
24
+ if errorcode > 0:
25
+ raise ValueError('Input size mismatch')
26
+ p = np.asarray(p)
27
+ a = np.asarray(a)
28
+ b = np.asarray(b)
29
+ # Weed out any out of range parameters or probabilities.
30
+ okAB = (0 < a) & (a < np.inf) & (0 < b) & (b < np.inf)
31
+ k = okAB & (0 <= p) & (p <= 1)
32
+ allOK = np.all(k)
33
+ # Fill in NaNs for out of range cases.
34
+ x = np.full(k.shape, np.nan, dtype=float)
35
+ if not allOK:
36
+ if np.any(k):
37
+ if p.size > 1:
38
+ p2 = p[k]
39
+ else:
40
+ p2 = p
41
+ if a.size > 1:
42
+ a2 = a[k]
43
+ else:
44
+ a2 = a
45
+ if b.size > 1:
46
+ b2 = b[k]
47
+ else:
48
+ b2 = b
49
+ else:
50
+ return x
51
+ else:
52
+ p2, a2, b2 = p, a, b
53
+ # Call betaincinv to find a root of betainc(q,a,b) = p
54
+ q = betaincinv(a2, b2, p2)
55
+ delta = np.finfo(float).eps
56
+ badcdf = (np.abs(betainc(a2, b2, q) - p2) / np.maximum(p2, 1e-12)) > np.sqrt(delta)
57
+ if np.any(badcdf):
58
+ # Intentar ajustar con betacdf
59
+ idx = np.where(badcdf)[0]
60
+ for i in idx:
61
+ q_i = q[i]
62
+ a_i = a2[i] if a2.size > 1 else a2
63
+ b_i = b2[i] if b2.size > 1 else b2
64
+ p_i = p2[i] if p2.size > 1 else p2
65
+ q_minus = q_i - delta
66
+ q_plus = q_i + delta
67
+ cdf_minus = betacdf(q_minus, a_i, b_i)
68
+ cdf_plus = betacdf(q_plus, a_i, b_i)
69
+ if (cdf_minus - p_i) * (cdf_plus - p_i) > 0:
70
+ warnings.warn(f'betainv: NoConvergence for a={a_i}, b={b_i}, p={p_i}')
71
+ # Broadcast the values to the correct place if need be.
72
+ if allOK:
73
+ x = q
74
+ else:
75
+ x[k] = q
76
+ return x