From 1d0c5ae3c8ec3a5a2eb34620d6bdddd0887947f9 Mon Sep 17 00:00:00 2001 From: Julien Malard Date: Thu, 9 Nov 2017 15:41:25 -0500 Subject: [PATCH] Parecen funcionar las calibraciones. --- .gitignore | 5 +- tikon/Coso.py | 1 - "tikon/Interfaz/N\303\272meros.py" | 282 +++++++++++++----- "tikon/Matem\303\241ticas/Calib.py" | 18 +- "tikon/Matem\303\241ticas/Incert.py" | 139 ++++----- tikon/Proyectos/Artificial/Artificial.py | 17 +- .../Opisina_arenosella/Red_Opisina.py | 2 +- .../Proyectos/Opisina_arenosella/a_prioris.py | 27 +- tikon/RAE/Planta.py | 6 +- tikon/__init__.py | 9 +- "tikon/versi\303\263n.txt" | 2 +- 11 files changed, 303 insertions(+), 205 deletions(-) diff --git a/.gitignore b/.gitignore index 6c3c1638..26584c20 100644 --- a/.gitignore +++ b/.gitignore @@ -126,4 +126,7 @@ crashlytics.properties crashlytics-build.properties fabric.properties -docs/.tx \ No newline at end of file +docs/.tx + +*.2mdl +*.vdf \ No newline at end of file diff --git a/tikon/Coso.py b/tikon/Coso.py index 05e111e4..916b5540 100644 --- a/tikon/Coso.py +++ b/tikon/Coso.py @@ -1,5 +1,4 @@ import copy as copiar -import io import json import math as mat import os diff --git "a/tikon/Interfaz/N\303\272meros.py" "b/tikon/Interfaz/N\303\272meros.py" index a4b9a13c..f3a6ec3a 100644 --- "a/tikon/Interfaz/N\303\272meros.py" +++ "b/tikon/Interfaz/N\303\272meros.py" @@ -1,7 +1,9 @@ import re -trads_núm = {'हिंदी': {'núms': ('०', '१', '२', '३', '४', '५', '६', '७', '८', '९'), +dic_trads = {'Latino': {'núms': ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0'), + 'sep_dec': '.'}, + 'हिंदी': {'núms': ('०', '१', '२', '३', '४', '५', '६', '७', '८', '९'), 'sep_dec': '.'}, 'ਪੰਜਾਬੀ': {'núms': ('੦', '੧', '੨', '੩', '੪', '੫', '੬', '੭', '੮', '੯'), 'sep_dec': '.'}, @@ -31,55 +33,34 @@ } -def núm_a_tx(núm, lengua, bases=False): +def trad_núm(núm, lengua_final, bases=True): """ + Esta función traduce un número. - :param núm: - :type núm: float | int + :param núm: El número para traducir, en formato de número o de texto. + :type núm: float | int | str - :param lengua: - :type lengua: str + :param lengua_final: La lengua a la cual traducir. + :type lengua_final: str - :param bases: - :type bases: bool + :param bases: Si hay que devolver el número en formato de bases o no. Solamente aplica a algunas lenguas, tal como + el Chino, el Japonés y el Tamil. Por ejemplo, `123` se traducirá a `百二十三` (Chino) o `௱௨௰௩` (Tamil) con + ``bases=True`` y a `一二三` o `௧௨௩` con ``bases=False``. - :return: + :return: El número traducido. :rtype: str - """ - núms = trads_núm[lengua]['núms'] - sep_dec = trads_núm[lengua]['sep_dec'] - try: - l_bases = trads_núm[lengua]['bases'] - except KeyError: - l_bases = None - - tx_número = str(núm) - - entero, dec = tx_número.split('.') - - if bases: - - if l_bases is not None: - trad_ent = '' - con_bases = gen_bases(entero, bases=l_bases) - for i, n in enumerate(con_bases): - try: - trad_ent += núms[int(n)] - except KeyError: - trad_ent += n - - else: - raise ValueError('No hay sistema de bases definido para la lengua %s.' % lengua) - + # Convertir el número a un valor numérico en Python, si necesario + if isinstance(núm, str): + val = tx_a_núm(texto=núm) else: - trad_ent = ''.join(núms[int(n)] for n in entero) - trad_dec = ''.join(núms[int(n)] for n in dec) + val = núm - trad_núm = '{ent}{sep_dec}{dec}'.format(ent=trad_ent, dec=trad_dec, sep_dec=sep_dec) + # Convertir el valor numérico a la lengua deseada + núm_trad = núm_a_tx(núm=val, lengua=lengua_final, bases=bases) - return trad_núm + return núm_trad def tx_a_núm(texto): @@ -94,77 +75,192 @@ def tx_a_núm(texto): """ - for lengua, d_l in trads_núm.items(): + for lengua, d_l in dic_trads.items(): + # Intentar cada lengua disponible. + + sep_dec = d_l['sep_dec'] # El separador de decimales + l_núms = list(d_l['núms']) # Los números - sep_dec = d_l['sep_dec'] - l_núms = d_l['núms'] + # Ver si hay posibilidad de un sistema de bases try: bases = d_l['bases'] except KeyError: bases = None try: - núm = trad_texto(texto=texto, núms=l_núms, sep_dec=sep_dec) + # Intentar traducir literalmente, número por número + núm = _trad_texto(texto=texto, núms=l_núms, sep_dec=sep_dec) + + # ¿Funcionó? ¡Perfecto! return núm except ValueError: - if bases is not None: - try: - try: - entero, dec = texto.split(sep_dec) - except ValueError: - entero = texto + pass # ¿No funcionó? Qué pena. Ahora tenemos que trabajar. - regex_núm = r'[{}]'.format(''.join([n for n in l_núms])) - regex_unid = r'[{}]'.format(''.join([b[1] for b in bases])) + if bases is not None: + # Intentar ver si puede ser un sistema de bases (unidades). - regex = r'((?P{})?(?P{}|$))'.format(regex_núm, regex_unid) + try: - m = re.finditer(regex, entero) - if m is None: - continue + # Ver si hay de separar decimales + try: + entero, dec = texto.split(sep_dec) + except ValueError: + entero = texto + dec = None + + # Expresiones RegEx para esta lengua + regex_núm = r'[{}]'.format(''.join([n for n in l_núms])) + regex_unid = r'[{}]'.format(''.join([b[1] for b in bases])) + regex = r'((?P{})?(?P{}|$))'.format(regex_núm, regex_unid) + + # Intentar encontrar secuencias de unidades y de números en el texto. + m = re.finditer(regex, entero) + resultados = [x for x in list(m) if len(x.group())] + + if not len(resultados): + # Si no encontramos nada, seguir con la próxima lengua + continue + + # Grupos de números y de sus bases (unidades) + grupos = resultados[:-1] + + # Dividir en números y en unidades + núms = [_trad_texto(g.group('núm'), núms=l_núms, sep_dec=sep_dec) for g in grupos] + unids = [_trad_texto(g.group('unid'), núms=[b[1] for b in bases], sep_dec=sep_dec) + for g in grupos] + + # Calcular el valor de cada número con su base. + vals = [núms[i] * u for i, u in enumerate(unids)] + + # Agregar o multiplicar valores, como necesario. + val_entero = vals[0] + for i, v in enumerate(vals[1:]): + if unids[i + 1] > unids[i]: + val_entero *= v else: - grupos = list(m)[:-1] + val_entero += v - núms = [trad_texto(g.group('núm'), núms=l_núms, sep_dec=sep_dec) for g in grupos] - unids = [trad_texto(g.group('unid'), núms=[b[1] for b in bases], sep_dec=sep_dec) - for g in grupos] + # Calcular el número traducido + if dec is not None: + # Si había decima, convertir el texto decimal + val_dec = _trad_texto(texto=dec, núms=l_núms, sep_dec=sep_dec, txt=True) - vals = [núms[i] * u for i, u in enumerate(unids)] + # Calcular el número + núm = float(str(val_entero) + sep_dec + val_dec) - val_entero = vals[0] - for i, v in enumerate(vals[1:]): - if unids[i+1] > unids[i]: - val_entero *= v - else: - val_entero += v + else: + # ... si no había decimal, no hay nada más que hacer + núm = val_entero - tx_dec = trad_texto(texto=dec, núms=l_núms, sep_dec=sep_dec, txt=True) + return núm # Devolver el número - núm = str(val_entero) + sep_dec + tx_dec + except (KeyError, ValueError): + # Si no funcionó, intentemos otra lengua + pass - return núm + # Si ninguna de las lenguas funcionó, hubo error. + raise ValueError('No se pudo decifrar el número %s' % texto) - except (KeyError, ValueError): - pass - raise ValueError('No se pudo decifrar el número %s' % texto) +def _trad_texto(texto, núms, sep_dec, txt=False): + """ + Esta función traduce un texto a un valor numérico o de texto (formato latino). + + :param texto: El texto para traducir. + :type texto: str + :param núms: La lista, en orden ascendente, de los carácteres que corresponden a los números 0, 1, 2, ... 9. + :type núms: list[str] + :param sep_dec: El separador de decimales + :type sep_dec: str + :param txt: Si hay que devolver en formato de texto + :type txt: bool + :return: El número convertido. + :rtype: float | txt + """ + if all([x in núms + [sep_dec,] for x in texto]): + # Si todos los carácteres en el texto están reconocidos... -def trad_texto(texto, núms, sep_dec, txt=False): - if all([x in núms + (sep_dec,) for x in texto]): + # Cambiar el separador de decimal a un punto. texto = texto.replace(sep_dec, '.') for n, d in enumerate(núms): + # Reemplazar todos los números también. texto = texto.replace(d, str(n)) + # Devolver el resultado, o en texto, o en formato numeral. if txt: return texto else: return float(texto) else: - raise ValueError + # Si no se reconocieron todos los carácteres, no podemos hacer nada más. + raise ValueError('Texto "{}" no reconocido.'.format(texto)) + + +def núm_a_tx(núm, lengua, bases=True): + """ + Esta función convierte un número Python en texto traducido. + + :param núm: El numero para convertir a texto. + :type núm: float | int + + :param lengua: La lengua del texto deseado. + :type lengua: str + + :param bases: Si hay que convertir a formato con bases (solamente aplica a algunas lenguas). + :type bases: bool + + :return: El número en formato de texto traducido. + :rtype: str + + """ + + # Los números y separador de decimal de la lengua escogida. + núms = dic_trads[lengua]['núms'] + sep_dec = dic_trads[lengua]['sep_dec'] + + # La lista de bases para la lengua escogida + l_bases = None + if bases: + try: + l_bases = dic_trads[lengua]['bases'] # type: list[tuple] + except KeyError: + pass + + # Convertir el número a texto + tx_número = str(núm) + + # Dividir las partes enteras y de decimales + entero, dec = tx_número.split('.') + + # Si queremos utilizar bases... + if bases: + + # Si la lengua tiene opciones de bases... + if l_bases is not None: + + trad_ent = '' + con_bases = gen_bases(int(entero), bases=l_bases) + for i, n in enumerate(con_bases): + try: + trad_ent += núms[int(n)] + except KeyError: + trad_ent += n + + else: + raise ValueError('No hay sistema de bases definido para la lengua %s.' % lengua) + + else: + trad_ent = ''.join(núms[int(n)] for n in entero) + trad_dec = ''.join(núms[int(n)] for n in dec) + + trad_núm = '{ent}{sep_dec}{dec}'.format(ent=trad_ent, dec=trad_dec, sep_dec=sep_dec) + + return trad_núm + def gen_bases(núm, bases, t=''): @@ -180,17 +276,27 @@ def gen_bases(núm, bases, t=''): :rtype: str """ + # Ordenar las bases bases.sort() - for símb, mag in reversed(bases): + # Para cada base, en orden de magnitud disminuyendo + for mag, símb in reversed(bases): + # Calcular el dividendo del número dividido por la magnitud dividendo = núm // mag + if dividendo == 0: + # Si el número era más pequeño, seguir a la próxima base posible continue + else: - if dividendo >= bases[-1][0]: + # Sino... + + # Si el dividendo queda más alto que la base más pequeña, hay que seguir. + if dividendo >= bases[0]: t += gen_bases(núm=dividendo, bases=bases, t=t) else: + # El resto de la división resto = núm % mag if resto > 1: t += str(resto) + símb @@ -201,9 +307,21 @@ def gen_bases(núm, bases, t=''): def leer_bases(texto, núms, sep_dec, bases, n=0): + """ - '௨௲௩௱௰' - + :param texto: + :type texto: + :param núms: + :type núms: + :param sep_dec: + :type sep_dec: + :param bases: + :type bases: + :param n: + :type n: + :return: + :rtype: + """ res = re.match(r'[%s]+' % ''.join([b[1] for b in bases]), texto[::-1]) if res: @@ -234,8 +352,12 @@ def leer_bases(texto, núms, sep_dec, bases, n=0): if __name__ == '__main__': tx_a_núm('௨௲௩௰') - for leng in trads_núm: + for leng in dic_trads: número = 123456.7809 tx = núm_a_tx(número, leng) latín = tx_a_núm(tx) print(leng, ':', número, tx, latín) + + tx = núm_a_tx(número, leng, bases=True) + latín = tx_a_núm(tx) + print(leng, ':', número, tx, latín) diff --git "a/tikon/Matem\303\241ticas/Calib.py" "b/tikon/Matem\303\241ticas/Calib.py" index 17837f5c..7dad5e7e 100644 --- "a/tikon/Matem\303\241ticas/Calib.py" +++ "b/tikon/Matem\303\241ticas/Calib.py" @@ -91,20 +91,18 @@ def __init__(símismo, función, dic_argums, d_obs, lista_d_paráms, aprioris, l l_var_paráms = trazas_a_dists(id_simul=símismo.id, l_d_pm=lista_d_paráms, l_lms=lista_líms, l_trazas=aprioris, formato='calib', comunes=False) + # Quitar variables sin incertidumbre. Sino, por una razón muy rara, simul() no funcionará en PyMC. + l_var_paráms = [x for x in l_var_paráms + if not (isinstance(x, pymc.Uniform) and x.parents['lower'] == x.parents['upper']) + and not isinstance(x, pymc.Degenerate) + ] + # Incluir también los parientes de cualquier variable determinístico (estos se crean cuando se necesitan # transformaciones de las distribuciones básicas de PyMC) for parám in l_var_paráms: if isinstance(parám, pymc.Deterministic): l_var_paráms.append(min(parám.extended_parents)) - # Quitar variables sin incertidumbre. Por una razón muy rara, simul() no funcionará en PyMC sino. - for parám in l_var_paráms.copy(): - if isinstance(parám, pymc.Uniform): - if parám.parents['upper'] == parám.parents['lower']: - l_var_paráms.remove(parám) - if isinstance(parám, pymc.Degenerate): - l_var_paráms.remove(parám) - # Llenamos las matrices de coeficientes con los variables PyMC recién creados. función_llenar_coefs(nombre_simul=id_calib, n_rep_parám=1, dib_dists=False) @@ -113,8 +111,8 @@ def __init__(símismo, función, dic_argums, d_obs, lista_d_paráms, aprioris, l # porque si no PyMC no se dará cuenta de que la función simular() depiende de los otros parámetros y se le # olvidará de recalcularla cada vez que cambian los valores de los parámetros. @pymc.deterministic(trace=False) - def simul(d=dic_argums, _=l_var_paráms): - return función(**d) + def simul(_=l_var_paráms): + return función(**dic_argums) # Ahora, las observaciones l_var_obs = [] # Una lista para los variables de observación diff --git "a/tikon/Matem\303\241ticas/Incert.py" "b/tikon/Matem\303\241ticas/Incert.py" index 0c7d3c9c..1eb4da71 100644 --- "a/tikon/Matem\303\241ticas/Incert.py" +++ "b/tikon/Matem\303\241ticas/Incert.py" @@ -347,11 +347,11 @@ def texto_a_dist(texto, usar_pymc=False, nombre=None): # Crear la distribución dist = clase_dist(nombre, *paráms) - # Y aplicaar las transformaciones - if transform['sum'] != 0: - dist = pymc.Lambda('%s_s' % nombre, lambda x=dist, s=transform['sum']: x + s) + # Y aplicar las transformaciones if transform['mult'] != 1: dist = pymc.Lambda('%s_m' % dist, lambda x=dist, m=transform['mult']: x * m) + if transform['sum'] != 0: + dist = pymc.Lambda('%s_s' % dist, lambda x=dist, s=transform['sum']: x + s) else: # Sino, hay error. @@ -433,7 +433,7 @@ def rango_a_texto_dist(rango, certidumbre, líms, cont): if cont: dist = 'Uniforme~({}, {})'.format(rango[0], (rango[1] - rango[0])) else: - dist = 'UnifDiscr~({}, {})'.format(rango[0], rango[1]) + dist = 'UnifDiscr~({}, {})'.format(rango[0], rango[1] + 1) else: # Si hay incertidumbre... @@ -742,8 +742,8 @@ def límites_a_texto_dist(límites, cont=True): dist = 'Degenerado~({})'.format(máx) else: if cont: - loc = máx - mín - dist = 'Uniforme~({}, {})'.format(mín, loc) + esc = máx - mín + dist = 'Uniforme~({}, {})'.format(mín, esc) else: dist = 'UnifDiscr~({}, {})'.format(mín, mín + 1) @@ -929,10 +929,11 @@ def ajustar_dist(datos, límites, cont, usar_pymc=False, nombre=None, lista_dist # Y crear la distribución. dist = dic_dist['pymc'](nombre, *args_pymc) - if transform['sum'] != 0: - dist = dist + transform['sum'] if transform['mult'] != 1: dist = dist * transform['mult'] + + if transform['sum'] != 0: + dist = dist + transform['sum'] mejor_ajuste['dist'] = dist else: @@ -1032,7 +1033,10 @@ def paráms_scipy_a_pymc(tipo_dist, paráms): paráms_pymc = (mu, 1 / paráms[3] ** 2, mín * paráms[3] + mu, máx * paráms[3] + mu) elif tipo_dist == 'Uniforme': - paráms_pymc = (paráms[0], paráms[1] + paráms[0]) + # Normalizar la distribución Uniforme para PyMC. Sino hace muchos problemas. + paráms_pymc = (0, 1) + transform_pymc['sum'] = paráms[0] + transform_pymc['mult'] = paráms[1] elif tipo_dist == 'VonMises': paráms_pymc = (paráms[1], paráms[0]) @@ -1204,147 +1208,114 @@ def calc_r2(y_obs, y_pred): return r2 -# Para hacer: implementar pymc3 def paráms_scipy_a_dist_pymc3(tipo_dist, paráms): - if pm3 is None: # Para hacer: quitar esto después de migrar a PyMC 3 + if pm3 is None: raise ImportError( 'PyMC 3 (pymc3) no está instalado en esta máquina.\nDeberías de instalarlo un día. De verdad que' 'es muy chévere.') transform_pymc = {'mult': 1, 'sum': 0} - try: - clase_dist = Ds.obt_dist(dist=tipo_dist, tipo='pymc3') - except ValueError as e: + if not Ds.obt_dist(dist=tipo_dist, tipo='pymc3'): raise ValueError('La distribución "{}" no parece existir en Tiko\'n al momento.'.format(tipo_dist)) if tipo_dist == 'Beta': - dist_pm3 = clase_dist(alpha=paráms['a'], beta=paráms['b']) + dist_pm3 = pm3.Beta(alpha=paráms['a'], beta=paráms['b']) transform_pymc['mult'] = paráms['scale'] transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Cauchy': - dist_pm3 = clase_dist(alpha=paráms['a'], beta=paráms['scale']) + dist_pm3 = pm3.Cauchy(alpha=paráms['a'], beta=paráms['scale']) elif tipo_dist == 'Chi2': - dist_pm3 = clase_dist(nu=paráms['df']) + dist_pm3 = pm3.ChiSquared(nu=paráms['df']) transform_pymc['mult'] = paráms['scale'] transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Exponencial': - dist_pm3 = clase_dist(lam=1/paráms['scale']) + dist_pm3 = pm3.Exponential(lam=1 / paráms['scale']) transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Gamma': - dist_pm3 = clase_dist(alpha=paráms['alpha'], beta=1/paráms['scale']) + dist_pm3 = pm3.Gamma(alpha=paráms['alpha'], beta=1 / paráms['scale']) transform_pymc['sum'] = paráms['loc'] - elif tipo_dist == 'MitadCauchy': # para hacer: trabajar desde aquí - paráms_pymc = (paráms[0], paráms[1]) - dist_pm3 = pm3.HalfCauchy() + elif tipo_dist == 'MitadCauchy': + dist_pm3 = pm3.HalfCauchy(beta=paráms['scale']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'MitadNormal': - paráms_pymc = (1 / paráms[1] ** 2,) - transform_pymc['sum'] = paráms[0] - dist_pm3 = pm3.HalfNormal() + dist_pm3 = pm3.HalfNormal(sd=paráms['scale']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'GammaInversa': - paráms_pymc = (paráms[0], paráms[2]) - transform_pymc['sum'] = paráms[1] - dist_pm3 = pm3.InverseGamma() + dist_pm3 = pm3.InverseGamma(alpha=paráms['a'], beta=paráms['scale']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Laplace': - paráms_pymc = (paráms[0], 1 / paráms[1]) - dist_pm3 = pm3.Laplace() + dist_pm3 = pm3.Laplace(mu=paráms['loc'], b=paráms['scale']) elif tipo_dist == 'Logística': paráms_pymc = (paráms[0], 1 / paráms[1]) - dist_pm3 = NotImplemented + dist_pm3 = pm3.Logistic(mu=paráms['loc'], s=paráms['scale']) elif tipo_dist == 'LogNormal': - paráms_pymc = (np.log(paráms[2]), 1 / (paráms[0] ** 2)) - transform_pymc['mult'] = paráms[2] - transform_pymc['sum'] = paráms[1] - dist_pm3 = pm3.Lognormal() - - elif tipo_dist == 'TNoCentral': - paráms_pymc = (paráms[2], 1 / paráms[3], paráms[0]) - dist_pm3 = NotImplemented + dist_pm3 = pm3.Lognormal(mu=paráms['loc'], sd=paráms['scale']) # para hacer: verificar elif tipo_dist == 'Normal': - paráms_pymc = (paráms[0], 1 / paráms[1] ** 2) - dist_pm3 = pm3.Normal() + dist_pm3 = pm3.Normal(mu=paráms['loc'], sd=paráms['scale']) elif tipo_dist == 'Pareto': - paráms_pymc = (paráms[0], paráms[2]) - transform_pymc['sum'] = paráms[1] - dist_pm3 = pm3.Pareto() + dist_pm3 = pm3.Pareto(alpha=paráms['b'], m=paráms['scale']) # para hacer: verificar elif tipo_dist == 'T': - paráms_pymc = (paráms[0],) - transform_pymc['sum'] = paráms[1] - transform_pymc['mult'] = 1 / np.sqrt(paráms[2]) - dist_pm3 = pm3.StudentT() + dist_pm3 = pm3.StudentT(nu=paráms['df'], mu=paráms['loc'], sd=paráms['scale']) # para hacer: verificar elif tipo_dist == 'NormalTrunc': - mu = paráms[2] mín, máx = min(paráms[0], paráms[1]), max(paráms[0], paráms[1]) # SciPy, aparamente, los puede inversar - paráms_pymc = (mu, 1 / paráms[3] ** 2, mín * paráms[3] + mu, máx * paráms[3] + mu) - dist_pm3 = pm3.Bound(pm3.Normal) + mín_abs, máx_abs = mín * paráms['scale'] + paráms['mu'], máx * paráms['scale'] + paráms['mu'] + NormalTrunc = pm3.Bound(pm3.Normal, lower=mín_abs, upper=máx_abs) + dist_pm3 = NormalTrunc(mu=paráms['loc'], sd=paráms['scale']) elif tipo_dist == 'Uniforme': - paráms_pymc = (paráms[0], paráms[1] + paráms[0]) - dist_pm3 = pm3.Uniform() + dist_pm3 = pm3.Uniform(paráms['loc'], paráms['loc'] + paráms['scale']) elif tipo_dist == 'VonMises': - paráms_pymc = (paráms[1], paráms[0]) - transform_pymc['mult'] = paráms[2] - dist_pm3 = pm3.VonMises() + dist_pm3 = pm3.VonMises(mu=paráms['loc'], kappa=paráms['kappa']) + transform_pymc['mult'] = paráms['scale'] elif tipo_dist == 'Weibull': - dist_pm3 = pm3.Weibull() raise NotImplementedError # Para hacer: implementar la distrubución Weibull (minweibull en SciPy) + dist_pm3 = pm3.Weibull() elif tipo_dist == 'Bernoulli': - paráms_pymc = (paráms[0],) - transform_pymc['sum'] = paráms[1] - dist_pm3 = pm3.Bernoulli() + dist_pm3 = pm3.Bernoulli(p=paráms['p']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Binomial': - paráms_pymc = (paráms[0], paráms[1]) - transform_pymc['sum'] = paráms[2] - dist_pm3 = pm3.Binomial() + dist_pm3 = pm3.Binomial(n=paráms['n'], p=paráms['p']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Geométrica': - paráms_pymc = (paráms[0],) - transform_pymc['sum'] = paráms[1] - dist_pm3 = pm3.Geometric() - - elif tipo_dist == 'Hypergeométrica': - paráms_pymc = (paráms[1], paráms[0], paráms[2]) - transform_pymc['sum'] = paráms[3] - dist_pm3 = NotImplemented + dist_pm3 = pm3.Geometric(p=paráms['p']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'BinomialNegativo': - paráms_pymc = (paráms[1], paráms[0]) - transform_pymc['sum'] = paráms[2] - dist_pm3 = pm3.NegativeBinomial() + n = paráms['n'] + p = paráms['p'] + dist_pm3 = pm3.NegativeBinomial(mu=n(1-p)/p, alpha=n) # para hacer: verificar + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'Poisson': - paráms_pymc = (paráms[0],) - transform_pymc['sum'] = paráms[1] - dist_pm3 = pm3.Poisson() + dist_pm3 = pm3.Poisson(mu=paráms['mu']) + transform_pymc['sum'] = paráms['loc'] elif tipo_dist == 'UnifDiscr': - paráms_pymc = (paráms[0], paráms[1] - 1) - dist_pm3 = pm3.DiscreteUniform() + dist_pm3 = pm3.DiscreteUniform(lower=paráms['low'], upper=paráms['high']) + transform_pymc['sum'] = paráms['loc'] else: - raise ValueError('La distribución %s no existe en la base de datos de Tikon para distribuciones PyMC 3.' % + raise ValueError('La distribución %s no existe en la base de datos de Tikon para distribuciones de PyMC 3.' % tipo_dist) return dist_pm3 - - -def anal_sens(): - pass diff --git a/tikon/Proyectos/Artificial/Artificial.py b/tikon/Proyectos/Artificial/Artificial.py index 132aa8d6..98519c2b 100644 --- a/tikon/Proyectos/Artificial/Artificial.py +++ b/tikon/Proyectos/Artificial/Artificial.py @@ -6,12 +6,13 @@ from tikon.Proyectos.Opisina_arenosella.a_prioris import a_prioris from tikon.Matemáticas.Experimentos import Experimento -dib_aprioris = True -dib_valid_perf = True -dib_simul = True -dib_dists = True -dib_valid = True -dib_calibs = True +dib = True +dib_aprioris = dib +dib_valid_perf = dib +dib_simul = dib +dib_dists = dib +dib_valid = dib +dib_calibs = dib proyecto = 'Artificial' @@ -156,7 +157,7 @@ def _agregar_exp(red, exper): # Aplicar a prioris _aplicar_a_prioris(red=Red_coco, d_a_pr=a_prioris) Coco = Red_coco.organismos['Coco'] -Coco.estimar_densidad(rango=(38000e6, 42000e6), certidumbre=0.95) +Coco.estimar_densidad(rango=(38, 42), certidumbre=0.95) # Por el momento, tenemos que conectar con un experimento aunque no lo usemos. Para hacer: Esto tendrá que cambiar Exper = Experimento(nombre='Sitio A', proyecto=Red_coco.proyecto) @@ -210,7 +211,7 @@ def _agregar_exp(red, exper): utilizador='Julien Malard', contacto='julien.malard@mail.mcgill.ca') print('Validando con p={}...'.format(p)) valid = Red_coco.validar(nombre='Valid con calib prec. {}'.format(p), exper=Exper_artificial, - usar_especificadas=True, detalles=False, guardar=True, + usar_especificadas=False, detalles=False, guardar=True, dibujar=dib_valid, n_rep_parám=10, n_rep_estoc=10) print('Resultados de validación después de calib con precisión de {}%:\n============='.format(p)) diff --git a/tikon/Proyectos/Opisina_arenosella/Red_Opisina.py b/tikon/Proyectos/Opisina_arenosella/Red_Opisina.py index 2d2b1209..d99dc621 100644 --- a/tikon/Proyectos/Opisina_arenosella/Red_Opisina.py +++ b/tikon/Proyectos/Opisina_arenosella/Red_Opisina.py @@ -21,7 +21,7 @@ Parasitoide_pupa.parasita(O_arenosella, etps_infec=['pupa'], etp_sale='pupa') -Red_coco = Red(nombre='Red coco_AM', organismos=[O_arenosella, Parasitoide_larvas, Parasitoide_pupa, Coco], +Red_coco = Red(nombre='Red coco_prueba', organismos=[O_arenosella, Parasitoide_larvas, Parasitoide_pupa, Coco], proyecto=proyecto) Araña = Ins.Sencillo('Araña', proyecto=proyecto) diff --git a/tikon/Proyectos/Opisina_arenosella/a_prioris.py b/tikon/Proyectos/Opisina_arenosella/a_prioris.py index e250234c..560688a8 100644 --- a/tikon/Proyectos/Opisina_arenosella/a_prioris.py +++ b/tikon/Proyectos/Opisina_arenosella/a_prioris.py @@ -25,13 +25,14 @@ dict(etapa='adulto', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'a'], org_inter='Palma de coco', etp_inter='planta', - # Unidades: mm d -1 - rango=((1823-100*1.96)/(53.1+10.64*1.96), (1823-100*1.96)/(53.1-10.64*1.96)), + # Unidades: 100m**2 d -1 + rango=((1823-100*1.96)/(53.1+10.64*1.96)*1e-9, (1823-100*1.96)/(53.1-10.64*1.96)*1e-9), certidumbre=0.80), dict(etapa='adulto', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'b'], org_inter='Palma de coco', etp_inter='planta', - rango=(((1823-100*1.96)/(53.1+10.64*1.96))**2, ((1823-100*1.96)/(53.1-10.64*1.96))**2), + rango=(((1823-100*1.96)/(53.1+10.64*1.96)*1e-9)**2, + ((1823-100*1.96)/(53.1-10.64*1.96)*1e-9)**2), certidumbre=0.80) # Para hacer ], @@ -122,12 +123,12 @@ certidumbre=1), dict(etapa='juvenil_1', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'a'], - rango=((1823-100*1.96)/(53.1+10.64*1.96)*.2, (1823-100*1.96)/(53.1-10.64*1.96)*.2), + rango=((1823-100*1.96)/(53.1+10.64*1.96)*1e-9*.2, (1823-100*1.96)/(53.1-10.64*1.96)*1e-9*.2), certidumbre=0.80, ), dict(etapa='juvenil_1', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'b'], - rango=(((1823-100*1.96)/(53.1+10.64*1.96))**2*.2, ((1823-100*1.96)/(53.1-10.64*1.96))**2*.2), + rango=(((1823-100*1.96)/(53.1+10.64*1.96)*.2*1e-9)**2, ((1823-100*1.96)/(53.1-10.64*1.96)*.2*1e-9)**2), certidumbre=0.80, ), dict(etapa='juvenil_1', @@ -151,12 +152,12 @@ certidumbre=1), dict(etapa='juvenil_2', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'a'], - rango=((1823-100*1.96)/(53.1+10.64*1.96)*.2, (1823-100*1.96)/(53.1-10.64*1.96)*.2), + rango=((1823-100*1.96)/(53.1+10.64*1.96)*1e-9*.2, (1823-100*1.96)/(53.1-10.64*1.96)*1e-9*.2), certidumbre=0.80, ), dict(etapa='juvenil_2', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'b'], - rango=(((1823-100*1.96)/(53.1+10.64*1.96))**2*.2, ((1823-100*1.96)/(53.1-10.64*1.96))**2*.2), + rango=(((1823-100*1.96)/(53.1+10.64*1.96)*.2*1e-9)**2, ((1823-100*1.96)/(53.1-10.64*1.96)*.2*1e-9)**2), certidumbre=0.80, ), dict(etapa='juvenil_2', @@ -179,11 +180,11 @@ certidumbre=1), dict(etapa='juvenil_3', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'a'], - rango=((1823-100*1.96)/(53.1+10.64*1.96)*.2, (1823-100*1.96)/(53.1-10.64*1.96)*.2), + rango=((1823-100*1.96)/(53.1+10.64*1.96)*1e-9*.2, (1823-100*1.96)/(53.1-10.64*1.96)*1e-9*.2), certidumbre=0.80), dict(etapa='juvenil_3', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'b'], - rango=(((1823-100*1.96)/(53.1+10.64*1.96))**2*.2, ((1823-100*1.96)/(53.1-10.64*1.96))**2*.2), + rango=(((1823-100*1.96)/(53.1+10.64*1.96)*.2*1e-9)**2, ((1823-100*1.96)/(53.1-10.64*1.96)*.2*1e-9)**2), certidumbre=0.80), dict(etapa='juvenil_3', ubic_parám=['Muertes', 'Ecuación', 'Constante', 'q'], @@ -203,11 +204,11 @@ certidumbre=1), dict(etapa='juvenil_4', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'a'], - rango=((1823-100*1.96)/(53.1+10.64*1.96)*.2, (1823-100*1.96)/(53.1-10.64*1.96)*.2), + rango=((1823-100*1.96)/(53.1+10.64*1.96)*1e-9*.2, (1823-100*1.96)/(53.1-10.64*1.96)*1e-9*.2), certidumbre=0.80), dict(etapa='juvenil_4', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'b'], - rango=(((1823-100*1.96)/(53.1+10.64*1.96))**2*.2, ((1823-100*1.96)/(53.1-10.64*1.96))**2*.2), + rango=(((1823-100*1.96)/(53.1+10.64*1.96)*.2*1e-9)**2, ((1823-100*1.96)/(53.1-10.64*1.96)*.2*1e-9)**2), certidumbre=0.80), dict(etapa='juvenil_4', ubic_parám=['Muertes', 'Ecuación', 'Constante', 'q'], @@ -227,11 +228,11 @@ certidumbre=1), dict(etapa='juvenil_5', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'a'], - rango=((1823-100*1.96)/(53.1+10.64*1.96)*.2, (1823-100*1.96)/(53.1-10.64*1.96)*.2), + rango=((1823-100*1.96)/(53.1+10.64*1.96)*1e-9*.2, (1823-100*1.96)/(53.1-10.64*1.96)*1e-9*.2), certidumbre=0.80), dict(etapa='juvenil_5', ubic_parám=['Depredación', 'Ecuación', 'Kovai', 'b'], - rango=(((1823-100*1.96)/(53.1+10.64*1.96))**2*.2, ((1823-100*1.96)/(53.1-10.64*1.96))**2*.2), + rango=(((1823-100*1.96)/(53.1+10.64*1.96)*.2*1e-9)**2, ((1823-100*1.96)/(53.1-10.64*1.96)*.2*1e-9)**2), certidumbre=0.80), dict(etapa='juvenil_5', ubic_parám=['Muertes', 'Ecuación', 'Constante', 'q'], diff --git a/tikon/RAE/Planta.py b/tikon/RAE/Planta.py index 1d3955ad..4a608f7d 100644 --- a/tikon/RAE/Planta.py +++ b/tikon/RAE/Planta.py @@ -90,11 +90,11 @@ def estimar_densidad(símismo, rango, certidumbre, parte='hoja'): """ :param rango: - :type rango: + :type rango: tuple[float | int, float | int] :param certidumbre: - :type certidumbre: + :type certidumbre: float | int :param parte: - :type parte: + :type parte: str """ diff --git a/tikon/__init__.py b/tikon/__init__.py index e134aa0f..657e59c9 100644 --- a/tikon/__init__.py +++ b/tikon/__init__.py @@ -25,18 +25,21 @@ } mods_faltan = [] +ctrls_cambiados = False for mod in dirs_modelos: if not os.path.exists(dirs_modelos[mod]): if mod in dirs_auto and os.path.exists(dirs_auto[mod]): dirs_modelos[mod] = dirs_auto[mod] - - with open(archivo_ctrls, 'w', encoding='utf8') as d: - json.dump(dirs_modelos, d, ensure_ascii=False, sort_keys=True, indent=2) # Guardar todo + ctrls_cambiados = True else: mods_faltan.append(mod) +if ctrls_cambiados: + with open(archivo_ctrls, 'w', encoding='utf8') as d: + json.dump(dic_ctrls, d, ensure_ascii=False, sort_keys=True, indent=2) # Guardar todo + if len(mods_faltan): avisar('Directorios no encontrados para los modelos de cultivo %s. ' 'No se pueden usar estos modelos de cultivos en esta sesión de Tiko\'n.' % ', '.join(mods_faltan) diff --git "a/tikon/versi\303\263n.txt" "b/tikon/versi\303\263n.txt" index e6d5cb83..1cc5f657 100644 --- "a/tikon/versi\303\263n.txt" +++ "b/tikon/versi\303\263n.txt" @@ -1 +1 @@ -1.0.2 \ No newline at end of file +1.1.0 \ No newline at end of file