MDCIPROPE2026/ValoresExtremosFunciones/valores_extremos_imf.ipynb

1039 lines
36 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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": [
"<IPython.core.display.Markdown object>"
]
},
"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
}