Sistema de ayuda de Yamwi en línea

Introducción

Esta página web permite hacer todo tipo de cálculos matemáticos y gráficos en línea.

Para hacer un cálculo cualquiera tan solo es necesario escribir en el cuadro el código correspondiente y a continuación pulsar en el botón que está debajo.

Los ejemplos que se incluyen en esta página se pueden copiar y pegar (CTRL-C y CTRL-V) en el área de edición antes de pulsar en el botón. El usuario puede hacer los cambios que quiera en esta área.

La ayuda de esta página es muy precaria y básica. Para profundizar más:

La información que vamos a obtener tiene aspecto de conversación. Nuestras peticiones llevan siempre la etiqueta %i seguida de un número (i de input) y los resultados llevan la etiqueta %o seguida del correspondiente número de orden (o de output).


Contenido


Números


Enteros

Se pueden utilizar enteros tan grandes como sea necesario. Aquí calculamos el factorial de 100,

100! ;

Como en cualquier otro lenguaje de programación, podemos sumar (+), restar (-), multiplicar (*), dividir (/), calcular potencias (^) y raíces cuadradas (sqrt).

3^4 * (5-91+(-24)) + 75 / sqrt(25) ;

Veamos la lista de los divisores de un entero dado y su factorización en números primos,

/* primero guardamos el numero en la variable a */
a: 169996284 $
divisors(a) ;
factor(a) ;

Preguntamos a Maxima si 1502933 es un número primo.

primep(1502933);

Utilizamos gcd para calcular el máximo común divisor de dos números y lcm para el mínimo común múltiplo de un conjunto arbitrario de enteros, pero teniendo en cuenta que para usar lcm debemos cargar primero la librería functs.

gcd(16479936, 43375500000); 

load("functs")$
lcm(16479936, 43375500000, 111375);

La función divide devuelve una lista con dos elementos, el cociente y el resto (módulo) de una división entera.

divide(34, 5);


Racionales

Maxima siempre evita trabajar con cantidades aproximadas. Con el siguiente código operamos con racionales. Cada instrucción debe terminar con un punto y coma (;).

1 + 5 * (5 - 7/9)^4 ;

Si queremos la aproximación decimal de un resultado podemos proceder como sigue: primero guardamos (con dos puntos :) en una variable (en este caso x) el valor de la expresión exacta y después ejecutamos la función float para que la transforme a decimal.

x : 1 + 5 * (5 - 7/9)^4 ;
float(x);

El mismo resultado se puede conseguir con una sola instrucción.

float (1 + 5 * (5 - 7/9)^4) ;

Otro ejemplo en el que se ve el uso de variables. Lo que se escribe entre los símbolos /* y */ son comentarios para los humanos, siendo ignorados por la máquina, de manera que este ejemplo es autoexplicativo.

/* Guardamos un valor en la variable 'a' */
a : 8 / 24;

/* Guardamos otro valor en la variable 'b' */
b: 1/5 ;

/* El cuadrado de la suma de 'a' e 'b' */
(a + b)^2;

La función float devuelve un número limitado de decimales. Veamos cómo pedir el número π con cinco mil decimales. Para eso debemos indicarle a la variable global fpprec la precisión deseada y después hacer una llamada a la función bfloat. Conviene recordar que π se representa en Maxima por %pi. También calculamos la raíz cuadrada de 2 con 5000 cifras decimales.

fpprec : 5000;
bfloat(%pi);

/* Tambien queremos la raiz cuadrada de dos */
bfloat( sqrt(2) );


Complejos

La unidad imaginaria se representa por %i. Con este símbolo, podemos escribir cualquier número complejo y realizar algunas operaciones con ellos.

z1: 3 + 5*%i;
z2: 2/3 - %i;

z1 + z2;
z1 - z2;

A veces, Maxima devuelve expresiones complejas con paréntesis. Si queremos simplificar estas expresiones, podemos llamar a la función expand.

z1: 3 + 5*%i $
z2: 2/3 - %i $

3*z1 - 7*z2;
expand(3*z1 - 7*z2);

z1 * z2;
expand(z1 * z2);

Podemos transformar números complejos en forma binomial a su forma polar y viceversa.

z: 3 + 5*%i ;
p: polarform(z);
b: rectform(p);

Dividamos dos números complejos y obtengamos el resultado en forma binomial,

d: (3 + 5*%i) / (7/8 - 1/4*%i) ;
rectform(d);

Dado un número complejo, podemos obtener sus partes real e imaginaria, así como su módulo y ángulo.

z: 7/8 - 1/4*%i;
realpart(z);
imagpart(z);
cabs(z);
carg(z);


Factores de conversión

La librería ezunits contiene todo lo que necesitamos para cambiar unidades. Veamos algunos ejemplos.

load("ezunits") $

/* cambia m/s a km/hour */
5 ` m/s `` km/hour ;

/* cambia N/cm^2 a Pa */
32 ` N/cm^2 `` Pa ;

/* cambia m a inch en dos pasos */
d : 10 ` m $
d `` inch;

/* lista todos los factores de conversión */
for k in known_unit_conversions do print(k)$

Podemos declarar nuestros propios factores de conversión.

load("ezunits") $

declare_unit_conversion (
    Pa = 9.869*10^-6 * atm,
    bar = 100000 * Pa ) $

5.3 ` atm `` bar ;

Podemos pasar cualquier unidad física a fundamental.

load("ezunits") $

f: 7 ` kg*km/minute^2;

/* dime las dimensiones */
dimensions (f);

/* dime las unidades fundamentales */
fundamental_units (f);

/* haz la conversión */
f `` fundamental_units (f);

Álgebra


Polinomios

De la misma forma que podemos operar con números, lo podemos hacer con variables. Fíjate cómo se reducen las expresiones algebraicas.

1 + x + 5 * y - 2/3 * x + y + 2 ;

(5*x^2 * u * r) / (u^2 * t) ;

Expandimos productos.

expand( (x+1)^2 * (x+5) * (x-a) ) ;

Factorizamos polinomios.

factor(u^6 - 14*u^5 - 23*u^4 + 808*u^3 - 320*u^2 - 12800*u) ;

Si queremos calcular el valor numérico de una expresión algebraica, haremos uso de la función subst tal como se indica a continuación, donde guardamos en la variable f la fórmula para la fuerza de atracción gravitatoria y la calculamos para diferentes masa y distancias. El uso de los corchetes ([ y ]) en Maxima es muy común, ya que con ellos podemos construir listas y cualesquiera otras estructuras de datos.

f : 6.67 * 10^-11 * m1 * m2 / r^2 ;

subst([m1 = 4, m2 = 5, r = 7], f) ;
subst([m1 = mass, m2 = mass], f) ;


Ecuaciones

En general, la función a utilizar es solve. Necesitamos dos argumentos: el primero será una lista de ecuaciones separadas por comas y el segundo otra lista con las incógnitas.

Una sencilla ecuación de primer grado.

solve([5 * (x + 1/2) = 1 + x /3], [x]) ;

La misma ecuación pero con una constante.

solve([5 * (x + 1/2) = k + x /3], [x]) ;

Una ecuación polinómica de segundo grado. Recuerda que la raíz cuadrada se representa en Maxima por sqrt y la unidad imaginaria por %i.

solve([2*x^2 - 3*x + 5 = 0], [x]) ;

Un sistema de ecuaciones. Vemos en este ejemplo que podemos hacer uso de varias líneas para escribir una sentencia. También pedimos el resultado en formato decimal.

sol : solve([5*x + y/8 = 4, x^2 = y],
            [x,y]) ;

float(sol);

Cuando los métodos algebraicos no se puedan utilizar, podemos hacer uso de las rutinas numéricas. La librería mnewton puede resolver ecuaciones y sistemas de ecuaciones por el método de Newton. Llamamos a la función mnewton con tres argumentos: la lista de ecuaciones, la lista de incógnitas y las coordenadas del punto inicial.

load("mnewton") $

/* equation with sigle unknown */
mnewton([2*a^a = 5],[a],[1]);

/* multiple unknowns */
mnewton([2*3^u-v/u-5 = 0, u+2^v = 4], [u, v], [2, 2]);


Inecuaciones

La resolución de inecuaciones necesita la librería fourier_elim. Primero resolvemos una inecuación lineal de una incógnita. La función fourier_elim necesita dos argumentos, la lista de inecuaciones y la de incógnitas.

load("fourier_elim") $
ine : (5*x-16)/6 + (x+8)/12 < (x+1)/3;
fourier_elim([ine], [x]);

Una inecuación de grado cuatro.

load("fourier_elim") $
fourier_elim([x^4+5*x^3+5*x^2-5*x-6 > 0],[x]);

Un sistema de inecuaciones de una incógnita.

load("fourier_elim") $
fourier_elim(
  [(x+2)/4 <= x/2-3,
   (8-x)/3 < (1+x)/2-1],
  [x]);

Un sistema de inecuaciones de dos incógnitas.

load("fourier_elim") $

des1: 3*x - 5*y < 2;
des2: x+y> (1+x)/3;
des3: y < 2;
fourier_elim([des1, des2, des3],[x,y]);


Vectores

Los vectores se representan como listas encerradas entre corchetes. Podemos realizar con ellos algunas operaciones habituales.

v1: [1, 2, 3] $
v2: [a, b, c] $

/* suma y resta */
v1 + v2;
v1 - v2;

/* producto por un numero */
k * v1;

/* producto escalar */
v1 . v2;

El producto vectorial está definido en la librería vector3d.

load(vector3d) $
cross([a, b, c] , [x, y, z]);

Aquí hay un ejemplo de cómo se define una nueva función en Maxima. Queremos escribir una función que calcule el módulo de un vector; obsérvese que las funciones se definen por medio del operador :=. Vale, no te preocupes si no entiendes la parte interna de la función.

modulus(v):= sqrt(apply("+", v^2)) $
modulus([a, 5, c]);


Matrices

Las matrices se pueden introducir de varias maneras. La más frecuente es hacer uso de la función matrix declarando las filas. En este ejemplo se introducen dos matrices para después sumarlas y restarlas.

a : matrix([1, 2, 3], [4, 5, 6]) ;
b : matrix([7, 1/9, 2], [z, x+y, -5]) ;

a + b ;
a - b ;

El producto matricial se indica con el punto (.), no con el asterisco.

a : matrix([1, 2, 3], [4, 5, 6]) ;
b : matrix([7, 1/9], [z, -5], [1, 0]) ;

a . b ;

Otra particularidad es que el cálculo de la potencia de una matriz se indica mediante el doble acento circunflejo.

a : matrix([1, 2, 3], [4, 5, 6], [7, 8, 9]) ;
a^^3 ;

Otras operaciones con matrices.

a : matrix([1, 4, 3], [7, 5, 6], [3, 8, 9]) ;

/* Matriz inversa */
invert(a) ;

/* Matriz transpuesta */
transpose(a) ;

/* Determinante */
determinant(a) ;

Hay matrices que se definen de forma especial, como la identidad y la matriz nula.

ident(4);
zeromatrix(4,2);

Dada una matriz, calculamos su polinomio característico, sus valores y vectores propios.

A: matrix([1,3], [5,7]);

/* el segundo argumento es el nombre de la variable */
charpoly(A, x);

/* los valores propios y sus multiplicidades */
eigenvalues(A);

/* los valores propios y sus vectores correspondientes */
eigenvectors(A);

Cálculo


Límites

La función limit es la que nos permite calcular límites.

El más infinito se representa por inf y el menos infinito por minf.

f: (x-1) / (2*x + 3) ;

/* x se aproxima a 1 */
limit(f, x, 1);

/* x se aproxima a mas infinito */
limit(f, x, inf);

/* x se aproxima a menos infinito */
limit(f, x, minf);

Podemos aproximar el límite por la derecha o por la izquierda.

g: 1 / (x-1);
limit(g, x, 1);

/* nos aproximamos a 1 por la derecha */
limit(g, x, 1, plus);

/* nos aproximamos a 1 por la izquierda */
limit(g, x, 1, minus);


Derivadas

Tenemos que llamar a la función diff.

fun: sin(x) * x^4 ;
diff(f, x);

Calculando derivadas de orden mayor que uno.

/* orden tres */
diff(log(x)*x^x, x, 3);

Si queremos calcular derivadas implícitas, tenemos que decirle a Maxima qué variables dependen de la variable independiente.

/* y es una constante */
i: x^4 - x*y = cos(y^2+x);
diff(i, x);

/* ahora, y depende de x */
depends(y,x) $
diff(i, x);


Integrales

Llamamos a la función integrate tanto para las integrales indefinidas como definidas.

/* integral indefinida */
integrate(sin (2 + 3 * x), x) ;

/* integral definida */
integrate( x * exp(x), x, 1, 2) ;

Cuando los métodos simbólicos no se pueden aplicar, podemos hacer uso de algunas rutinas numéricas. Una de ellas es quad_qag; necesita cinco argumentos, el integrando, la variable independiente, los dos límites de integración y un entero entre 1 y 6, que es un parámetro del procedimiento (3 suele ser una buena elección). Lo que se obtiene es una lista de números; el primero es el valor de la integral definida y el segundo una estimación del error cometido.

quad_qag(exp(sin(x)),x,2,7,3);


Ecuaciones diferenciales

Para trabajar con ecuaciones diferenciales necesitamos decirle a Maxima qué variable depende de la variable independiente. Tendremos que hacer uso de la función ode2 para resolver ecuaciones diferenciales ordinarias.

depends(y, x) $

/* una ecuacion con variables separadas */
e: (x-1)*y^3+(y-1)*x^3*diff(y,x)=0;
r: ode2(e,y,x);

/* aplicamos condiciones iniciales */
ic1(r,x=2,y=-3);

Resolvemos una ecuación diferencial de Bernoulli.

depends(y, x) $
r: ode2(diff(y,x)-y+sqrt(y),y,x);

/* despejamos la variable dependiente con solve */
solve(r, y);

Junto con la función ode2, la librería contrib_ode añade más funcionalidades para resolver ecuaciones diferenciales; véase la documentación disponible.

Resolviendo una ecuación diferencial de orden dos, se trata de la ecuación del movimiento armónico simple.

depends(x, t) $

assume(k>0) $
e: diff(x,t,2) + k^2 * x = 0;
r: ode2(e, x, t);

/* aplicamos condiciones iniciales */
ic2(r, t=0, x=1, diff(x,t)=1/2);

/* o aplicamos condiciones de contorno */
bc2(r, t=0, x=1, x=3, t=-1);

/* la dibujamos! */
draw2d(explicit(rhs(s), t, 0, 10))$

Con la función desolve podemos resolver sistemas de ecuaciones diferenciales, pero en este caso debemos indicar explícitamente las dependencias de las funciones.

desolve(
    [diff(f(x),x)=3*f(x)-2*g(x),
     diff(g(x),x)=2*f(x)-2*g(x)],
    [f(x),g(x)]);

Si queremos aplicar condiciones iniciales, tenemos que declararlas con atvalue antes de llamar a desolve.

atvalue(f(x),x=0,-1)$
atvalue(g(x),x=0,3)$
atvalue(h(x),x=0,1)$

desolve(
  [diff(f(x),x)=f(x)+g(x)+3*h(x),
   diff(g(x),x)=g(x)-2*h(x),
   diff(h(x),x)=f(x)+h(x)],
  [f(x),g(x),h(x)]);

Cuando los métodos simbólicos no están permitidos, podemos usar el método de Runge-Kutta (rk). Aquí también dibujamos la función resultante.

/* resolvemos dy/dt = 2 y^2-exp(-3 t) */
sol: rk(2*y^2-exp(-3*t), y, 0, [t, 0, 10, 0.2]) $

draw2d(
  points_joined = true,
  points(sol))$

Gráficos

La mejor referencia para aprender a hacer gráficos con Maxima es el documento A Maxima-Gnuplot interface, que contiene multitud de ejemplos que se pueden copiar y pegar en el formulario. El manual de Maxima también tiene una sección dedicada a los gráficos.


Gráficos 2D

Los gráficos en 2D pueden hacerse con la función draw2d.

Las opciones se escriben en el formato opción = valor y los objetos gráficos de la forma objeto(arg1, arg2, ...).

Aquí se representa una función explícita en rojo. Las funciones explícitas necesitan una expresión, el nombre de la variable independiente y los extremos del dominio a representar.

draw2d (
  color = red,
  explicit(x^3-2*x^2+x-1, x, -3, 3) ) $

Las opciones se leen secuencialmente y afectan a los objetos gráficos que se declaren a continuación. A continuación una función explícita junto con otra paramétrica. Se añade una rejilla en el fondo.

draw2d (
  explicit(x^3-2*x^2+x-1, x, -3, 3),
  grid       = true,
  color      = red,
  line_width = 4,
  parametric(sin(t), t^2, t, -2*%pi, 2*%pi) ) $

Podemos dibujar puntos aislados y líneas poligonales. Las coordenadas de los puntos se pueden pasar al objeto points como una lista de pares, escribiendo la lista de abscisas seguida de la lista de ordenadas o dando solamente la lista de ordenadas. También se ve que los colores se pueden declarar en forma hexadecimal y que el estilo de los puntos, excepto el color, afecta a los últimos dos objetos.

draw2d (
  /* estilo por defecto */
  points([[2,3], [7,4], [0,5], [5,2/3], [7,-1], [8,3], [-2,10]]),

  point_type    = circle,
  point_size    = 3,
  color         = brown,
  points_joined = true,
  points([3, 4, 6, 8], [-2, -5, 3, 1]),

  color = "#ff670d",
  points([2, 6, 2, 8, 9])  ) $

Una función implícita, una función definida en coordenadas polares y un polígono.

draw2d(
  /* opciones globales */
  title      = "Escribe tu titulo",
  xlabel     = "eje-x",
  ylabel     = "eje-y",
  grid       = true,
  dimensions = [500,500],

  /* funcion implícita */
  key = "Implicita",
  implicit(y^2=x^3-2*x+1, x, -4,4, y, -4,6),

  /* coordenadas polares */
  key   = "Polar",
  color = red,
  polar(10/theta,theta,1,3*%pi),

  /* poligono */
  key        = "Polígono",
  fill_color = sea_green,
  color      = aquamarine,
  line_width = 6,
  polygon([[1,1],[3,0],[4,5],[0,3]]) ) $


Gráficos 3D

Los gráficos en 3D se realizan con la función draw3d.

Tres estilos diferentes de dibujar la misma superficie explícita.

/* rejilla */
draw3d(
  explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3)) $

/* superficie oculta con líneas rojas */
draw3d(
  surface_hide = true,
  color        = red,
  explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3)) $

/* superficie coloreada en función de las coordenadas */
draw3d(
  enhanced3d = [sin(x*y), x, y, z],
  explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3)) $

También podemos representar superficies paramétricas.

draw3d(
  /* se fija el número de nodos a calcular */
  xu_grid      = 50,
  yv_grid      = 15,

  surface_hide = true,
  parametric_surface(
      cos(a)*(3+b*cos(a/2)),
      sin(a)*(3+b*cos(a/2)),
      b*sin(a/2),
      a,-%pi,%pi,b,-1,1) )$

Una curva paramétrica. Véase cómo depende el color del parámetro u.

draw3d(
   /* se fija el número de puntos a calcular */
   nticks     = 60,
   title      = "Curva parametrica coloreada",
   line_width = 2,
   enhanced3d = (u-1)^2,
   dimensions = [500, 500], /* tamaño de la imagen */
   parametric(cos(5*u)^2,sin(7*u),u-2,u,0,2)) $

Una superficie implícita.

draw3d(
  enhanced3d = [x-z,x,y,z],
  palette    = gray,
  dimensions = [500, 600],
  implicit(min(x^2+y^2+z^2,2*x^2+2*y^2)=1,
           x,-1.5,1.5,y,-1.5,1.5,z,-1.5,1.5)) $

Puntos aislados y líneas poligonales.

xx: [1,2,3,4,5]$
yy: [4,5,7,1,2]$
zz: [3,2,1,9,4]$
xyz: [[10,15,12],[11,13,16],[16,10,11],[15,15,15]]$

draw3d(
  point_type = filled_square,
  color      = blue,
  points(xx,yy,zz),
  point_type = circle,
  color      = green,
  points_joined = true,
  points(xyz)) $

Superficie definida en coordenadas esféricas.

draw3d(
  color        = green,
  surface_hide = true,
  axis_3d      = false,
  xtics        = none,
  ytics        = none,
  ztics        = none,
  title        = "Nautilus",
  spherical(a+z,a,0,3*%pi,z,0,%pi))$

Familia de superficies en coordenadas cilíndricas.

draw3d(
  proportional_axes = xyz,
  dimensions   = [500,500],
  surface_hide = true,
  axis_3d      = false,
  xtics        = none,
  ytics        = none,
  ztics        = none,
  color        = blue,
  cylindrical(z,z,-2,2,a,0,2*%pi), /*cono*/
  color        = brown,
  cylindrical(3,z,-2,2,az,0,%pi),  /*cilindro*/
  color        = green,
  cylindrical(sqrt(25-z^2),z,-5,5,a,0,%pi) /*esfera*/ )$


Gráficos múltiples

Para representar varias escenas independientes, se llamará a la función draw, a la que se le pasarán tantos gráficos en 2D y 3D como sean necesarios con los objetos gr2d y gr3d, respectivamente. Aquí un sencillo ejemplo, donde fijamos las dimensiones del gráfico compuesto a nuestra voluntad.

draw(
  dimensions = [400, 600],
  gr2d(
    color = red,
    explicit(sin(x), x, -5, 5)),
  gr3d(
    color        = black,
    surface_hide = true,
    explicit(sin(x)*cos(y), x, -5, 5, y, -5, 5))  ) $

Por defecto, los gráficos múltiples se disponen en una sola columna, pero podemos cambiar este comportamiento con la opción columns.

draw(
  columns = 2,
  dimensions = [600, 300],
  gr2d(
    color = red,
    explicit(sin(x), x, -5, 5)),
  gr3d(
    color        = black,
    surface_hide = true,
    explicit(sin(x)*cos(y), x, -5, 5, y, -5, 5))  ) $

Este último ejemplo muestra una escena dentro de otra. La opción allocation necesita una lista de dos pares de números: las coordenadas de la esquina inferior izquierda de la escena, junto con su ancho y alto; todos estos valores deben darse con valores relativos, entre 0 y 1.

draw(
  dimensions = [500, 400],
  gr2d(
    background_color = cyan,
    color            = red,
    explicit(x^2,x,-1,1)),
  gr2d(
    allocation        = [[0.30, 0.50],[0.50, 0.40]],
    background_color = green,
    explicit(x^3,x,-1,1),
    grid = true) ) $


Animaciones

Para animaciones, tenemos que utilizar la función draw y declarar terminal = animated_gif.

draw(terminal   = animated_gif,
     delay      = 40,
     dimensions = [300,300],
     makelist(gr2d(explicit(x^(k/10),x,0,1)), k, 1, 10) ) $

Estadística

Las funciones estadísticas están definidas en un fichero de nombre descriptive, por lo que hay que cargarlo antes de hacer uso de ellas.

Los gráficos estadísticos definidos en el paquete descriptive se deben escribir con la pimera letra en mayúscula: Scatterplot, Histogram, Barsplot, Piechart, Boxplot y Starplot.

En este ejemplo, a partir de una serie de datos calculamos algunos parámetros estadísticos y generamos a partir de ellos un diagrama de sectores.

load(descriptive) $
mostra :
  [4, 7, 6, 1, 5, 10, 3, 6, 6, 6, 9, 9, 5, 2,
   2, 7, 7, 4, 6, 7, 8, 4, 10, 10, 4] $

/* media */
mean(mostra) ;

/* mediana */
median(mostra) ;

/* desviacion tipica */
std(mostra) ;

/* diagrama de sectores */
Piechart(mostra) $

En caso de muestra bivariante, los pares debemos introducirlos como una matriz de dos columnas. A partir de ahí podemos generar varios resultados.

load(descriptive) $
mostra:
  matrix(
    [125.1,140.7], [130.6,155.1], [135.1,160.3],
    [140.0,167.2], [145.4,169.8], [142.7,168.5])$

/* vector de medias */
mean(mostra) ;

/* matriz de covarianzas */
cov(mostra) ;

/* matriz de correlaciones */
cor(mostra) ;

/* grafico de dispersion */
draw2d(
   point_type = circle,
   point_size = 3,
   color = navy,
   points(mostra)) $

Mario Rodríguez Riotorto