# mini-Tutorial ¿Cómo se hace con wxMaxima?

 Este documento continene una información muy básica porque sólo pretende
ser un documento de introducción a wxMaxima o de consulta rápida y ayuda de urgencia.

José Sánchez Marín.- Departamento de Química Física- Universitat de València.- octubre-2010

/* Probado wxMaxima 11.04.0 (MacOSX 10.5.8 Intel Core 2 Duo) */  octubre-2011

## Uso básico

Un "click" de ratón en la pantalla hace aparecer el cursor horizontal
Una celda de input se genera, donde esté el cursor horizontal, simplemente tecleando input.

Cada instrucción de input acaba con ";". 
Se ejecuta la celda en que está el cursor vertical de escritura, pulsando a la vez Mayuscula+Enter.
Todas las instrucciones de una celda se ejecutan, consecutivamente,

100;  100+100;
100+50;

"$" en lugar de ";" inhibe el output.  La instrucción se ejecuta.

100;  100+100$  100+50;

"/*    */"   Lo que se escribe entre /*   y  */ se considera "comentario" y no se ejecuta

100; /* 100 + 200 */ 100+50;

Haciendo "click" en el triángulo superior del simbolo de celda, solo se muestra la primera línea de input.

"%" hace referencia siempre al resultado de la última instrucción ejecutada, esté visible o no

/* En este ejemplo % vale 5, que es el resultado (no mostrado) de 4+1  */
4+1$ 
%*2;

Muchas instrucciones aparecen como instrucciones tipo "comando con argumentos".
Por ejemplo... 
abs(num)  da el valor absoluto del número num

abs(-5); abs(0); abs(5);

Operador "'" (apóstrofe o "single quote") : 
    Se usa como prefijo de una expr:  'expr   o de una expresión entre paréntesis '(expr)
    Aplicado a ciertos símbolos, inhibe la evaluación de los mismos.
    (Se verán ejemplos de su uso en otros lugares de este documento).

Operador " '' " (apóstrofe-apóstrofe o "quote-quote") :
    Se usa como prefijo de una expr:  ''expr   o de una expresión entre paréntesis ''(expr)
    Aplicado a ciertos símbolos, provoca la evaluación de los mismos.
    (Se verán ejemplos de su uso en otros lugares de este documento, especialmente en la sección de derivadas).

## Aritmética elemental y resultados numéricos

Los operadores aritméticos simples son "+" , "-", "*" , "/" . 
Un espacio en blanco no opera como multiplicador.  "x" tampoco.

2+3; 2-3; 2*3; 2/3;

expr, numer;    Da el valor numérico  "en coma flotante" de la expresión "expr" .

2/3 , numer;

Si se desea más información sobre cómo controlar el número de dígitos que se muestran,
 consultar la sección "input/output" (entrada/salida).

El operador "elevado a" es "^" .  También puede usarse "**" (como en lenguaje FORTRAN)

3^2; 3**2;

3^-2;

3^(1/2);

3^(1/2), numer;

El factorial de un número n se calcula con el operador sufijo  "!"

0!; 5!; 50!;

Para los números "en coma flotante" ("floating point") se usa el punto decimal "."  (no la coma decimal  ",") 
Para usar números como potencias de 10 se usa el formato "en coma flotante"  con la letra E 

1.00E3; 5.111E-6; 1.E12; 1.E24; 1.E126;

/* Un millon por una millonesima */
1.E6 * 1.E-6;

También admite D y B  ("Double precision") y ("Big floating point") 

2.D-20 ^ 2;  1.5B-30 ^2;

5D7*1E-3;5D7*1B3;

## Constantes predefinidas

Algunos valores predefinidos se introducen con nombres que comienzan por "%"

%pi; %e; %i;

%pi , numer; %e ,numer ; %i, numer;

%pi es el número irracional pi   (longitud de la circunferencia usando como unidad el diámetro). 
%e es el número irracional e   (base de los logaritmos naturales)
%i es la unidad imaginaria   (raiz cuadrada de la unidad negativa)

(-2)^(1/2);

%i^2;

%pi*%e;
%, numer; /* aqui el % tiene su significado habitual: resultado de la ultima operacion */1$

%phi  es la "razón aurea", que es la media aritmética entre 1 y raíz de cinco  (1+5^(1/2))/2

%phi;

%phi, numer;

## Asignación de variables

### operador ":"

":"  El operador ":" permite asignar un nombre arbitrario a una expresión.

"var: expr"   asigna la expresión "expr" a la variable "var"   

a: 10+10; /* a partir de ahora, donde usemos "a" estaremos usando el valor "20" */
2*a;

/* "var" pasa a ser un nombre simbolico para "expr" */
a;

Para poder volver a usar una variable de forma simbólica, hay que desasignarla
remvalue(a);   desasigna la variable a
remvalue(all); desasigna todas las variables

remvalue(all);

El operador prefijo "'" delante del nombre de una variable asignada, inhibe la evaluación
de la misma y la deja en su "forma de nombre" (noun form)

a: %pi * %phi$ 
'a;   /* devuelve una "a" */
a;    /* devuelve el valor de a declarado antes*/
'a = a;

remvalue(all);

### declaraciones

declare( xxx, prop)  permite (entre muchas otras cosas) declarar xxx  como
 enteras, racionales, reales, imaginarias,...
declare( xxx, constant)  declara xxx como constante simbólica

declare se anula con kill(xxx)  

assume(cond)  permite asumir condiciones como igualdades o desigualdades del tipo n >= 0, L < 0 ....
forget(cond)  anula el efecto de assume

Se veran ejemplos de la utilidad de declare y assume en las secciones de funciones, integrales, etc...

declare(n,integer);

/*  para anular el declare anterior  */ 
kill(n);

assume(L>0);

/* para anular el assume anterior */
forget(L>0);

Un ejemplo del efecto de forget y assume. 
La instruccion "is(condicion)" responde "true" si la condicion es verdadera para Maxima.

forget(T>0)$ 
is(T^(1/2)>0);

assume(T>0)$
is(T^(1/2)>0);

## listas

Una lista de expresiones tiene el formato [expr1, expr2, expr3 ,...]

Usando una lista en el lugar de un operando se puede generar una lista de resultados

3*[1,3,5];

/* podemos asignar una variable a la lista var: [   ,   ,  .... ,   ] */
lis: [1,3,5]$

3+lis;
3-lis;
3*lis;
3/lis;
3^lis;

Lista de valores simbólicos 

ls: [a,b,c,d]$
3+ls;
3-ls;
3*ls;
3/ls;
3^ls;

si ls es una lista, ls[n] es el elemento "n" de la lista ls.

remvalue(all)$

ls: [a,b,c,d]$ 
ls[1]*ls[4];

ls:[metro, segundo, kilogramo, amperio]$
unidad_velocidad: ls[1]/ls[2];
unidad_intensidad_electrica: ls[4];
unidad_fuerza: ls[3]*ls[1]*ls[2]^-2;

si ls es una lista, part(ls,n) es el elemento "n" de la lista ls.

ls: [a,b,c,d]$ 
part(ls,1)*part(ls,4);

Para generar listas ....
makelist(expr_que_contiene_var, var, inicial, final, incremento)   
El valor de incremento es 1 por defecto y puede omitirse. Algunas versiones de maxima pueden no admitir este argumento.

makelist( i+1/2, i, 0, 6);

makelist( 1/i, i, 5, 100, 5);

makelist admite esta otra forma:
makelist(expr_que_contiene_var, var, lista_de_valores_de_var)

makelist( i/2, i, [a,b,c,d]);

/* La lista de valores de var puede ser generada por makelist...  */
/* De esta forma, podemos generar listas con valores de "i" que cambian
en saltos diferentes de uno */
makelist(b*i, i, makelist(2*k,k,-4,5));

## vectores

Los vectores se representan como listas.
Un vector en el espacio tridimensional, se representa con una lista de tres elementos.

v: [1,3,5]$
w: [2,4,6]$

/* Suma de vectores */
v+w;

/* Resta de vectores */
v-w;

El producto de vectores puede ser "escalar" o "vectorial"

Producto ESCALAR:  Operador "."   ("dot product" en inglés)

v.w;

r: [r[x],r[y],r[z]]$
s: [s[x],s[y],s[z]]$

r.s;

Podemos usar el operador prefijo "'" para inhibir la expansión de los vectores

'r.'s  = r.s;

'(r.s) = r.s;

Producto VECTORIAL:  No tiene un operador definido en la versión básica de MAXIMA.   
Para trabajar con productos vectoriales hay que cargar un paquete adicional con load(vect). 
Una vez cargado el paquete "vect", el operador para el cross product es "~"

remvalue(all);

load(vect)$

r: [r[x],r[y],r[z]]$
s: [s[x],s[y],s[z]]$

v: r~s;   
/* para que se desarrolle el producto hay que pedir express(   ) */
v: express(v);

/* r~s debe ser ortogonal a los vectores r y  s */
v.r;
v.s;
expand(v.r);
expand(v.s);

NOTA:*EL paquete "vect" define el producto escalar ("dot product") como conmutativo.
El producto matricial no es conmutativo. 
Para seguir calculando con matrices, despues de cargar el paquete "vect" , 
puede ser conveniente ejecutar la instrucción   "kill(all)"  . 

kill(all)$
load(vect)$

/* test que da true/false si la igualdad se cumple/no se cumple */
is(r.s = s.r);

kill(all)$
is(P.Q = Q.P);

## matrices 

remvalue(all)$

matrix( fila1, fila2,... )  donde cada fila es una lista

P: matrix(
[-3,1,-5], 
 [5,2,6], 
 [2,7,1]  );

determinant(P);

Q: matrix(
 [a,b,c], 
 [b,p,d], 
 [c,d,q]  );

determinant(Q);

inversión de una matriz con determinante no nulo

invert(P);

determinant(invert(P));

multiplicación de matrices: operador "."  ("dot product")

M: matrix( [1,3,5], [7,11,13], [17,19,23] );

N: matrix( [1,2,3], [8,9,10], [11,22,33] );

A: M.N;

B: N.M;

A-B;

M.invert(M);

## expresiones algebraicas

### manipulación básica de expresiones

expand(expr)

remvalue(all)$

(a+b)^5;

expand((a+b)^5);

expand((1+x^2+x^3)*100);

expand( (a/b +  c/d)^3 );

expand((a+b)*(a-b));

/* podemos obtener resultados de formato tradicional */
(a+b)*(a-b) = expand((a+b)*(a-b));

/* Efecto del operador prefijo "'" */
'expand((a+b)*(a+b)) = expand((a+b)*(a+b));

factor(expr)

remvalue(all)$

factor(25468); factor(25469); factor(25470);

factor(50!);factor(100!);

factor(100!)/factor(50!);
factor(%);

expr: b^5+5*a*b^4+10*a^2*b^3+10*a^3*b^2+5*a^4*b+a^5;
factor(expr);

expr: 3*x^9+x^8+x^6+9*x^4+3*x^3+3*x;
factor(expr);

Suma de fracciones (se considera un tipo de simplificación: "simplificacion racional").
ratsimp(expr)        

remvalue(all)$

expr: 1/a + 1/b;

ratsimp(expr);

ratsimp(expr+1/d);

expr: 1 + 1/(1+1/((a+1)));

ratsimp(expr);

expand(expr);

Simplificacion:  La simplificación ordinaria se realiza siempre por defecto.

ratsimp(expr)     se considera la forma general para intentar simplificar más.

"expand" o "factor" pueden ayudar a simplificar expresiones. 

fullratsimp(expr)     En casos especiales fullratsimp puede simplifica más que ratsimp(expr)

remvalue(all)$

/* la simplificacion ordinaria se efectua por defecto en muchos casos */
(4*x+2*x)/2;
(a*x+2*a*x)/a;

expr: (a^2 + a*b)/a^3;

ratsimp(expr);

expr: (a^2 + b^2)*(a^3 + b^3)/(a^3*b^3);

ratsimp(expr);

expand(expr);

/* En esta caso fullratsimp no ayuda */
fullratsimp(expr);

/* En este caso fullratsimp si que ayuda */
expr: (x^(b/2) + 1)^3*(x^(b/2) - 1)^3/((x^a - 1)*(x^b-1));

fullratsimp(expr);

ratsimp(expr);

El operador prefijo  "'" puede usarse para inhibir evaluaciones durante el "parsing" o
análisis sintáctico del input.

remvalue(all)$

/* En este ejemplo, el analizador de input  ("parser") no sustituye a ni b por sus valores
respectivos */
a: x/2$   b: y$
'(a+b)^4 = expand((a+b)^4);

/* En este caso, al no estar el operador prefijo " ' ", el "parser" o analizador de input si 
substituye a por su valor y b por el suyo */
(a+b)^4 = expand((a+b)^4);

### substituciones

Hay varias formas de substituir una expresion por otra
expr, v1=ex;   /*  substituye v1 en expr. */

remvalue(all)$

ex1: 6*x^3 - 2*x ;
ex1, x=(a+b);    /*  ex1 con x substituida por (a+b) pero ex1 no se modifica */
ex1;

/* Usando esta forma, 
todas las substituciones se hacen en la expresion inicial, no son consecutivas */
ex1: a + B*a;
ex1, a = B, B = T;  
ex1,  B=T,  a=B;

"substitute"
Puede abreviarse por "subst". 
Tiene dos formas:
subst(expr1,expr2, expr) reemplaza expr2 en <expr> colocando en su lugar expr1.

subst(expre2=expr1, expr )    equivale  a  expr, expr2=expr1;

remvalue(all)$

ex1: a + B*a;
subst(T,B,ex1);

ex1: a + B*a;
subst(a=B,ex1);
ex1, a=B;

at(expr, [v1=exp1, v2=exp2,...]) da el valor de  expr para los valores de las variables
Las sustituciones tienen lugar en serie, no en paralelo.
expr no cambia.

remvalue(all)$

ex1: a + B*a;
at(ex1, [ a = B, B = T]);
at(ex1, [ B = T , a = B]);
ex1;

## funciones de una variable (predefinidas)

### algunas funciones básicas

Las funciones matemáticas más importantes están predefinidas (en informática se puede decir
"son funciones intrínsecas" de la aplicación)

remvalue(all)$

raiz cuadrada

sqrt(2);

sqrt(-1);

exponencial

exp(0); exp(1);

exp(a+b);

exp(a^b);

exp(minf); exp(inf);

logaritmo

/* log(x) calcula el logaritmo natural o en base %e de x */
log(%e); log(10), numer;

log(a*b);
log(a*b), logexpand=all;

log(a/b);
log(a/b), logexpand=all;

/* log de una potencia se expande por defecto */
log(a^4);

/* el logaritmo decimal puede calcularse dividiendo por log(10) */
log(2), numer;
log(2)/log(10), numer;

/* los logaritmos de numeros negativos son numeros imaginarios */
log(-5), numer;

El factorial de un número no entero también se puede calcular porque se
hace por medio de una función especial llamada gamma. x! = gamma(x+1)

a: 2.5;
a!;
gamma(a+1);

trigonométricas....

sin(x), cos(x), tan(x)
asin(x), acos(x), atan(x)
sec(x), csc(x), cot(x)
....  y sus correspondientes hiperbólicas sinh(x), cosh(x), tanh(x) ....

/* los argumentos de las funciones trigonometricas se toman en radianes */
/* para calcular sobre  n grados hay que convetir los grados en radianes
 multiplicando por %pi/180     */ 
sin(%pi/6); sin(30 * %pi/180);

cos(%pi/3); cos(60 * %pi/180);

Utilizacion de declare(n, integer)  .... kill(n)

sin(2*%pi); cos(2*%pi);

sin(2*%pi*n);cos(2*%pi*n);

declare(n,integer);

sin(2*%pi*n);cos(2*%pi*n);

kill(n);

sin(2*%pi*n);cos(2*%pi*n);

simplificación trigonométrica

cos(x)^2+sin(x)^2;  /* Esta suma no se simplifica a su valor 1 hasta que no se simplifica */
trigsimp(%);

sin(A+B);
trigexpand(%);

cosh(x)^2-sinh(x)^2;  /* Esta suma no se simplifica a su valor 1 hasta que no se simplifica */
trigsimp(%);

tan(A+B);
trigexpand(%);
trigsimp(%);

trigrat(%);  /* La expresion anterior se simplifica al pedir la "canonical form" 
o "forma canonica" (ver menu Simplificar) */1$

### función aplicada a lista de argumentos 

Se puede aplicar la funcion f(x) a una lista usando map(f, lista)

/* para aplicar la funcion seno a una lista de angulos expresados en grados */
lis: [-45,-30,30,45,60,90,120,270,360]*%pi/180;
sin(lis);   /* en ocasiones no produce el efecto deseado de aplicarse a la lista */
map(sin, lis);
fpprintprec:4$  /* reduce el numero de cifras significativas que se muestran */
%,numer;
fpprintprec:0$   /* el numero de cifras significativas que se muestran retorna al valor por defecto */1$

/*En general las funciones predefinidas si aplican el "mapeo" por defecto */
exp(lis);
abs(lis);

log(abs(lis));
log(abs(lis)), numer;

map(log,abs(lis));
map(log,lis), numer;

### números complejos

Los numeros complejos en forma cartesiana tienen la forma a + %i*b

z1: a + %i*b;
z2: c + %i*d;

zsum: z1+z2;
zres: z1-z2;

Para obtener la forma "a + %i*b" puede usarse  rectform( expr )
También puede usarse "collectterm(expr,%i)" para agrupar los términos que contienen el factor %i

rectform(zsum);
collectterms(zsum,%i);

z1*z2;
expand(%);
rectform(%);

z1/z2;
expand(%);
rectform(%);

El valor absoluto o módulo del complejo xxx se obtiene con abs(xxx)  

abs(z1);

El complejo conjugado de z se obtiene con conjugate(xxx)

zz1: conjugate(z1);
zz2: conjugate(z2);

El cuadrado del módulo del complejo xxx se obtiene como conjugate(xxx)*xxx

zz1*z1;
expand(%);

La forma polar del complejo xxx se obtiene con polarform(xxx)

z: 3+7*%i;
polarform(z);
%, numer;
polarform(%);

La forma polar de xxx puede expresarse como forma de De Moivre

z: r*%e^(-%i*A);
demoivre(z);

Se puede extraer la parte real y la parte imaginaria (sin la %i)  del complejo xxx con
realpart(xxx)
imagpart(xxx)

z1: a + %i*b;
z2: c + %i*d;
zp: z1*z2;

realpart(zp);

imagpart(zp);

## funciones. El operador ":="

Se pueden definir funciones usando el operador  ":=" 

remvalue(all)$

remfunction(fun);

fun(x):= 1/(1+x);

fun(3); fun(P);

fun(fun(x));

fun(x)^5;

/* funcion para calcular logaritmos decimales */
log10(x):=log(x)/log(10);

log10(2), numer;

/* Podemos usar la funcion definida para definir el pH de una disolucion
 con una concentracion molar de protones "cH" */
pH: -log10(cH)$
pH, cH=0.01;
%, numer;

/* Podemos definir el pH como una funcion de la concentracion molar de protones, cH */
pH(cH):=-log10(cH);

pH(0.01)$
%,numer;

Las funciones definidas puenden ser de varias variables

z(x,y):= x*y - x^2 - (y+1)^2;

z(2,5);

z(p,q);

z(1/p,1/q);
expand(%);

z(p^3,q^3);
expand(%);

/* funcion para calcular el logaritmo de x en base b */
logxb(x,b):=log(x)/log(b);

logxb(100,2), numer;

logxb(b,b);

Pueden definirse las funciones parte real y parte imaginaria
 de una función que tenga forma compleja 

z: 4*x^2 + %i * 7/x;

f(x):= ''(realpart(z));  /* El uso de ''(expr) fuerza la ejecucion inmediata de expr */ 
g(x):= ''(imagpart(z));

## ecuaciones. El operador "="

El operador "=" puede entenderse como una igualdad supuesta, 
una condición que se establece por el usuario.

solve(ecuacion, variable)   

solve ( x + (30-x) + 5*x = 300, x);

solve(x^3+10*x^2-23*x-132 = 0 , x);

solve(x^4-7*x^3-11*x^2+87*x+90= 0 , x), numer;

solve(  (p+ a/V^2)*(V-b)= R*T, b);

La "igualdad" que impone "=" siempre es de la forma
lhs = rhs     ("left hand side" = "right hand side")

remvalue(all)$

ec1:  4*x = 2/(x+2)$
lhs(ec1)-rhs(ec1);

solve(x^7-2 = 0 , x);

allroots(lhs = rhs) intenta encontar las soluciones numéricas
realroots(lhs = rhs) intenta encontrar la soluciones numéricas reales

allroots(x^10-2=0);

realroots(x^10-2=0);
%,numer;

Puede usarse solve para despejar ("isolate") variables, variables con subíndices, y otras expresiones 
(IMPORTANTE: solve NO PUEDE DESPEJAR sumas ni productos)

remvalue(all)$

ec1: p[1]*V=n[1]*R*T;
solve( ec1, p[1]);

ec1: (a+b)/(c+d) = (A[1]+f(t))*B[1];
solve(ec1,(a+b));  /* No da resultado */
solve(ec1,f(t));

/* solve puede "despejar" en algunos casos la potencia de la suma o del producto */
ec1: (a+b)^n / (p*q)^m = A/(B+1) ;
solve(ec1, (a+b)^n ); 
solve(ec1, (p*q)^m);

SISTEMAS DE ECUACIONES
solve(lista_de_ecuaciones, lista_de_variables)

remvalue(all)$

solve([2*x+5*y=3, x-y=7], [x,y]);

solve([a^2+b=3, a-b=7], [a,b]);

solve([a^2+b=P, a-b=Q], [a,b]);

Si hay mas variables que ecuaciones...
algsys(lista_de_ecuaciones, lista_de_variables)

algsys([a^2+b=3], [a,b]);

/*  El resultado queda en funcion de un parametro %r1  */
/* algsys creara tantas variables %r como necesite */1$

Si hay más ecuaciones que incógnitas, pueden eliminarse algunas variables...

eliminate(lista_de_ecuaciones, lista_de_variables_a_eliminar)
Las expresiones resultantes son iguales a cero

remvalue(all)$

eliminate([a^2+b=P, a-b=Q], [a]);

solve(%,b);  /* Si no hay signo =, solve asume que las expresiones son = 0 */1$

solve(Q^2-b*(-2*Q-1)-P+b^2=0, b);

eliminate([a+b+c=P, a-b=Q, 7*a+8*c=R], [a]);

## estructuras de programación: "if" , "for"

"if" cond_1 "then" expr_1 "else" expre_2 ; 

remvalue(all)$

n: 3;
a: tan(%pi/n);
if a <= 1 then print("menor") else print("mayor");

a: [3,7,1]$
if a[1] <= a[3] 
   then c: 2*a[1]
   else c: 2*a[2]$
c;

"for" variable: valor_inicial "step" incremento "thru" limite "do" cuerpo_del_bucle

remvalue(all)$

p:0$   /* este es el valor inicial de p */
for i: 1/2 step 1/2 thru 10/2 do p: p+i ;
p;   /* este es el valor final de p */
p, numer;

p:1;   /* este es el valor inicial de p */
for i: 100 step -4 thru 10 do p: p*i ;
p;   /* este es el valor final de p */
p, numer$

DOS  VARIANTES  de for : "mientras" y "a menos que"

"for" variable: valor_inicial "step" incremento "while" condicion  "do" cuerpo_del_bucle

"for" variable: valor_inicial "step" incremento "unless" condicion  "do" cuerpo_del_bucle

sum: 0;
for i:100 step -1 while i >= 50 do  sum: sum + 1/i; 
sum, numer;

sum: 0;
for i:100 step -1 unless i < 50 do  sum: sum + 1/i; 
sum, numer;

sum: 0;
for i:100 step -1 while i >= 50 do  sum: sum + 1/i; 
sum, numer;

Se pueden hacer varias instrucciones en el bloque do usando do(  ,  ,  )

sum: 0;  k: 0;
for i:100 step -1 while i >= 90  
    do (sum: sum + 1/i ,  k: k+1 ); 
k;  /* esta k es un contador de los ciclos "for" realizados */
sum, numer;

/* Podemos imprimir las etapas intermedias... si no son muchas  */
sum: 0;  k: 0;
for i:100 step -1 while i >= 90  
    do (sum: sum + 1/i ,  k: k+1, print(" k ",k, " sum ",float(sum))); 
k;  /* esta k es un contador de los ciclos "for" realizados */
sum, numer;

prod: 1; k:0 $
for i:100 step -6.20 while i >= 75 do  (prod: prod*(i/2) , k: k+1 ); 
k;
prod;

remvalue(all)$

## derivadas 

diff(y(x))   calcula el diferencial de la función y(x).   

remvalue(all)$

diff(sin(x));
diff(log(x));

/* del(x) es el diferencial de la variable independiente x */
diff(cos(x))  /  del(x);

diff(log(z^2));
diff(1/z);

diff(y(x),x)   calcula la derivada de y(x) respecto de la variable x

remvalue(all)$

diff(sin((1/k)*x),x);

diff(sin((1/k)*x),k);

diff(y(x),x,n)  calcula la n-ésima derivada de y(x) respecto a x

diff(sin(k*x),x,3);
diff(sin(k*x),x,5);

diff(expr)  calcula el diferencial TOTAL de expr tomando todas las posibles variables.

diff(a*x+b*y^2);

z(x,y):= a*x - 3*x*y + b*y^2;
diff(z(x,y),x);   /* derivada parcial */1$

diff(z(x,y));

El uso del operador "'" (apóstrofe o "single quote") :  
 Aplicado a ciertos símbolos, inhibe la evaluación de los mismos.
    En particular:
Puede usarse para obtener expresiones de output más claras, en notación convencional
NOTA MUY IMPORTANTE:
(Observese que del signo "=" somos responsables nosotros, no MAXIMA. 
Si cometemos un error, podemos obtener expresiones matemáticamente inconsistentes). !!!!

y(x):= x^x$
'diff(y(x),x) = diff(y(x),x);

y(x):= sin(x)*cos(x)$
'diff(y(x),x) = diff(y(x),x);

El uso del operador "''" (apóstrofe o "quote-quote") :  
 Aplicado a ciertos símbolos, provoca la evaluación de los mismos por el "parser" o analizador sintáctico.
    En particular:
Puede usarse para definir funciones en las que interviene el operador diff

y(x):= x^log(x);
y1(x):= ''(diff(y(x),x,1));
y2(x):= ''(diff(y(x),x,2));

/* NOTA: se necesita ''(  ) para que afecte a toda la operacion ... */
/* Observense en cambio estos dos casos  */
y(x):= x^log(x);
y1(x):= diff(y(x),x,1);
y2(x):= ''diff(y(x),x,2);

/* otro uso de ''  */
auxi: x^x$
h(x):= auxi;   /* h(x) no se comporta como funcion */
h(a); 

f(x):= ''auxi;   /* f(x) aqui si se comporta como funcion */
f(a);

f1(x):= diff(auxi,x,1); 
f1(a);           /* f1(x) asi definido no se comporta como una funcion de a */

f1(x):= diff(''auxi,x,1);
f1(a);
f1(x):= ''(diff(''auxi,x,1));
f1(a);

Derivadas parciales y de varias variables
diff(funcion, var1, n1, var2, n2 ....)

z(x,y):= a*x^3*y^2 - b*y^3*x^2;
'diff(z(x,y),x,1,y,1) = diff(z(x,y),x,1,y,1);

/* Importa el orden? */
'diff(z(x,y),y,1,x,1) = diff(z(x,y),y,1,x,1);

'diff(z(x,y),x,2,y,2) = diff(z(x,y),x,2,y,2);

Desarrollo en serie de potencias de Taylor hasta orden n en torno al punto x=a
taylor(expr, x, a, n);   expr puede ser una expresion que contiene la x o puede ser una funcion de x

remvalue(all)$

fun(x):= 1/x;
taylor(fun(x),x,1,6);

expand(%);

el desarrollo de Taylor-McLaurin corresponde al caso en que a = 0
taylor(expr, x, 0, n);

expr: sin(k*x)*cos(x)$
taylor(expr,x,0,6);
taylor(expr,k,0,6);

## integrales 

integrate(f(x),x)      Integral indefinida.
integrate(f(x),x,a,b)   Integral definida entre x=a y x=b

remvalue(all)$

/* Maxima no incluye la constante de integracion indefinida */
integrate((-1/x),x);

integrate(sin(w*x),x);

integrate((1/sqrt(1-x^2)),x);

integrate((1/sqrt(1+x^2)),x);

Puede usarse el operador "'" con integrate para inhibir la evaluación

'integrate((1/sqrt(1-x^2)),x) = integrate((1/sqrt(1-x^2)),x);

'integrate((1/sqrt(1+x^2)),x) = integrate((1/sqrt(1+x^2)),x);

integrate(f(x),x,a,b)   Integral definida entre x=a y x=b

remvalue(all)$

'integrate((k*x^2),x,a,b) = integrate((k*x^2),x,a,b);

'integrate((1/(1-x^2)),x,a,b) = integrate(1/(1-x^2),x,a,b);

'integrate((1/(1-x^2)),x,5,10) = integrate(1/(1-x^2),x,5,10);
%,numer;

remvalue(all)$

integrate(log(k*x^2),x, 1, x);

assume( cond  )  puede ayudar a establecer condiciones.
forget( cond  )  las anula

remvalue(all)$

/* ejemplo usando la variable x como limite de integracion */
assume (x > 1);
assume (k > 1);
integrate(log(k*x^2),x, 1, x);

remvalue(all)$

'integrate((x^2)*(sin(k*x))^2, x, 0, L);

assume(L > 0);
'integrate(x*(sin(k*x))^2, x, 0, L) = integrate(x*(sin(k*x))^2, x, 0, L);

declare( xxx, prop) puede establecer condiciones adicionales

forget(L>0,n>0);

assume(L>0, n>0);
declare(n,integer);
integrate((sin(k*x))^2, x, 0, L);
subst((n*%pi)/L, k,%);

forget(L>0,n>0); /* anula assume */
kill(n);  /* anula declare(n,integer) */1$

assume(L>0, n>0);
integrate((sin(k*x))^2, x, 0, L);
subst((n*%pi)/L, k,%);

## ecuaciones diferenciales

Para resolver ecuaciones diferenciales ordinarias (ODE):
ode2(ec1,y,x);
donde ec1 es una ecuación donde aparece la derivada en la forma 'diff(y,x,1) .  
El "'" antes de diff es obligatorio.

Consideraremos aquí ecuaciones de una sola variable. 

ode2 resuelve ecuaciones diferenciales ordinarias de primer y segundo orden. 
(Con primeras y/o segundas derivadas como máximo).

La solución general de una ecuación diferencial de orden "n" contiene "n" 
constantes indeterminadas. Maxima las introduce como %c,  ... para primer orden 
y %k1, %k2... para segundo orden.

y' = -a*y

remvalue(all)$

ed1: 'diff(y,x,1) + a* y = 0;
ode2(ed1, y, x);

Condiciones "iniciales" para una ec. dif. de primer orden.
ic1 (soluc, x = x0, y = y0)  siendo  (x0,y0)  un punto conocido de la curva (valores "iniciales")

ed1: 'diff(y,x,1) - a* y = 0;
ode2(ed1, y, x);
ic1(%, x=0, y= %pi);

/* En este ejemplo, la variable independiente es t, la variable dependiente es p */
ed1: 'diff(p,t,1) = -k * p;
ode2(ed1, p, t);
ic1(%, t=0, y= p[0]);

/* En este ejemplo, la variable independiente es t, la variable dependiente es \[A\]
(notacion tradicional para concentraciones molares en Quimica) */
ed1: 'diff(\[A\],t,1) = -k * \[A\];
ode2(ed1, \[A\], t);
ic1(%, t=0, \[A\] = \[A\][0]);

Ejemplo de ecuación diferencial de segundo orden

remvalue(all)$

assume (k>0);
ed2: 'diff(y,x,2) = - k * y ;
ode2(ed2, y, x);

bc2 (soluc, x=x1, y=y1, x=x2, y=y2) establece condiciones de contorno ("boundary conditions") para
la solución proporcionada por ode2.

remvalue(all)$

assume (k>0)$
ed2: 'diff(y,x,2) = - k * y $
ode2(ed2, y, x);
bc2(%, x=0,y=Y[0], x=L, y=Y[0]);

## gráficas: "plot".

(existe un paquete "draw" que pueda cargarse con load(draw) para aumentar 
las capacidades gráficas)

El formato general de plot tiene esta forma
wxplot2d([     ],[       ],[         ],.....  )
Todas las opciones tiene el formato de  listas.  
Las dos primeras son necesarias: Lista de expresiones a representar y la variable independiente [x, xmin, xmax]
Otras opciones (no obligatorias):

[y, ymin, ymax]           : El rango del eje vertical.
[xlabel, " etiqueta del eje horizontal"]
[ylabel, "etiqueta del eje vertical"]
[logx] y [logy]          : ejes logaritmicos, no necesitan parámetros.
[legend, ["label1","label2",...]  : etiquetas en la leyenda 
                            (por defecto, usará las expresiones o nombres dados en wxplot2d(...))
[grid,numx,numy] : retícula de cálculo (por defecto: [grid,30,30])
[style, [estilo1, parametros],[estilo2,param... ]]  . Tantos estilos como funciones o datos... 
    estilos: lines (segmentos lineales)   [lines,anchura,color]  ej: [lines,1,3]
             points                       [points, radio, color, objeto]   ej: [points,1,2,5] 
             linespoints (segmentos y puntos)  [linespoints, ancho, radio, color],  
      dots (pequeños puntos aislados)
             impulses (aceptado por Gnuplot).
    Códigos de color (defecto: pueden cambiar con el terminal definido)
     1, azul; 2, rojo; 3, magenta; 4, naranja; 5, marrón; 6, verde lima; 7, aguamarina.
    Código de objetos:
    1, círculos rellenos; 2, circunferencias; 3, +; 4, x; 5, *; 6, cuadrados rellenos;
    7, cuadrados huecos; 8, triángulos rellenos; 9, triángulos huecos;
    10, triángulos rellenos invertidos; 11, triángulos huecos invertidos;
    12, rombos rellenos; 13, rombos huecos.

Representación de puntos dicretos

remvalue(all)$

pts1: [[1,1.3],[3,3.5],[5,6.7],[7,8.1],[9,10.7],[13,14.1],[15,16.9]];

pts2:[[3,2.5],[4, 2.8],[6.5,3.12],[10, 3.5],[14, 3.75]];

wxplot2d([discrete, pts1],[style, points]);

wxplot2d([[discrete, pts1],[discrete,pts2]],[style, points],[x,-5,25]);

Representación de funciones

remfunction(fun,fu1,fu2)$

fun(x):= 4*sin(2.5*x)+5*sin(4.3*x+%pi/6);

/* opcion [style,[lines, grosor, color] */

wxplot2d([fun(x)],
 [x,-5,5],
[y,-20,20],
[style,[lines,2,2]])$

fu1(x):= 4*sin(2.5*x)+5*sin(4.3*x+%pi/6)$
fu2(x):= 4*sin(2.5*x)*sin(4.3*x+%pi/6)$

wxplot2d([fu1(x),fu2(x)],
 [x,-5,5],
[y,-15,15],
[style,[lines,2,2],[lines,3,1]])$

/* usando 'fu1(x) se evita que se expanda toda la expresion en la leyenda  */
/*   */
wxplot2d(['fu1(x),'fu2(x)],
 [x,-5,5],
[y,-15,15],
[style,[lines,2,2],[lines,3,1]],
[xlabel,"t / segundos"],
[ylabel, "Intensidad / miliamperios "])$

wxplot2d(['fu1(x),'fu2(x)],
 [x,-5,5],
[y,-15,15],
[style,[lines,2,2],[lines,3,1]],
[xlabel,"t / segundos"],
[ylabel, "Intensidad / miliamperios "],
[legend, "suma de ondas desfasadas", "producto de ondas desfasadas"])$

Representación en polares

wxplot2d([cos(9*ph+2.5)], [ph,0,2*%pi],
 [gnuplot_preamble, "set polar; set zeroaxis;"])$

Se puede hacer una representación que cambia al variar un parámetro.
Una vez representado, seleccionando  el gráfico con un  "click" se activa el mando de reproducción

remvalue(all)$

 /* los dos primeros argumentos son el parametro y su lista de valores */
 /* Los demas argumentos son los de wxplot2d  */

with_slider(   n, makelist(i, i, 1, 30),

   [cos(9*ph + n)], [ph,0,2*%pi],
[gnuplot_preamble, "set polar; set zeroaxis; set size ratio 1"]    )$

Representacion en 3D

remvalue(all)$

wxplot3d(x^3 - x*y + y^3, [x,-4,4], [y,-3,3], [z,-60,60],
 [grid,40,40],
[xlabel," largo "],[ylabel,"ancho"],
[zlabel,"F"])$

## input/output

### Cifras significativas

Se puede controlar el número de cifras SIGNIFICATIVAS del output con la variable fpprintprec
El valor por defecto de fpprintprec es fpprintprec:0  que produce un output con 16 decimales

remvalue(all)$

sqrt(2)*100, numer;

fpprintprec:4$  /* no controla directamente el numero de decimales, sino el de cifras */
sqrt(2), numer;
sqrt(2)*100, numer;

fpprintprec:0$  /* reestablece el valor por defecto */
sqrt(2)*100, numer;

La variable fpprec controla la precisión interna con que se realizan los cálculos.
bfloat(expr) da la expresion expr en "big double precision".

fpprec: 50;
bfloat(%pi);
fpprec: 70;
bfloat(%pi);

El modo de "display" gráfico (el que se tiene por defecto) trunca las series de dígitos
 si se desean valores de fpprec muy grandes.

fpprec: 100$   /* el valor por defecto es 16 */
100!;
bfloat(%pi);
fpprec: 16$

Si se desean ver todos los dígitos , se usa  "set_display('ascii)$"  
(menu Maxima > Cambiar pantalla 2D > ascii)
Se vuelve la ventana wx al modo gráfico estándar con "set_diplay('xml)$"
(menu Maxima > Cambiar pantalla 2D > xml)

set_display('ascii)$
fpprec: 100;
100!;
bfloat(%pi);
set_display('xml)$
fpprec: 16$

### ficheros externos de datos

Se pueden generar y leer datos en formato CSV ("comma separated values") de ficheros externos

remvalue(all)$

pts1: [[1,1.3],[3,3.5],[5,6.7],[7,8.1],[9,10.7],[13,14.1],[15,16.9]];

pts2:[[3,2.5],[4, 2.8],[6.5,3.12],[10, 3.5],[14, 3.75]];

datosX: makelist(pts1[i][1],i,1,length(pts1));

datosY: makelist(pts1[i][2],i,1,length(pts1));

file_search("nombre_de_fichero").     Devuelve "false" si no existe. "true" si existe
"nombre_del_fichero" es una direccion completa ("un path"). 
  En linux o Mac sera del tipo "/home/usuario/documentos/.../mifichero.cvs"
     ATENCION:
     En PC también se usan "/", en vez de "\" :   "C:/docsMaxima/docsDatos/mifichero.cvs"    

file_search("/Users/pepesanc/Desktop/datosMX/puntos1.csv");

write_data(Datos, nombre_del_fichero, separador)
Datos puede ser una lista , una matriz, un "array" declarado....
nombre_del_fichero ("un path"). 
Separadores que reconoce write_data:   comma, pipe, semicolon, space, tab

write_data(pts1,"/Users/pepesanc/Desktop/datosMX/puntos1.csv",comma);

En la carpeta "Users/..../datosMX" se ha creado un fichero texto puntos1.csv
con contenido:

1,1.3
3,3.5
5,6.7
7,8.1
9,10.7
13,14.1
15,16.9

Puede leerse el contenido del fichero.  
El fichero puede haber sido escrito o preparado con otra aplicación.

M1: read_matrix("/Users/pepesanc/Desktop/datosMX/puntos1.csv")$

L1: read_list("/Users/pepesanc/Desktop/datosMX/puntos1.csv")$

LN1: read_nested_list("/Users/pepesanc/Desktop/datosMX/puntos1.csv")$

M1;

L1;

LN1;

## APENDICE. símbolos griegos y otros símbolos

/* El orden corresponde al del alfabeto griego. */
/* omicron y upsilon minúscula no dan respuesta aunque tampoco dan error  */

/* El orden corresponde al del alfabeto griego. */
[%alpha,%beta,%gamma,%delta,%epsilon];
[%zeta,%eta,%theta];
[%iota,%kappa,%lambda,%mu,%nu];
[%xi,%omicron,%pi,%rho,%sigma,%tau];
[%upsilon,%phi,%chi,%psi,%omega];

/* Todas las mayusculas dan respuesta */
[%Alpha,%Beta,%Gamma,%Delta,%Epsilon];
[%Zeta,%Eta,%Theta];
[%Iota,%Kappa,%Lambda,%Mu,%Nu];
[%Xi,%Omicron,%Pi,%Rho,%Sigma,%Tau];
[%Upsilon,%Phi,%Chi,%Psi,%Omega];

Puede usarse "\" como caracter escape.  lambda minuscula se comporta de modo diferente porque 
es un nombre protegido.

[\alpha,\beta,\gamma,\delta,\epsilon];
[\zeta,\eta,\theta];
[\iota,\kappa,\lambda,\mu,\nu];
[\xi,\omicron,\pi,\rho,\sigma,\tau];
[\upsilon,\phi,\chi,\psi,\omega];

[\Alpha,\Beta,\Gamma,\Delta,\Epsilon];
[\Zeta,\Eta,\Theta];
[\Iota,\Kappa,\Lambda,\Mu,\Nu];
[\Xi,\Omicron,\Pi,\Rho,\Sigma,\Tau];
[\Upsilon,\Phi,\Chi,\Psi,\Omega];

El uso del simbolo de "escape" \ permite usar otras notaciones tradicionales.

log10(x):=log(x)/log(10)$
pH(x):= log10(x)$

fpprintprec: 4$

\[H\+\]: Kw/(\[OH\-\])$
pH(\[H\+\]);
%, logexpand=super;
expand(%), numer;

remvalue(all)$

eq_quim: K = (\[C\]^c * \[D\]^d)/(\[A\]^a * \[B\]^b);
solve(eq_quim, \[B\]);
solve(eq_quim, a);