{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "17db8fb0",
   "metadata": {},
   "source": [
    "# Clase 1 — Modelado de Cadenas de Markov en Tiempo Continuo (CTMC)\n",
    "## Caso: deterioro de la fachada de un edificio\n",
    "\n",
    "**Contexto (basado en un paper real).** Zbiciak et al. (2026), *\"Continuous-Time Markov Chain Modelling for Service Life Prediction of Building Elements\"* (Applied Sciences), modela el deterioro de elementos de construcción (fachadas, cubiertas, instalaciones, etc.) como una CTMC con un **estado absorbente** que representa la falla, y usa la ecuación diferencial de Kolmogorov $\\frac{d}{dt}\\mathbf{p}(t)=\\mathbf{p}(t)\\mathbf{Q}$ para calcular la supervivencia y el riesgo del elemento a lo largo del tiempo.\n",
    "\n",
    "En esta clase modelamos, con el mismo enfoque, el deterioro de la **fachada** de un edificio, clasificada por inspección en 4 estados de condición (igual que en el paper). En la Clase 2 retomaremos este mismo sistema para resolverlo con las ecuaciones de Kolmogorov de forma explícita, y calcularemos la vida útil esperada.\n",
    "\n",
    "Curso: Modelado de Sistemas bajo Incertidumbre · Universidad de los Andes · 2026-20\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "254a8184",
   "metadata": {},
   "source": [
    "## Descripción del problema\n",
    "\n",
    "Un equipo de inspección clasifica la fachada de un edificio, cada cierto tiempo, en uno de 4 estados de condición (siguiendo la clasificación del paper): muy bueno, medio, satisfactorio o malo. El deterioro es monótono: la fachada nunca \"mejora\" por sí sola, solo pasa al siguiente estado de desgaste. El estado \"malo\" se considera terminal: en ese punto el elemento requiere reemplazo.\n",
    "\n",
    "**Variable de estado.** $X(t)$: ...\n",
    "\n",
    "**Espacio de estados.** $S= ... $:\n",
    "- Estado  ... "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c6a7c27b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# importar librerías\n",
    "import numpy as np\n",
    "from jmarkov.ctmc import ctmc\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dffa8ff8",
   "metadata": {},
   "source": [
    "## Parámetros del problema\n",
    "\n",
    "Los inspectores estiman, para esta fachada, un tiempo medio de permanencia en cada estado antes de pasar al siguiente:\n",
    "- Estado ... \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc0730da",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO 1: \n",
    "q1 = None\n",
    "q2 = None\n",
    "q3 = None\n",
    "print(f'q1={q1:.4f}, q2={q2:.4f}, q3={q3:.4f}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea4ebcec",
   "metadata": {},
   "source": [
    "## Diagrama de transiciones\n",
    "\n",
    "\n",
    "\n",
    "## Matriz generadora\n",
    "\n",
    "$$Q=\\begin{pmatrix} \\end{pmatrix}$$\n",
    "\n",
    "Nota: la última fila es toda ceros porque el estado 4 es absorbente (una vez ahí, el proceso no vuelve a salir)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d41594dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO 2: construye la matriz generadora Q (nxn) siguiendo la fórmula de arriba\n",
    "Q = np.array([\n",
    "    # fila 0\n",
    "    # fila 1 \n",
    "    # fila 2 \n",
    "    # fila 3 \n",
    "])\n",
    "\n",
    "mc = ctmc(Q)\n",
    "print(f'Q=\\n{mc.generator}')\n",
    "\n",
    "# --- prueba rápida (no la modifiques) ---\n",
    "assert np.allclose(Q.sum(axis=1), 0), 'cada fila de Q debe sumar 0'\n",
    "print('OK: Q es una matriz generadora válida (filas suman 0).')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb0d836f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO 3: construye el vector de condiciones iniciales alpha\n",
    "# la fachada es nueva: arranca en el estado n (XXX)\n",
    "alpha = np.array([])\n",
    "print(f'alpha={alpha}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17d1781e",
   "metadata": {},
   "source": [
    "## Evaluar la distribución transitoria\n",
    "\n",
    "Calcula $\\pi(t)$ para $t\\in\\{5,\\,10,\\,20,\\,30,\\,40,\\,60,\\,80\\}$ años usando `mc.transient_probabilities(t, alpha)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58e8ed50",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO 4: evalúa pi(t) para cada uno de los tiempos dados, usando un ciclo for\n",
    "tiempos = [5, 10, 20, 30, 40, 60, 80]\n",
    "for t in tiempos:\n",
    "    pi_t = None  # usa mc.transient_probabilities(t, alpha)\n",
    "    print(f'pi({t})={np.round(pi_t,4)}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "263944b4",
   "metadata": {},
   "source": [
    "## Función de supervivencia\n",
    "\n",
    "La fachada \"sobrevive\" (no ha sido reemplazada) mientras no esté en el estado absorbente 4. La supervivencia en el instante $t$ es:\n",
    "\n",
    "$$S(t)=P(X(t)\\neq 4)=\\pi_1(t)+\\pi_2(t)+\\pi_3(t) = 1-\\pi_4(t)$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c115ef4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO 5: calcula S(t) = 1 - pi_4(t) para cada uno de los mismos tiempos\n",
    "for t in tiempos:\n",
    "    pi_t = mc.transient_probabilities(t, alpha)\n",
    "    S_t = None\n",
    "    print(f'S({t}) = {S_t:.4f}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b14dbce5",
   "metadata": {},
   "source": [
    "## Evaluar la distribución estacionaria\n",
    "\n",
    "Como el estado 4 es absorbente, toda la masa de probabilidad termina ahí: $\\pi\\to(0,0,0,1)$ cuando $t\\to\\infty$. Verifica esto con `mc.steady_state()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1fae8a1f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO 6: calcula la distribución estacionaria\n",
    "ss = None  # usa mc.steady_state()\n",
    "print(f'pi={np.round(ss,4)}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "190d3b64",
   "metadata": {},
   "source": [
    "## Conclusión\n",
    "\n",
    "_¿Por qué toda la probabilidad termina, eventualmente, en el estado 4? ¿Qué significa esto físicamente para la fachada? ¿A qué edad (en años) te parece que la probabilidad de supervivencia cae por debajo del 50%, según los valores que calculaste?_"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
