Matemáticas con Mathematica

Práctica 6. Resolución de ecuaciones.

Francisco Javier Pérez González
Departamento de Análisis Matemático
Universidad de Granada

Resolución de ecuaciones

En esta práctica empezamos a explorar algunas de las muchas posibilidades de Mathematica como herramienta de cálculo. Concretamente, vamos a estudiar la resolución de varios tipos de ecuaciones que por su sencillez conceptual nos han parecido apropiadas como punto de partida, pero cuya dificultad numérica pone de manifiesto la utilidad de Mathematica para realizar cálculos laboriosos y facilitar así la resolución de muchos problemas.
Recuerda que en Mathematica el símbolo de igualdad  "='' es la forma usual de escribir el comando "Set[ ]" (léase atribuye o asigna). Así "expr1=expr2" y "Set[expr1,expr2]" son dos formas de decirle a Mathematica  que evalúe inmediatamente expr2 y el resultado de esta operación lo asigne en adelante al símbolo expr1. Se comprende así que "='' no pueda usarse en Mathematica para representar ecuaciones. Fíjate en que resolver una ecuación, por ejemplo (x^4)-3  (x^2)+7=0, consiste realmente en comprobar una igualdad; es decir, se trata de obtener los valores de la variable (o de las variables) que hacen que dicha igualdad sea verdadera.
Mathematica dispone de un operador, "Equal[ ]", que sirve para comprobar igualdades. Su sintaxis es "Equal[expr1,expr2]" que suele escribirse en la forma más corta "expr1==expr2" y lo que hace es evaluar ambas expresiones devolviendo el valor True si la igualdad es verdadera y False en otro caso. Pues bien, una ecuación en Mathematica se representa, precisamente, en la forma "expr1==expr2" donde al menos una de las expresiones expr1 o expr2 es simbólica, es decir contiene símbolos (variables) a los que no se han asignado anteriormente valores. Es claro que en tal caso la igualdad no puede comprobarse por lo que "expr1==expr2" da también como salida "expr1==expr2". A continuación veremos algunas de las muchas funciones de Mathematica para trabajar con ecuaciones y resolverlas.

Resolución de ecuaciones en una variable

Los comandos Solve[ ] , NSolve[ ] y Reduce[ ]

La orden "Solve[ecuación,var]", intenta resolver "ecuación" en la variable "var". Por ejemplo, Mathematica conoce las fórmulas algebraicas para las soluciones simbólicas exactas de ecuaciones polinómicas en una variable de grado menor que cinco.

Solve[a*x^2 + b*x + c == 0, x]

Solve[x^3 + a*x^2 + b*x + c == 0, x]

Mejor que no le pidas a Mathematica las soluciones de la ecuación de cuarto grado: son demasiado complicadas. Es importante que observes que  la salida de "Solve[ ]" es una lista cuyos elementos son listas de reglas de sustitución, cada una de las cuales representa  una solución. Si quieres obtener una lista con las soluciones de la ecuación puedes conseguirlo con el operador de sustitución /. que ya conoces.

sol = Solve[6  x^3 + 5  x^2 - 2  x - 1 == 0, x]x /. sol

La forma que tiene la salida de "Solve[ ]"  permite sustituir fácilmente en una función las soluciones de una ecuación.

f[x_] := x^2sol = Solve[6 - 35 x + 21 (x^2) + 20 (x^3) == 0, x]f[x] /. sol

El comando "Solve[ ]" repite cada raíz tantas veces como su orden.

Solve[-1 + x + 2 (x^2) - 3 (x^3) + (x^4) == 0]

Y, ya puestos, ¿qué pasa con las ecuaciones polinómicas de grado mayor o igual que cinco? Bueno, como seguramente sabes, Evariste Galois (1811-1832) demostró que no pueden, en general, resolverse  por radicales; es decir, que es matemáticamente imposible encontrar fórmulas explícitas para sus soluciones. Por ello, no te extrañes de que con frecuencia Mathematica no pueda resolverlas de forma exacta.

Solve[70 + 66  x + 29  x^2 - 39  x^3 - 34  x^4 + 3  x^5 + x^6 == 0, x]
      Solve[
      3 + 3  x - 7  x^2 - x^3 + 2  x^4 + 3  x^ 7 - 3  x^ 8 - x^9 + x^10 == 
        0, x]

En el primer caso hemos tenido suerte: "Solve[ ]" ha sido capaz de encontrar todas las soluciones de la ecuación (observa que dos de ellas son complejas). En el segundo Mathematica no ha podido encontrar todas las raíces de un polinomio tan complicado. Ha encontrado tres raíces exactas 1, -(Sqrt[3]) y (Sqrt[3]); y nos dice que las restantes siete son las raíces del polinomio 1 + 2  x + (x^7).
En los casos en que "Solve[ ]" no puede dar soluciones exactas, podemos conseguir soluciones numéricas aproximadas con el comando "NSolve[ecuación,var]".

NSolve[
      3 + 3  x - 7  x^2 - x^3 + 2  x^4 + 3  x^ 7 - 3  x^ 8 - x^9 + x^10 == 
        0, x]

Usamos "NSolve[ecuación,var,n]" si queremos las soluciones con n dígitos de precisión. Haz la prueba en el ejemplo anterior con n=30.

Hasta ahora hemos considerado ecuaciones polinómicas pero "Solve[ecuación,var]" también puede resolver otros tipos de ecuaciones. Por ejemplo, teniendo en cuenta que "var" puede ser cualquier símbolo que aparezca en "ecuación", podemos resolver respecto de "var=f[x]" ecuaciones de la forma "p[f[x]]==0", donde "p" es una función polinómica.

Solve[3 - 15  Log[x] + 7  Log[x]^2 == 0, Log[x]]

A veces "Solve[ ]" puede resolver ecuaciones en las que intervienen funciones trascendentes (trigonométricas y sus inversas, logaritmos, exponenciales).

x /. Solve[ArcCos[x] - ArcTan[x] == 0, x]

Simplify[TrigToExp[%]]

Solve[Log[x + (a + x^2)^ (1/2)] == b, x]

Pero lo más frecuente es que dichas ecuaciones no puedan ser resueltas exactamente en forma simbólica o que no puedan obtenerse todas las soluciones posibles de la ecuación. Mathematica suele dar en estos casos mensajes de advertencia. Por ejemplo, cuando al resolver una ecuación Mathematica utiliza alguna función inversa, lo indica con un mensaje en el que también advierte de que puede haber más soluciones.

Solve[Sin[x] == 1/2, x]

El comando FindRoot[ ]

Pero también puede ocurrir que una ecuación no pueda resolverse con ninguno de los comandos que hemos visto hasta ahora.

NSolve[Cos[x]  ==  x, x]

En estos casos podemos todavía encontrar una solución numérica aproximada usando el comando "FindRoot[función,{var,valor inicial}]" el cual utiliza el método de Newton-Raphson para obtener un cero de "función" partiendo del "valor inicial" de la variable "var". Este comando también admite la sintaxis "FindRoot[ecuación,{var,valorinicial}]".

FindRoot[Cos[x]  == x, {x, 1}]FindRoot[Cos[x] - x, {x, 1}]

El valor inicial debe ser un punto que esté "próximo" de la solución que queremos calcular.

FindRoot[Cos[x] == 1, {x, 4}]

FindRoot[x*Exp[-x] == 0, {x, 2}]

La solución obtenida en el último ejemplo no es correcta. Eso es debido a que hemos arrancado de un valor inicial demasiado lejos del valor de la solución y también a que la función "x Exp[-x]" es muy plana, es decir, se apróxima muy rápidamente a cero cuando la variable aumenta, por eso Mathematica puede interpretar valores grandes de la variable como ceros de la función y eso es lo que ha hecho en este caso. Podemos aumentar la precisión de "FindRoot[ ]" con las opciones "WorkingPrecision", "AccuracyGoal" y "MaxIterations".
 "WorkingPrecision" es una opción que indica cuántos dígitos deben mantenerse en los cálculos internos. Por defecto es igual a "MachinePrecision" (16 en la mayoría de los ordenadores).
 "AccuracyGoal" especifica el número de dígitos a la derecha del punto decimal que deben tenerse en cuenta al evaluar la función en una posible solución. Por defecto es igual a "WorkingPrecision"-10.
 "MaxIterations" especifica el máximo de iteraciones a realizar antes de encontrar la solución teniendo en cuenta el valor actual de "AccuracyGoal". Por defecto es igual a 15.

El siguiente ejemplo proporciona, debido a que la función es muy plana, un resultado muy poco exacto.

FindRoot[(x - 2)^4  Exp[-x^2], {x, 1}]

Tratamos de mejorarlo aumentando el número de dígitos con que se realizan los cálculos.

FindRoot[(x - 2)^4  Exp[-x^2], {x, 1}, 
      WorkingPrecision -> 32]

Casi no lo hemos mejorado y Mathematica nos dice que 15 iteraciones son insuficientes para obtener una solución con "AccuracyGoal=22". Debemos hacer más iteraciones.

\(\(FindRoot[\((x - 2)\)^4  Exp[\(-x^2\)], {x, 1}, 
      WorkingPrecision -> 32, MaxIterations -> 50]
 (*\ 
      Observa\ que\ la\ solución\ se\ presenta\ con\ 32\ 
        dígitos\ *) \)\)

(x - 2)^4 Exp[-x^2] /. %

Para elegir los valores iniciales  suele ser de gran utilidad una representación gráfica; pues podemos selecionar un gráfico con el ratón y pulsando la tecla "Control" el puntero se convierte en una cruz y vemos las coordenadas de los puntos sobre los que nos desplazamos.

Plot[Exp[-x] - x^2 + 1, {x, 1, 2}];

\(\(FindRoot[Exp[\(-x\)] - x^2 + 1, {x, 1.2}] (*\ 
      Sobre\ la\ gráfica\ se\ ve\ que\ el\ valor\ de\ la\ raíz
        \ está\ próximo\ a\ 1.2\ *) 
 (*\ 
      NSolve\ no\ calcula\ las\ soluciones\ de\ Exp[\(-x\)] - x^2 + 1 == 0
        \ *) \)\)

Resolución de sistemas de ecuaciones en varias variables

Los comandos vistos pueden usarse también para calcular las soluciones de sistemas de ecuaciones en varias variables. Lo único que hay que hacer es sustituir en cada caso "ecuación" por una lista de ecuaciones "{ecuac1,ecuac2,...}" y especificar también en una lista las variables respecto de las que queremos resolver el sistema "{var1,var2,...}". Al igual que antes, "Solve[ ]" y "NSolve[ ]" sirven principalmente para resolver sistemas de ecuaciones polinómicas. El primero sólo resuelve sistemas de grado bajo pero con soluciones exactas, expresadas mediante radicales. El segundo da soluciones aproximadas pero sirve para cualquier grado. Como puedes suponer, el comando "Reduce[ ]" cuando se aplica a sistemas de ecuaciones que contienen parámetros realiza una discusión de las soluciones del sistema según los posibles valores de los parámetros. Este comando es particularmente útil para sistemas de ecuaciones lineales con parámetros.

Solve[{x^2 + y^2 == 1, (x - 2)^2 + (y - 2)^2 == 4}, {x, y}]

Cuando hay más variables que ecuaciones algunas variables son tratadas como parámetros.

sol = Solve[{x^2 + y^2 + z^2 == 1, x + y + z == 0}, {y, z}]

Hemos obtenido de esta forma las ecuaciones paramétricas de la circunferencia intersección de la esfera (x^2)+(y^2)+(z^2)=1 y el plano x + y + z = 0.

Naturalmente, podemos usar "Solve[ ]" para resolver sistemas de ecuaciones lineales.

Solve[{x + y + z == 2, x - 2 y + z == -1, 
        x + 3 y - 2 z == 4}, {x, y, z}]

Solve[{x + y + z == 2, x - 2 y + z == -1, 
        x - (y/2) + z == (1/2)}, {x, y, z}]

El sistema anterior no tiene solución única y Mathematica te informa de ello. Cuando no hay soluciones la salida de "Solve[ ]" es una lista vacía "{ }".

Solve[{x + y + z == 2, x + y + z == 0, x + 3 y - 2 z == 4}, {x, y, 
        z}]

Y la salida es "{{}}" si cualquier valor es solución.

Solve[x^2 + x == x (x + 1), x]

Ejercicio 1

Discute el sistema de ecuaciones x + a*y + z = 1,  3  x - 2  y + z = b,  
      x + y - z = 1 en función de los parámetros a y b.

Ejercicio 2

Ejercicio 3

Ejercicio 4

Ejercicio 5

Ejercicio 6

Ejercicio 7