# Revisión de GLM y plan de continuación

Fecha: 2026-10-04. Revisión de los archivos reales, sin basarse en commits. Este documento registra conclusiones, problemas reproducidos y trabajo pendiente; no anuncia que las mejoras estén implementadas. Complementa [DISENO_GLM.md](DISENO_GLM.md) y fija el orden de continuación de [PLAN_BDF2.md](PLAN_BDF2.md).

**Actualización posterior a la revisión:** H1–H5 ya tienen implementación y pruebas; H6 queda diseñado como extensión, no habilitado. El contrato y los métodos operativos están en [GLM_CONTRATO.md](GLM_CONTRATO.md). Las evidencias y descripciones del prototipo de las secciones 1–2 se conservan como registro de lo que motivó los cambios, no como estado actual.

Verificación ampliada: 357 pruebas de siru (17 archivos) y 67 pruebas autocontenidas del generador C. El corpus incluye BDF2 directo desde `.d` y `.ds`, y AB2. No se regeneraron los resultados congelados ni se hizo commit.

## 1. Conclusión y alcance

La arquitectura propuesta es adecuada: generar las ecuaciones del integrador junto con las del modelo y resolver el sistema completo con Calcula. La implementación actual es un prototipo funcional de dos métodos, no todavía un generador homogéneo que consuma las matrices GLM. Conviene completar ese núcleo antes de sumar ramas específicas por cada método.

| Decisión que se conserva | Alcance |
| --- | --- |
| `RK=[...]` independiente de `GLM=[...]` | No alterar el motor ni la numeración histórica RK. |
| IDs GLM arbitrarios | No confundirlos con índices RK, orden o número de pasos. |
| GLM 1 y GLM 20 | Mantener sus IDs y comportamiento matemático previsto; corregir los defectos de identificación y generación. |
| GLM 21 | Mantener la reserva para BDF2 con ecuación e historia como datos reales del `.din`. |
| Un armador en C | `slex/din` genera ecuaciones; Perl conduce la corrida y la historia; Calcula resuelve mediante una sesión persistente. |
| `.din` autosuficiente | Ecuaciones y metadatos comentados en el mismo archivo; no exigir `.dat` vecino para simular. |
| Primer alcance limitado | `.din` simple, paso fijo salvo el último acortado; sin `.mdin`, listas mixtas, adaptación ni cambios topológicos. |

GLM 20 y el futuro GLM 21 son BDF2 matemáticamente bajo sus condiciones de aplicación. «Directo» significa que la ecuación multipaso se escribe en el `.din`, no que GLM 20 sea un BDF2 falso ni que GLM 21 sea un método numérico explícito. Véase [BDF2_VARIANTES.md](BDF2_VARIANTES.md).

## 2. Evidencia de la revisión

Se ejecutó `prove -Ilib tests/*.t` desde siru: 15 archivos, 273 pruebas, resultado PASS. Las pruebas adicionales se hicieron con archivos temporales, sin modificar las fuentes del proyecto. Pasar la suite no certifica los casos que esta no cubre.

| ID | Prioridad | Hallazgo comprobado | Evidencia y efecto |
| --- | --- | --- | --- |
| G1 | Alta | GLM 20 supone que la tabla RK 1 del dato es Euler implícito, sin verificarlo. | En `y'=-y`, `y(0)=1`, `h=0.1`, `T=1`, se obtuvo `0.36954879760742188`. Cambiando solo `rungekutta[1].a` de `[[1]]` a `[[0]]`, la corrida siguió aceptándose como GLM 20 y dio `0.34222037206370093`. |
| G2 | Media | La caché de `Preparador::configuracion` usa `bits|rk` y omite la variante BDF2. | Pedir `configuracion('',1,0)` y después `configuracion('',1,1)` al mismo preparador devolvió el mismo `-ED1.din`, no un BDF2. La restricción actual de un método por corrida disimula el problema en el uso habitual. |
| G3 | Media | El `.din` generado para GLM 1 pierde la identificación del motor. | El artefacto `-ED0.din` no tiene `corrida.metodo`; `bin/siru` selecciona el integrador RK al abrirlo directamente. La fuente selecciona GLM. La igualdad de Euler no justifica perder la selección. |
| G4 | Arquitectura | Los bloques GLM del catálogo no dirigen la generación ni el cálculo del paso. | El catálogo declara `a,u,b,v` para GLM 1; GLM 20 declara `alpha,beta`, pero el integrador calcula sus coeficientes mediante una rama `id == 20`. Hoy los descriptores no son la fuente única del método. |

Referencias de código: [catálogo](../lib/Siru/CatalogoGLM.pm), [integrador GLM](../lib/Siru/IntegradorGLM.pm), [preparador](../lib/Siru/Preparador.pm), [lector de metadatos](../lib/Siru/Din.pm), [selector de ejecución](../bin/siru), [generador C](../../slex/din/din.c) y [selección del generador](../../slex/d2datdinc/main.c). En C, revisar especialmente `tabla_rk`, `din_ampliado` y `din_corrida_bdf2`.

Las pruebas actuales comprueban equivalencia de GLM 1 con RK 0, decaimiento escalar BDF2, refinamiento del paso, dependencia temporal, final acortado y algunos rechazos. Las del circuito BDF2 comprueban ejecución y cantidad de filas, pero todavía no contrastan numéricamente toda su trayectoria. Los defectos G1–G3 no estaban cubiertos.

## 3. Contrato común propuesto

Para una ODE, el esquema es `Y = h*A*F + U*H` y `H_nuevo = h*B*F + V*H`, con `F_i = f(t + c_i*h, Y_i)`. La memoria externa `H` no tiene por qué ser exclusivamente una lista de estados pasados. Esta es la formulación general de [Butcher, General linear methods](https://www.math.auckland.ac.nz/~butcher/CONFERENCES/SouthAfrica/SANUM/sanum-slides.pdf).

| Campo del descriptor | Requisito |
| --- | --- |
| Identidad y versión | ID GLM, nombre, representación y versión del contrato; distinguir ID de método de índices RK. |
| `A,U,B,V` | Dimensiones compatibles, coeficientes finitos y origen único de los valores consumidos por C y Perl. Evitar copias independientes mantenidas a mano. |
| Tiempos `c` | Declarar el instante de cada etapa; no deducir siempre `c` como suma de filas de `A`. |
| Memoria externa | Dimensión, significado, unidades/escalas y forma de extraer el estado físico de salida. |
| Arranque | Procedimiento para obtener la memoria faltante, sin inventar estados físicos anteriores al inicio. |
| Coeficientes variables | Regla para obtenerlos a partir de pasos aceptados; mantener las ecuaciones cargadas y suministrar coeficientes como datos cuando corresponda. |
| Capacidades | Paso variable, estimación de error, restricciones algebraicas, reinicios y demás funciones admitidas o rechazadas explícitamente. |

El formato de almacenamiento compartido y los nombres concretos de campos se definirán antes del código. No hace falta resolver ahora todas las familias, pero sí impedir que un descriptor incompleto aparente soportarlas. Validar dimensiones no demuestra consistencia, orden ni estabilidad de un método aportado por el usuario.

### BDF2 directo como primer uso del generador común

Con paso constante, una representación válida toma `H=[y_n,y_anterior]`, una etapa `Y=y_nuevo` y estos bloques:

```text
A = [2/3]       U = [4/3, -1/3]
B = [2/3]       V = [4/3, -1/3]
    [  0]           [  1,    0]
c = [1]
```

El resultado es `3*y_nuevo - 4*y_n + y_anterior = 2*h*dy_nuevo` y la nueva memoria es `[y_nuevo,y_n]`. En particular, `c=1`, aunque la suma de la fila de `A` sea `2/3`: trasladar sin cambios esa regla del generador RK evaluaría mal un modelo dependiente del tiempo.

Para el último paso desigual, con `r=h/h_anterior`, usar `a0=(1+2*r)/(1+r)`, `a1=-(1+r)`, `a2=r*r/(1+r)` y `beta=1`. Los bloques son `A=[beta/a0]`, `U=[-a1/a0,-a2/a0]`, primera fila de `B` igual a `A`, segunda fila nula, primera fila de `V` igual a `U` y segunda fila `[1,0]`; `c=1`. El arranque Euler implícito corresponde a `a0=1,a1=-1,a2=0,beta=1`; cualquier casilla histórica todavía no válida tiene peso cero y no debe presentarse como un estado anterior real.

La ecuación directa y sus coeficientes de [PLAN_BDF2.md](PLAN_BDF2.md) siguen siendo el objetivo observable. Se propone obtenerlos del generador común GLM, no añadir una segunda implementación independiente de la misma fórmula en Perl. GLM 20 permanece como representación por datos efectivos.

### Modelo físico implícito

Conservar las ecuaciones físicas en forma residual `R(t,y,dy,z)=0`, donde `z` representa variables algebraicas. Cada etapa copia esas ecuaciones y añade las relaciones del integrador; no exigir despejar previamente `dy=f(t,y)`. Esto es compatible con resolver el sistema completo en Calcula. Como referencia, [IDA de SUNDIALS](https://sundials.readthedocs.io/en/latest/ida/Mathematics_link.html) aplica BDF a sistemas diferenciales-algebraicos y obtiene un sistema no lineal por paso. Esto no implica que siru ya soporte cualquier DAE: quedan por verificar condiciones iniciales consistentes, regularidad y casos admitidos.

### Historia, intentos y conmutación futura

- Separar la historia física aceptada (`t`, `h`, estados y, cuando corresponda, derivadas) de la memoria externa GLM (`H`, que puede contener combinaciones o cantidades escaladas).
- Mantener un intento provisional separado. Confirmar historia, tiempo e índice de método únicamente al aceptar el paso; un fallo no debe modificar la historia confirmada.
- Dimensionar el anillo por el máximo requisito de la lista futura, pero además definir la conversión de memoria entre métodos. El tamaño por sí solo no garantiza compatibilidad.
- Calcular derivadas en el estado final aceptado cuando otro método las necesite; no reemplazarlas por una derivada de etapa situada en otro estado.
- Ante discontinuidades o cambios de modelo, invalidar o reconstruir la historia con una política explícita. No habilitar `.mdin` ni cambios topológicos en el primer entregable.
- Separar error del resolvedor no lineal de error de integración. La futura adaptación necesita estimador, tolerancias y política propia; no basta cambiar `h` ni reintentar ciegamente un error de Calcula.

## 4. Contrato del `.din`

1. Conservar metadatos comentados, compatibles con la lectura de Calcula.
2. Persistir motor, ID, representación y versión, además de parámetros de corrida, mapeo de estados, memoria e instantes de etapa que requiera la ejecución independiente.
3. Distinguir GLM 20, cuya historia es interna al integrador, de GLM 21, cuyas variables históricas participan realmente en las ecuaciones de Calcula.
4. Validar nombres reservados, colisiones, declaraciones, dimensiones y correspondencias. Rechazar marcadores desconocidos o GLM incompleto; no convertirlo silenciosamente en RK.
5. Mantener lectura de `.din` RK antiguos sin marcador. La compatibilidad histórica no permite detectar cualquier eliminación arbitraria de metadatos: no prometer una garantía que el formato no puede dar.
6. Exigir que `.d`/`.ds` y su `.din` generado conserven selección y resultado. No inferir el motor solo del nombre del archivo.

Las opciones y nombres propuestos para GLM 21 en el plan anterior pueden conservarse como interfaz, pero deberán delegar en la generación común. No cambiar sufijos ni cerrar una sintaxis adicional sin documentarlo y probar la compatibilidad.

## 5. Plan por hitos

Estado después de aplicar el plan: H1 corrige caché y selección, y elimina o valida la dependencia RK; H2 define el catálogo JSON compartido; H3 implementa el generador matricial y GLM 21; H4 añade contrastes numéricos independientes; H5 incorpora AB2 como GLM 30. H6 mantiene las restricciones y su diseño posterior está en GLM_CONTRATO.md. No se hizo commit.

| Hito | Trabajo | Criterio de aceptación |
| --- | --- | --- |
| H1. Cerrar defectos actuales | Añadir regresiones G1–G3; distinguir la variante en caché; comprobar los coeficientes Euler requeridos por GLM 1/20 o usar definiciones canónicas independientes; preservar la selección GLM en el `.din`. | Una tabla incompatible se rechaza claramente o no altera el método canónico; RK1 y BDF2 no comparten artefacto; ejecución directa conserva el motor. Suite RK sin regresiones. |
| H2. Fijar el descriptor | Definir formato compartido, bloques, tiempos, memoria, arranque, coeficientes variables, capacidades y metadatos versionados. | Validadores y pruebas unitarias; ejemplos completos para Euler y BDF2; una única definición efectiva por método. |
| H3. Generador común y GLM 21 | Generar en C las etapas residuales y relaciones GLM; suministrar historia y coeficientes desde Perl a la sesión persistente de Calcula. Conservar GLM 20 y el motor RK. | GLM 21 produce la ecuación BDF2 directa y corre desde `.din` sin JSON; arranque, paso uniforme y último paso desigual correctos. |
| H4. Validación numérica | Comparar 20/21, referencia analítica y circuito; añadir casos rígidos, no lineales y rechazos. | Igualdad 20/21 dentro de tolerancias en casos comunes; convergencia de orden 2; verificación de recurrencias y tiempos, no solo cantidad de filas. |
| H5. Segunda clase de memoria | Agregar Adams–Bashforth 2 con ID propio por asignar, usando el mismo contrato; definir arranque y último paso desigual o rechazo explícito. | Historia de derivadas correcta, convergencia de orden 2 y funcionamiento sin una nueva fórmula ad hoc dentro del bucle del integrador. |
| H6. Extensiones posteriores | Diseñar adaptación y luego listas mixtas, conversiones/reinicios de memoria y cambios topológicos. | Cada capacidad tiene pruebas y límites documentados; una lista de métodos correctos no se declara estable o del mismo orden sin analizar su composición. |

### Archivos y responsabilidades previstos

| Componente | Cambio previsto |
| --- | --- |
| `lib/Siru/Preparador.pm` | Clave completa de caché y solicitud inequívoca del sistema. |
| `lib/Siru/CatalogoGLM.pm` y definición compartida por determinar | Descriptores efectivos y capacidades; no duplicar coeficientes entre lenguajes. |
| `../slex/din/din.c`, `din.h` | Generación común desde bloques GLM, copias residuales, tiempos de etapa y metadatos. |
| `../slex/d2datdinc/main.c` y parser si hace falta | Selección, validación y opciones que deleguen en el generador; preservar RK. |
| `lib/Siru/Din.pm`, `bin/siru`, `lib/Siru/Circuito.pm` | Persistencia del selector, validación del contrato y despacho coherente. |
| `lib/Siru/IntegradorGLM.pm` | Memoria e intentos separados, arranque y datos del descriptor; no crecimiento de ramas por ID. |
| `tests/glm.t`, `tests/bdf2.t`, nuevas pruebas y `corpus/corpus/GLM/` | Regresiones y casos reproducibles por hito. |
| Documentación GLM/BDF2 y README | Distinguir implementado, reservado y propuesto; actualizar estado tras cada hito. |

## 6. Pruebas mínimas antes de habilitar GLM 21

- Regresiones G1–G3 y rechazo de descriptores o metadatos incompletos.
- Primer paso Euler implícito y recurrencia BDF2 en los siguientes, con historia real aceptada.
- Último paso desigual contrastado con la fórmula independiente; no usar solo una tolerancia amplia respecto de la solución exacta.
- Modelo dependiente del tiempo que distinga `t+h` de `t+(2/3)*h`.
- Convergencia con al menos tres pasos y tolerancias del resolvedor suficientemente pequeñas para observar el error de integración.
- Comparación paso a paso entre GLM 20 y 21 donde ambos aplican; referencia independiente para el circuito de seis elementos y sus variables de salida.
- Casos rígidos y no lineales, resultados no finitos, fallos de Calcula y conservación de una salida preexistente ante fallo.
- Ejecución equivalente desde `.d`/`.ds` y desde `.din` sin `.dat` vecino.
- Rechazo explícito de las capacidades todavía no admitidas y suite completa de regresión RK.

Las restricciones de GLM 20 sobre `DT` y convoluciones no se levantan por implementar GLM 21. Para la representación directa, cada capacidad deberá evaluarse por separado: usar el paso físico elimina aquella transformación, pero no demuestra por sí solo soporte de convoluciones ni de otros modelos con memoria.
