Sindbad~EG File Manager

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

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