{ "cells": [ { "cell_type": "markdown", "id": "23e4485d", "metadata": {}, "source": [ "### *Módulo 4: Cálculo · Valores Extremos de Funciones de Dos Variables*\n", ">Objetivo\n", "\n", "Elaborar un programa en Python que, mediante variables simbólicas (SymPy),\n", "encuentre los valores extremos locales de funciones reales de dos variables reales.\n", "El programa debe identificar: máximos locales, mínimos locales y puntos silla." ] }, { "cell_type": "code", "execution_count": 46, "id": "ef27609c", "metadata": {}, "outputs": [], "source": [ "import sympy as sp\n", "from IPython.display import display, Markdown\n", "from sympy.abc import x, y\n", "\n", "\n", "def get_critical_points(fn, constants=None):\n", " if constants is None:\n", " constants = set()\n", " else:\n", " constants = set(constants)\n", "\n", " variables = sorted(list(fn.free_symbols - constants), key=lambda s: s.name)\n", " \n", " # 1. Calcular el gradiente: f = (∂f/∂x, ∂f/∂y) ∇\n", " gradient = [sp.diff(fn, v) for v in variables]\n", " \n", " # 2. Resolver el sistema f = 0 para hallar los puntos críticos. ∇\n", " return sp.solve(gradient, variables, dict=True)\n", "\n", "def classify_critical_points(fn, constants=None, report=False):\n", " if constants is None:\n", " constants = set()\n", " else:\n", " constants = set(constants)\n", "\n", " variables = sorted(list(fn.free_symbols - constants), key=lambda s: s.name)\n", " if len(variables) != 2:\n", " raise ValueError(\"La función debe tener exactamente dos variables\")\n", "\n", " # 3. Calcular la matriz Hessiana H y su determinante D = fxx·fyy − (fxy)².\n", " H = sp.hessian(fn, variables)\n", " f_xx = H[0, 0]\n", " f_yy = H[1, 1]\n", " f_xy = H[0, 1]\n", "\n", " D = sp.simplify(f_xx * f_yy - f_xy**2)\n", " critical_points = get_critical_points(fn, constants)\n", "\n", " results = []\n", "\n", " if report:\n", " gradient_matrix = sp.Matrix([sp.diff(fn, v) for v in variables])\n", " vars_str = \", \".join([str(v) for v in variables])\n", " full_report_md = (\n", " f\"**a) Gradiente simbólico:**\\n\\n\"\n", " f\"$$\\\\nabla f({vars_str}) = {sp.latex(gradient_matrix)}$$\\n\\n\"\n", " f\"---\\n\\n\"\n", " f\"**b) Hessiana completa:**\\n\\n\"\n", " f\"$$H = {sp.latex(H)}$$\\n\\n\"\n", " f\"---\\n\\n\"\n", " f\"**c) Clasificación de puntos críticos e impresión de valores:**\\n\\n\"\n", " )\n", "\n", " for point in critical_points:\n", " d = D.subs(point)\n", " dxx = f_xx.subs(point)\n", " value = fn.subs(point)\n", "\n", " # 4. Clasificar cada punto crítico (p₀): si D>0 y fxx>0 → mínimo; D>0 y fxx<0 → máximo; D<0 → silla; D=0 → inconcluso.\n", " if d.is_positive and dxx.is_positive: \n", " classification = \"mínimo local\"\n", " elif d.is_positive and dxx.is_negative:\n", " classification = \"máximo local\"\n", " elif d.is_negative:\n", " classification = \"punto silla\"\n", " else:\n", " classification = \"inconcluso\"\n", "\n", " item = {\n", " \"point\": point,\n", " \"D\": d,\n", " \"f_xx\": dxx,\n", " \"value\": value,\n", " \"classification\": classification\n", " }\n", "\n", " if report:\n", " sorted_point = sorted(point.items(), key=lambda x: str(x[0]))\n", " coordinates = \", \".join([sp.latex(v) for k, v in sorted_point])\n", " \n", " point_md = (\n", " f\"Para el punto crítico $({coordinates})$:\\n\"\n", " f\"* El determinante evaluado es $D = {sp.latex(d)}$\\n\"\n", " f\"* La segunda derivada parcial es $f_{{xx}} = {sp.latex(dxx)}$\\n\"\n", " f\"* Conclusión: Es un **{classification}** con valor extremo $f({coordinates}) = {sp.latex(value)}$.\\n\\n\"\n", " )\n", " \n", " item[\"markdown_report\"] = point_md\n", " full_report_md += point_md\n", " \n", " results.append(item)\n", "\n", " if report:\n", " display(Markdown(full_report_md))\n", " return\n", "\n", " return results" ] }, { "cell_type": "markdown", "id": "13780078", "metadata": {}, "source": [ "### Ejercicio 1.\n", "\n", "Dada la función:\n", "\n", "$$\n", "f(x, y) = x^2 + y^2 - 4x - 6y + 13\n", "$$\n", "\n", "\n", "a) Calcula analíticamente el gradiente y el punto crítico antes de codificar.\n", "\n", "b) Implementa el programa y verifica que SymPy reproduce tu resultado.\n", "\n", "c) Imprime el tipo de punto crítico con su valor \\(f(x_0, y_0)\\)." ] }, { "cell_type": "code", "execution_count": 47, "id": "896e2de0", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "Punto $(2, 3)$: **mínimo local** con valor $f(x_0, y_0) = 0$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = x**2 + y**2 - 4*x - 6*y + 13\n", "\n", "results = classify_critical_points(fn)\n", "\n", "for res in results:\n", " point = sorted(res['point'].items(), key=lambda item: str(item[0]))\n", " coords = \", \".join([str(v) for k, v in point])\n", " \n", " linea_md = f\"Punto $({coords})$: **{res['classification']}** con valor $f(x_0, y_0) = {res['value']}$\"\n", " \n", " display(Markdown(linea_md))" ] }, { "cell_type": "markdown", "id": "bda4bb69", "metadata": {}, "source": [ "### Ejercicio 2.\n", "\n", "Dada la función:\n", "\n", "$$\n", "f(x, y) = 3x^2 + 2y^2 - 12x + 8y + 5\n", "$$\n", "\n", "a) Determina el punto crítico y clasifícalo usando el criterio de la segunda derivada.\n", "\n", "b) Reporta \\(D\\), \\(f_{xx}\\) evaluados en el punto crítico, y el valor extremo." ] }, { "cell_type": "code", "execution_count": 48, "id": "5b4629e5", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "En el punto crítico $(2, -2)$ se tiene:\n", "* **Determinante:** $D = 24$\n", "* **Segunda derivada:** $f_{xx} = 6$\n", "* **Clasificación:** Es un **mínimo local**\n", "* **Valor extremo:** $f(2, -2) = -15$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] } ], "source": [ "fn = 3*x**2 + 2*y**2 - 12*x + 8*y + 5\n", "\n", "results = classify_critical_points(fn)\n", "\n", "for res in results:\n", " sorted_point = sorted(res['point'].items(), key=lambda item: str(item[0]))\n", " coordinates = \", \".join([sp.latex(v) for k, v in sorted_point])\n", " \n", " d_val = sp.latex(res['D'])\n", " fxx_val = sp.latex(res['f_xx'])\n", " extreme_value = sp.latex(res['value'])\n", " classification = res['classification']\n", " \n", " markdown_text = (\n", " f\"En el punto crítico $({coordinates})$ se tiene:\\n\"\n", " f\"* **Determinante:** $D = {d_val}$\\n\"\n", " f\"* **Segunda derivada:** $f_{{xx}} = {fxx_val}$\\n\"\n", " f\"* **Clasificación:** Es un **{classification}**\\n\"\n", " f\"* **Valor extremo:** $f({coordinates}) = {extreme_value}$\"\n", " )\n", " \n", " display(Markdown(markdown_text))\n", " print(\"-\" * 50) " ] }, { "cell_type": "markdown", "id": "a1535fbe", "metadata": {}, "source": [ "### Ejercicio 3.\n", "\n", "Dada la función:\n", "\n", "$$\n", "f(x, y) = x^3 - 3xy + y^3\n", "$$\n", "\n", "a) Encuentra todos los puntos críticos.\n", "\n", "b) Evalúa la Hessiana en cada punto crítico por separado.\n", "\n", "c) Determina cuál es un mínimo local y cuál es un punto silla.\n", "\n", "### Consideración\n", "\n", "Aplica `subs()` en la Hessiana para cada punto crítico." ] }, { "cell_type": "code", "execution_count": 49, "id": "27110314", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "En el punto crítico $(0, 0)$ se tiene:\n", "* **Determinante:** $D = -9$\n", "* **Segunda derivada:** $f_{xx} = 0$\n", "* **Clasificación:** Es un **punto silla**\n", "* **Valor extremo:** $f(0, 0) = 0$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] }, { "data": { "text/markdown": [ "En el punto crítico $(1, 1)$ se tiene:\n", "* **Determinante:** $D = 27$\n", "* **Segunda derivada:** $f_{xx} = 6$\n", "* **Clasificación:** Es un **mínimo local**\n", "* **Valor extremo:** $f(1, 1) = -1$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] }, { "data": { "text/markdown": [ "En el punto crítico $(\\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{2}, - \\frac{1}{2} - \\frac{\\sqrt{3} i}{2})$ se tiene:\n", "* **Determinante:** $D = -9 + 36 \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{3}$\n", "* **Segunda derivada:** $f_{xx} = 6 \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{2}$\n", "* **Clasificación:** Es un **inconcluso**\n", "* **Valor extremo:** $f(\\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{2}, - \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}) = \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{6} - 2 \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{3}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] }, { "data": { "text/markdown": [ "En el punto crítico $(\\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{2}, - \\frac{1}{2} + \\frac{\\sqrt{3} i}{2})$ se tiene:\n", "* **Determinante:** $D = -9 + 36 \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{3}$\n", "* **Segunda derivada:** $f_{xx} = 6 \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{2}$\n", "* **Clasificación:** Es un **inconcluso**\n", "* **Valor extremo:** $f(\\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{2}, - \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}) = - 2 \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{3} + \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{6}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] } ], "source": [ "fn = x**3 - 3*x*y + y**3\n", "\n", "results = classify_critical_points(fn)\n", "\n", "for res in results:\n", " sorted_point = sorted(res['point'].items(), key=lambda item: str(item[0]))\n", " coordinates = \", \".join([sp.latex(v) for k, v in sorted_point])\n", " \n", " d_val = sp.latex(res['D'])\n", " fxx_val = sp.latex(res['f_xx'])\n", " extreme_value = sp.latex(res['value'])\n", " classification = res['classification']\n", " \n", " markdown_text = (\n", " f\"En el punto crítico $({coordinates})$ se tiene:\\n\"\n", " f\"* **Determinante:** $D = {d_val}$\\n\"\n", " f\"* **Segunda derivada:** $f_{{xx}} = {fxx_val}$\\n\"\n", " f\"* **Clasificación:** Es un **{classification}**\\n\"\n", " f\"* **Valor extremo:** $f({coordinates}) = {extreme_value}$\"\n", " )\n", " \n", " display(Markdown(markdown_text))\n", " print(\"-\" * 50) " ] }, { "cell_type": "markdown", "id": "5ee44291", "metadata": {}, "source": [ "### Ejercicio 4.\n", "\n", "Dada la función:\n", "\n", "$$\n", "f(x, y) = -2x^2 - y^2 + 4x + 2y + 1\n", "$$\n", "\n", "a) Muestra el gradiente simbólico en pantalla.\n", "\n", "b) Computa la Hessiana completa:\n", "\n", "\n", "\\begin{bmatrix}\n", "f_{xx} & f_{xy} \\\\\n", "f_{yx} & f_{yy}\n", "\\end{bmatrix}\n", "\n", "c) Clasifica el punto crítico e imprime el valor máximo \\(f(x_0, y_0)\\)." ] }, { "cell_type": "code", "execution_count": 50, "id": "476a1dcf", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "**a) Gradiente simbólico:**\n", "\n", "$$\\nabla f(x, y) = \\left[\\begin{matrix}4 - 4 x\\\\2 - 2 y\\end{matrix}\\right]$$\n", "\n", "---\n", "\n", "**b) Hessiana completa:**\n", "\n", "$$H = \\left[\\begin{matrix}-4 & 0\\\\0 & -2\\end{matrix}\\right]$$\n", "\n", "---\n", "\n", "**c) Clasificación de puntos críticos e impresión de valores:**\n", "\n", "Para el punto crítico $(1, 1)$:\n", "* El determinante evaluado es $D = 8$\n", "* La segunda derivada parcial es $f_{xx} = -4$\n", "* Conclusión: Es un **máximo local** con valor extremo $f(1, 1) = 4$.\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = -2*x**2 - y**2 + 4*x + 2*y + 1\n", "\n", "classify_critical_points(fn, report=True)" ] }, { "cell_type": "markdown", "id": "be871497", "metadata": {}, "source": [ "\n", "### Ejercicio 5.\n", "\n", "Dada la función:\n", "\n", "$$\n", "f(x, y) = x^4 - 4x^2 + y^4 - 4y^2\n", "$$\n", "\n", "Esta función posee múltiples puntos críticos. El programa debe:\n", "\n", "a) Encontrar todos los puntos críticos usando `solve()` con el sistema:\n", "\n", "$$\n", " \\nabla f = 0\n", "$$\n", "\n", "\n", "b) Iterar sobre cada punto crítico y evaluar \\(D\\) en cada uno.\n", "\n", "c) Generar un reporte estructurado en consola que muestre:\n", "\n", "```text\n", "Punto crítico: (x₀, y₀) | D = ... | fxx = ... | Clasificación: ...\n", "\n", "d) Contar cuántos mínimos, máximos y puntos silla existen." ] }, { "cell_type": "code", "execution_count": 51, "id": "c0473f61", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Punto Crítico $(x, y)$ | Discriminante ($D$) | Segunda Derivada ($f_{xx}$) | Valor $f(x,y)$ | Clasificación |\n", "| :---: | :---: | :---: | :---: | :---: |\n", "| $(0, 0)$ | $64$ | $-8$ | $0$ | **máximo local** |\n", "| $(0, - \\sqrt{2})$ | $-128$ | $-8$ | $-4$ | **punto silla** |\n", "| $(0, \\sqrt{2})$ | $-128$ | $-8$ | $-4$ | **punto silla** |\n", "| $(- \\sqrt{2}, 0)$ | $-128$ | $16$ | $-4$ | **punto silla** |\n", "| $(- \\sqrt{2}, - \\sqrt{2})$ | $256$ | $16$ | $-8$ | **mínimo local** |\n", "| $(- \\sqrt{2}, \\sqrt{2})$ | $256$ | $16$ | $-8$ | **mínimo local** |\n", "| $(\\sqrt{2}, 0)$ | $-128$ | $16$ | $-4$ | **punto silla** |\n", "| $(\\sqrt{2}, - \\sqrt{2})$ | $256$ | $16$ | $-8$ | **mínimo local** |\n", "| $(\\sqrt{2}, \\sqrt{2})$ | $256$ | $16$ | $-8$ | **mínimo local** |\n", "\n", "---\n", "\n", "### Conteo Total de Puntos Críticos\n", "\n", "* **Mínimos locales:** 4\n", "* **Máximos locales:** 1\n", "* **Puntos silla:** 4\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = x**4 - 4*x**2 + y**4 - 4*y**2\n", "\n", "results = classify_critical_points(fn)\n", "classification_counts = {\n", " \"mínimo local\": 0,\n", " \"máximo local\": 0,\n", " \"punto silla\": 0,\n", " \"inconcluso\": 0\n", "}\n", "\n", "table_md = (\n", " \"| Punto Crítico $(x, y)$ | Discriminante ($D$) | Segunda Derivada ($f_{xx}$) | Valor $f(x,y)$ | Clasificación |\\n\"\n", " \"| :---: | :---: | :---: | :---: | :---: |\\n\"\n", ")\n", "\n", "for res in results:\n", " sorted_point = sorted(res['point'].items(), key=lambda item: str(item[0]))\n", " coordinates = \", \".join([sp.latex(v) for k, v in sorted_point])\n", " \n", " d_val = sp.latex(res['D'])\n", " fxx_val = sp.latex(res['f_xx'])\n", " extreme_value = sp.latex(res['value'])\n", " classification = res['classification']\n", " \n", " table_md += f\"| $({coordinates})$ | ${d_val}$ | ${fxx_val}$ | ${extreme_value}$ | **{classification}** |\\n\"\n", " \n", " if classification in classification_counts:\n", " classification_counts[classification] += 1\n", "\n", "table_md += (\n", " \"\\n---\\n\\n\"\n", " \"### Conteo Total de Puntos Críticos\\n\\n\"\n", " f\"* **Mínimos locales:** {classification_counts['mínimo local']}\\n\"\n", " f\"* **Máximos locales:** {classification_counts['máximo local']}\\n\"\n", " f\"* **Puntos silla:** {classification_counts['punto silla']}\\n\"\n", ")\n", "\n", "display(Markdown(table_md))" ] }, { "cell_type": "markdown", "id": "119d61e6", "metadata": {}, "source": [ "### Ejercicio 6.\n", "\n", "Dada la función:\n", "\n", "$$ f(x, y) = e^{-(x^2+y^2)} \\cos(x) \\cos(y) $$\n", "\n", "a) Calcula el gradiente simbólicamente con `diff()`.\n", "\n", "b) Encuentra los puntos críticos resolviendo:\n", "\n", "$$\n", " \\nabla f = 0\n", "$$\n", "\n", "c) Evalúa la Hessiana en cada punto crítico usando `evalf()` para obtener valores numéricos.\n", "\n", "d) Clasifica cada punto crítico e imprime su valor \\(f(x_0, y_0)\\)." ] }, { "cell_type": "code", "execution_count": 52, "id": "d5b399bf", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Punto Crítico $(x, y)$ | Discriminante ($D$) Exacto | Valor Numérico ($D$) | Segunda Derivada ($f_{xx}$) | Valor $f(x_0, y_0)$ | Clasificación |\n", "| :---: | :---: | :---: | :---: | :---: | :---: |\n", "| $(\\frac{\\pi}{2}, \\frac{\\pi}{2})$ | $- \\frac{1}{e^{\\pi^{2}}}$ | `-0.00005172` | $0$ | $0$ | **punto silla** |\n", "| $(\\frac{\\pi}{2}, \\frac{3 \\pi}{2})$ | $- \\frac{1}{e^{5 \\pi^{2}}}$ | `-3.702E-22` | $0$ | $0$ | **punto silla** |\n", "| $(\\frac{3 \\pi}{2}, \\frac{\\pi}{2})$ | $- \\frac{1}{e^{5 \\pi^{2}}}$ | `-3.702E-22` | $0$ | $0$ | **punto silla** |\n", "| $(\\frac{3 \\pi}{2}, \\frac{3 \\pi}{2})$ | $- \\frac{1}{e^{9 \\pi^{2}}}$ | `-2.650E-39` | $0$ | $0$ | **punto silla** |\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = sp.exp(-(x**2 + y**2)) * sp.cos(x) * sp.cos(y)\n", "results = classify_critical_points(fn)\n", "\n", "table_md = (\n", " \"| Punto Crítico $(x, y)$ | Discriminante ($D$) Exacto | Valor Numérico ($D$) | Segunda Derivada ($f_{xx}$) | Valor $f(x_0, y_0)$ | Clasificación |\\n\"\n", " \"| :---: | :---: | :---: | :---: | :---: | :---: |\\n\"\n", ")\n", "\n", "for res in results:\n", " sorted_point = sorted(res['point'].items(), key=lambda item: str(item[0]))\n", " coordinates = \", \".join([sp.latex(v) for k, v in sorted_point])\n", " \n", " d_exact = sp.latex(res['D'])\n", " d_numeric = res['D'].evalf(4) if hasattr(res['D'], 'evalf') else res['D']\n", " \n", " fxx_val = sp.latex(res['f_xx'])\n", " extreme_value = sp.latex(res['value'])\n", " classification = res['classification']\n", " \n", " table_md += f\"| $({coordinates})$ | ${d_exact}$ | `{d_numeric}` | ${fxx_val}$ | ${extreme_value}$ | **{classification}** |\\n\"\n", "\n", "display(Markdown(table_md))" ] }, { "cell_type": "markdown", "id": "fb0cacca", "metadata": {}, "source": [ "### Ejercicio 7.\n", "Considera la familia de funciones parametrizadas por $a \\in \\mathbb{R}$, con $a \\neq 0$:\n", "\n", "$$\n", "f(x,y)=x^3+y^3-3a\\,x\\,y\n", "$$\n", "\n", "donde $a$ es un `Symbol` de SymPy.\n", "\n", "a) Calcula $\\nabla f$ en términos de $x$, $y$ y $a$.\n", "\n", "b) Resuelve:\n", "\n", "$$\n", "\\nabla f = 0\n", "$$\n", "\n", "obteniendo los puntos críticos en función de $a$.\n", "\n", "c) Calcula la Hessiana y su determinante en función de $a$.\n", "\n", "d) Determina para qué valores de $a$ cada punto crítico es mínimo, máximo o punto silla.\n", "\n", "e) En una celda Markdown, argumenta algebraicamente para qué valores de $a$ cada punto crítico es mínimo, máximo o silla, apoyándote en el signo del determinante $D$ obtenido en el inciso c).\n", "\n", "El inciso e) se evalúa como razonamiento escrito, no como código." ] }, { "cell_type": "code", "execution_count": 53, "id": "d553324f", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "En el punto crítico $(0, 0)$ se tiene:\n", "* **Determinante:** $D = - 9 a^{2}$\n", "* **Segunda derivada:** $f_{xx} = 0$\n", "* **Clasificación:** Es un **inconcluso**\n", "* **Valor extremo:** $f(0, 0) = 0$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] }, { "data": { "text/markdown": [ "En el punto crítico $(a, a)$ se tiene:\n", "* **Determinante:** $D = 27 a^{2}$\n", "* **Segunda derivada:** $f_{xx} = 6 a$\n", "* **Clasificación:** Es un **inconcluso**\n", "* **Valor extremo:** $f(a, a) = - a^{3}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] }, { "data": { "text/markdown": [ "En el punto crítico $(a \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{2}, a \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right))$ se tiene:\n", "* **Determinante:** $D = - 9 a^{2} + 36 a^{2} \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{3}$\n", "* **Segunda derivada:** $f_{xx} = 6 a \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{2}$\n", "* **Clasificación:** Es un **inconcluso**\n", "* **Valor extremo:** $f(a \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{2}, a \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)) = a^{3} \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{6} - 2 a^{3} \\left(- \\frac{1}{2} - \\frac{\\sqrt{3} i}{2}\\right)^{3}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] }, { "data": { "text/markdown": [ "En el punto crítico $(a \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{2}, a \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right))$ se tiene:\n", "* **Determinante:** $D = - 9 a^{2} + 36 a^{2} \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{3}$\n", "* **Segunda derivada:** $f_{xx} = 6 a \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{2}$\n", "* **Clasificación:** Es un **inconcluso**\n", "* **Valor extremo:** $f(a \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{2}, a \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)) = - 2 a^{3} \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{3} + a^{3} \\left(- \\frac{1}{2} + \\frac{\\sqrt{3} i}{2}\\right)^{6}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------\n" ] } ], "source": [ "a = sp.symbols('a', real=True)\n", "fn = x**3 + y**3 - 3*a*x*y\n", "\n", "results = classify_critical_points(fn, constants=[a])\n", "\n", "for res in results:\n", " sorted_point = sorted(res['point'].items(), key=lambda item: str(item[0]))\n", " coordinates = \", \".join([sp.latex(v) for k, v in sorted_point])\n", " \n", " d_val = sp.latex(res['D'])\n", " fxx_val = sp.latex(res['f_xx'])\n", " extreme_value = sp.latex(res['value'])\n", " classification = res['classification']\n", " \n", " markdown_text = (\n", " f\"En el punto crítico $({coordinates})$ se tiene:\\n\"\n", " f\"* **Determinante:** $D = {d_val}$\\n\"\n", " f\"* **Segunda derivada:** $f_{{xx}} = {fxx_val}$\\n\"\n", " f\"* **Clasificación:** Es un **{classification}**\\n\"\n", " f\"* **Valor extremo:** $f({coordinates}) = {extreme_value}$\"\n", " )\n", " \n", " display(Markdown(markdown_text))\n", " print(\"-\" * 50) \n", "\n", "\n" ] }, { "cell_type": "markdown", "id": "af65b330", "metadata": {}, "source": [ "El algoritmo automatizado clasifica los puntos como **\"inconcluso\"** debido a que el parámetro $a$ es simbólico y el intérprete no puede asumir su signo. A continuación, se presenta el análisis analítico basado en la restricción matemática del enunciado ($a \\in \\mathbb{R}$ y $a \\neq 0$):\n", "\n", "---\n", "\n", "### 1. Análisis para el punto crítico $(0, 0)$\n", "* **Determinante:** $D = -9a^2$\n", "* **Evaluación del signo:** Por propiedad de los números reales, cualquier valor $a \\neq 0$ elevado al cuadrado siempre es estrictamente positivo ($a^2 > 0$). Al multiplicarlo por $-9$, la expresión $-9a^2$ será **siempre negativa** ($D < 0$), independientemente del valor de $a$.\n", "* **Conclusión:** Al ser el determinante un valor universalmente negativo en el campo real, el origen $(0,0)$ es un **punto silla** con un valor extremo de $f(0,0) = 0$.\n", "\n", "### 2. Análisis para el punto crítico $(a, a)$\n", "* **Determinante:** $D = 27a^2$\n", "* **Evaluación del signo de $D$:** Como $a^2 > 0$, el discriminante $27a^2$ es **siempre positivo** ($D > 0$). Esto nos asegura que el punto $(a,a)$ es un extremo local. Para conocer su naturaleza exacta, evaluamos el signo de la segunda derivada parcial ($f_{xx} = 6a$):\n", " * **Caso $a > 0$ (parámetro positivo):** La segunda derivada resulta positiva ($f_{xx} > 0$). Al cumplirse que $D > 0$ y $f_{xx} > 0$, el punto crítico es un **mínimo local** con valor extremo $f(a,a) = -a^3$.\n", " * **Caso $a < 0$ (parámetro negativo):** La segunda derivada resulta negativa ($f_{xx} < 0$). Al cumplirse que $D > 0$ y $f_{xx} < 0$, el punto crítico es un **máximo local** con valor extremo $f(a,a) = -a^3$.\n", "\n", "### 3. Exclusión de los puntos críticos complejos\n", "El sistema devuelve dos soluciones adicionales que involucran la unidad imaginaria $i$ (provenientes de las raíces complejas de la ecuación de los componentes del gradiente):\n", "* $\\left(a\\left(-\\frac{1}{2} - \\frac{\\sqrt{3}i}{2}\\right)^2, a\\left(-\\frac{1}{2} - \\frac{\\sqrt{3}i}{2}\\right)\\right)$\n", "* $\\left(a\\left(-\\frac{1}{2} + \\frac{\\sqrt{3}i}{2}\\right)^2, a\\left(-\\frac{1}{2} + \\frac{\\sqrt{3}i}{2}\\right)\\right)$\n", "\n", "* **Conclusión:** Dado que estamos optimizando una función clásica de dos variables reales ($f: \\mathbb{R}^2 \\to \\mathbb{R}$), estos puntos no pertenecen al plano cartesiano real y **se descartan** del análisis de extremos locales." ] }, { "cell_type": "markdown", "id": "3ac6ea0e", "metadata": {}, "source": [ "### Ejercicio 8.\n", "\n", "Se desea optimizar $f$ sujeta a la curva de nivel $g(x,y)=0$:\n", "\n", "$$\n", "f(x,y)=x^2+y^2\n", "$$\n", "\n", "$$\n", "g(x,y)=x^2+xy+y^2-3=0\n", "$$\n", "\n", "El método de multiplicadores de Lagrange plantea el sistema:\n", "\n", "$$\n", "\\nabla f=\\lambda \\nabla g\n", "$$\n", "\n", "y\n", "\n", "$$\n", "g(x,y)=0\n", "$$\n", "\n", "a) Declara $x$, $y$, $\\lambda$ como `symbols` y construye el sistema de 3 ecuaciones.\n", "\n", "b) Resuelve el sistema completo con `solve()` obteniendo $(x,y,\\lambda)$.\n", "\n", "c) Evalúa $f$ en cada solución y determina cuál corresponde al mínimo y cuál al máximo.\n", "\n", "d) Verifica que cada solución satisface $g(x,y)=0$ usando `subs()` y `simplify()`.\n", "\n", "e) Presenta un reporte final con:\n", "\n", "```text\n", "Mínimo de f sobre g=0: f(x₀,y₀) = ... en (x₀, y₀)\n", "\n", "Máximo de f sobre g=0: f(x₁,y₁) = ... en (x₁, y₁)\n", "```\n", "\n", "Este ejercicio integra:\n", "\n", "- Cálculo de gradiente.\n", "- Solución de sistemas no lineales.\n", "- Verificación simbólica.\n" ] }, { "cell_type": "code", "execution_count": 54, "id": "b0cc8f38", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "## Reporte del Ejercicio 8: Multiplicadores de Lagrange\n", "\n", "**a) Sistema de ecuaciones de Lagrange planteado:**\n", "* Ec. 1: $2 x = \\lambda \\left(2 x + y\\right)$\n", "* Ec. 2: $2 y = \\lambda \\left(x + 2 y\\right)$\n", "* Ec. 3 (Restricción): $x^{2} + x y + y^{2} - 3 = 0$\n", "\n", "---\n", "\n", "**b, c y d) Análisis individual de soluciones encontradas:**\n", "\n", "**Solución 1:** $(x = -1,\\ y = -1,\\ \\lambda = \\frac{2}{3})$\n", "* **Evaluación:** $f(-1, -1) = 2$\n", "* **Verificación de restricción:** $g(x, y) = 0$ $\\implies$ Satisface la curva.\n", "\n", "**Solución 2:** $(x = 1,\\ y = 1,\\ \\lambda = \\frac{2}{3})$\n", "* **Evaluación:** $f(1, 1) = 2$\n", "* **Verificación de restricción:** $g(x, y) = 0$ $\\implies$ Satisface la curva.\n", "\n", "**Solución 3:** $(x = - \\sqrt{3},\\ y = \\sqrt{3},\\ \\lambda = 2)$\n", "* **Evaluación:** $f(- \\sqrt{3}, \\sqrt{3}) = 6$\n", "* **Verificación de restricción:** $g(x, y) = 0$ $\\implies$ Satisface la curva.\n", "\n", "**Solución 4:** $(x = \\sqrt{3},\\ y = - \\sqrt{3},\\ \\lambda = 2)$\n", "* **Evaluación:** $f(\\sqrt{3}, - \\sqrt{3}) = 6$\n", "* **Verificación de restricción:** $g(x, y) = 0$ $\\implies$ Satisface la curva.\n", "\n", "---\n", "\n", "**e) Reporte Final en Consola:**\n", "\n", "```text\n", "Mínimo de f sobre g=0: f(x₀,y₀) = 2 en (-1, -1), (1, 1)\n", "\n", "Máximo de f sobre g=0: f(x₁,y₁) = 6 en (-sqrt(3), sqrt(3)), (sqrt(3), -sqrt(3))\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x, y, lam = sp.symbols('x y lambda')\n", "\n", "f = x**2 + y**2\n", "g = x**2 + x*y + y**2 - 3\n", "\n", "eq1 = sp.diff(f, x) - lam * sp.diff(g, x)\n", "eq2 = sp.diff(f, y) - lam * sp.diff(g, y)\n", "eq3 = g\n", "\n", "solutions = sp.solve([eq1, eq2, eq3], (x, y, lam), dict=True)\n", "\n", "min_val = float('inf')\n", "max_val = float('-inf')\n", "min_points_text = []\n", "max_points_text = []\n", "\n", "report_md = \"## Reporte del Ejercicio 8: Multiplicadores de Lagrange\\n\\n\"\n", "report_md += f\"**a) Sistema de ecuaciones de Lagrange planteado:**\\n\"\n", "report_md += f\"* Ec. 1: ${sp.latex(sp.Eq(sp.diff(f, x), lam * sp.diff(g, x)))}$\\n\"\n", "report_md += f\"* Ec. 2: ${sp.latex(sp.Eq(sp.diff(f, y), lam * sp.diff(g, y)))}$\\n\"\n", "report_md += f\"* Ec. 3 (Restricción): ${sp.latex(sp.Eq(g, 0))}$\\n\\n\"\n", "report_md += \"---\\n\\n\"\n", "report_md += \"**b, c y d) Análisis individual de soluciones encontradas:**\\n\\n\"\n", "\n", "for i, sol in enumerate(solutions, start=1):\n", " x_sol = sol[x]\n", " y_sol = sol[y]\n", " lam_sol = sol[lam]\n", " \n", " # Evalúa f en cada solución\n", " f_eval = f.subs({x: x_sol, y: y_sol})\n", " f_num = float(f_eval.evalf())\n", " \n", " # Verifica que cada solución satisface g(x,y) = 0\n", " g_verify = sp.simplify(g.subs({x: x_sol, y: y_sol}))\n", " \n", " # Guarda los valores para el reporte final de texto plano\n", " pt_str = f\"({str(x_sol)}, {str(y_sol)})\"\n", " if f_num < min_val:\n", " min_val = f_num\n", " min_val_sym = f_eval\n", " if f_num > max_val:\n", " max_val = f_num\n", " max_val_sym = f_eval\n", " \n", " report_md += (\n", " f\"**Solución {i}:** $(x = {sp.latex(x_sol)},\\\\ y = {sp.latex(y_sol)},\\\\ \\\\lambda = {sp.latex(lam_sol)})$\\n\"\n", " f\"* **Evaluación:** $f({sp.latex(x_sol)}, {sp.latex(y_sol)}) = {sp.latex(f_eval)}$\\n\"\n", " f\"* **Verificación de restricción:** $g(x, y) = {sp.latex(g_verify)}$ $\\\\implies$ Satisface la curva.\\n\\n\"\n", " )\n", "\n", "for sol in solutions:\n", " x_sol = sol[x]\n", " y_sol = sol[y]\n", " f_eval = f.subs({x: x_sol, y: y_sol})\n", " pt_str = f\"({str(x_sol)}, {str(y_sol)})\"\n", " \n", " if float(f_eval.evalf()) == min_val:\n", " min_points_text.append(pt_str)\n", " if float(f_eval.evalf()) == max_val:\n", " max_points_text.append(pt_str)\n", "\n", "report_md += \"---\\n\\n**e) Reporte Final en Consola:**\\n\\n```text\\n\"\n", "report_md += f\"Mínimo de f sobre g=0: f(x₀,y₀) = {str(min_val_sym)} en {', '.join(min_points_text)}\\n\\n\"\n", "report_md += f\"Máximo de f sobre g=0: f(x₁,y₁) = {str(max_val_sym)} en {', '.join(max_points_text)}\\n\"\n", "\n", "display(Markdown(report_md))" ] } ], "metadata": { "kernelspec": { "display_name": "propedeutico", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.20" } }, "nbformat": 4, "nbformat_minor": 5 }