I am trying, inside a program, to find zeros of this expression (x-1)*(x-2)*(x+1)*e^(-1/2*x^2). Inside a prgm. I changed the expression to string and use zeros("expression", "v"), v="x". I should be getting 3 zeros [1,2,-1] which I get in CAS and in HOME but when running program to find the zeros of the same expression I am getting all kind of numbers around twenty which are obviously not zeros I should get. I have no idea how to fix the problem.

Thanks.

Would you mind sharing how you implemented this into code -- it would make it easier to figure out how to address the issue(s).

(01-20-2014 03:11 PM)Han Wrote: [ -> ]Would you mind sharing how you implemented this into code -- it would make it easier to figure out how to address the issue(s).

This is a simple program to find extrema of a function. The prgm gives mi this problem only when finding the roots, critical points, of the first derivative and only when there is exponential function. I think it could be the problem the way the 'zeroes' works, if I remember correctly it uses the secant method and maybe it changes the sign for some x's and thinks they are the zeros of the function.

I plan to fix the problem by passing the roots through some kind of 'root cleaning' program that will reject the root that evaluate to values smaller than, I do not know, but perhaps 1E-8 and that should fix the problem for now.

Thanks.

EXPORT FNEXTREMA(f,v)

BEGIN

LOCAL d,k,fd,sd,rts,cpts,infpts;

LOCAL temp,fcpts,finfpts,sdcpts;

d:=NDIFF(f,v,2);

fd:=collect(d(1));

sd:=collect(d(2));

rts:=zeros(f,v);

rts:=sort(VECT2LIST(rts));

temp:=""+fd+"";

cpts:=zeros(temp,v); <------- HERE IS THE PROBLEM.

cpts:=sort(VECT2LIST(cpts));

...

zeros() works fine when used as follows:

Code:

`zeros("(x-1)*(x-2)*(x+1)*e^(-1/2*x^2)","x")`

as does the case when e^() is replaced with exp(). You were correct to cast fd as a string. I wonder if there is an issue with your use of collect() -- it too is a CAS command and requires its arguments to be cast as strings. So if d(1) is not a string, you might get nonsensical results since it will be evaluated via the Home view.

Also you do not need to add two null strings when forming temp, if the goal is simply to cast fd as a string. Use one of the two shown below:

Code:

`temp:=""+fd; // or`

temp:=STRING(fd);

Be aware that STRING() and string() behave slightly differently depending on Home vs CAS view. This is not an issue in a program since everything executes as if in the Home view.

An easy way to track down the problem debug it.

Here's an example of how to implement it. Usage: EXTREMA("x^3-3*x","x") Note that only minimal error checking is in place. Your actual program should check to see if complex mode is on (this may affect the results of zeros()), and other details I have left out.

Code:

TestSD();

EXPORT EXTREMA(f,v)

BEGIN

local fd,cp,sd,n,j,r={};

fd:=STRING(diff(f,v));

// create a second deriv test function

sd:="sd_(" + v + "):=" + diff(fd,v);

CAS(sd);

cp:=zeros(fd,v);

n:=SIZE(cp);

if TYPE(n)==6 then n:=n(1); end;

if n then

r:=makelist(TestSD(cp(X)),X,1,n);

else

return("No extrema found");

end;

// delete function

CAS("purge(sd_)");

return(r);

END;

TestSD(x)

begin

local s;

// ensure no singularities

iferr

s:=EXPR("sign(sd_("+x+"))");

then

return({x,"2nd deriv singularity"});

end;

case

if s>0 then return({x,"Min"}); end;

if s<0 then return({x,"Max"}); end;

return({x,"2nd deriv = 0"});

end;

end;

(01-20-2014 11:08 AM)John P Wrote: [ -> ]I am trying, inside a program, to find zeros of this expression (x-1)*(x-2)*(x+1)*e^(-1/2*x^2). Inside a prgm. I changed the expression to string and use zeros("expression", "v"), v="x". I should be getting 3 zeros [1,2,-1] which I get in CAS and in HOME but when running program to find the zeros of the same expression I am getting all kind of numbers around twenty which are obviously not zeros I should get. I have no idea how to fix the problem.

Thanks.

Use the following form in your program:

CAS("zeros((x-1)*(x-2)*(x+1)*e^(-1/2*x^2),x)");

It works fine.

He's trying to make it dynamic, so that it works with any generic function.

Thanks to all. Everything works great now. Something was messing up because I wasn't consistent with strings. IMHO when you write a prgm. in CAS: USE STRINGS AND BE CONSISTENT WITH STRINGS.

As for the output: I put everything in a list of list (curly brackets) so I have:

- in the first row {fn, fd, sd}

- in second row { roots, critical points, inflection points}

- in third row { sign(sd(crit. pts.)), f(crit.pts.), sd(inf.pts.)}

This way everything that relates: to the fn is in the 1st col, to the fd is in the 2nd col. and to the sd in the 3rd col. and I have the output in one piece so I can save it for later if I need to.

When the prgm. returns the out. I do factor(out.) so I get everything in nice matrix and can approximate or round it to desired precision.