Página Web do Sadao Massago

Página de Maxima

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

Lendo e gravando arquivo no 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 codigos e comentarios F5 abre o campo de comando F6 abre o campo de comentario (texto)
Estes o eoutros comandos estão no menu "cell".
F1 abre a ajuda do Maxima. Se o cursor estiver sobre a palavra, procurara por esta paravra na ajuda.

Assume que já leu o "part01_intro.wxm" ("Introdução ao Maxima")

(%i1) /* limpando a memória */
kill(all);
reset();
\[\mathrm{\tt (\%o0) }\quad \mathit{done}\]\[\mathrm{\tt (\%o1) }\quad [\%,\_,\mathit{\_\_},\mathit{lispdisp},\mathit{tr-unique},\mathit{labels}]\]

1 Escrevendo uma expressão no arquivo

Para que um programa externo possa obter a expressão final processado pelo maxima, poderá gravar no arquivo texto.
Para gravar uma expressão no formato maxima, usa-se o stringout()

(%i5) f('x,'y,'z) := 'x^2+'y^2+'z^2;
load("linearalgebra");
jacobian([f('x,'y,'z)], ['x, 'y, 'z]);
stringout("part05_meu_gradiente.mac", %);
\[\mathrm{\tt (\%o2) }\quad \mathrm{f}\left( 'x,'y,'z\right) :={{'x}^{2}}+{{'y}^{2}}+{{'z}^{2}}\]\[\mathrm{\tt (\%o3) }\quad /usr/share/maxima/5.38.0/share/linearalgebra/linearalgebra.mac\]\[\mathrm{\tt (\%o4) }\quad \begin{pmatrix}2\cdot x & 2\cdot y & 2\cdot z\end{pmatrix}\]\[\mathrm{\tt (\%o5) }\quad /home/sadao/MEGA/core/maxima/mactutor/part05\_meu\_gradiente.mac\]

Note que no stringout(), a expressão será gravada no sintaxe do maxima, tendo ";" no final do comando. Para gravar somentente a expressão, por exemplo, deverá abrir o arquivo desejado, gravar com printf, e fechar.
Note que o print() imprime na tela, mas não no arquivo.
O comando printf() tem muito mais recursos e permite imprimir tanto na tela como no arquivo.

(%i10) arq : openw("part05_minha_funcao.txt");
/* "~a" especifica que é saida igual a do maxima.
 sobre printf que efetua a saída formatada,
 veja o manual de maxima */
expr : x^2+1;
printf(true, "Será gravado: ~a", expr); /* na tela */
printf(arq, "~a", expr); /* no arquivo */
close(arq);
\[\mathrm{\tt (\%o6) }\quad \mathit{Stream [CHARACTER]}\]\[\mathrm{\tt (\%o7) }\quad {{x}^{2}}+1\mbox{}\\\mbox{Será gravado: x\textasciicircum2+1}\]\[\mathrm{\tt (\%o8) }\quad \mbox{false}\]\[\mathrm{\tt (\%o9) }\quad \mbox{false}\]\[\mathrm{\tt (\%o10) }\quad \mbox{true}\]

openw() abre o arquivo para gravação. ele retorna uma referência na qual deverá ser recebido por alguma variável. printf() imprime a saída formatada no arquivo. O seu primeiro parâmetro pode ser true ou referência para arquivos. Se for true, efetuará a saída na tela Após imprimir dados no arquivo, não esqueça de fechar o arquivo com close()
Para ler do arquvio, troque openw() por openr()
O "~a" no segundo parâmetro do printf() significa que o terceiro parâmetro é impresso como a saída do maxima da expressão. terceiro parâmetro e a expresão que queremos imprimir.
Se já usou o printf() do C, não terá dificuldade em entender o funcionamento do printf() do maxima, apesar do caracter de escape no C eh "\" e no maxima e "~".
Para mais sobre formatação, veja a ajuda sobre printf

(%i17) arq : openr("part05_minha_funcao.txt");
/* para que x seja símbolo, sem destruir valor de x, foi
  declarado local. Para isso, coloca-se dentro do block */

/* uma linha do arq e evalua a expressão.
  Ele será atribuido para expressao de f(x) com o define */
block([x],
 /* define(f(x), eval_string(readline(arq))) */
   define(f(x), parse_string(readline(arq)))
);
close(arq);


df : diff(f('x), 'x);

arq : openw("part05_minha_funcao_derivada.txt");
printf(arq, "~a", df);
close(arq);
\[\mathrm{\tt (\%o11) }\quad \mathit{Stream [CHARACTER]}\]\[\mathrm{\tt (\%o12) }\quad \mathrm{f}\left( x\right) :={{x}^{2}}+1\]\[\mathrm{\tt (\%o13) }\quad \mbox{true}\]\[\mathrm{\tt (\%o14) }\quad 2\cdot x\]\[\mathrm{\tt (\%o15) }\quad \mathit{Stream [CHARACTER]}\]\[\mathrm{\tt (\%o16) }\quad \mbox{false}\]\[\mathrm{\tt (\%o17) }\quad \mbox{true}\]

2 Lendo e escrevendo tabela numérica em maxima

Para que um programa externo comunique com maxima, costumamos utilizar o arquivo texto.
Para ler e escrever a tabela numérica de forma eficiente, usaremos o pacote numericalio

(%i37) load("numericalio");

/* abre o arquivo de entrada */
arq : openr("part05_minha_funcao.txt");
/* para que x seja símbolo, sem destruir valor de x, foi
  declarado local. Para isso, coloca-se dentro do block */

/* uma linha do arq e evalua a expressão.
  Ele será atribuido para expressao de f(x) com o define */
block([x],
 /* define(f(x), eval_string(readline(arq))) */
   define(f(x), parse_string(readline(arq)))
);
close(arq); /* fecha o arquivo */

/* tabelando x e f(x) */
a : 0;
b : 1;
N : 10;
h : (b-a)/N;
x : makelist(a+i*h, i, 0, N);
y : map(f, x);

/* x e y como ponto flutuante */
x : map(lambda([x], ev(x, numer)), x);
y : map(lambda([x], ev(x, numer)), y);

/* gravando */
/* abre o arquivo de saía */
arq : openw("part05_minha_tabela.txt");
write_data(transpose(matrix(x,y)), arq); /* grava dados */
close(arq); /* fecha o arquivo */

/* mostrando o conteúdo do arquivo na tela para confirmação */
printfile("part05_minha_tabela.txt");

/* lendo o que gravou */
arq : openr("part05_minha_tabela.txt");
tab : transpose(read_matrix(arq));
close(arq);

/* desenhando */
wxplot2d([discrete, tab[1], tab[2] ]);
\[\mbox{}\\\mbox{Loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/numericalio/encode-decode-float.o}\mbox{}\\\mbox{Finished loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/numericalio/encode-decode-float.o}\mbox{}\\\mbox{Loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/numericalio/numericalio.o}\mbox{}\\\mbox{Finished loading /home/sadao/.maxima/binary/5\_38\_0/gcl/GCL\_2\_6\_12/share/numericalio/numericalio.o}\]\[\mathrm{\tt (\%o18) }\quad /usr/share/maxima/5.38.0/share/numericalio/numericalio.mac\]\[\mathrm{\tt (\%o19) }\quad \mathit{Stream [CHARACTER]}\]\[\mathrm{\tt (\%o20) }\quad \mathrm{f}\left( x\right) :={{x}^{2}}+1\]\[\mathrm{\tt (\%o21) }\quad \mbox{true}\]\[\mathrm{\tt (\%o22) }\quad 0\]\[\mathrm{\tt (\%o23) }\quad 1\]\[\mathrm{\tt (\%o24) }\quad 10\]\[\mathrm{\tt (\%o25) }\quad \frac{1}{10}\]\[\mathrm{\tt (\%o26) }\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 (\%o27) }\quad [1,\frac{101}{100},\frac{26}{25},\frac{109}{100},\frac{29}{25},\frac{5}{4},\frac{34}{25},\frac{149}{100},\frac{41}{25},\frac{181}{100},2]\]\[\mathrm{\tt (\%o28) }\quad [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]\]\[\mathrm{\tt (\%o29) }\quad [1,1.01,1.04,1.09,1.16,1.25,1.36,1.49,1.64,1.81,2]\]\[\mathrm{\tt (\%o30) }\quad \mathit{Stream [CHARACTER]}\]\[\mathrm{\tt (\%o31) }\quad \mathit{done}\]\[\mathrm{\tt (\%o32) }\quad \mbox{true}\mbox{}\\\mbox{0 1}\mbox{}\\\mbox{0.1 1.01}\mbox{}\\\mbox{0.2 1.04}\mbox{}\\\mbox{0.3 1.09}\mbox{}\\\mbox{0.4 1.16}\mbox{}\\\mbox{0.5 1.25}\mbox{}\\\mbox{0.6 1.36}\mbox{}\\\mbox{0.7 1.49}\mbox{}\\\mbox{0.8 1.64}\mbox{}\\\mbox{0.9 1.81}\mbox{}\\\mbox{1 2}\]\[\mathrm{\tt (\%o33) }\quad part05\_minha\_tabela.txt\]\[\mathrm{\tt (\%o34) }\quad \mathit{Stream [CHARACTER]}\]\[\mathrm{\tt (\%o35) }\quad \begin{pmatrix}0 & 0.1 & 0.2 & 0.3 & 0.4 & 0.5 & 0.6 & 0.7 & 0.8 & 0.9 & 1\cr 1 & 1.01 & 1.04 & 1.09 & 1.16 & 1.25 & 1.36 & 1.49 & 1.64 & 1.81 & 2\end{pmatrix}\]\[\mathrm{\tt (\%o36) }\quad \mbox{true}\]\[\mathrm{\tt (\%t37) }\quad \]  (Graphics) \[\mathrm{\tt (\%o37) }\quad \]

No exemplo anterior, a primeira parte lê a expressão válida de maxima, evalua ele e define a função.
Na segunda parte, cria a tabela e grava no arquivo
Note que, para abrir arquivo de leitura, usa-se o openr() e para a escrita, openw(). Em ambos casos, fecha o arquivo com o clese().
readline() do pacote stringproc lê uma linha do arquivo de texto.

A abertura de arquivo pode ser feito com openr() → para leitura openw() → para gravar (se existir, será substituido) opena() continua no arquivo existente (sem apagar, acrescenta os dados)
Para gravar, usa-se o printf().
Para lei uma linha, usa-se o readline()
Para ler/gravar estruturas prontas, como lista e matriz, use o pacote numericalio
Para fechar, usa-se o close().

3 Redirecionando a saida pelo with_stdout()

Para saída rapida de algum dado no arquivo, poderá usar o with_stdout que redireciona a saida do print e similar para o arquivo. with_stdout(arquivo, expr, ..., expr) executará os comandos expr1, ..., exprn em sequencia e grava a sua saída na tela para o arquivo.
Para gravacao mais complexa, opte em usar o fluxo openw()/prontf()/close()
Atenção: Para que saída seja arquivo texto convencional sem formatação, Configure display2d como false.

(%i48) load(distrib); /* para random_normal */
load(lsquares); /* para mínimos quadrados */

kill(a,b);

/* gera dados e grava no arquivo y = x^2 + ruido */
with_stdout("part05_with_sdtout.txt",
   set_random_state (make_random_state (654321)), /* inicia o número aleatório */
   for i:0 thru 10 do
     print(i, ev(random_normal(i^2, 2.0), numer)  ) /* valor em ponto flutuante */
), display2d:false$ /* display2d : false faz com que imprima sem formatação */

/* mostra o conteúdo do arquivo na tela */
printfile ("part05_with_sdtout.txt")$

/* lendo o que gravou */
arq : openr("part05_with_sdtout.txt")$
dado : read_matrix(arq)$
close(arq);

/* ajuste de mínimos quadrados:
  Obtem os valores de a e b, para y = a*x^2 + b */
sol : lsquares_estimates(dado, ['x, 'y], 'y = 'a*'x^2 + 'b, ['a, 'b] )$
[a, b] : map(rhs, first(sol)), numer; /* lado diretio da equação */

/* desenhando */
/* tab : transpose(dado)$
wxplot2d([a*x^2+b, [discrete, tab[1], tab[2] ] ],
   [x,0,10], [style, lines, points ], [legend, "ajuste", "dado"])$
*/

wxplot2d([a*'x^2+b, [discrete, args(dado) ] ],
   ['x,0,10], [style, lines, points ], [legend, "ajuste", "dado"])$
\[\mathrm{\tt (\%o38) }\quad /usr/share/maxima/5.38.0/share/distrib/distrib.mac\]\[\mathrm{\tt (\%o39) }\quad /usr/share/maxima/5.38.0/share/lsquares/lsquares.mac\]\[\mathrm{\tt (\%o40) }\quad \mathit{done}\mbox{}\\\mbox{0 1.419061919370969 }\mbox{}\\\mbox{1 -1.196122044218204 }\mbox{}\\\mbox{2 4.407162369144823 }\mbox{}\\\mbox{3 8.823827676238203 }\mbox{}\\\mbox{4 17.19956007466073 }\mbox{}\\\mbox{5 20.70791559250069 }\mbox{}\\\mbox{6 35.67117018424332 }\mbox{}\\\mbox{7 48.57088423690455 }\mbox{}\\\mbox{8 67.65251329657957 }\mbox{}\\\mbox{9 80.62684849788265 }\mbox{}\\\mbox{10 100.4756914144889 }\]\[\mathrm{\tt (\%o45) }\quad \mbox{true}\]\[\mathrm{\tt (\%o47) }\quad [1.012685953778233,-0.5023253624385163]\]\[\mathrm{\tt (\%t48) }\quad \]  (Graphics)

4 Lendo do console

read(expr1,...,exprn) exibe resultados de expr1,...,exprn no console e lê o dado digitado no console, evalua e retorna. Note que, no wxmaxima, deve pressionar <ctrl><ENTER> en vez de <ENTER> após entrar com o dado.
Quando é executado diretamente pelo maxima ou pelo xmaxima, devera colocar ; ou $  no final, antes de pressionar <ENTER> para que a expressão seja comando maxima valido.
No wxmaxima, deverá pressionar <ctrl><ENTER> em vez do <ENTER> mas ele colocara automaticamente o ";" (assim, ";" nao será necessário)

(%i51) kill(x);
y : read("f(x)=");
wxplot2d(y, [x,-1,1]);
\[\mathrm{\tt (\%o49) }\quad \mathit{done}\mbox{}\\f(x)=x^2;\]\[\mathrm{\tt (\%o50) }\quad {{x}^{2}}\]\[\mathrm{\tt (\%t51) }\quad \]  (Graphics) \[\mathrm{\tt (\%o51) }\quad \]

Para apenas ler, mas sem evaluar, usa-se o readonly() Por exemplo, se tiver valor de x  já definido, read() substitui na expressao fornecida, o que não é a intenção. readonnly() lê a expressão, sem que x seja substituida.

(%i54) x : 1;
y : readonly("f(x)=");
wxplot2d(y, ['x,-1,1]);
\[\mathrm{\tt (\%o52) }\quad 1\mbox{}\\f(x)=x^3;\]\[\mathrm{\tt (\%o53) }\quad {{x}^{3}}\]\[\mathrm{\tt (\%t54) }\quad \]  (Graphics) \[\mathrm{\tt (\%o54) }\quad \]

Para ler matriz do console, usa-se o entermatrix() Cada entrada deve estar com ; ou $.
No wxmaxima, isto não é necessário, mas deve precionar <ctrl><ENTER> em vez de <ENTER>

(%i55) A : entermatrix(2,2);
\[\mbox{}\\\mbox{Is the matrix 1. Diagonal 2. Symmetric 3. Antisymmetric 4. General}Answer 1, 2, 3 or 4 : 1;Row 1 Column 1: 1;Row 2 Column 2: -1;\mbox{}\\\mbox{Matrix entered.}\]\[\mathrm{\tt (\%o55) }\quad \begin{pmatrix}1 & 0\cr 0 & -1\end{pmatrix}\]
Created with wxMaxima.