Página de Maxima
Usando o Maxima
Autor: Sadao Massago
instituição: DM-UFSCar
web: http://www.dm.ufscar.br/~sadao
data: 2017-12-25
site do maxima e manual
http://maxima.sourceforge.net/
http://maxima.sourceforge.net/documentation.html
Um dos manuais mais recomendado é
http://maxima.sourceforge.net/docs/manual/en/maxima.html
A versão em PDF em
http://maxima.sourceforge.net/docs/manual/en/maxima.pdf
A versão em português (um pouco desatualizado) em
http://maxima.sourceforge.net/docs/manual/pt/maxima.html
Para executar
<cntrl><ENTER> executa o bloco de comando onde o cursor esta
<ctrl>R executa todo arquivo
Para acrescentar códigos e comentários
F5 abre o campo de comando
F6 abre o campo de comentario (texto)
Estes o eoutros comandos estao no menu "cell".
F1 abre a ajuda do Maxima. Se o cursor estiver sobre a palavra,
procurará por esta paravra na ajuda.
Assume que já leu o "part01_intro.wxm" ("Introdução ao maxima")
1 Estabelecendo tipo de variáveis
Podemos usar o "declare()" para estabelecer o tipo de variáveis Por exemplo, a potência do produto é o produto da potencia, para n inteiro declare() serve para especificar o tipo de variaveis remove() elimina a condição estabelecida pelo declare()
| (%i5) |
expand ((x * y)^n); /* não há regra para n geral */ declare(n, integer); /* n é inteiro */ expand ((x * y)^n); /* usa a regra do caso de n inteiro */ remove(n, integer); /* eliminando condição sobre n */ %$ |
2 Estabelecendo condição nas variáveis
Existem regras que só funcionam para algumas condições.
Por exemplo, o método de integração ou simplificação
das regras requer alguma restrição.
Além do tipo de variáveis que pode ser especificado pelo declare(),
poderá estabelecer condições extras
A condição pode ser acrescentado pelo assume() e removido pelo forget()
O "forget(all);" removerá todas condições anteriormente estabelecidas
| (%i13) |
abs(x); assume(x>=0); /* estabelece uma condição para x */ abs(x); forget(x>=0); /* elimina esta condição */ assume(x<=0); abs(x); facts(); /* ver todas condições remanescentes */ forget(all); |
Os parametros de assume() e forget() são lista de desigualdades
separado pela vírgula.
Para condições, serão aceitas: >, ≥, <, ≤
"equal()" e "not equal()".
Ficar atento ao fato de "=" usado para definir equação
é uma igualdade literária e não funciona para comparação
da equivalência de expressões. Para equivalências, deverá usar
"equal() e "not equal"
Ma versao atual do maxima (2010), a condicao "or" (ou)
não é aceito no assume(), apesar de "and" (e) ser aceito.
Em resumo
pode especificar um intervalo como no caso de a ≤ x ≤ b,
pode excluir pontos como no caso de x diferente de a
mas nao poderá especificar dois intervalos como do caso de x ≤ a ou b ≤ x
"=" é uma igualdade literaria (escrito de forma exatamente igual) equal() é quando são equivalentes em todo contexto. Mesmo para "#" (literalmente diferente) e "not equal()" (ou "notequal()" que é não equivalente)
| (%i16) |
is( (x+1)^2 = x^2 + 2*x +1); is( expand((x+1)^2) = x^2 + 2*x +1); is( equal((x+1)^2, x^2 + 2*x +1)); |
facts() lista todos declares e todos assumes.
facts(n) é para condições estabelecidas sobre n
integerp (n) retorna "true" se ne tem flag de inteiro,
mas se armazena valores diferentes de inteiro será "false".
Note que o "flag" é usado para minipulacao (escolher regra certa) quando é expressão,
mas não está probibido de armazenar valores diferêntes do especificado.
remove (n, integer); remove flag de inteiro do n
remove (all,integer); remove flag de inteiro de todas variáveis
| (%i20) |
declare(n,integer); integerp (n); facts (n); properties (n); |
Algumas regras só aplica para condição específica
Por exemplo,
integrate(1/x, x) = log(x)
integrate(x^n, x) = x^(n+1)/(n+1) se n não for 1
(Obs.: integrate(x^0, x) = x)
| (%i23) |
/* integral de x^n é x^(n+1)/(n+1) se n não for -1 */ /* integral de 1/x é log(x) */ assume(not equal(n, -1)); integrate('x^n,'x); forget(all); |
3 Uso de evaluação forçada.
Uso de '' (dois apostrofos seguidos) Um apóstrofos indica que o que segue é um símbolo (não evaluar), enquanto que dois apóstrofos (não é aspas) significa que a exprssão será evaluada.
| (%i30) |
kill(x); expr : x^2+1; f(x) := expr; g(x) := ''expr; x : 0; f(1); g(1); |
Na definição da função, a evaluação é suprimida.
Assim,
g(x) := diff(expr, x)
não define g(x) como derivada de expr
e g(1) rsultará em erro, pois será tratado como diff(expr, 1).
Para que diff(expr, x) seja evaluada antes de atribuir a g,
usa-se o ''. Note o uso de parenteses para que '' seja aplicado a
expressão inteira e não só a palavra diff.
| (%i34) |
expr : '(x^2+x+1); g('x) := ''(diff(expr,'x)); x : 0; g(1); |
4 apply e map
apply aplica a funcao, tomando a lista como parametros.
Uso de apply
| (%i38) |
soma([L]) := apply ("+", L); soma_lista(L) := apply ("+", L); soma(1,'a,'x); soma_lista([1,'a,'x]); |
| (%i42) |
f(x) := x^2+1; g(x,y) := x^2+y^2; apply(f, [1]); apply(g, [1, 2]); |
map por sua vez, aplica a função em cada elemento da lista e retorna a lista
| (%i50) |
f(x) := x^2; a : 0; b : 1; n : 10; h : (b-a)/n; x : makelist(a+i*h, i, 0, n); y : map(f, x); wxplot2d([discrete, x, y]); |
\[\mathrm{\tt (\%o50) }\quad \]
5 Mais um pouco sobre listas e matrizes
Poderá receber cada elemento da lista em uma variável. Para isso, coloque a variável que recebe dentro de []
| (%i52) |
X0 : [1, 2, 3]; [x, y, z] : X0; |
| (%i56) |
a : 1; b : -1; [a, b] : [b, a]; /* trocando valores */ %$ |
O primeiro, segundo, ... até decimo elemento pode ser obtido pelo first, second, ..., tenth em vez de usar indice 1,2,...,10 e o último elemento pelo last.
| (%i60) |
l : [2,4,6,8,10]; first(l); /* igual a l[]1] */ last(l); /* igual a l[length(l)] */ %$ |
cons acrescenta no começo da lista e endcons no final da lista append concatena as listas
| (%i64) |
l : [2,4,6,8,10]; cons(1, l); /* acrescenta no início da lista: append([1], l) */ endcons(1, l); /* acrescenta no final da lista: append(l, [1]) */ append(l, l); |
Existem muitas funções pré-definidas para manipular as listas. Veja a ajuda sobre topico list para detalhes.
Produto de matrizes é feito eplo "." e não pelo "*" que é produto elemento a elemento, o que requer cuidados. A potenciação de matrizes "^^" também é diferente dos casos de números que é "^" Na matriz ou vetores, "^" é elevar cada elemento.
| (%i70) |
kill(x,y); A : matrix([1,2],[3,4]); v : [x, y]; A . v; /* aqui, v é visto como matriz coluna */ v . A; /* aqui, v é visto como matriz linha */ %$ |
| (%i75) |
A : matrix([1,2],[3,4]); b : [1, 2]; v : A^^(-1) . b; /* aqui, v é visto como matriz coluna */ A . v; /* tirando a prova */ %$ |
Note que u . v nao é produto interno para o caso complexo. Assim, use inprod do pacote eigen para produto interno
| (%i81) |
load("eigen"); u : [1, %i]; v : [3, 1]; u . v; /* não é produto interno no caso complexo */ inprod(u, v); /* produto interno */ %$ |
6 Alterando valor da variável global somente para uma expressão
Para alterar o valor da variável global somente para uma expressão,
usa-se o comando ev(expr, arg1, arg2, ..., argn)
Neste caso, criará um ambiente executando arg1, ..., argn e depois evaluara o expr.
Se atribui valor em alguns args, o valor de fora será mantida.
| (%i84) |
x; ev(y:x^2+1, x : 2); x; |
arg pode ser atribuição para variavel, ou palavras-chave.
Sobre significado de cada palavra-chave, veja a ajuda no topico ev
Por exemplo, "numer" faz com que alguns constantes serem
substituidos pelo seu valor no ponto flutuante
| (%i87) |
x : 2; %e^x; ev(%e^x, numer); |
Para expressões pequenas, podemos omitir o ev() e excrever simplesmente como
expr, arg1, ..., argn
Não confundir este com o
(expr1, expr, ..., exprn)
que é delimitado pelos parenteses, que é sequencia de comandos.
| (%i90) |
x : 2; %e^x, numer; /* igual a ev(%e^x, numer); */ %$ |
A seguir, caso que altera o valor da variavel global somente para uma expressão
| (%i94) |
fpprec; /* no. de digitos atual */ bfloat(%pi); /* %pi em ponto flutuante */ bfloat(%pi),fpprec=32; /* somente esta saída, com 32 digitos */ fpprec; |
7 Um pouco mais de equações
O rhs(expressao) retorn 0 quando expressão não é equação e lhs(expressao) retorna a própria expressão quando ele não é equação. Assim, funções que recebem equação como parametro, também pode receber expressão e interpretar como expressão=0
| (%i97) |
expr : x^2+x+1; lhs(expr); rhs(expr); |
| (%i99) | solve('(2*x^2+x+1), 'x); /* será interpretado como 2*x^2+x+1=0 */ %$ |
| (%i101) |
load(implicit_plot)$ /* será interpretado como x^2+y^2-1=0 */ wximplicit_plot('(x^2+y^2-1),['x,-2,2],['y,-2,2]); |
\[\mathrm{\tt (\%o101) }\quad \]
rhs() e lhs() funciona também para definiçoes das funções
Definicao da funcao é obtido pelo fundef()
| (%i105) |
f(x) := x^2+1; expr1 : rhs(fundef(f)); fname : op(lhs(fundef(f))); vars : args(lhs(fundef(f))); |
8 Decompondo expressões
As vezes, precisamos decompor uma expressão para manipulação. Dado uma expressão, op(expr) e args(expr) retornam operador e seus arguentos respectivamente. No caso de f(x), f é operador e x e argumento.
| (%i108) |
expr : 2*x^2+cos(x)+1; op(expr); args(expr); |
| (%i111) |
A : matrix([a,b],[c,d]); op(A); /* operador principal */ /* convertendo para lista de lista */ args(A); |
Para obter operador e parte de seus argumentos,
poderá usar part(expr, i) ou inpart(expr, i)
Quando i=0, retorna o operador e i diferente de zero,
part retorna i-ésimo argumento, e
inpart retorna i-ésimo argumento da sua representação interna
que difere de como será mostrado (por exemplo, na soma e no produto,
a ordem é de trás para frente).
inpart é mais rápida que part.
| (%i117) |
expr : 2*x^2+cos(x)+1; inpart(expr,0); /* igual a op(expr); */ part(expr,1);/* igual a args(expr)[2]; */ %$ inpart(expr,1);/* igual a args(expr)[length(expr)+1-2]; */ %$ |
Para saber se seu argumento é composta, poderá usar o atom() atom() retorna true se não por composta (átomo). O átomo pode ser símbolo ou número. numberp() verifica se é número
| (%i123) |
expr : 'x+1; args(expr); atom(inpart(expr,1)); numberp(inpart(expr,1)); atom(inpart(expr,2)); numberp(inpart(expr,2)); |
substpart() e substinpart() substitui uma parte da expressão Ordem de acesso é mesmo de part e inpart respectivamente
| (%i127) |
expr : a+ b + c; substinpart("*", expr, 0); /* trocar some pelo produto */ A : matrix([a, b], [c, d]); /* trocar array por [, convertendo para lista da lista mesmo efeito de args(A) */ substinpart("[", A, 0); |
9 Gravando gráfico no arquivo
Para gravar gráfico feito pela família plot
(plot2d, plot3d, coutour_plot, implicit_plot),
para o arquivo em vez de mostrar na tela, use a versão
sem o wx e coloque a opção [pdf_file, arquivo]
onde arquivo é o nome do arquivo.
Para que ele grave na pasta corrente,
coloque "./" no começo do nome.
| (%i129) |
load(implicit_plot)$ implicit_plot('x^2+'y^2=1,['x,-1.5, 1.5],['y,-1.5, 1.5], [pdf_file,"./part02_grafico.pdf"] ); |
Para gráfico feito pelo draw/draw2d/draw3d/drawdf,
use o terminal para configurar formato de saída e
file_name para indicar o nome do arquivo.
A extensão será colocado automaticamente.
Também use a versao sem o wx.
| (%i131) |
load(draw)$ draw3d(implicit('(x^2+y^2+z^2=1),'x,-1.2,1.2,'y,-1.2,1.2,'z,-1.2,1.2), surface_hide = true, proportional_axes='xyz, terminal = 'pdf, file_name="./part02_grafico3d") $ |
| (%i133) |
load(drawdf); drawdf(['y,-'x],['x,-1,1], ['y,-1,1],proportional_axes = 'xy, terminal = 'pdf, file_name="./part02_grafico2"); |
10 Recursos extendidos de wxmaxima
Wxmaxima tem algunas extensões de maxima.
Note que, ao usar extensões do wxmaxima,
o código não pode ser executado fora dela, como no xmaxima
ou no console do maxima.
Uma delas e a versão wx do plot, draw e histogram que permitem manter gráficos
dentro da área de trabalho do wxmaxima, apesar dele perder a iteratividade
(dar zoom, rotacionar, etc).
Na versão wx do plot/draw/histogram, etc, o tamanho do desenho é controlado
pelo wxplot_size.
| (%i138) |
load("draw"); wxplot_size:[1200,800]; wxplot2d(sin('x), ['x,0,3*%pi])$ wxplot_size:[600,400]; /* restaurando o valor padrao */ %$ |
\[\mathrm{\tt (\%o137) }\quad [600,400]\]
Para tera valor novo somente no plot atual, coloque depois do plot, separado pela virgula
| (%i140) |
kill(x); wxplot2d(sin('x), ['x,0,3*%pi]),wxplot_size:[1200,800]$ |
Outro recurso extendido do wxmaxima é animação.
os comandos wxanimate_draw()
e wxanimate_draw3d() geram animações usando sintaxe
similar ao do draw()
Clicando no botão direito sobre a animação,
poderá salvar (requer imagemagick) ou iniciar animação.
wxanimate_framerate serve para controlar o frame por segundo.
| (%i141) |
wxanimate_draw( /* variável da animação */ f, /* valores da variável da animação */ makelist(i,i,1,10), /* parametros do draw2d() */ title=concat("f=",f,"Hz"), explicit(sin(2*%pi*f*'x), 'x,0,1), grid=true ), wxanimate_framerate=6$ |
A animação 3d é feito pelo animate_draw3d
| (%i142) |
wxanimate_draw3d( /* variável da animação */ a, /* valores da variável da animação */ makelist(i,i,1,10), /* parametros do draw3d() */ title=concat("a=",a), surface_hide = true, explicit(sin(2*%pi*a*'x*'y), 'x,0,1,'y,0,1), grid=true ), wxanimate_framerate=6$ |
Para usar parâmetros similar a plot2d(), poderá usar o wxanimate()
ele não tem a versão 3d
Note que nas animações, se passar um inteiro n no segundo parametro,
será equivalente a lista de 1 a n que é makelist(i,i,1,n)
| (%i143) |
wxanimate(a, 10, sin(%pi*a*'x), ['x,-1,1], ['y,-2,2]), wxanimate_framerate=6; |
\[\mathrm{\tt (\%o143) }\quad \]
Para versões antigas do wxmaxima, eram with_slider,
o que continua existindo nas versões atuais.
Recomendo o uso da versão animate para maior clareza do que
estará gerando.
with_slider() → equivalente a wxanimate()
with_slider_draw() → equivalente a wxanimate_draw()
with_slider_draw3d() → equivalente a wxanimate_draw3d()
11 Registrando atividades (console de maxima)
Quando executa o maxima dentro do wxmmaxima,
não é necessário ter registro de atividades,
pois basta salvar a área de trabalho do mesmo,
mas quando executa diretamente no maxima via comando de linha,
pode desejar que crie o registro de atividades que terão
os comandos executados para uso posterior.
O registro de atividades inicia com writefile() e encerra com closefile()
Se quer acrescentar no arquivo que já existe (continuar o registro),
use appendfile() em vez de writefile().
Se resolveu gravar a sessão depois de ter feito várias coisas,
não se desespere.
Após o writefile() ou appendfile(), execute o playback()
que exibirá as entradas e saidas anteriormente executadas pelo maxima.
| (%i147) |
/* só funcionará dentro do console de maxima */ writefile("part02_diario.txt"); y : 'x^2+1; dy : diff(y, 'x); closefile(); |
Note que writefile()/closefile() só funciona no console do maxima.
No wxmaxima ou no xmaxima, ele apenas criará um arquivo vazio.
Portanto, no wxmaxima/xmaxima, use a sua interface gráfica para
gravar para arquivo, o trabalho feito dentro dele.
Diferente de wxmaxima, o xmaxima não perguntará se quer salvar
a sessão quando fechar. Portanto, fiquem atentos.
O arquivo de atividades gerado pelo writefile() não pode ser executado
no maxima, pois misturam entrada e saida.
Ele serve para ver as atividades e não para criar script maxima.
Assim, é recomendável que use o maxima dentro de xmaxima ou wxmaxima na
qual podem salvar a sessão que permite ser executado novamente.