Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/algebra/
Upload File :
Current File : /usr/home/beeson/MathXpert/algebra/sqfree.c

/*
12.5.92 file created
1.29.98 last modified
*/
/* nsquarefree(), which is used to control \sqrt (a/b) = \sqrt a/\sqrt b  */


#include <assert.h>

#include "terms.h"
#include "arith.h"
#include "nfactor.h"

/*_________________________________________________________________*/
int nsquarefree(term t)
/* t is an integer or bignum.  Return 1 if it is squarefree,
so far as factor_integer can tell.  (At present that means free of
repeated 16-bit factors.) Return 0 if it has square factors or is too
big to factor. Keep a static table of some previously computed values
so it can be called twice on the same input with little overhead.
This table is never reset. Instead the table is treated as a
circular list, so recent answers are always stored.   */
#define NTABLE 10

{ return rootfree(t,2);
}
/*__________________________________________________________________*/
#define NDIGITS 5
int rootfree(term t, unsigned n)
/* like nsquarefree, but free of n-th powers */

{ unsigned short i;
  unsigned nfactors;
  term factoredform;
  long k;                      /* the number to be factored   */
  int err,ans;
  static long input[NTABLE];  /* previous inputs             */
  static int answers[NTABLE];  /* previous answers            */
  static unsigned indices[NTABLE];  /* previous values of n   */
  static int nanswers=0;       /* number of answers stored    */
  static int mostrecent=NTABLE;/* index of most recent answer */
  static digit bigval[NDIGITS];      /* keep ONE bignum answer      */
  static unsigned bigln;
  static int nbiganswers = 0;
  static int bigans;
  bignum b;
  if(!INTEGERP(t))
     return 0;                 /* fail, wrong input           */
  /* Now look in the answer table */
  if(ISINTEGER(t))
     { k = INTDATA(t);
       for(i=0;i<nanswers;i++)
         { if(k == input[i] && n == indices[i])
               return answers[i];
         }
     }
  else if(OBJECT(t) && TYPE(t) == BIGNUM && nbiganswers)
     { b = BIGNUMDATA(t);
       if(b.ln == bigln)
          { for(i=0;i<bigln;i++)
              { if(bigval[i] != b.val[i])
                     break;
              }
            if(i == bigln)
                return bigans;       /* answer was stored */
           }
      }
  /* answer not in table, must compute it */
  err = factor_integer(t,&nfactors,&factoredform);
  if(err==6)                   /* no 16-bit factors           */
     { ans = 1;                /* apparently squarefree       */
       goto out;
     }
  if(err==2)                   /* prime or 1                  */
     { ans = 1;                /* yes, squarefree             */
       goto out;
     }
  if(err == 4)                 /* partially factored          */
     --nfactors;               /* ignore the unfactored part  */
  if(err != 0 && err != 4)     /* factored or partially so    */
     return 1;  /* for example if somebody erroneously calls it
                   with t = zero, factor_integer will return 1.  */
  if(nfactors == 1)
     { if(FUNCTOR(factoredform) == '^' && (unsigned)INTDATA(ARG(1,factoredform)) >= n)
           ans = 0;            /* not free of n-th roots      */
       else
           ans = 1;            /* yes, rootfree               */
       goto out;
     }
  for(i=0;i<nfactors;i++)
     { if(FUNCTOR(ARG(i,factoredform)) == '^' && (unsigned) INTDATA(ARG(1,ARG(i,factoredform))) >= n)
          { ans = 0;           /* not rootfree                */
            goto out;
          }
     }
  ans = 1;                     /* it is rootfree            */
  out:  /* enter ans in the table and return it */
  if(ISINTEGER(t))
     { if(nanswers < NTABLE-1)     /* table not yet full */
          ++nanswers;
       if(mostrecent < NTABLE-1)
          ++mostrecent;
       else
          mostrecent = 0;
       answers[mostrecent] = ans;
       input[mostrecent] = INTDATA(t);
       indices[mostrecent] = n;
     }
  else
     { assert(OBJECT(t) && TYPE(t)==BIGNUM);
       b = BIGNUMDATA(t);
       if(b.ln > NDIGITS)
          return ans;  /* without storing it */
       bigln = b.ln;
       for(i=0;i<bigln;i++)
          bigval[i] = b.val[i];
       bigans = ans;
       nbiganswers = 1;
     }
  return ans;
}
#undef NDIGITS

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