Sindbad~EG File Manager

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

/* infinite series */
/*
2.6.92 original date
1.21.99 last modified
9.2.04 added get_new_fname, which used to be in userfunc.c
*/

#include <string.h>
#include <assert.h>
#define SERIES_DLL
#include "globals.h"
#include "series.h"
#include "match.h"
#include "prover.h"  /*  getnewindexvar */
#include "symbols.h"
#include "errbuf.h"
#include "psubst.h"
#include "pvalaux.h"  /* twoparts */
#include "ssolve.h"
#include "userfunc.h"

/*________________________________________________________________*/
MEXPORT_SERIES int oneminusxseries(term t, term arg, term *next, char *reason)
{ int flag=0;
  term a,temp,denom;
  int err;
  term n;
  short savenextassumption = get_nextassumption();
  if(!FRACTION(t))
     return 1;
  denom = ARG(1,t);
  if(FUNCTOR(denom) != '+' || ARITY(denom) != 2)
     return 1;
  temp = make_fraction(one,sum(one,tnegate(var0)));
  err = unify1(temp,t,&a,&flag);
  if(err)
     { RELEASE(ARG(1,temp));
       RELEASE(temp);
       return 1;
     }
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  err = check(lessthan(abs1(a),one));
  if(err)
     { errbuf(0,english(2325)); /* The resulting series would not be convergent */
       set_nextassumption(savenextassumption);
       return 1;
     }
  err = infer(equation(a,zero));
  if(!err)
     { errbuf(0,english(2326));  /* The resulting series would converge only at isolated points */
       set_nextassumption(savenextassumption);
       return 1;
     }
  *next = sigma(make_power(a,n),n,zero,infinity);
  HIGHLIGHT(*next);
  strcpy(reason,"$$1/(1-x) = sum(x^n,n,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int oneminusxseries2(term t, term arg, term *next, char *reason)
/* 1/(1-x) = ...  with 3 terms and ldots */
{ term temp;
  int err = oneminusxseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"$1/(1-x)=1+x+x^2+...$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int oneminusxseries3(term t, term arg, term *next, char *reason)
/* 1/(1-x) = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = oneminusxseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"$1/(1-x)=1+x+...x�...$");
  return 0;
}

/*________________________________________________________________*/
MEXPORT_SERIES int oneplusxseries(term t, term arg, term *next, char *reason)
{ int flag=0;
  term a,temp,denom;
  short savenextassumption = get_nextassumption();
  int err;
  term n;
  if(!FRACTION(t))
     return 1;
  denom = ARG(1,t);
  if(FUNCTOR(denom) != '+' || ARITY(denom) != 2)
     return 1;
  if(ONE(ARG(1,denom)))
     temp = make_fraction(one,sum(var0,one));
  else
     temp = make_fraction(one,sum(one,var0));
  err = unify1(temp,t,&a,&flag);
  if(err)
      { RELEASE(ARG(1,temp));
        RELEASE(temp);
        return 1;
      }
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  err = check(lessthan(abs1(a),one));
  if(err)
     { errbuf(0,english(2325)); /* The resulting series would not be convergent */
       set_nextassumption(savenextassumption);
       return 1;
     }
  err = infer(equation(a,zero));
  if(!err)
     { errbuf(0,english(2326));  /* The resulting series would converge only at isolated points */
       set_nextassumption(savenextassumption);
       return 1;
     }
  *next = sigma(product(make_power(minusone,n),make_power(a,n)),n,zero,infinity);
  HIGHLIGHT(*next);
  strcpy(reason,"$$1/(1+x) = sum((-1)^nx^n,n,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int oneplusxseries2(term t, term arg, term *next, char *reason)
/* 1/(1+x) = ...  with 3 terms and ldots */
{ term temp;
  int err = oneplusxseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"$1/(1+x)=1-x+x^2+...$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int oneplusxseries3(term t, term arg, term *next, char *reason)
/* 1/(1+x) = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = oneplusxseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"$1/(1+x)=1-x+...x�...$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int lnseries(term t, term arg, term *next, char *reason)
/* ln(1-x) = x+x^2/2+...+x�/n... */
{ int flag=0;
  term a,temp;
  int err;
  term n;
  short savenextassumption;
  temp = ln1(sum(one,tnegate(var0)));
  err = unify1(temp,t,&a,&flag);
  if(err)
     { RELEASE(ARG(0,temp));
       RELEASE(temp);
       temp = ln1(sum(one,var0));
       err = unify1(temp,t,&a,&flag);
       if(err)
          { RELEASE(ARG(0,temp));
            RELEASE(temp);
            return 1;
          }
     }
  savenextassumption = get_nextassumption();
  err = check(lessthan(abs1(a),one));
  if(err)
     { errbuf(0,english(2325)); /* The resulting series would not be convergent */
       set_nextassumption(savenextassumption);
       return 1;
     }
  err = infer(equation(a,zero));
  if(!err)
     { errbuf(0,english(2326));  /* The resulting series would converge only at isolated points */
       set_nextassumption(savenextassumption);
       return 1;
     }
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  *next = sigma(make_fraction(make_power(a,n),n),n,one,infinity);
  strcpy(reason,"$$ln(1-x) = sum(x^n/n,n,1,infinity)$$");
  HIGHLIGHT(*next);
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int lnseries2(term t, term arg, term *next, char *reason)
/* ln(1-x) = ...  with 3 terms and ldots */
{ term temp;
  int err = lnseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"ln(1-x) =             x+x^2/2+x^3/3...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int lnseries3(term t, term arg, term *next, char *reason)
/* 1/(1+x) = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = lnseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  strcpy(reason,"ln(1+x) =             x+x^2/2+...x^n/3...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int lnseriesminus(term t, term arg, term *next, char *reason)
/* ln(1+x) = x-x^2/2+...+x�/n... */
{ int flag=0;
  term a,temp;
  int err;
  term n;
  short savenextassumption;
  temp = ln1(sum(one,var0));
  err = unify1(temp,t,&a,&flag);
  if(err)
     { RELEASE(ARG(0,temp));
       RELEASE(temp);
       temp = ln1(sum(one,var0));
       err = unify1(temp,t,&a,&flag);
       if(err)
          { RELEASE(ARG(0,temp));
            RELEASE(temp);
            return 1;
          }
     }
  savenextassumption = get_nextassumption();
  err = check(lessthan(abs1(a),one));
  if(err)
     { errbuf(0,english(2325)); /* The resulting series would not be convergent */
       set_nextassumption(savenextassumption);
       return 1;
     }
  err = infer(equation(a,zero));
  if(!err)
     { errbuf(0,english(2326));  /* The resulting series would converge only at isolated points */
       set_nextassumption(savenextassumption);
       return 1;
     }
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  *next = sigma(product(make_power(minusone,sum(n,one)),make_fraction(make_power(a,n),n)),n,one,infinity);
  strcpy(reason,"$$ln(1-x)= sum((-1)^nx^(n+1),n,1,infinity)$$");
  HIGHLIGHT(*next);
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int lnseriesminus2(term t, term arg, term *next, char *reason)
/* ln(1+x) = ...  with 3 terms and ldots */
{ term temp;
  int err = lnseriesminus(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"ln(1+x) =             x-x^2/2+x^3/3-...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int lnseriesminus3(term t, term arg, term *next, char *reason)
/* 1/(1+x) = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = lnseriesminus(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  strcpy(reason,"ln(1+x) =             x+x^2/2+...x^n/3...");
  return 0;
}

/*________________________________________________________________*/
MEXPORT_SERIES int expseries(term t, term arg, term *next, char *reason)
/* e^x = 1+x+...x�/n!... */
{ term a,n;
  if(FUNCTOR(t) != '^')
     return 1;
  if(!equals(ARG(0,t),eulere))
     return 1;
  a = ARG(1,t);
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  *next = sigma(make_fraction(make_power(a,n),factorial1(n)),n,zero,infinity);
  HIGHLIGHT(*next);
  strcpy(reason,"$$e^x = sum(x^n/n!,n,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int expseries2(term t, term arg, term *next, char *reason)
/* 1/(1-x) = ...  with 3 terms and ldots */
{ term temp;
  int err = expseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"e^x = 1+x+x^2/2!+...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int expseries3(term t, term arg, term *next, char *reason)
/* 1/(1-x) = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = expseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"e^x = 1+x+...x^n/n!...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int negexpseries(term t, term arg, term *next, char *reason)
/* e^-x = 1-x+...x�/n!... */
{ term a,n;
  if(FUNCTOR(t) != '^')
     return 1;
  if(!equals(ARG(0,t),eulere))
     return 1;
  a = ARG(1,t);
  if(!NEGATIVE(a))
     return 1;
  a = ARG(0,a);
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  *next = sigma(make_fraction(product(make_power(minusone,n),make_power(a,n)),factorial1(n)),n,zero,infinity);
  HIGHLIGHT(*next);
  strcpy(reason,"$$e^x = sum((-1)^nx^n/n!,n,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int negexpseries2(term t, term arg, term *next, char *reason)
/* 1/(1-x) = ...  with 3 terms and ldots */
{ term temp;
  int err = negexpseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"e^-x = 1-x+x^2/2!+...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int negexpseries3(term t, term arg, term *next, char *reason)
/* 1/(1-x) = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = negexpseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"e^x = 1-x+...x^n/n!...");
  return 0;
}

/*________________________________________________________________*/
MEXPORT_SERIES int sinseries(term t, term arg, term *next, char *reason)
/* expand sin x in a power series */
{ term a,twonplusone,n;
  if(FUNCTOR(t) != SIN)
     return 1;
  a = ARG(0,t);
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  twonplusone = sum(product(two,n),one);
  *next = sigma(product(make_fraction(make_power(minusone,n),factorial1(twonplusone)),
                        make_power(a,twonplusone)
                       ),
                n,zero,infinity
               );
  SETCOLOR(*next,YELLOW);
  strcpy(reason,"$$sin x = sum((-1)^n/(2n+1)! x^(2n+1),n,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int sinseries2(term t, term arg, term *next, char *reason)
/* sin x = ...  with 3 terms and ldots */
{ term temp;
  int err = sinseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"sin x =              x-x^3/3!+x^5/5!+...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int sinseries3(term t, term arg, term *next, char *reason)
/* sin x = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = sinseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"sin x =              x-x^3/3!+(-1)^nx^n/n!+...");
  return 0;
}

/*________________________________________________________________*/
MEXPORT_SERIES int cosseries(term t, term arg, term *next, char *reason)
/* expand cos x in a power series */
{ term a,twon,n;
  if(FUNCTOR(t) != COS)
     return 1;
  a = ARG(0,t);
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  twon = product(two,n);
  *next = sigma(product(make_fraction(make_power(minusone,n),factorial1(twon)),
                        make_power(a,twon)
                       ),
                n,zero,infinity
               );
  HIGHLIGHT(*next);
  strcpy(reason, "$$cos x = sum((-1)^n/(2n)! x^(2n),n,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int cosseries2(term t, term arg, term *next, char *reason)
/* cos x = ...  with 3 terms and ldots */
{ term temp;
  int err = cosseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"cos x =              1-x^2/2+x^4/4!+...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int cosseries3(term t, term arg, term *next, char *reason)
/* cos x = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = cosseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"cos x =              1-x^2/2!+(-1)^nx^(2n)/(2n)!+...");
  return 0;
}

/*________________________________________________________________*/
MEXPORT_SERIES int atanseries(term t, term arg, term *next, char *reason)
/* atan x = x - x^3/3 + x^5/5... */
{ term a,twonplusone,n;
  int err;
  short savenextassumption;
  if(FUNCTOR(t) != ATAN)
     return 1;
  a = ARG(0,t);
  savenextassumption = get_nextassumption();
  err = check(lessthan(abs1(a),one));
  if(err)
     { errbuf(0,english(2325)); /* The resulting series would not be convergent */
       set_nextassumption(savenextassumption);
       return 1;
     }
  err = infer(equation(a,zero));
  if(!err)
     { errbuf(0,english(2326));  /* The resulting series would converge only at isolated points */
       set_nextassumption(savenextassumption);
       return 1;
     }
  n = getnewindexvar(t,"knmjpqrs");
  if(FUNCTOR(n) == ILLEGAL)
     { errbuf(0, english(1448));
       /* Too many subscripted variables, can't make more. */
       return 1;
     }
  twonplusone = sum(product(two,n),one);
  *next = sigma(product(make_power(minusone,n),
                        make_fraction(make_power(a,twonplusone),twonplusone)
                       ),
                n,zero,infinity
               );
  HIGHLIGHT(*next);
  strcpy(reason,"$$arctan x = sum((-1)^k (x^(2k+1)/(2k+1)),k,0,infinity)$$");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int atanseries2(term t, term arg, term *next, char *reason)
/* atan x = ...  with 3 terms and ldots */
{ term temp;
  int err = atanseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
  HIGHLIGHT(*next);
  strcpy(reason,"atan x =              x-x^3/3+x^5/5+...");
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int atanseries3(term t, term arg, term *next, char *reason)
/* atan x = ...  with 2 terms and ldots and general term */
{ term temp;
  int err = atanseries(t,arg,&temp,reason);
  if(err)
     return 1;
  *next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
  HIGHLIGHT(*next);
  strcpy(reason,"atan x = x-x^3/3+...  +x^(2n+1)/(2n+1)+...");
  return 0;
}

/*________________________________________________________________*/
MEXPORT_SERIES int difseries(term t, term arg, term *next, char *reason)
/* Push d/dx into sigma for a power series */

{ term u,n,lo,hi,s,x,a;
  if(FUNCTOR(t) != DIFF)
     return 1;
  x = ARG(1,t);
  s = ARG(0,t);
  if(!is_power_series(s,x,&a))
     return 1;
  u = ARG(0,s);
  n = ARG(1,s);
  lo = ARG(2,s);
  hi = ARG(3,s);
  *next = ARITY(s) == 4  ? sigma(diff(u,arg),n,lo,hi) : series(diff(u,arg),n,lo,hi,ARG(4,s));
  strcpy(reason,"$d/dx( u) = � du/dx$");
  if(equals(hi,infinity))
     strcat(reason,english(2170));    /*      for power series */
  HIGHLIGHT(ARG(0,*next));
  return 0;
}


/*________________________________________________________________*/
MEXPORT_SERIES int intseries(term t, term arg, term *next, char *reason)
/* Integrate a power series term by term */
{ term u,n,s,x,lo,a,w,c,b,newpower;
  if(FUNCTOR(t) != INTEGRAL)
     return 1;
  s = ARG(0,t);
  x = ARG(1,t);
  if(!is_power_series(s,x,&a))
     return 1;
  u = ARG(0,s);
  n = ARG(1,s);
  lo = ARG(2,s);
  twoparts(u,x,&c,&b);
  if(FUNCTOR(b)!='^')
     return 1;  /* assert(0), since is_power_series succeeded */
  polyval(sum(ARG(1,b),one),&newpower);
      /* make w the evaluated indefinite integral of u */
  polyval(make_fraction(product(c,make_power(ARG(0,b),newpower)),newpower),&w);
  if(ARITY(t) == 2)
     { /* an indefinite integral */
       *next = ARITY(s) == 4 ? sigma(w,n,lo,infinity) : series(w,n,lo,infinity,ARG(4,s));
       /* Mathpert's general machinery will insert a constant of integration */
     }
  else
     { /* a definite integral */
       *next = ARITY(s) == 4 ? sigma(evalat(w,x,ARG(2,t),ARG(3,t)),n,lo,infinity):
                               series(evalat(w,x,ARG(2,t),ARG(3,t)),n,lo,infinity,ARG(4,s));
     }
  strcpy(reason, english(2327));    /* integrate power series term by term */
  SETCOLOR(ARG(0,*next),YELLOW);
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int reversedifseries(term t, term arg, term *next, char *reason)
/* pull d/dx out of a series. */

{ term u,n,lo,hi,w;
  if(FUNCTOR(t) != SUM)
     return 1;
  u = ARG(0,t);
  n = ARG(1,t);
  lo = ARG(2,t);
  hi = ARG(3,t);
  if(FUNCTOR(u) != DIFF)
      return 1;
  w = ARITY(t) == 4 ? sigma(ARG(0,u),n,lo,hi) : series(ARG(0,u),n,lo,hi,ARG(4,t));
  *next = diff(w,ARG(1,u));
  strcpy(reason,"$ � du/dx = d/dx � u$");
  if(equals(hi,infinity))
     strcat(reason,english(2170));    /*      for power series */
  HIGHLIGHT(ARG(0,*next));
  return 0;
}
/*________________________________________________________________*/
MEXPORT_SERIES int reverseintseries(term t, term arg, term *next, char *reason)
{ term u,n,lo,hi,w;
  if(FUNCTOR(t) != SUM)
     return 1;
  u = ARG(0,t);
  n = ARG(1,t);
  lo = ARG(2,t);
  hi = ARG(3,t);
  if(FUNCTOR(u) != INTEGRAL)
     return 1;
  w = ARITY(t) == 4 ? sigma(ARG(0,u),n,lo,hi) : series(ARG(0,u),n,lo,hi,ARG(4,t));
  if(ARITY(u) == 2)
     *next = integral(w,ARG(1,u));
  else
     *next = definite_integral(w,ARG(1,u),ARG(2,u),ARG(3,u));
  strcpy(reason,"$�(� u) dx  = � �u dx$");
  if(equals(hi,infinity))
     strcat(reason,english(2170));  /*      for power series */
  SETCOLOR(ARG(0,*next),YELLOW);
  return 0;
}


/*________________________________________________________________________*/
MEXPORT_SERIES int seriesfirstterms(term t, term arg, term *next, char *reason)
/* split off the first few terms (how many is given by arg) of an infinite series. */
/* The number of terms is limited to 1000 */

{ long nn;
  unsigned short n;
  term l,newlo,temp,index,q,last,u;
  int saveflag;
  int i;
  aflag flag1, flag2;
  if(!ISINTEGER(arg))
     return 1;
  nn =  INTDATA(arg);
  if(nn > 1000)
     { errbuf(0, english(828));
          /* You can't show more than 1000 terms */
       return 1;
     }
  flag1 = flag2 = get_arithflag();
  flag1.intexp = flag1.ratexp = flag1.negexp = flag1.fract = flag1.gcd = 0;
  set_arithflag(flag1);
  n = (unsigned short) nn;
  if(FUNCTOR(t) != SUM)
     return 1;
  if(!equals(ARG(3,t),infinity))
     return 1;
  q = ARG(0,t);  /* summand */
  l = ARG(2,t);  /* lower limit of sum */
  index = ARG(1,t);  /* index variable */
  saveflag = get_polyvalzeropowerflag();
  set_polyvalzeropowerflag(1);
  if(ZERO(l))
     newlo = arg;
  else
     { temp = sum(l,arg);
       polyval(temp,&newlo);
     }
  *next = make_term('+',(unsigned short)(n+1));
  for(i=0;i<n;i++)
     { polyval(sum(make_int(i),l),&temp);
       subst(temp,index,q,&u);
       polyval(u,ARGPTR(*next) + i);
       HIGHLIGHT(ARG(i,*next));
     }
  set_polyvalzeropowerflag(saveflag);
  set_arithflag(flag2);
  copy(t,&last);
  ARGREP(last,2,newlo);
  HIGHLIGHT(ARG(2,last));
  ARGREP(*next,n,last);
  strcpy(reason, english(831));  /* split off first terms */
  return 0;
}
/*________________________________________________________________________*/
MEXPORT_SERIES int seriesmoreterms(term t, term arg, term *next, char *reason)
/* lower the first limit of an infinite series, subtracting off the
corresponding terms.  Example:  sum(x^n,n,2,infinity) becomes
sum(x^n,n,0,infinity) - (1+x)  */
/* The number of terms is limited to 1000 */
/* The prompt is, Decrease the lower limit by how much?  */

{ long nn;
  unsigned short n;
  term l,newlo,temp,index,q,p,newseries;
  int i;
  if(!ISINTEGER(arg))
     return 1;
  nn =  INTDATA(arg);
  if(nn > 1000)
     { errbuf(0, english(2245));
          /* You can't insert more than 1000 terms */
       return 1;
     }
  n = (unsigned short) nn;
  if(FUNCTOR(t) != SUM)
     return 1;
  if(!equals(ARG(3,t),infinity))
     return 1;
  if(equals(ARG(2,t),minusinfinity))
     return 1;
  q = ARG(0,t);  /* summand */
  l = ARG(2,t);  /* lower limit of sum */
  index = ARG(1,t);  /* index variable */
  if(ZERO(l))
     newlo = tnegate(arg);
  else if(equals(arg,l))
     newlo = zero;
  else
     { temp = sum(l,tnegate(arg));
       polyval(temp,&newlo);
     }
  p = make_term('+',n);
  for(i=0;i<n;i++)
    { polyval(sum(make_int(i),newlo),&temp);
      subst(temp,index,q,ARGPTR(p) + i);
    }
  HIGHLIGHT(p);
  copy(t,&newseries);
  ARGREP(newseries,2,newlo);
  HIGHLIGHT(ARG(2,newseries));
  *next = sum(newseries,tnegate(p));
  strcpy(reason, english(2252));  /* decrease lower limit */
  return 0;
}
/*________________________________________________________________________*/
MEXPORT_SERIES int seriessubindex(term t, term arg, term *next, char *reason)
/* arg is in response to, Subtract ? from the index variable? */
{ term k;  /* the index variable */
  term hi,lo;  /* the limits */
  term u;    /* the summand */
  term newlo, v,kk;
  if(FUNCTOR(t) != SUM || ARITY(t) != 4)
      return 1;
  u = ARG(0,t);
  k = ARG(1,t);
  lo = ARG(2,t);
  hi = ARG(3,t);
  if(!equals(hi,infinity))
     return 1;
  if(contains(arg,FUNCTOR(k)))
     { errbuf(0, english(2239));
       /* expression to shift by cannot depend on the index variable */
       return 1;
     }
  if(equals(lo,minusinfinity))
     newlo = minusinfinity;
  else
     polyval(sum(lo,arg),&newlo);
  polyval(sum(k,tnegate(arg)),&kk);
  HIGHLIGHT(kk);
  subst(kk,k,u,&v);
  *next = make_term(SUM,4);
  ARGREP(*next,0,v);
  ARGREP(*next,1,k);
  HIGHLIGHT(newlo);
  ARGREP(*next,2,newlo);
  ARGREP(*next,3,infinity);
  strcpy(reason, english(2247));  /* subtract from index variable */
  return 0;
}
/*________________________________________________________________________*/
MEXPORT_SERIES int seriesaddindex(term t, term arg, term *next, char *reason)
/* arg is in response to, Add ? to the index variable? */
{ int err = seriessubindex(t,tnegate(arg),next,reason);
  if(err)
     return 1;
  strcpy(reason,english(2246));  /* add to index variable */
  return 0;
}
/*________________________________________________________________________*/
MEXPORT_SERIES int seriesintdif(term t, term arg, term *next, char *reason)
/*  */
{ term x;
  if(!equals(t,history(get_currentline())))
     return 1;
  x = get_eigenvariable();
  if(!contains(t,FUNCTOR(x)))
     return 1;
  *next = integral(diff(t,x),x);
  HIGHLIGHT(*next);
  strcpy(reason,"$$u = integral(diff(u,x),x)$$");
  return 0;
}

/*________________________________________________________________________*/
MEXPORT_SERIES int seriesintdifdef(term t, term arg, term *next, char *reason)
/* $$u = integral(diff(u,t),t,0,x) + u0$$ */
{ term x,v,t0,tofv;
  x = get_eigenvariable();
  if(!equals(t,history(get_currentline())))
     return 1;
  x = get_eigenvariable();
  if(!contains(t,FUNCTOR(x)))
     return 1;
  v = getnewvar(t,"tuvwz");
  psubst(zero,x,t,&t0);
  subst(v,x,t,&tofv);
  *next = sum(definite_integral(diff(tofv,v),v,zero,x),t0);
  HIGHLIGHT(*next);
  strcpy(reason,"$$u = integral(diff(u,t),t,0,x) + u0$$");
  return 0;
}
/*________________________________________________________________________*/
MEXPORT_SERIES int seriesdifint(term t, term arg, term *next, char *reason)
/* $$u = diff(integral(u,x),x)$$ */
{ term x;
  if(!equals(t,history(get_currentline())))
     return 1;
  x = get_eigenvariable();
  if(!equals(t,history(get_currentline())))
     return 1;
  if(!contains(t,FUNCTOR(x)))
     return 1;
  *next = diff(integral(t,x),x);
  HIGHLIGHT(*next);
  strcpy(reason,"$$u = diff(integral(u,x),x)$$");
  return 0;
}
/*________________________________________________________________________*/
static int get_origin(term t, term x, term *a)
/*  if t contains a power series in (x-a) return a in *a;
    if t contains a power series in x return zero in *a.
    Return 0 for success.
*/
{ unsigned short i,n;
  if(ATOMIC(t))
     return 1;
  if(FUNCTOR(t) == SUM && equals(ARG(3,t),infinity))
     { if(is_power_series(t,x,a))
          return 0;
       return 1;
     }
  n = ARITY(t);
  for(i=0;i<n;i++)
     { if(get_origin(ARG(i,t),x,a) == 0)
          return 0;
     }
  return 1;
}
/*________________________________________________________________________*/
static int get_cofi(term t, term *ans)
/* return a subterm of t with functor CONSTANTOFINTEGRATION in *ans,
if one exists, returning 0 for success.
*/
{ unsigned short i,n;
  if(FUNCTOR(t) == CONSTANTOFINTEGRATION)
     { *ans = t;
       return 0;
     }
  if(ATOMIC(t))
     return 1;
  n = ARITY(t);
  for(i=0;i<n;i++)
     { if(get_cofi(ARG(i,t),ans) == 0)
          return 0;
     }
  return 1;
}
/*________________________________________________________________________*/
MEXPORT_SERIES int eliminatecofi(term t, term arg, term *next, char *reason)
/* Solve for constant of integration */
/* example, once we have reduced arctan x to
x-x^3/3 + ... + C
we change C to arctan(0)  with this operation
*/
{ term orig,x,a,u,v,w,r,q,ans;
  int err;
  int saveflag;
  if(!equals(t,history(get_currentline())))
     return 1;
  x = get_eigenvariable();
  if(contains(t,INTEGRAL))
     return 1;
  orig = history(0);
  /* check if t contains a power series in x or (x-a) */
  err = get_origin(t,x,&a);
  if(err)
     return 1;
  subst(a,x,t,&u);  /* example, t = x-x^2/2 +x^3/3 + ... + c1, a = 0 */
  saveflag = get_polyvalzeropowerflag();
  set_polyvalzeropowerflag(1);
  polyval(u,&v);    /* In the example v comes out 0 since polyval can simplify
                       a series with general term 0 to 0 */
  subst(a,x,orig,&w);  /* in the example, orig is ln(1+x) so w comes out ln 1 */
  polyval(w,&q);
  set_polyvalzeropowerflag(saveflag);
  if(FUNCTOR(arg) != CONSTANTOFINTEGRATION)
     { err = get_cofi(t,&arg);
       if(err)
          return 1;
     }
  subst(x,arg,equation(v,q),&r);    /* r comes out 0 + x = ln 1  */
  err = ssolve(r,x,&ans);           /* x = ln 1  */
  if(err || FUNCTOR(ans) != '=')
     return 1;
  HIGHLIGHT(ARG(1,ans));
  subst(ARG(1,ans),arg,t,next);
  strcpy(reason, english(2324));  /* solve for constant of integration */
  return 0;
}

/*____________________________________________________________________________________*/
MEXPORT_SERIES int is_power_series(term t, term x, term *a)
/* return 1 if t is a power series in x about x=a.  Return a in *a. */
{ term c,s,base,u,c2,s2;
  if(FUNCTOR(t) != SUM)
     return 1;
  if(!equals(ARG(3,t),infinity))
     return 1;
  u = ARG(0,t);
  twoparts(u,x,&c,&s);
  if(FUNCTOR(s) != '^')
     { if(FUNCTOR(s) == '/' || FUNCTOR(s) == '*')
       twoparts(s,x,&c2,&s2);
       if(FUNCTOR(s2)!= '^')
          return 1;
       polyval(product(c,c2),&c);
       s = s2;
     }
  if(equals(ARG(0,s),x))
     { *a = zero;
       return 1;
     }
  base = ARG(0,s);
  if(FUNCTOR(base) != '+')
     return 0;
  polyval(sum(x,tnegate(base)),a);
  return contains(*a,FUNCTOR(x)) ? 0 : 1;
}
/*____________________________________________________________*/
MEXPORT_SERIES int get_new_fname(unsigned short *f, char *buffer)
/* return a new function name suitable for use as coefficients in a
power series defined by series division;  in this case Mathpert has
to make a (recursive) function definition internally.  Return 0 for
success or 1 if there is no room for more function definitions, or
(very unlikely) all the candidate letters in the 'letters' array below
are used up.
*/

{ int i,j;
  char *letters = "cabdpqrsuvwzCABPQRSUVWZ";
  int nletters = strlen(letters);
  char c;
  char *name;
  term *varlist = get_varlist();
  int nvars = get_nvariables();
  int nextfunction = nuserfunctions();
  if(nextfunction == MAXUSERFUNCTIONS)
     return 1;
  /* pick the first member of 'letters' that is not in varlist or
     already used for a function definition. */
  for(i=0;i<nletters;i++)
     { c = letters[i];
       for(j=0;j<nvars;j++)
          { if(FUNCTOR(varlist[j])==c)
               break;
          }
       if(j<nvars)
          continue;
       for(j=0;j< (int)nextfunction;j++)
          { name = get_defnstring(j);
            if(c == name[0] && name[1] == '(')
               break;
          }
       if(j == (int)nextfunction)
          break;
     }
  if(i==nletters)
     return 1;
  *f = (unsigned short) c;
  buffer[0] = c;
  buffer[1] = '\0';
  return 0;
}

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