Sistema de axuda de Yamwi en liña

Introdución

Esta páxina web permite facer todo tipo de cálculos matemáticos e gráficos en liña.

Para facer un cálculo calquera tan só é necesario escribir no cadro o código correspondente e a continuación premer no botón que está debaixo.

Os exemplos que se inclúen nesta páxina pódense copiar e pegar (CTRL-C e CTRL-V) na área de edición antes de premer no botón. O usuario pode facer os cambios que queira nesta área.

A axuda desta páxina é moi precaria e básica. Para afondar máis:

A información que imos obter ten aspecto de conversación. As nosas peticións levan sempre a etiqueta %i seguida dun número (i de input) e os resultados levan a etiqueta %o seguida do correspondente número de orde (o de output).


Contido


Números


Enteiros

Pódense utilizar enteiros tan grandes como sexa necesario. Aquí calculamos o factorial de 100,

100! ;

Coma en calquera outra linguaxe de programación, podemos sumar (+), restar (-), multiplicar (*), dividir (/), calcular potencias (^) y raíces cadradas (sqrt).

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

Vexamos a lista dos divisores dun enteiro dado e a súa factorización en números primos,

/* primeiro gardamos o numero na variable a */
a: 169996284 $
divisors(a) ;
factor(a) ;

Preguntamos a Maxima se 1502933 é un número primo.

primep(1502933);

Facemos uso de gcd para calcular o máximo común divisor de dous números e lcm para o mínimo común múltiplo dun conxunto arbitrario de enteiros, pero tendo en conta que para usar lcm temos que cargar primeiro a libraría functs.

gcd(16479936, 43375500000); 

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

A función divide devolve unha lista con dous elementos, o cociente e o resto (módulo) dunha división enteira.

divide(34, 5);


Racionais

Maxima sempre evita traballar con cantidades aproximadas. Co seguinte código operamos con racionais. Cada instrucción debe rematar cun punto e coma (;).

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

Se queremos a aproximación decimal dun resultado podemos proceder como segue: primeiro gardamos (cos dous puntos :) nunha variable (neste caso x) o valor da expresión exacta e despois executamos a función float para que a transforme en decimal.

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

O mesmo resultado se pode acadar cunha soa instrucción.

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

Outro exemplo onde se ve o uso de variables. O que se escribe entre os símbolos /* e */ son comentarios para os humanos, sendo ignorados pola máquina, polo que este exemplo é autoexplicativo.

/* Gardamos un valor na variable 'a' */
a : 8 / 24;

/* Gardamos outro valor na variable 'b' */
b: 1/5 ;

/* O cadrado da suma de 'a' e 'b' */
(a + b)^2;

A función float devolve un número limitado de decimais. Vexamos como pedir o número π con cinco mil decimais. Para iso debemos indicarlle á variable global fpprec a precisión desexada e despois facer unha chamada á función bfloat. Convén lembrar que π se representa en Maxima por %pi. Tamén calculamos a raíz cadrada de 2 con 5000 cifras decimais.

fpprec : 5000;
bfloat(%pi);

/* Tamen queremos a raiz cuadrada de dous */
bfloat( sqrt(2) );


Complexos

A unidade imaxinaria represéntase por %i. Con este símbolo, podemos escribir cualquera número complexo e realizar algunhas operacións con eles.

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

z1 + z2;
z1 - z2;

Ás veces, Maxima devolve expresións complexas con parénteses. Se queremos simplificalas, podemos chamar á 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 complexos en forma binomial á súa forma polar e ó revés.

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

Dividamos dous números complexos e obteñamos o resultado en forma binomial,

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

Dado un número complexo, podemos obter as súas partes real e imaxinaria, así coma o seu módulo e ángulo.

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


Factores de conversión

A libraría ezunits contén todo canto fai falla para cambiar unidades. Vexamos alguns exemplos.

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 dous pasos */
d : 10 ` m $
d `` inch;

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

Podemos declarar os nosos 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 cualquera unidade física a fundamental.

load("ezunits") $

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

/* dime as dimensións */
dimensions (f);

/* dime as unidades fundamentais */
fundamental_units (f);

/* fai a conversión */
f `` fundamental_units (f);

Álxebra


Polinomios

Da mesma maneira que podemos operar con números podemos facelo con variables. Fíxate como se reducen as expresións alxébricas.

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

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

Expandimos produtos.

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) ;

Se queremos calcular o valor numérico dunha expresión alxébrica, faremos uso da función subst tal como se indica a continuación, onde gardamos na variable f a fórmula para a forza de atracción gravitatoria e a calculamos para diferentes masas e distancias. O uso dos corchetes ([ e ]) en Maxima é moi común, xa que con eles podemos construir listas e calesqueira outras estruturas 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) ;


Ecuacións

En xeral, a función a utilizar é solve. Necesitará dous argumentos: o primeiro será unha lista de ecuacións separadas por comas, e o segundo a lista de incógnitas.

Unha sinxela ecuación de primeiro grao.

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

A mesma ecuación pero cunha constante.

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

Unha ecuación polinómica de segundo grao. Recorda que a raíz cuadrada se representa en Maxima por sqrt e a unidade imaxinaria por %i.

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

Un sistema de ecuacións. Vemos neste exemplo que podemos facer uso de varias liñas para escribir unha sentencia. Tamén pedimos o resultado en formato decimal.

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

float(sol);

Cando os métodos alxébricos non se poidan utilizar, podemos facer uso das rutinas numéricas. A libraría mnewton pode resolver ecuacións e sistemas de ecuacións polo método de Newton. Chamamos á función mnewton con tres argumentos: a lista de ecuacións, a lista de incógnitas e as coordenadas do 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]);


Inecuacións

A resolución de inecuacións necesita a libraría fourier_elim. Primeiro resolvemos unha inecuación linear de unha incógnita. A función fourier_elim necesita dous argumentos, a lista de inecuacións e a de incógnitas.

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

Unha inecuación de grao catro.

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

Un sistema de inecuacións de unha incógnita.

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

Un sistema de inecuacións de dúas 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

Os vectores represéntanse como listas pechadas entre corchetes. Podemos realizar con eles algunhas operacións habituais.

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

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

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

/* produto escalar */
v1 . v2;

O produto vectorial está definido na libraría vector3d.

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

Aquí hai un exemplo de como se define unha nova función en Maxima. Queremos escribir unha función que calcule o módulo dun vector; obsérvese que as funcións defínense por medio do operador :=. Vale, non te preocupes se non entendes a parte interna da función.

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


Matrices

As matrices pódense introducir de varios xeitos. O máis frecuente é facer uso da función matrix declarando as filas. Neste exemplo introdúcense dúas matrices para despois sumalas e restalas.

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

a + b ;
a - b ;

O produto matricial indícase co punto (.), non co asterisco.

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

a . b ;

Outra particularidade é que o cálculo da potencia dunha matriz indícase mediante o doble acento circunflexo.

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

Outras operacións con matrices.

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

/* Matriz inversa */
invert(a) ;

/* Matriz trasposta */
transpose(a) ;

/* Determinante */
determinant(a) ;

Hai matrices que se definen de xeito especial, como a identidade e a matriz nula.

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

Dada unha matriz, calculamos o seu polinomio característico, os seus valores e vectores propios.

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

/* o segundo argumento e o nome da variable */
charpoly(A, x);

/* os valores propios e as suas multiplicidades */
eigenvalues(A);

/* os valores propios e os seus vectores correspondentes */
eigenvectors(A);

Cálculo


Límites

A función limit á a que nos permite calcular límites.

O máis infinito represéntase por inf e o menos infinito por minf.

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

/* x achegase a 1 */
limit(f, x, 1);

/* x achegase a mais infinito */
limit(f, x, inf);

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

Podemos achegarnos ó límite pola dereita o pola esquerda.

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

/* achegamonos a 1 pola dereita */
limit(g, x, 1, plus);

/* achegamonos a 1 pola esquerda */
limit(g, x, 1, minus);


Derivadas

Temos que chamar á función diff.

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

Calculando derivadas de orde maior ca un.

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

Se queremos calcular derivadas implícitas, temos que dicirlle a Maxima que variables dependen da variable independente.

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

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


Integrais

Chamamos á función integrate tanto para as integrais indefinidas como definidas.

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

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

Cando os métodos simbólicos non se poidan aplicar, podemos facer uso dalgunhas rutinas numéricas. Unha delas é quad_qag; pasarémoslle cinco argumentos, o integrando, a variable independente, os dous límites de integración e un enteiro entre 1 e 6, que é un parámetro do procedemento (3 adoita ser unha boa elección). O que se obtén é unha lista de números; o primero é o valor da integral definida e o segundo unha estimación do erro cometido.

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


Ecuacións diferenciais

Para traballar con ecuacións diferenciais necesitamos dicirlle a Maxima que variable depende da variable independiente. Teremos que facer uso da función ode2 para resolver ecuacións diferenciais ordinarias.

depends(y, x) $

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

/* aplicamos condicions iniciais */
ic1(r,x=2,y=-3);

Resolvemos unha ecuación diferencial de Bernoulli.

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

/* despexamos a variable dependente con solve */
solve(r, y);

Xunto coa función ode2, a libraría contrib_ode engade máis funcionalidades para resolver ecuacións diferenciais; véxase a documentación dispoñible.

Resolvendo unha ecuación diferencial de orde dous, trátase da ecuación do movemento harmónico simple.

depends(x, t) $

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

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

/* ou aplicamos condicions de contorna */
bc2(r, t=0, x=1, x=3, t=-1);

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

Coa función desolve podemos resolver sistemas de ecuacións diferenciais, pero neste caso debemos indicar explícitamente as dependencias das funcións.

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)]);

Se queremos aplicar condicións iniciais, temos que declaralas con atvalue antes de chamar 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)]);

Cando os métodos simbólicos non estean permitidos, podemos usar o método de Runge-Kutta (rk). Aquí tamén debuxamos a 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

A mellor referencia para aprender a facer gráficos con Maxima é o documento A Maxima-Gnuplot interface, que contén multitude de exemplos que se poden copiar e pegar no formulario. O manual de Maxima tamén ten unha sección adicada ós gráficos.


Gráficos 2D

Os gráficos en 2D pódense facer coa función draw2d.

As opcións escríbense co formato opción = valor e os obxectos gráficos da forma obxecto(arg1, arg2, ...).

Aquí represéntase unha función explícita en vermello. As funcións explícitas necesitan una expresión, o nome da variable independente e os extremos do dominio a representar.

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

As opcións lense secuencialmente e afectan ós obxectos gráficos que se declaren a continuación. De seguido unha función explícita xunto con outra paramétrica. Engádese unha grella ó 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 debuxar puntos illados e liñas poligonais. As coordenadas dos puntos pódenselle pasar ó obxecto points como una lista de pares, escribindo a lista de abscisas seguida da lista de ordenadas ou ben dando soamente a lista de ordenadas. Tamén vese que as cores se pueden declarar en forma hexadecimal e que o estilo dos puntos, agás a cor, afecta ós últimos dous obxectos.

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])  ) $

Unha función implícita, unha función definida en coordenadas polares e un polígono.

draw2d(
  /* opcións globais */
  title      = "Escribe o teu titulo",
  xlabel     = "eixe-x",
  ylabel     = "eixe-y",
  grid       = true,
  dimensions = [500,500],

  /* función 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),

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


Gráficos 3D

Os gráficos en 3D fanse coa función draw3d.

Tres estilos diferentes de debuxar a mesma superficie explícita.

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

/* superficie oculta con liñas vermellas */
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 das coordenadas */
draw3d(
  enhanced3d = [sin(x*y), x, y, z],
  explicit(20*exp(-x^2-y^2)-10,x,-3,3,y,-3,3)) $

Tamén podemos representar superficies paramétricas.

draw3d(
  /* fíxase o número de nos 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) )$

Unha curva paramétrica. Véxase como depende da cor do parámetro u.

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

Unha 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 illados e liñas poligonais.

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 esceas independentes, chamarase á función draw, á que se lle pasarán tantos gráficos en 2D e 3D como sexan necesarios cos obxectos gr2d e gr3d, respectivamente. Aquí un sinxelo exemplo, onde fixamos as dimensións do gráfico composto a vontade.

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, os gráficos múltiples dispóñense nunha soa columna, pero podemos cambiar este comportamento coa 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))  ) $

Neste último exemplo amósase unha escena dentro dotra. A opción allocation necesita unha lista de dous pares de números: as coordenadas do recanto inferior esquerdo da escea, xunto co seu ancho e alto; todos estes valores débense dar con valores relativos, entre 0 e 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) ) $


Animacións

Para animacións, temos que utilizar a función draw e 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) ) $

Estatística

As funcións estatísticas están definidas nun ficheiro de nome descriptive, polo que hai que invocalo antes de facer uso delas.

Os gráficos estatísticos definidos no paquete descriptive débense escribir coa pimeira letra en maiúscula: Scatterplot, Histogram, Barsplot, Piechart, Boxplot e Starplot.

Neste exemplo, a partir dunha serie de datos calculamos algúns parámetros estatísticos e xeramos a partir deles 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) $

No caso dunha mostra bivariante, os pares debemos introducilos como unha matriz de dúas columnas. A partir de aí podemos xerar 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 correlacions */
cor(mostra) ;

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

Mario Rodríguez Riotorto