Sindbad~EG File Manager
/* compute the sup and inf of functions such as 1 + cos x */
/* M. Beeson, for Mathpert
Original date 12.21.93
modified 11.7.98
5.5.13 made infsupabs static
*/
#include <math.h>
#include "globals.h"
#include "prover.h"
#include "deval.h"
#include "infsup.h"
#include "order.h"
static int infsup(int which, term u, term *ans);
static int infsupabs(term u, term *min,term *max);
/*_______________________________________________________________*/
int inf(term u, term *ans)
/* example, inf(1+cos x, &ans) yields ans = zero */
/* see infsup below for more documentation */
{ return infsup(0,u,ans);
}
/*_______________________________________________________________*/
int sup(term u, term *ans)
{ return infsup(1,u,ans);
}
/*_______________________________________________________________*/
static int infsupabs(term u, term *min,term *max)
/* compute lower and upper bounds on the absolute value of u */
{ unsigned short f = FUNCTOR(u);
unsigned short n;
int i,err,flag;
term temp,temp2,tempmax,tempmin,power;
if(ATOMIC(u))
{ *max = abs1(u);
*min = zero;
return 0;
}
switch(f)
{ case '-':
return infsupabs(ARG(0,u),max,min);
case '*':
n = ARITY(u);
flag = 0;
tempmin = make_term('*',n);
tempmax = make_term('*',n);
for(i=0;i<n;i++)
{ err = infsupabs(ARG(i,u),&temp,&temp2);
if(!err)
flag = 1;
ARGREP(tempmin,i, err ? ARG(i,u) : temp);
ARGREP(tempmax,i, err ? ARG(i,u) : temp2);
}
if(flag)
{ *max = lpt(tempmax);
*min = lpt(tempmin);
RELEASE(tempmax); /* lpt uses fresh space */
RELEASE(tempmin);
return 0;
}
RELEASE(tempmax);
RELEASE(tempmin);
*min = *max = u;
return 1;
case '+':
n = ARITY(u);
flag = 0;
tempmin = make_term('*',n);
tempmax = make_term('*',n);
for(i=0;i<n;i++)
{ err = infsupabs(ARG(i,u),&temp,&temp2);
if(!err)
flag = 1;
ARGREP(tempmin,i, err ? ARG(i,u) : temp);
ARGREP(tempmax,i, err ? ARG(i,u) : temp2);
}
if(flag)
{ *max = lpt(tempmax);
*min = lpt(tempmin);
RELEASE(tempmax); /* lpt uses fresh space */
RELEASE(tempmin);
return 0;
}
RELEASE(tempmax);
RELEASE(tempmin);
*min = *max = u;
return 1;
case '^':
power = ARG(1,u);
if(NEGATIVE(power) && POSNUMBER(ARG(0,power)))
{ err = infsupabs(ARG(0,u),&temp,&temp2);
if(err)
{ *min = *max = u;
return 1;
}
*min = make_power(temp2,power);
*max = make_power(temp,power);
return 0;
}
if(POSNUMBER(ARG(0,power)))
{ err = infsupabs(ARG(0,u),&temp,&temp2);
if(err)
{ *min = *max = u;
return 1;
}
*min = make_power(temp,power);
*max = make_power(temp2,power);
return 0;
}
*min = *max = u;
return 1;
case SIN: /* fall-through */
case COS:
*min = zero;
*max = one;
return 0;
case ABSFUNCTOR:
return infsupabs(ARG(0,u),min,max);
case ACOT: /* fall-through */
case ATAN:
*min = zero;
*max = make_fraction(pi_term,two);
return 0;
case ROOT:
if(INTEGERP(ARG(0,u)) && ISODD(ARG(0,u)))
{ err = infsupabs(ARG(0,u),&temp,&temp2);
if(err)
{ *min = zero;
*max = u;
return 0;
}
*min = make_root(ARG(0,u),temp);
*max = make_root(ARG(0,u),temp2);
return 0;
}
if(INTEGERP(ARG(0,u))) /* and it's an even index */
{ err = infsupabs(ARG(0,u),&temp,&temp2);
if(err || infer(le(zero,temp)))
{ *min = *max = u;
return 0;
}
*min = make_root(ARG(0,u),temp);
*max = make_root(ARG(0,u),temp2);
return 0;
}
return 1;
case SQRT:
err = infsupabs(ARG(0,u),&temp,&temp2);
if(err || infer(le(zero,temp)))
{ *min = *max = u;
return 1;
}
*min = sqrt1(temp);
*max = sqrt1(temp2);
return 0;
default:
*min = *max = u;
return 1;
}
}
/*_______________________________________________________________*/
static int infsup(int which, term u, term *ans)
/* if which == 0, compute the 'infimum' of u, replacing cos and sin by -1 or 1,
so that *ans <= u. If it can't be computed just make *ans = u.
If which ==1, compute the sup similarly.
The return value is nonzero if *ans equals u.
*/
{ unsigned short f = FUNCTOR(u);
unsigned short n;
int i,err,flag;
term temp,temp2,num,c,s,power;
double z;
if(ATOMIC(u))
{ *ans = u;
return 1;
}
switch(f)
{ case '-':
err = infsup(which ? 0 : 1,ARG(0,u),&temp);
tneg(temp,ans);
return err;
case '+':
n = ARITY(u);
flag = 0;
temp2 = make_term('+',n);
for(i=0;i<n;i++)
{ err = infsup(which,ARG(i,u),&temp);
if(!err)
flag = 1;
ARGREP(temp2,i, err ? ARG(i,u) : temp);
}
if(flag)
{ *ans = lpt(temp2);
RELEASE(temp2); /* lpt uses fresh space */
return 0;
}
RELEASE(temp2);
*ans = u;
return 1;
case '*' :
ncs(u,&num,&c,&s);
{ if(FUNCTOR(s) == '*')
{ term p,q;
err = infsupabs(s,&p,&q);
if(err)
{ *ans = u;
return 1;
}
if(which == 0)
{ tneg(q,ans);
return 0;
}
else
{ *ans = q;
return 0;
}
}
}
err = deval(num,&z);
if(err)
{ *ans = u;
return 1;
}
if(fabs(z) < VERYSMALL)
{ *ans = zero;
return 0;
}
if(z > 0.0)
{ err = infsup(which,s,&temp);
if(err)
{ *ans = u;
return 1;
}
*ans = product3(num,c,temp);
return 0;
}
/* Now z < 0.0 */
err = infsup(which ? 0 : 1,s,&temp);
if(err)
{ *ans = u;
return 1;
}
*ans = tnegate(product3(num,c,temp));
return 0;
case '^':
power = ARG(1,u);
if(NEGATIVE(power) && POSNUMBER(ARG(0,power)))
{ err = infsup(which ? 0 : 1, ARG(0,u),&temp);
if(err)
{ *ans = u;
return 1;
}
*ans = make_power(temp,power);
return 0;
}
if(POSNUMBER(ARG(0,power)))
{ err = infsup(which,ARG(0,u),&temp);
if(err)
{ *ans = u;
return 1;
}
*ans = make_power(temp,power);;
return 0;
}
*ans = u;
return 1;
case SIN: /* fall-through */
case COS:
*ans = which ? one : minusone;
return 0;
case ABSFUNCTOR:
err = infsupabs(ARG(0,u),&temp,&temp2);
if(err)
{ *ans = u;
return 1;
}
*ans = which ? temp2 : temp;
return 0;
case ACOT: /* fall-through */
case ATAN:
*ans = which ? tnegate(make_fraction(pi_term,two)) : make_fraction(pi_term,two);
return 0;
case ROOT:
if(INTEGERP(ARG(0,u)) && ISODD(ARG(0,u)))
{ err = infsup(which,ARG(0,u),&temp);
if(err)
{ *ans = u;
return 1;
}
*ans = make_root(ARG(0,u),temp);
return 0;
}
if(INTEGERP(ARG(0,u)))
{ err = infsup(which,ARG(0,u),&temp);
if(err)
{ *ans = u;
return 1;
}
if(which)
{ *ans = make_root(ARG(0,u),temp);
return 0;
}
err = infer(le(zero,temp));
if(!err)
{ *ans = make_root(ARG(0,u),temp);
return 0;
}
*ans = zero;
return 0;
}
*ans = u;
return 1;
case LN:
err = infsup(which,ARG(0,u),&temp);
if(err)
{ *ans = u;
return 1;
}
*ans = ln1(temp);
return 0;
case SQRT:
err = infsup(which,ARG(0,u),&temp);
if(err)
{ *ans = u;
return 1;
}
if(which)
{ *ans = sqrt1(temp);
return 0;
}
err = infer(le(zero,temp));
if(!err)
{ *ans = sqrt1(temp);
return 0;
}
*ans = zero;
return 0;
default:
*ans = u;
return 1;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists