complex function works only after defining it twice



Thanks for your answer!


On Thu, May 15, 2008 at 06:28:05PM -0400, Stavros Macrakis wrote:
> Thanks for your interest in Maxima.
> 
> Here are some observations on your code.
> 
> -- As Barton observes, "error" is a built-in function; you shouldn't
> redefine it.

I changed the name to error_fun, so this is "fixed".

> -- The ''(...) construction is evaluated at the time your function is
> *defined*, not at the time it is executed, so the ''diff's at the end
> can't possibly be doing the right thing (this is probably related to
> your second-time-around problem).  In fact, all the '' 's seem to be
> unnecessary -- the whole point of "define" is that both the first and
> the second arguments are evaluated, so you could perfectly well do
> define( funmake(pt,vars), diff( ... ) ).

Ok, i did not know that ''(..) stuff was evaluated even within a
non-evaluating function definition (:= ... ). I thought it would just
do an extra evaluation when the function is executed. Now i know the
problem was not too few evaluations, but evaluation at the wrong time.

> -- The functions you are defining (pt, tempfunc, etc.) will be defined
> *globally*.  Is that what you want?

I found that out, too, and thought about doing remfunction() for those
afterwards...

> -- the cons(reservoir[i]...) loop can more simply be written as dvars:
> makelist(reservoir[i],i,1,num_vars)

Another thing i learned from Barton's answer. I tried concat(d_, x)
for variable creation before, which didn't work. Barton uses the
prefix quoted, which is fine and makes the reservoir thing obsolete.

> --   (for j:1 thru length(dep[i]) do (vars: cons(part(dep[i], j),
> vars)))), reverse(...) can be more simply written as vars:args(dep[i])

... and learning... ;)

> --  (for i:1 step 1 while i<=N ...) can be more simply written as (for
> i thru N...)

I think i used the "thru" notation somewhere else... has something to
do with c&p'ing code from someone using the while notation.

> -- I think you really should be operating on expressions rather than
> defining functions

I still am overwhelmed with the simplicity of Barton's solution. As i
answered him (but forgot to CC to mailing list), i am now building my
code upon his short (and working) version of my function.

But one thing about expressions vs. functions: I need to apply those
functions (e.g., f and error_f) to some numerical values. With both
being functions, i write apply(f, list_of_arguments), same for the
error. With expressions, i need the at(f, [x=x1, y=y1, ...]) notation,
right? Or something like block([x, y],  [x,y]:list_of_arguments,''f).
Or is there a way to use a named expression like a function?

> -- I'm not quite sure what you're trying to do but is it something like this?:
> 
>      er(f,args) := xreduce("+", makelist( abs(diff(f,a)) * del(a) , a, args) ) $
> 
>      er(f,[a,b,c])
> 
> But keeping track of the arguments in the 'depends' system?

Hm, another very short way of achieving about the same
thing... replacing del(a) by concat('delta_, a), this does what i need.

> 
> Hope this helps,
> 
>             -s

It really does. Thank you!

Best regards,
 Christoph