# ==========================================================
# Aproximación de e (MicroPython)
# Métodos:
# 1) Taylor: e = sum_{n=0..∞} 1/n!
# 2) Límite: e = lim_{N→∞} (1 + 1/N)^N
# 3) Serie alternativa: e = 2*sum_{n=0..∞} (n+1)/(2n+1)!
#
# Tabla experimental:
# Metodo | N | e_aprox | error_abs | tiempo_us
# ==========================================================
import math
import time
# -----------------------------
# Compatibilidad de ticks_us
# -----------------------------
def _ticks_us():
# MicroPython: ticks_us()
if hasattr(time, "ticks_us"):
return time.ticks_us()
# Fallback CPython: perf_counter_ns
if hasattr(time, "perf_counter_ns"):
return time.perf_counter_ns() // 1000
# Último recurso (menos preciso)
return int(time.time() * 1_000_000)
def _ticks_diff(t1, t0):
# MicroPython: ticks_diff()
if hasattr(time, "ticks_diff"):
return time.ticks_diff(t1, t0)
return t1 - t0
def bench(func, N):
t0 = _ticks_us()
val = func(N)
dt = _ticks_diff(_ticks_us(), t0)
return val, dt
# ==========================================================
# 1) Taylor (Maclaurin)
# e = sum_{n=0..∞} 1/n!
# Recur: term_{n+1} = term_n / (n+1)
# ==========================================================
def e_taylor(N):
s = 0.0
term = 1.0 # 1/0!
for n in range(N):
s += term
term /= (n + 1) # genera 1/(n+1)!
return s
# ==========================================================
# 2) Límite fundamental
# e ≈ (1 + 1/N)^N
# ==========================================================
def e_limite(N):
if N <= 0:
return 1.0
return (1.0 + 1.0 / N) ** N
# ==========================================================
# 3) Serie alternativa
# e = 2 * sum_{n=0..∞} (n+1)/(2n+1)!
#
# Recur para el factorial impar:
# fact = (2n+1)!
# fact_{n+1} = fact_n * (2n+2) * (2n+3)
# ==========================================================
def e_serie_alt(N):
s = 0.0
fact = 1.0 # (2*0+1)! = 1! = 1
for n in range(N):
# término: (n+1)/(2n+1)!
s += (n + 1) / fact
# actualizar fact para siguiente n
# fact <- (2(n+1)+1)! = (2n+3)!
a = 2 * n + 2 # 2n+2
b = 2 * n + 3 # 2n+3
fact *= a * b
return 2.0 * s
# -----------------------------
# Lista de métodos
# -----------------------------
METHODS_E = [
("Taylor", e_taylor),
("Limite", e_limite),
("SerieAlt", e_serie_alt),
]
def tabla_convergencia_e(N_list):
ref = math.e
print("\n==== Comparativa experimental de e (MicroPython) ====")
print("Referencia math.e =", ref)
print("Columnas: Metodo | N | e_aprox | error_abs | tiempo_us")
print("-" * 72)
for N in N_list:
print("\n--- N =", N, "---")
for name, f in METHODS_E:
val, dt = bench(f, N)
err = abs(val - ref)
print("{:<8s} | {:>6d} | {:>12.10f} | {:>10.3e} | {:>8d}".format(
name, N, val, err, dt
))
def main():
# Puede ajustar según su placa.
# En ESP32/Pico suele estar bien:
N_list = [3, 5, 10, 20, 50, 100]
tabla_convergencia_e(N_list)
print("\nNotas:")
print("- Taylor converge muy rápido (pocos términos dan alta precisión).")
print("- El límite converge lento: útil para concepto, no para precisión.")
print("- SerieAlt es una alternativa interesante para comparación académica.")
main()