[edA-qa mort-ora-y <eda-qa@disemia.com>, Mon, 27 Sep 2004 07:35:36 +0200]:
> Okay, now I get a different error (which I also don't really understand).
>
> (C47) constWalk( raw_org, P, E_S, E_AS, E_BS, E_Org );
> Improper name or value in functional position:
> E_AS j + E_Org
> #0: cw(expr=(E_AS*j+E_Org)[q])
> #1: cw(expr=(E_AS*j+E_Org)[q]-P[q])
> #2: cw(expr=2*(E_S[3]^2+E_S[2]^2+E_S[1]^2)*((E_AS*j+E_Org)[q]-P[q]))
> -- an error. Quitting. To debug this try DEBUGMODE(TRUE);)
The error message is quite clear: the code tries to use E_AS j + E_Org
as a function, which it isn't.
Before explaining the error message, let me stress that constWalk and
cw were not intended as working code but rather as a sketch of how you
might start defining that for yourself (I wouldn't mind if you posted
a polished and working version once it's done). Obviously, a name
like CW is likely to cause clashes; you have found it doesn't handle
arrays; it is quite simplistic; it may be preferable to use symbols
that are guaranteed to be new instead of the constN symbols; it
doesn't handle associative and distributive functions, nor does it
handle impure functions like RANDOM that are not constant even when
all their arguments are. And I am sure there are many other flaws for
you to discover ;)
Look at the code: It is quite clear that it just looks at successive
sub-terms, one at a term (by recursive calls to the auxiliary function
cw()): If we have an atom, the result is either [true, e], if e is
constant, or [false, e] otherwise. If e is not an atom, it is taken
to be a function application, and it is taken to be constant if all
arguments are constant; if so, a new constant is generated and [ true,
new constant ] returned, otherwise [false, expression with any new
constants substituted]. The way of combining the new arguments with
the original function is to use APPLY.
In your case, you have the term (E_AS*j+E_Org)[q], which is not atomic
but uses (E_AS*j+E_Org) as an array, q as an index. I do not know
whether this is legal in Maxima - I have never had any use for arrays
so far at all. At any rate, if this is to work, you have to make sure
that APPLY is replaced by ARRAYAPPLY by checking e. One way would be
to note the following:
,----
| (C36) ?pprint(foo[bar]);
|
|
| ((|$foo| SIMP ARRAY) |$bar|)
| (D36) FALSE
| (C37) ?pprint(foo(bar));
|
|
| ((|$foo| SIMP) |$bar|)
| (D37) FALSE
`----
So you could check for the presence of 'ARRAY in the CAR of the Lisp
expression; the best I have found is
has_an_array_subscript(expr) :=
not(?atom(?member(
?find\-symbol(?subseq(?symbol\-name("ARRAY"),1)),
?car(expr)))) $
but I suppose there is a simpler (and less ugly) way of doing this.
With such a function HAS_AN_ARRAY_SUBSCRIPT you should replace
apply(part(expr,0), maplist(second, foo))
with
if has_an_array_subscript(expr)
then arrayapply(part(expr,0), maplist(second, foo))
else apply(part(expr,0), maplist(second, foo))
> Also, how do I display the output of my expression in a non-formatted
> way (like the input way)? Then I could cut-n-paste the entire
> expression here.
,----
| Info from file /usr/share/info/maxima.info:
| - Variable: DISPLAY2D
| default: [TRUE] - if set to FALSE will cause the standard display
| to be a string (1-dimensional) form rather than a display
| (2-dimensional) form. This may be of benefit for users on printing
| consoles who would like to conserve paper.
`----
HTH,
Albert.