Izquierda Indice Derecha

Resolver ecuaciones. Ceros de funciones

 

Resolver ecuaciones con wxmaxima

Resolver una ecuación del tipo Fórmula=0 es determinar el conjunto de valores de la variable (o variables) para los que la Fórmula se anula. Es ésta una cuestión complicada y sólo para algunos tipos de Fórmula es posible encontrar soluciones exactas, reales o complejas. En muchos casos sólo es posible encontrar soluciones aproximadas.

 

indice

Soluciones exactas: ecuaciones lineales y algunas otras

Los sistemas lineales de ecuaciones y algunas otras ecuaciones sencillas pueden resolverse con ayuda del comando

Internamente el comando solve puede hacer uso del comando linsolve y de otros comandos, dependiendo de la naturaleza de las ecuaciones a resolver. Para más información véase en la consola de Maxima el resultado de la ejecución del siguiente código ? solve;.

Se dedica más atención al comando linsolve en la sección correspondiente a las matrices, que es el ámbito natural para estudiar los sistemas de ecuaciones lineales. Veamos a continuación algunos ejemplos de utilización del comando solve.

  1. /* para algunos polinomios, Maxima es capaz de encontrar sus raíces, reales y complejas */ solve(-4*x^3 - 12*x^2 + 12, x);
  2. /* pero para otros no es capaz de hacerlo */ solve(x^5-2*x^2-1);
  3. /* raíces de un sistema lineal de ecuaciones */ solve([2*x-7*y-2,x-y+3], [x,y]);
  4. /* en este ejemplo, y el siguiente (que no pone =0), aparecen funciones no polinómicas */ solve(2*log(x)=-1);
  5. /* además, advierte aquí que algunas soluciones pueden haberse perdido (incitando a reflexionar) */ solve (asin (cos (3*x))*(f(x) - 1), x);
  6. solve(x^3-x^2-5*x-3,x); multiplicities;
  7. Un polinomio de interpolación de Lagrange es una función polinómica P de grado n-1 determinada por el hecho de pasar por n puntos [x_1,y_1],[x_2,y_2],...[x_n,y_n] previamente fijados. El problema puede ser abordado como la solución de un sistema lineal de ecuaciones (en la sección Interpolación se utilizan otros recursos).
    /* polinomio con coeficientes a calcular */ p(x):= a*x^4+b*x^3+c*x^2+d*x+e$ /* puntos por los que pasa */ [[7,2],[8,2],[1,5],[3,2],[6,7]]$ /* en consecuencia, ha de cumplir las 5 ecuaciones */ e1: ev(p(x),[x=7])=2; e2: ev(p(x),[x=8])=2; e3: ev(p(x),[x=1])=5; e4: ev(p(x),[x=3])=2; e5: ev(p(x),[x=6])=7; /* resolviendo, determinamos los coeficientes */ linsolve([e1,e2,e3,e4,e5],[a,b,c,d,e]);
    Alternativamente, en lugar del comando ev podría haberse utilizado el comando at.

 

indice

Soluciones aproximadas

Para la obtención de soluciones aproximadas el teorema de Bolzano proporciona un marco teórico muy útil al garantizar que un función real de variable real que toma valores con signos opuestos en los puntos Punto1 y Punto2 necesariamente se anula en algún punto intermedio.
Si se eligen bien las parejas de puntos de forma que sólo se produzca un cambio de signo en cada un de los intervalos que definen dichas parejas es posible entonces obtener numéricamente todas las soluciones reales. El grafismo (y eventualmente resultados del cálculo diferencial) puede servir de gran ayuda para conseguir tales soluciones aproximadas con ayuda de Maxima.

Veamos algunos ejemplos y posibles estrategias a usar

  1. Para la función que aparece a continuación, el dibujo de la misma ayuda a identificar los intervalos en los que la función tiene un cambio de signo, y sólo uno. Lo cual permite calcular, de forma aproximada, las soluciones que existen.
    f(x):= x- x^2 + 1+log (1+x)$ plot2d( f(x),[x,-0.9,5]);

    find_root( f(x)=0, x,-0.9,0);

    find_root( f(x)=0, x, 0,3);

  2. Más arriba habíamos constatado que solve había fracasado en el cálculo de las raíces del polinomio x^5-2*x^2-1. Dibujar la gráfica de la función, no resulta tan "transparente" como en el ejemplo precedente y por ello analizaremos también la función derivada que nos da información sobre los intervalos de crecimiento de la función.
    kill(f)$ f(x) := x^5-2*x^2-1; plot2d(f(x) ,[x,-3,3]);
    a la vista de la gráfica es claro que en el intervalo [-3,3] existe al menos un cambio de signo, pero cabe la duda de si existe más de un cambio de signo. Vamos a analizar la derivada para mayor seguridad.
    kill(g); define(g(x),diff(f(x),x)); solve(g(x),x); /* a la vista de los ceros de la derivada es natural elegir el intervalo */ plot2d(g(x),[x,-1,2]);
    plot2d(f(x),[x,-1,2]);
    find_root(f(x)=0, x, -1, 2);
  3. Debido a que se trata de un polinomio, y no de una función general, podemos obviar lo anterior y dejar que sea Maxima el encargado de realizar las actuaciones que considere oportunas para encontrar las raíces utilizando fracciones (como ya hemos dicho).
    realroots(f(x)); %,numer;
  4. Pero un polinomio de grado 5 tiene cinco raíces en el cuerpo de los complejos: las otras 4 las podemos obtener con ayuda del otro comando de Maxima
    allroots(f(x));
  5. Otro comando diferente para el mismo polinómio
    algsys([f(x)],[x]);
  6. Encontrar los puntos de corte entre una circunferencia y una elipse
    algsys([x^2+y^2=1,(x-1)^2+y^2=1/4],[x,y]);
  7. Para acabar vamos, jugando con ventaja, a preparar un polinomio con raíces conocidas a fin de comparar los resultados de los diferentes comandos
    kill(f)$ f(x):=(x-0.1)*(x+3)*(x^2+x+1); solve(f(x));
    f(x):=(x-0.1)*(x+3)*(x^2+x+1)$ realroots(f(x)); ev(%,numer);
    f(x):=(x-0.1)*(x+3)*(x^2+x+1)$ allroots(f(x));

 

Colaborando con Maxima en la solución de ecuaciones

A veces Maxima fracasa al resolver ecuaciones que, objetivamente, no son complicadas. En esas ocasiones si usted tiene idea de como se podría resolver la ecuación y le ayuda un poquito, Maxima puede ser capaz de tener éxito. Ayudarle, generalmente, consiste pedirle que realice una transformación en la ecuación que le lleva a otra que sea capaz de resolver. Comandos para contraer o expandir logaritmos, para tomar logaritmos o exponenciales en una igualdad, etc. son estrategias útiles. A continuación hay algunos ejemplos que sirven como botones de muestra.

Primer ejemplo.

  1. Comenzamos matando las asignaciones previas
    kill(all);.
    Como en esta sección no hemos cargado ningún paquete adicional, no hay riesgo de que se borre de la memoria el contenido del mismo; pero en otras condiciones puede también tener efectos secundarios.
    Ponemos nombre a la ecuación que queremos resolver (no es imprescindible)
    EC:log(y)-log(y+1)=log(x-1)-log(x);
  2. Tratamos, sin éxito de resolver la ecuación:
    solve(EC,y);
  3. Como no sabe resolver la ecuación anterior, comenzamos nuestro proceso de ayuda. Le decimos que previamente "contraiga" los logaritmos usando el comando logcontract.
    EC2:logcontract(EC);
    tras lo cual, ya sabe resolver la ecuación
    solve(EC2,y);.

Segundo ejemplo (variante del anterior)

  1. Ya hemos fracasado con
    EC:log(y)-log(y+1)=log(x-1)-log(x); solve(EC,y);
  2. Hagamos la exponencial de ambos miembros, utilizando el comando map de Maxima, a ver qué ocurre
    EC3:map(exp,EC);
    La ecuación se ha simplificado enormemente y resolverla ya no es problema.
    solve(EC3,y);

Tercer ejemplo.

  1. Comenzamos matando las asignaciones anteriormente realizadas (una buena práctica)
    kill(all); EC:0.5=exp(k*500)
  2. Le pedimos a Maxima que resuelva la ecuación:
    solve(EC,k);
    La solución, que tarda bastante tiempo, aparece en la pantalla correspondiente a la consola de Maxima. Si se cansa de esperar reinicie Maxima desde uno de los items que aparecen del menú "Archivo" llamado "Reiniciar".
  3. Maxima no se ha dado cuenta, pero tomando logaritmos el problema se simplifica. Para ayudarle le decimos que tome logaritmos en la ecuación antes de resolverla. De nuevo hacemos uso del comando map
    kill(all); EC:0.5=exp(k*500);
    Aplicamos logaritmos
    EC2:map(log,EC);
    E intentamos resolver de nuevo
    solve(EC2,k);
  4. Las dos soluciones anteriores no son equivalentes. Para convencerse de ello podemos resolver la misma ecuación (en la ventana de la consola) con un exponente de menor tamaño, como por ejemplo,
    kill(all)$ EC: 0.5=exp(k*5);
    Pedimos que la resuelva
    solve(EC,k);.

 

indice

Reutilizar las soluciones

La solución de un sistema lineal de ecuaciones proporciona unos valores para las incognitas que pueden ser requeridos para realizar otros cálculos con posterioridad. Pero las variables tienen un carácter local y las asignaciones se pierden después de ejecutar el comando Maxima que permite resolverlas. En algunos casos el resultado obtenido puede recuperarse de forma simple utilizando % (o % con el número de salida que corresponda), pero en otros casos las salidas son listas y las variables tienen un carácter local y las asignaciones no se conservan después de ejecutar comandos como solve. En el caso del comando solve es posible mantener la asignación con carácter global utilizando la variable booleana globalsolve. Otro comando útil para la reutilización de soluciones es rhs

Veamos algunos ejemplos:

  1. Por defecto, globalsolve:false. En este ejemplo, aunque calcula los valores de x e y, no los retiene.
    print("El valor de globalsolve es: ", globalsolve)$ solve([2*x-y=a,3*x+y=b],[x,y]); print("El producto de las soluciones es:")$ x*y;
  2. Haciendo globalsolve:true conseguimos que retenga en memoria los valores.
    kill(x,y)$ globalsolve:true$ print("El valor de globalsolve es: ", globalsolve)$ solve([2*x-y=a,3*x+y=b],[x,y]); print("Compare este resultado con el anterior. El = se ha transformado en : ")$ print("El producto de las soluciones es:")$ x*y;
  3. El comando rhs permite usar una técnica diferente para abordar la cuestión precedente, e ilustra el funcionamiento del mismo:
    kill(all)$ globalsolve:false$ print("El valor de globalsolve es: ", globalsolve)$ solve([2*x-y=a,3*x+y=b],[x,y]); %[1]; [x,y]:[ rhs(%[1]),rhs(%[2]) ]; print("Como la solución es una lista, cuyo único elemento es a su vez una lista, hemos procedido a recuper dicho elemento, que es el que nos interesa, y que contenía dos ecuaciones. Hemos recuperado la partes derechas de tales ecuaciones. Haciendo uso de : se las asignamos a x e y. Ahora ya podemos calcular xy")$ x*y;
  4. Una variante usando second :
    kill(all)$ print("El valor de globalsolve es: ", globalsolve)$ solve([2*x-y=a,3*x+y=b],[x,y]); %[1]; [x,y]:[ second(%[1]),second(%[2]) ]; x*y;
  1. Ap_ResolverEcuaciones.wxmx


 

Izquierda Indice Derecha