Sindbad~EG File Manager
/* M. Beeson, for Mathpert's prover */
/* code to determine if a function is monotone on an interval;
code to find the max and min of a function on an interval
*/
/* 1.9.95 original date
1.29.98 last modified
*/
#include <assert.h>
#include "globals.h"
#include "prover.h"
#include "extrema.h"
#include "integral.h" /* islinear */
#include "deriv.h" /* derivative */
#include "deval.h" /* deval */
#include "islinear.h"
/*__________________________________________________________*/
int monotone(term u, term x, term a, term b)
/* return 1 if u is monotone non-decreasing on [a,b];
return -1 if u is monotone non-increasing on [a,b] and not constant;
return 0 if u is not (provably) differentiable on [a,b] or
for other failure; either u is not monotone or just can't be
shown to be monotone (e.g. if it's defined by cases but
happens to be continuous and monotone).
Assumes the binder list contains a <= x <= b.
*/
{ term p,q,deriv;
int i,err,flag = 0;
if(islinear(u,x,&p,&q))
{ /* u = px + q */
if(POSNUMBER(p))
return 1;
if(NEGATIVE(p) && POSNUMBER(ARG(0,p)))
return -1;
err = infer(le(zero,p));
if(!err)
return 1;
err = infer(le(p,zero));
if(!err)
return -1;
assume(le(zero,p));
return 1;
}
deriv = derivative(u,x);
if(seminumerical(a) && seminumerical(b))
{ /* before calling the prover make a couple of empirical
evaluations */
double z,za,zb,gap,saveit;
deval(a,&za);
deval(b,&zb);
if(za == BADVAL || zb == BADVAL)
return 0;
gap = (zb-za)/ 11.0;
saveit = VALUE(x);
for(i=0;i<10;i++)
{ SETVALUE(x,za + (i+ 0.21) *gap);
deval(deriv,&z);
if(z > 0.0)
{ if(flag < 0)
{ SETVALUE(x,saveit);
return 1;
}
else
flag = 1;
}
if(z < 0.0)
{ if(flag > 0)
{ SETVALUE(x,saveit);
return 1;
}
else
flag = -1;
}
SETVALUE(x,saveit);
}
}
err = infer(domain(deriv)); /* is deriv defined on [a,b] ? */
if(err)
/* not demonstrably differentiable on [a,b] */
return 1;
if(flag > 0)
{ err = infer(le(zero,deriv)); /* is derive >= 0 on [a,b] ? */
return err ? 0 : 1;
}
if(flag < 0)
{ err = infer(le(deriv,zero));
return err ? 0 : -1;
}
/* Now a and b were not seminumerical; example, x^3 on [a,b] */
err = infer(le(zero,deriv));
if(!err)
return 1;
err = infer(le(deriv,zero));
if(!err)
return -1;
return 0; /* Not (demonstrably) monotone */
}
/*__________________________________________________________*/
int extrema(term u, term x, term a, term b, term *min, term *max)
/* Find the minimum and maximum of u(x) on [a,b] if possible. Return
0 for success, 1 for failure. If possible do it exactly but otherwise
do it numerically. Assumes the binder list contains a <= x <= b.
Does not assume that u is differentiable, but does assume that
it is continuous on [a,b].
*/
{ int sign;
term uofa, uofb;
sign = monotone(u,x,a,b);
if(sign)
{ subst(a,x,u,&uofa);
subst(b,x,u,&uofb);
if(sign > 0)
{ *min = uofa;
*max = uofb;
return 0;
}
else
{ *min = uofb;
*max = uofa;
return 0;
}
}
/* FINISH THIS */
return 1;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists