Christoph Sarnowski | 15 May 22:11

complex function works only after defining it twice

First of all i want to say hello, as i am new to this mailing list,
and new to maxima.

I have defined a (programming) function, which take a mathematical
function as an argument, and should give me a new (mathematical)
function:

-8<-------------------------------------
/* the error is defined as

                     | df |             | df |
error(f(x,y, ...)) = | -- | * delta_x + | -- | * delta_y + ...
                     | dx |             | dy |

and is a function of all arguments to f() plus all deltas of its arguments:
df(x, y, ...., dx, dy, ...) */
error(fun, ret) := 
block(
  [
  dep:dependencies,
  N:length(dependencies),
  vars:[],
  all_vars:[],
  dvars:[],
  num_vars,
  reservoir: [d1, d2, d3, d4, d5, d6, d7, d8, d9, d10]
  ],
  /* find out what arguments fun() takes via dependencies */
  (for i:1 step 1 while i<=N
    do	if (part(dep[i], 0) = fun) then
(Continue reading)

Barton Willis | 15 May 22:43

Re: complex function works only after defining it twice

Try something like this:

(%i3) error(f) := block([listconstvars : false, var, acc : 0],
  var : listofvars(f),
  for x in var do
    acc : acc + diff(f,x) * concat('delta_,x),
  acc)$
(%i4) error(x^2 - y^2 + %pi);
(%o4) 2*delta_x*x-2*delta_y*y

I didn't try to find the bug in your code --- I'm off to an appointment.
This code doesn't work for things like depends(v,x), error(v). Another
thing:  "error" is a Maxima function -- overwriting it with your definition
can cause trouble.

welcome to Maxima.

Barton

-----maxima-bounces <at> math.utexas.edu wrote: -----

>To: maxima <at> math.utexas.edu
>From: Christoph Sarnowski <pixelbrei <at> h3c.de>
>Sent by: maxima-bounces <at> math.utexas.edu
>Date: 05/15/2008 03:12PM
>Subject: [Maxima] complex function works only after defining it twice
>
>First of all i want to say hello, as i am new to this mailing list,
>and new to maxima.
>
(Continue reading)

Stavros Macrakis | 16 May 00:28

Re: complex function works only after defining it twice

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.

-- 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( ... ) ).

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

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

--   (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])

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

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

(Continue reading)

Christoph Sarnowski | 16 May 21:40

Re: 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...
(Continue reading)

Stavros Macrakis | 16 May 22:29

Re: complex function works only after defining it twice

On Fri, May 16, 2008 at 3:40 PM, Christoph Sarnowski <pixelbrei <at> h3c.de> wrote:
> 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?

I'd recommend subst.

 Or something like block([x, y],  [x,y]:list_of_arguments,''f).

That won't work.  Remember ''f evaluates at *definition time*.  It is
really only useful in interactive contexts. What you want here is
ev(f), though that has its own issues -- so I would recommend sticking
with subst.

> Or is there a way to use a named expression like a function?

Maybe something like this:

    subst(map("=",'[a,b],[2,3]),a^2+b^2);

or you can build a lambda if you really need a function, but that
isn't as natural in the Maxima world (maybe it should be, but it
isn't...).

          -s
Robert Dodier | 17 May 04:13

Re: complex function works only after defining it twice

On Fri, May 16, 2008 at 1:40 PM, Christoph Sarnowski

>> -- 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...

Not sure what you're doing, but I suspect lambda
expressions (unnamed functions) could be useful here.

e.g.

foo : lambda ([x, y], x^2 + y^2);
foo (12, b - a);
 => (b - a)^2 + 144
apply (foo, [12, b - a]);
 => (b - a)^2 + 144

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

If you are trying to construct differentials of functions
of several variables, I think there is a package (maybe
pdiff) to do that kind of stuff. Also, maybe you should
try to use subscripted variables instead of distinguishing
variables by constructing symbols via concat; although
I'm not sure what you want here.

hope this helps
(Continue reading)

Edwin Woollett | 16 May 20:35

Re: complex function works only after defining it

Hi Christoph,

Stavros Macrakis wrote on Thu, 15 May 2008 18:28:05 -0400:

>I think you really should be operating on expressions rather than
>defining functions
> ....
>-- 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?
=====================================

Here is a simple example using an expression (rather than a Maxima 
function):

(%i1) display2d:false$
(%i2) er(f,args) := xreduce("+", makelist( abs(diff(f,a)) * del(a) , a, 
args) ) $
(%i3) f: (x^2 + y^2)/(%pi + z^2)$
(%i4) fargs : listofvars(f);
(%o4) [x,y,z]
(%i5) er(f,fargs);
(%o5) 2*(y^2+x^2)*abs(z)*del(z)/(z^2+%pi)^2
       +2*abs(y)*del(y)/(z^2+%pi)+2*abs(x)*del(x)/(z^2+%pi)
(Continue reading)


Gmane