Reputation: 5780
Starting from the following Maxima code taken from here
/* piecewise function definition */
itvs: [[x<0],[x>=0,x<1], [x>=1]]; /* intervals */
pfun: [ a, x^2+b, c*x ]; /* local functions */
/* piecewise function constructor */
f:0$
for i: 1 thru 3 do f:f+charfun(apply("and",itvs[i]))*pfun[i]$
f;
/* differentiation of piecewise function */
gradef(charfun(dummy),0)$
diff(f,x);
I'd like to make a function able to take 2 arguments like itvs
and pfun
and return a piecewise function like f
, but I was not able to do it because of errors due to evaluation of symbols. For example in the following try I get the error "incorrect syntax: itvs is not an infix operator":
define(pfc(itvs,pfun),(
f:0,
for i: 1 thru length(itvs) do f:f+charfun("and" itvs[i])*pfun[i],
f
));
How can I define such a function? The documentation I found is very concise and could not help me, is there some less known documentation about this subject?
EDIT
An alternative format of input argument, maybe simpler and more flexible, could be:
/* piecewise function definition */
pfd: [
[a, x<0],
[x^2+b, x>=0 and x<1],
[c*x, x>=1]
];
Writing a function constructor with this argument might be simpler.
FOLLOW UP
If you don't actually need a piecewise function since a piecewise expression is enough (as -- I discovered later -- in my case), writing a piecewise expression constructor (using the alternative format of input argument) becomes straightforward:
/* pec=piecewise expression constructor */
/* argument is an array of [expression,interval] couples */
pec(x) := sum(x[i][1]*charfun(x[i][2]), i,1,length(x));
f: pec( [[(1+x)/2, x>=-1 and x<1],[3, x<-1 or x>=1]] )
(f) 3*charfun(x<-1 or x>=1)+((x+1)*charfun(x>=-1 and x<1))/2
Upvotes: 0
Views: 1685
Reputation: 17577
OP indicates that they want pfc
to construct a piecewise function. Here is an attempt:
pfc (itvs, pfun) := block ([body],
body : sum (charfun (apply ("and", itvs[i]))*pfun[i], i, 1, length(itvs)),
buildq ([body], lambda ([x], body)));
Now pfc
takes intervals and expressions and constructs an unnamed function of one argument. It's assumed the argument is named x
; I guess if one wanted to make this a little more complicated, one could specify a different variable as an argument for pfc
and make it another variable for buildq
, e.g. buildq([body, var], lambda([var], body)
.
Upvotes: 2
Reputation: 17577
Couple of things. (1) Instead of charfun("and" itvs[i])
you want charfun(apply("and", itvs[i]))
. (2) Instead of pfc(itvs,pfun)
you want pfc(x)
. Also (3) probably you want to make f
a local variable.
I think this might work:
define(pfc(x), block([f:0],
for i: 1 thru length(itvs)
do f:f+charfun(apply("and", itvs[i]))*pfun[i],
f));
Upvotes: 2