Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/yyy/algebra/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/yyy/algebra/evalfunc.c

/* M. Beeson, for MathXpert
Evaluate a (user-defined) function numerically
Original date 1.19.99
Last modified 2.21.99
*/

#include <assert.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>   /* calloc */
#define ALGEBRA_DLL
#include "globals.h"
#include "userfunc.h"
#include "deval.h"
#include "errbuf.h"
#include "mpmem.h"
#include "feval.h"
/*_________________________________________________________________*/

MEXPORT_ALGEBRA int evalfunction(term t, term arg, term *next, char *reason)
/* Evaluate a numerical value of a user-defined function. */
{ unsigned short f = FUNCTOR(t);
  unsigned short n = ARITY(t);
  unsigned short j;
  unsigned short dependencies;
  aflag savearithflag,flag;
  term temp,temp2,x;
  int k;
  term *answers;
  term lhs,rhs;
  void  *savenode;
  if(!DEFINED_FUNCTION(f))
     return 1;
  if(!seminumerical(t))
     return 1;
  if(contains(t,INFINITY))
     return 1;
  k = is_defined(f);
  if(k < 0)
     return 1;
  get_definition(k,&lhs,&rhs);
  if(ARITY(lhs) != n)
     return 1;
  savearithflag = flag = get_arithflag();
  flag.fract = flag.intexp = flag.negexp = flag.ratexp = flag.roots = 1;
  flag.gcd = flag.abs = flag.factorial = flag.functions = flag.sums = 1;
  flag.complex = flag.comdenom = flag.complexpowers = 1;
  dependencies = get_dependencies(k);
  if(!dependencies)
     {  /* this is an explicit definition */
       temp = rhs;
       for(j=0;j<n;j++)
          { subst(ARG(j,t),ARG(j,lhs),temp,&temp2);
            if(j > 0)
               destroy_term(temp);
            temp = temp2;
          }
       return arith(temp,next,flag);
     }
  if(ARITY(lhs) == 1 &&
     dependencies == (1 << k) &&
     (TYPE(ARG(0,lhs)) == INTEGER || TYPE(ARG(0,lhs)) == NATNUM) &&
     well_founded(k)
    )
     { /* This is a simple recursion that will terminate */
       set_arithflag(flag);
       polyval(ARG(0,t),&x);
       if(!INTEGERP(x))
          { errbuf(0, english(2346)); /* Function argument must be an integer */
            return 1;
          }
       if(!ISINTEGER(x) || INTDATA(x) + 1 >= 0x8000)
			 { errbuf(0, english(2347));  /* Function argument too large. */
				return 1;
			 }
		 savenode = heapmax();
		 answers = (term *) calloc((int)(INTDATA(x)+1),sizeof(term));
       if(!answers)
          { errbuf(0,english(2347));
            return 1;
          }
       temp = feval(t,f,k,lhs,rhs,answers);
       if(FUNCTOR(temp) == ILLEGAL)
          { reset_heap(savenode);
            return 1;
          }
       save_and_reset(temp,savenode,next);
       free(answers);
       set_nanswers(0);   /* tell feval the answers are no good */
       set_arithflag(savearithflag);
       strcpy(reason,english(2348)); /* compute function value */
       HIGHLIGHT(*next);
       return 0;
     }
  return 1;  /* FINISH THIS: handle more complicated recursions and
                functions of more variables, such as Ackermann's function */
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists