| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Índice] | [ ? ] |
| 42.1 Introdução a Fluxo de Programa | ||
| 42.2 Definições para Fluxo de Programa |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Índice] | [ ? ] |
Maxima fornece um do para ciclos iterativos, também contruções mais
primitivas tais como go.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Índice] | [ ? ] |
Imprime a pilha de chamadas, que é, a lista de funções que foram chamadas pela função correntemente ativa.
backtrace() imprime toda a pilha de chamadas.
backtrace (n) imprime as n mais recentes chamadas a
funções, incluindo a função correntemente ativa.
backtrace pode ser chamada por um script, uma função, ou a partir da linha de comando interativa
(não somente em um contexto de depuração).
Exemplos:
backtrace() imprime toda a pilha de chamadas.
(%i1) h(x) := g(x/7)$
(%i2) g(x) := f(x-11)$
(%i3) f(x) := e(x^2)$
(%i4) e(x) := (backtrace(), 2*x + 13)$
(%i5) h(10);
#0: e(x=4489/49)
#1: f(x=-67/7)
#2: g(x=10/7)
#3: h(x=10)
9615
(%o5) ----
49
|
backtrace (n) imprime as n mais recentes chamadas a
funções, incluindo a função correntemente ativa.
(%i1) h(x) := (backtrace(1), g(x/7))$
(%i2) g(x) := (backtrace(1), f(x-11))$
(%i3) f(x) := (backtrace(1), e(x^2))$
(%i4) e(x) := (backtrace(1), 2*x + 13)$
(%i5) h(10);
#0: h(x=10)
#0: g(x=10/7)
#0: f(x=-67/7)
#0: e(x=4489/49)
9615
(%o5) ----
49
|
A declaração do é usada para executar iteração. Devido à sua
grande generalidade a declaração do será descrita em duas partes.
Primeiro a forma usual será dada que é análoga à forma que é usada em
muitas outras linguagens de programação (Fortran, Algol, PL/I, etc.); em segundo lugar
os outros recursos serão mencionados.
Existem três variantes do operador especial do que diferem somente por suas
condições de encerramento. São elas:
for Variável: valor_inicial step incremento
thru limite do corpo
for Variável: valor_inicial step incremento
while condition do corpo
for Variável: valor_inicial step incremento
unless condition do corpo
(Alternativamente, o step pode ser dado após a condição de encerramento
ou limite.)
valor_inicial, incremento, limite, e corpo podem ser quaisquer
expressões. Se o incremento for 1 então "step 1" pode ser omitido.
A execução da declaração do processa-se primeiro atribuindo o
valor_inicial para a variável (daqui em diante chamada a
variável de controle). Então: (1) Se a variável de controle excede
o limite de uma especificação thru, ou se a condição de unless for
true, ou se a condição de while for false então o do
será encerrado. (2) O corpo é avaliado. (3) O incremento é adicionado à
variável de controle. O processo de (1) a (3) é executado
repetidamente até que a condição de encerramento seja satisfeita. Pode-se também
dar muitas condições de encerramento e nesse caso o do termina
quando qualquer delas for satisfeita.
Em geral o teste thru é satisfeito quando a variável de controle for
maior que o limite se o incremento for não negativo, ou quando a
variável de controle for menor que o limite se o incremento for negativo.
O incremento e o limite podem ser expressões não numéricas enquanto essa
desigualdade puder ser determinada. Todavia, a menos que o incremento seja
sintaticamente negativo (e.g. for um número negativo) na hora em que a declaração do
for iniciada, Maxima assume que o incremento e o limite serão positivos quando o do for
executado. Se o limite e o incremento não forem positivos, então o do pode não terminar
propriamente.
Note que o limite, incremento, e condição de encerramento são
avaliados cada vez que ocorre um ciclo. Dessa forma se qualquer desses for responsável por
muitos cálculos, e retornar um resultado que não muda durante todas
as execuções do corpo, então é mais eficiente escolher uma
variável para seu valor anterior para o do e usar essa variável na
forma do.
O valor normalmente retornado por uma declaração do é o átomo done.
Todavia, a função
return pode ser usada dentro do corpo para sair da delcaração do prematuramente e dar
a isso qualquer valor desejado.
Note todavia que um return dentro de um do que
ocorre em um block encerrará somente o do e não o block. Note também
que a função go não pode ser usada para sair de dentro de um do dentro de um
block que o envolve.
A variável de controle é sempre local para o do e dessa forma qualquer
variável pode ser usada sem afetar o valor de uma variável com
o mesmo nome fora da declaração do. A variável de controle é liberada
após o encerramento da declaração do.
(%i1) for a:-3 thru 26 step 7 do display(a)$
a = - 3
a = 4
a = 11
a = 18
a = 25
|
(%i1) s: 0$ (%i2) for i: 1 while i <= 10 do s: s+i; (%o2) done (%i3) s; (%o3) 55 |
Note que a condição while i <= 10
é equivalente a unless i > 10 e também thru 10.
(%i1) series: 1$
(%i2) term: exp (sin (x))$
(%i3) for p: 1 unless p > 7 do
(term: diff (term, x)/p,
series: series + subst (x=0, term)*x^p)$
(%i4) series;
7 6 5 4 2
x x x x x
(%o4) -- - --- - -- - -- + -- + x + 1
90 240 15 8 2
|
que fornece 8 termos da série de Taylor para e^sin(x).
(%i1) poly: 0$
(%i2) for i: 1 thru 5 do
for j: i step -1 thru 1 do
poly: poly + i*x^j$
(%i3) poly;
5 4 3 2
(%o3) 5 x + 9 x + 12 x + 14 x + 15 x
(%i4) guess: -3.0$
(%i5) for i: 1 thru 10 do
(guess: subst (guess, x, 0.5*(x + 10/x)),
if abs (guess^2 - 10) < 0.00005 then return (guess));
(%o5) - 3.162280701754386
|
Esse exemplo calcula a raíz quadrada negativa de 10 usando a
iteração de Newton- Raphson um maximum de 10 vezes. Caso o critério de
convergêcia não tenha sido encontrado o valor retornado pode ser done.
Em lugar de sempre adicionar uma quantidade à variável de controle pode-se
algumas vezes desejar alterar isso de alguma outra forma para cada iteração.
Nesse caso pode-se usar next expressão em lugar de step incremento.
Isso fará com que a variável de controle seja escolhida para o
resultado da expressão de avaliação cada vez que o ciclo de repetição for executado.
(%i6) for count: 2 next 3*count thru 20 do display (count)$
count = 2
count = 6
count = 18
|
Como uma alternativa para for Variável: valor ...do... a sintaxe
for Variável from valor ...do... pode ser usada. Isso permite o
from valor ser colocado após o step ou proximo valor ou após a
condição de encerramento. Se from valor for omitido então 1 é usado como
o valor inicial.
Algumas vezes se pode estar interessado em executar uma iteração onde a variável de controle nunca seja usada. Isso é permissível para dar somente as condições de encerramento omitindo a inicialização e a informação de atualização como no exemplo seguinte para para calcular a raíz quadrada de 5 usando uma fraca suposição inicial.
(%i1) x: 1000$ (%i2) thru 20 do x: 0.5*(x + 5.0/x)$ (%i3) x; (%o3) 2.23606797749979 (%i4) sqrt(5), numer; (%o4) 2.23606797749979 |
Se isso for desejado pode-se sempre omitir as condições de encerramento
inteiramente e apenas dar o corpo do corpo que continuará a ser
avaliado indefinidamente. Nesse caso a função return será usada para
encerrar a execução da declaração do.
(%i1) newton (f, x):= ([y, df, dfx], df: diff (f ('x), 'x),
do (y: ev(df), x: x - f(x)/y,
if abs (f (x)) < 5e-6 then return (x)))$
(%i2) sqr (x) := x^2 - 5.0$
(%i3) newton (sqr, 1000);
(%o3) 2.236068027062195
|
(Note que return, quando executado, faz com que o valor corrente de
x seja retornado como o valor da declaração do. O block é encerrado e
esse valor da declaração do é retornado como o valor do block porque o
do é a última declaração do block.)
Uma outra forma de do é disponível no Maxima. A sintaxe é:
for Variável in list end_tests do corpo |
Os elementos de list são quaisquer expressões que irão
sucessivamente ser atribuídas para a variável a cada iteração do
corpo. O teste opcional end_tests pode ser usado para encerrar a execução da
declaração do; de outra forma o do terminará quando a lista for exaurida ou quando
um return for executado no corpo. (De fato, a lista pode ser qualquer
expressão não atômica, e partes sucessivas são usadas.)
(%i1) for f in [log, rho, atan] do ldisp(f(1))$
(%t1) 0
(%t2) rho(1)
%pi
(%t3) ---
4
(%i4) ev(%t3,numer);
(%o4) 0.78539816
|
Avalia expr_1, ..., expr_n uma por uma e
retorna [expr_n] (uma lista) se nenhum erro ocorrer. Se um
erro ocorrer na avaliação de qualquer argumento, errcatch
evita que o erro se propague e
retorna a lista vazia [] sem avaliar quaisquer mais argumentos.
errcatch
é útil em arquivos batch onde se suspeita que um erro possa estar ocorrendo o errcatch
terminará o batch se o erro não for detectado.
Avalia e imprime expr_1, ..., expr_n,
e então causa um retorno de erro para o nível mais alto do Maxima
ou para o mais próximo contendo errcatch.
A variável error é escolhida para uma lista descrevendo o erro.
O primeiro elemento de error é uma seqüência de caracteres de formato,
que junta todas as seqüências de caracteres entre os argumentos expr_1, ..., expr_n,
e os elementos restantes são os valores de quaisquer argumentos que não são seqüências de caracteres.
errormsg() formata e imprime error.
Isso efetivamente reimprime a mais recente mensagem de erro.
Reimprime a mais recente mensagem de erro.
A variável error recebe a mensagem,
e errormsg formata e imprime essa mensagem.
Usado em iterações. Veja do para uma descrição das
facilidades de iteração do Maxima.
é usada dentro de um block para transferir o controle para a declaração
do bloco que for identificada com o argumento para go. Para identificar uma
declaração, coloque antes dessa declaração um argumento atômico como outra declaração no
block. Por exemplo:
block ([x], x:1, loop, x+1, ..., go(loop), ...) |
O argumento para go deve ser o nome de um identificardor aparecendo no mesmo
block. Não se pode usar go para transferir para um identificador em um outro block que não seja
o próprio contendo o go.
A declaração if é usada para execução condicional. A sintaxe
é:
if <condição> then <expr_1> else <expr_2> |
O resultado de uma declaração if será expr_1 se condição for true e
expr_2 de outra forma. expr_1 e expr_2 são quaisquer
expressões Maxima (incluindo declarações if aninhadas), e condição é
uma expressão que avalia para true ou false e é composto de
operadores relacionais e lógicos que são os seguintes:
Operação Símbolo Tipo menor que < infixo relacional menor que <= ou igual a infixo relacional igualdade = (sintática) infixo relacional negação de = # infixo relacional igualdade (valor) equal função relacional negação de notequal igualdade função relacional maior que >= ou igual a infixo relacional maior que > infixo relacional e and infixo lógico ou or infixo lógico não not prefixo lógico |
Retorna uma expressão cujo operador principal
é o mesmo que o das expressões
expr_1, ..., expr_n mas cujas subpartes são os resultados da
aplicação de f nas correspondentes subpartes das expressões. f é ainda
o nome de uma função de n argumentos
ou é uma forma lambda de n argumentos.
maperror - se false fará com que todas as funções mapeadas
(1) parem quando elas terminarem retornando a menor expi se não forem todas as
expi do mesmo comprimento e (2) aplique fn a [exp1, exp2,...]
se expi não forem todas do mesmo tipo de objeto. Se maperror for true
então uma mensagem de erro será dada nas duas instâncias acima.
Um dos usos dessa função é para mapear (map) uma função (e.g. partfrac)
sobre cada termo de uma expressão muito larga onde isso comumente não poderia
ser possível usar a função sobre a expressão inteira devido a uma
exaustão de espaço da lista de armazenamento no decorrer da computação.
(%i1) map(f,x+a*y+b*z);
(%o1) f(b z) + f(a y) + f(x)
(%i2) map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2));
1 1 1
(%o2) ----- - ----- + -------- + x
x + 2 x + 1 2
(x + 1)
(%i3) map(ratsimp, x/(x^2+x)+(y^2+y)/y);
1
(%o3) y + ----- + 1
x + 1
(%i4) map("=",[a,b],[-0.5,3]);
(%o4) [a = - 0.5, b = 3]
|
Retorna true se e somente se expr for tratada pelas rotinas de
mapeamento como um átomo. "Mapatoms" são átomos, números
(incluíndo números racioanais), e variáveis subscritas.
Valor padrão: true
Quando maperror é false, faz com que todas as funções mapeadas, por exemplo
map (f, expr_1, expr_2, ...)) |
(1) parem quando elas terminarem
retornando a menor expi se não forem todas as expi do mesmo
comprimento e (2) aplique f a [expr_1, expr_2, ...] se expr_i não forem todas
do mesmo tipo de objeto.
Se maperror for true então uma ,mensagem de erro
é mostrada nas duas instâncias acima.
Retorna uma lista de aplicações de f em todas as partes das expressões expr_1, ..., expr_n. f é o nome de uma função, ou uma expressão lambda.
maplist difere de map (f, expr_1, ..., expr_n)
que retorna uma expressão com o mesmo operador principal que expr_i tem
(exceto para simplificações e o caso onde map faz um apply).
Valor padrão: true
Quando prederror for true, uma mensagem de erro é mostrada
sempre que o predicado de uma declaração if ou uma função is falha em
avaliar ou para true ou para false.
Se false, unknown é retornado
no lugar nesse caso. O modo prederror: false não é suportado no
código traduzido;
todavia, maybe é suportado no código traduzido.
Veja também is e maybe.
Pode ser usada para sair explicitamente de um bloco, levando
seu argumento. Veja block para mais informação.
Recursivamente aplica f a expr, de cima para baixo. Isso é muito útil quando uma fatoração completa é desejada, por exemplo:
(%i1) exp:(a^2+2*a+1)*y + x^2$
(%i2) scanmap(factor,exp);
2 2
(%o2) (a + 1) y + x
|
Note o caminho através do qual scanmap aplica a dada função factor para as
subexpressões constituintes de expr; se outra forma de expr é apresentada
para scanmap então o resultado pode ser diferente. Dessa forma, %o2 não é
recuperada quando scanmap é aplicada para a forma expandida de exp:
(%i3) scanmap(factor,expand(exp));
2 2
(%o3) a y + 2 a y + y + x
|
Aqui está um outro exemplo do caminho no qual scanmap aplica
recursivamente uma função dada para todas as subexpressões, incluindo expoentes:
(%i4) expr : u*v^(a*x+b) + c$
(%i5) scanmap('f, expr);
f(f(f(a) f(x)) + f(b))
(%o5) f(f(f(u) f(f(v) )) + f(c))
|
scanmap (f, expr, bottomup) aplica f a expr de
baixo para cima. E.g., para f indefinida,
scanmap(f,a*x+b) ->
f(a*x+b) -> f(f(a*x)+f(b)) -> f(f(f(a)*f(x))+f(b))
scanmap(f,a*x+b,bottomup) -> f(a)*f(x)+f(b)
-> f(f(a)*f(x))+f(b) ->
f(f(f(a)*f(x))+f(b))
|
Nesse caso, você pega a mesma resposta em ambos os caminhos.
Avalia expr e descarta o valor retornado para o mais recente
catch. throw é usada com catch como um mecanismo de retorno
não local.
Aplica a função f para cada um dos elementos do produto externo a_1 vezes a_2 ... vezes a_n.
f é para ser o nome de uma função de n argumentos ou uma expressão lambda de n argumentos. Os argumentos a_1, ..., a_n podem ser listas ou não listas. Argumentos listas podem ter diferentes comprimentos. Argumentos outros que não listas são tratados como listas de comprimento 1 para o propósito de construção do produto externo.
O resultado da aplicação de f para o produto externo é organizado como uma lista aninhada. A intensidade do aninhamento é igual ao número de argumentos listas (argumentos outros que não listas não contribuem com um nível de aninhamento). Uma lista de intensidade de aninhamento k tem o mesmo comprimento que o k'ésimo argumento da lista.
outermap avalia seus argumentos.
Veja também map, maplist, e apply.
Exemplos:
(%i1) f (x, y) := x - y$
(%i2) outermap (f, [2, 3, 5], [a, b, c, d]);
(%o2) [[2 - a, 2 - b, 2 - c, 2 - d],
[3 - a, 3 - b, 3 - c, 3 - d], [5 - a, 5 - b, 5 - c, 5 - d]]
(%i3) outermap (lambda ([x, y], y/x), [55, 99], [Z, W]);
Z W Z W
(%o3) [[--, --], [--, --]]
55 55 99 99
(%i4) g: lambda ([x, y, z], x + y*z)$
(%i5) outermap (g, [a, b, c], %pi, [11, 17]);
(%o5) [[a + 11 %pi, a + 17 %pi], [b + 11 %pi, b + 17 %pi],
[c + 11 %pi, c + 17 %pi]]
(%i6) flatten (%);
(%o6) [a + 11 %pi, a + 17 %pi, b + 11 %pi, b + 17 %pi,
c + 11 %pi, c + 17 %pi]
|
| [ << ] | [ >> ] | [Top] | [Contents] | [Índice] | [ ? ] |
This document was generated by root on Outubro, 3 2006 using texi2html 1.76.