complex function works only after defining it twice
Subject: complex function works only after defining it twice
From: Christoph Sarnowski
Date: Fri, 16 May 2008 21:40:22 +0200
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