Página Web do Sadao Massago

Página de Maxima

\( \DeclareMathOperator{\abs}{abs} \)

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 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 */ %$
\[\mathrm{\tt (\%o1) }\quad {{\left( x\cdot y\right) }^{n}}\]\[\mathrm{\tt (\%o2) }\quad \mathit{done}\]\[\mathrm{\tt (\%o3) }\quad {{x}^{n}}\cdot {{y}^{n}}\]\[\mathrm{\tt (\%o4) }\quad \mathit{done}\]

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);
\[\mathrm{\tt (\%o6) }\quad \left| x\right| \]\[\mathrm{\tt (\%o7) }\quad [x>=0]\]\[\mathrm{\tt (\%o8) }\quad x\]\[\mathrm{\tt (\%o9) }\quad [x>=0]\]\[\mathrm{\tt (\%o10) }\quad [x<=0]\]\[\mathrm{\tt (\%o11) }\quad -x\]\[\mathrm{\tt (\%o12) }\quad [0>=x]\]\[\mathrm{\tt (\%o13) }\quad [\mbox{true}]\]

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));
\[\mathrm{\tt (\%o14) }\quad \mbox{false}\]\[\mathrm{\tt (\%o15) }\quad \mbox{true}\]\[\mathrm{\tt (\%o16) }\quad \mbox{true}\]

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);
\[\mathrm{\tt (\%o17) }\quad \mathit{done}\]\[\mathrm{\tt (\%o18) }\quad \mbox{false}\]\[\mathrm{\tt (\%o19) }\quad [\mathrm{kind}\left( n,\mathit{integer}\right) ]\]\[\mathrm{\tt (\%o20) }\quad [database\,info,\mathrm{kind}\left( n,\mathit{integer}\right) ]\]

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);
\[\mathrm{\tt (\%o21) }\quad [\mathrm{notequal}\left( n,-1\right) ]\]\[\mathrm{\tt (\%o22) }\quad \frac{{{x}^{n+1}}}{n+1}\]\[\mathrm{\tt (\%o23) }\quad [\mbox{true}]\]

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);
\[\mathrm{\tt (\%o24) }\quad \mathit{done}\]\[\mathrm{\tt (\%o25) }\quad {{x}^{2}}+1\]\[\mathrm{\tt (\%o26) }\quad \mathrm{f}\left( x\right) :=\mathit{expr}\]\[\mathrm{\tt (\%o27) }\quad \mathrm{g}\left( x\right) :={{x}^{2}}+1\]\[\mathrm{\tt (\%o28) }\quad 0\]\[\mathrm{\tt (\%o29) }\quad {{x}^{2}}+1\]\[\mathrm{\tt (\%o30) }\quad 2\]

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);
\[\mathrm{\tt (\%o31) }\quad {{x}^{2}}+x+1\]\[\mathrm{\tt (\%o32) }\quad \mathrm{g}\left( 'x\right) :=2\cdot x+1\]\[\mathrm{\tt (\%o33) }\quad 0\]\[\mathrm{\tt (\%o34) }\quad 3\]

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]);
\[\mathrm{\tt (\%o35) }\quad \mathrm{soma}\left( [L]\right) :=\mathrm{apply}\left( +,L\right) \]\[\mathrm{\tt (\%o36) }\quad \mathrm{soma\_lista}\left( L\right) :=\mathrm{apply}\left( +,L\right) \]\[\mathrm{\tt (\%o37) }\quad x+a+1\]\[\mathrm{\tt (\%o38) }\quad x+a+1\]
(%i42) f(x) := x^2+1;
g(x,y) := x^2+y^2;
apply(f, [1]);
apply(g, [1, 2]);
\[\mathrm{\tt (\%o39) }\quad \mathrm{f}\left( x\right) :={{x}^{2}}+1\]\[\mathrm{\tt (\%o40) }\quad \mathrm{g}\left( x,y\right) :={{x}^{2}}+{{y}^{2}}\]\[\mathrm{\tt (\%o41) }\quad 2\]\[\mathrm{\tt (\%o42) }\quad 5\]

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 (\%o43) }\quad \mathrm{f}\left( x\right) :={{x}^{2}}\]\[\mathrm{\tt (\%o44) }\quad 0\]\[\mathrm{\tt (\%o45) }\quad 1\]\[\mathrm{\tt (\%o46) }\quad 10\]\[\mathrm{\tt (\%o47) }\quad \frac{1}{10}\]\[\mathrm{\tt (\%o48) }\quad [0,\frac{1}{10},\frac{1}{5},\frac{3}{10},\frac{2}{5},\frac{1}{2},\frac{3}{5},\frac{7}{10},\frac{4}{5},\frac{9}{10},1]\]\[\mathrm{\tt (\%o49) }\quad [0,\frac{1}{100},\frac{1}{25},\frac{9}{100},\frac{4}{25},\frac{1}{4},\frac{9}{25},\frac{49}{100},\frac{16}{25},\frac{81}{100},1]\]\[\mathrm{\tt (\%t50) }\quad \]  (Graphics) \[\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;
\[\mathrm{\tt (\%o51) }\quad [1,2,3]\]\[\mathrm{\tt (\%o52) }\quad [1,2,3]\]
(%i56) a : 1;
b : -1;
[a, b] : [b, a]; /* trocando valores */  %$
\[\mathrm{\tt (\%o53) }\quad 1\]\[\mathrm{\tt (\%o54) }\quad -1\]\[\mathrm{\tt (\%o55) }\quad [-1,1]\]

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)] */  %$
\[\mathrm{\tt (\%o57) }\quad [2,4,6,8,10]\]\[\mathrm{\tt (\%o58) }\quad 2\]\[\mathrm{\tt (\%o59) }\quad 10\]

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);
\[\mathrm{\tt (\%o61) }\quad [2,4,6,8,10]\]\[\mathrm{\tt (\%o62) }\quad [1,2,4,6,8,10]\]\[\mathrm{\tt (\%o63) }\quad [2,4,6,8,10,1]\]\[\mathrm{\tt (\%o64) }\quad [2,4,6,8,10,2,4,6,8,10]\]

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 */  %$
\[\mathrm{\tt (\%o65) }\quad \mathit{done}\]\[\mathrm{\tt (\%o66) }\quad \begin{pmatrix}1 & 2\cr 3 & 4\end{pmatrix}\]\[\mathrm{\tt (\%o67) }\quad [x,y]\]\[\mathrm{\tt (\%o68) }\quad \begin{pmatrix}2\cdot y+x\cr 4\cdot y+3\cdot x\end{pmatrix}\]\[\mathrm{\tt (\%o69) }\quad \begin{pmatrix}3\cdot y+x & 4\cdot y+2\cdot x\end{pmatrix}\]
(%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 */  %$
\[\mathrm{\tt (\%o71) }\quad \begin{pmatrix}1 & 2\cr 3 & 4\end{pmatrix}\]\[\mathrm{\tt (\%o72) }\quad [1,2]\]\[\mathrm{\tt (\%o73) }\quad \begin{pmatrix}0\cr \frac{1}{2}\end{pmatrix}\]\[\mathrm{\tt (\%o74) }\quad \begin{pmatrix}1\cr 2\end{pmatrix}\]

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 */  %$
\[\mathrm{\tt (\%o76) }\quad /usr/share/maxima/5.38.0/share/matrix/eigen.mac\]\[\mathrm{\tt (\%o77) }\quad [1,i]\]\[\mathrm{\tt (\%o78) }\quad [3,1]\]\[\mathrm{\tt (\%o79) }\quad i+3\]\[\mathrm{\tt (\%o80) }\quad 3-i\]

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;
\[\mathrm{\tt (\%o82) }\quad x\]\[\mathrm{\tt (\%o83) }\quad 5\]\[\mathrm{\tt (\%o84) }\quad 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);
\[\mathrm{\tt (\%o85) }\quad 2\]\[\mathrm{\tt (\%o86) }\quad {{e}^{2}}\]\[\mathrm{\tt (\%o87) }\quad 7.38905609893065\]

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); */  %$
\[\mathrm{\tt (\%o88) }\quad 2\]\[\mathrm{\tt (\%o89) }\quad 7.38905609893065\]

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;
\[\mathrm{\tt (\%o91) }\quad 16\]\[\mathrm{\tt (\%o92) }\quad 3.141592653589793b0\]\[\mathrm{\tt (\%o93) }\quad 3.1415926535897932384626433832795b0\]\[\mathrm{\tt (\%o94) }\quad 16\]

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);
\[\mathrm{\tt (\%o95) }\quad 7\]\[\mathrm{\tt (\%o96) }\quad 7\]\[\mathrm{\tt (\%o97) }\quad 0\]
(%i99) solve('(2*x^2+x+1), 'x); /* será interpretado como 2*x^2+x+1=0 */  %$
\[\mathrm{\tt (\%o98) }\quad [x=-\frac{\sqrt{7}\cdot i+1}{4},x=\frac{\sqrt{7}\cdot i-1}{4}]\]
(%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 (\%t101) }\quad \]  (Graphics) \[\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)));
\[\mathrm{\tt (\%o102) }\quad \mathrm{f}\left( x\right) :={{x}^{2}}+1\]\[\mathrm{\tt (\%o103) }\quad {{x}^{2}}+1\]\[\mathrm{\tt (\%o104) }\quad f\]\[\mathrm{\tt (\%o105) }\quad [x]\]

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);
\[\mathrm{\tt (\%o106) }\quad \mathrm{cos}\left( 2\right) +9\]\[\mathrm{\tt (\%o107) }\quad +\]\[\mathrm{\tt (\%o108) }\quad [\mathrm{cos}\left( 2\right) ,9]\]
(%i111) A : matrix([a,b],[c,d]);
op(A); /* operador principal */
/* convertendo para lista de lista */
args(A);
\[\mathrm{\tt (\%o109) }\quad \begin{pmatrix}-1 & [1,2]\cr c & d\end{pmatrix}\]\[\mathrm{\tt (\%o110) }\quad \mathit{matrix}\]\[\mathrm{\tt (\%o111) }\quad [[-1,[1,2]],[c,d]]\]

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]; */  %$
\[\mathrm{\tt (\%o112) }\quad \mathrm{cos}\left( 2\right) +9\]\[\mathrm{\tt (\%o113) }\quad +\]\[\mathrm{\tt (\%o114) }\quad \mathrm{cos}\left( 2\right) \]\[\mathrm{\tt (\%o116) }\quad 9\]

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));
\[\mathrm{\tt (\%o118) }\quad x+1\]\[\mathrm{\tt (\%o119) }\quad [x,1]\]\[\mathrm{\tt (\%o120) }\quad \mbox{true}\]\[\mathrm{\tt (\%o121) }\quad \mbox{true}\]\[\mathrm{\tt (\%o122) }\quad \mbox{true}\]\[\mathrm{\tt (\%o123) }\quad \mbox{false}\]

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);
\[\mathrm{\tt (\%o124) }\quad [c,c+1]\]\[\mathrm{\tt (\%o125) }\quad c\cdot \left( c+1\right) \]\[\mathrm{\tt (\%o126) }\quad \begin{pmatrix}-1 & [1,2]\cr c & d\end{pmatrix}\]\[\mathrm{\tt (\%o127) }\quad [[-1,[1,2]],[c,d]]\]

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"] );
\[\mathrm{\tt (\%o129) }\quad \mathit{done}\]

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") $
\[\mbox{}\\\mbox{Loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/grcommon.o}\mbox{}\\\mbox{Finished loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/grcommon.o}\mbox{}\\\mbox{Loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/gnuplot.o}\mbox{}\\\mbox{Finished loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/gnuplot.o}\mbox{}\\\mbox{Loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/vtk.o}\mbox{}\\\mbox{Finished loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/vtk.o}\mbox{}\\\mbox{Loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/picture.o}\mbox{}\\\mbox{Finished loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/draw/picture.o}\]
(%i133) load(drawdf);
drawdf(['y,-'x],['x,-1,1], ['y,-1,1],proportional_axes = 'xy,
 terminal = 'pdf,
 file_name="./part02_grafico2");
\[\mathrm{\tt (\%o132) }\quad /usr/share/maxima/5.38.0/share/diffequations/drawdf.mac\]\[\mathrm{\tt (\%o133) }\quad 0\]

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 (\%o134) }\quad /usr/share/maxima/5.38.0/share/draw/draw.lisp\]\[\mathrm{\tt (\%o135) }\quad [1200,800]\]\[\mathrm{\tt (\%t136) }\quad \]  (Graphics) \[\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]$
\[\mathrm{\tt (\%o139) }\quad \mathit{done}\]\[\mathrm{\tt (\%t140) }\quad \]  (Graphics)

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$
\[\mathrm{\tt (\%t141) }\quad \] Animated Diagram

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$
\[\mathrm{\tt (\%t142) }\quad \] Animated Diagram

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 (\%t143) }\quad \] Animated Diagram \[\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) /* funcionará dentro do console de maxima */
writefile("part02_diario.txt");
y : 'x^2+1;
dy : diff(y, 'x);
closefile();
\[\mbox{}\\\mbox{Starts dribbling to part02\_diario.txt (2018/1/5, 17:32:55).}\mbox{}\\\mbox{NIL}\]\[\mathrm{\tt (\%o144) }\quad \mathit{done}\]\[\mathrm{\tt (\%o145) }\quad {{x}^{2}}+1\]\[\mathrm{\tt (\%o146) }\quad 2\cdot x\mbox{}\\\mbox{Finished dribbling to part02\_diario.txt.}\mbox{}\\\mbox{NIL}\]\[\mathrm{\tt (\%o147) }\quad \mathit{done}\]

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.


Created with wxMaxima.