Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/prover/
Upload File :
Current File : /usr/home/beeson/MathXpert/prover/infsup.c

/* 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