

##
##    Title   :  algcurve,  the algebraic curves package  ( file 1/5)
##
##    Created :  Jul 24  1992
##
##    Author  :  Stefan Schwendimann
##               Institut fuer Informatik und 
##               angewandte Mathematik
##		 Laenggassstrasse 51 
##		 CH--3012 Bern
##
##		 <schwendi@iam.unibe.ch>
##
##    Documentation :   algcurve.tex (algcurve.ps)
##


macro ( 
  scalarmul   =  linalg['scalarmul'],
  crossprod   =  linalg['crossprod'],
  
  affvars     =  algcurve['affvars'],
  homvars     =  algcurve['homvars'],

  iszerolist  =  `algcurve/iszerolist`,
  getindets   =  `algcurve/getindets`,  
  hompoly     =  `algcurve/hompoly`,
  hompoint    =  `algcurve/hompoint`,
  affpoly     =  `algcurve/affpoly`,
  affpoint    =  `algcurve/affpoint`,
  poly2coord  =  `algcurve/poly2coord`,
  coord2poly  =  `algcurve/coord2poly`,
  standard    =  `algcurve/standard`,
  homequal    =  `algcurve/homequal`,
  grad        =  `algcurve/grad`
  
):


# ___  ISZEROLIST  _______________________________________________________

iszerolist := proc(v)
local i;
  for i from 1 to nops(v) do
    if simplify(v[i]) <> 0 then RETURN(false) fi
  od;
  RETURN(true)
end:  




# ___  GETINDETS  ________________________________________________________

getindets := proc (fromargs)
local inds;
  inds:= indets(fromargs,name);
  if inds intersect {op(affvars)} <> {} then
    if inds intersect {op(homvars)} <> {} then
      ERROR(`homogeneous and affine variables in the same expression`)
    fi;
    affvars
  elif inds intersect {op(homvars)} <> {} then
    homvars
  else
    ERROR(`neither homogeneous nor affine variables in expression`)  
  fi
end:


# ___  TPOLY  ________________________________________________________

`type/tpoly` := proc(p)
local vars;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= indets(p,name)
  else  
    ERROR(`wrong type or number of arguments`)
  fi;  
  type(p, { polynom(algebraic,vars), list(polynom(algebraic,vars)) } )
end:  


# ___  LISTLIST  ________________________________________________________

`type/listlist` := proc(A)
local z,n,b;
options `Copyright 1990 by the University of Waterloo`;
  if nargs <> 1 then ERROR(`wrong number of arguments`) fi;
  if type(A,list) then
    if A = [] then RETURN(true) fi;
    n := nops(op(1,A));
    b := true;
    for z in A while b do  b := type(z,list) and (n = nops(z)) od;
    RETURN(b)
  else false
  fi
end:

# ___  DOTPROD  ________________________________________________________

`algcurve/dotprod`:= proc(u,v)
local i;
  convert( [ seq(u[i]*v[i],i=1..nops(u)) ], `+`)
end:  




# ___  PROJPOLY  ________________________________________________________

`type/projpoly` := proc(F)
local lF,vars,deg,i,i0;
  if type([args],[anything,list(name),posint]) then
    vars:= args[2];
    deg:= args[3]
  elif type([args],[anything,list(name)]) then
    vars:= args[2];
    deg:= 0  
  elif type([args],[anything,posint]) then
    vars:= homvars;
    deg:= args[2]
  elif type([args],[anything]) then
    vars:= homvars;
    deg:= 0
  else  
    ERROR (`wrong number or type of arguments`)
  fi;
  vars:= convert(vars,set); 
  if not type(F,polynom(algebraic,vars)) then
    RETURN (false)
  fi;
  lF:= expand(F);  
  if type(lF,`+`) then lF:= [op(lF)] else lF:= [lF] fi;
  if deg=0 then 
    deg:= degree(lF[1],vars); 
    i0:= 2 
  else
    i0:= 1  
  fi;
  if deg = 0 then RETURN(false) fi;
  for i from i0 to nops(lF) do
    if degree(lF[i],vars) <> deg then
      RETURN (false)
    fi
  od;
  RETURN (true)
end:


# ___  PROJCOORD  ______________________________________________________

`type/projcoord` := proc (p)
local dim;
  if type ([args],[anything,posint]) then
    dim:= args[2]
  elif type ([args],[anything]) then
    dim:= 2
  else
    ERROR(`wrong number or type of arguments`)
  fi;  
  if nops(p)-1 <> dim then RETURN(false) fi;
  type(p,list) and (not iszerolist(p))
end:




# ___  HOMPOLY  ________________________________________________________

hompoly := proc (f)
local hompoly0,avars,hvars,nr,sublist,j;

    hompoly0 := proc(f,avars,homvar,sublist)
    local lf,deg;
      lf:= expand(f);
      deg:= degree(lf,avars);
      if deg = 0 then deg:= 1 fi;
      expand ( homvar^deg * subs(sublist,lf) )
    end:

  if type([args],[anything,list(name),list(name),nonnegint]) then
    avars:= args[2];
    hvars:= args[3];
    nr:= args[4]
  elif type([args],[anything]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= 0
  elif type([args],[anything,nonnegint]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= args[2]
  else
    ERROR(`wrong number or type of arguments`)
  fi;
  if not type(f,tpoly(avars)) then  ERROR(`illegal first argument`)  fi;
  if nr > nops(avars)      then  ERROR(`invalid projection number`) fi; 
  if nops(hvars) <> nops(avars)+1 then
    ERROR(`wrong number of homogeneous variables`)
  fi;
  sublist := [seq(avars[j]=hvars[j]/hvars[nr+1],j=1..nr),
    seq(avars[j]=hvars[j+1]/hvars[nr+1],j=nr+1..nops(avars))];
  avars:= convert(avars,set);  
  if type(f,list) then
    map(hompoly0,f,avars,hvars[nr+1],sublist)
  else
    hompoly0(f,avars,hvars[nr+1],sublist)    
  fi  
end:     





# ___  HOMPOINT  ______________________________________________________


hompoint := proc(p)
local nr,dim, hompoint0;

    hompoint0 := proc(p,nr,dim)
      [p[1..nr],1,p[nr+1..dim]]
    end:
    
  if type ([args],[list]) then
    nr:= 0
  elif type([args],[list,nonnegint]) then
    nr:= args[2]
  else
    ERROR(`wrong number or type of arguments`)  
  fi;
  if type(p,listlist) then
    dim:= nops(p[1]);
    if nr > dim then ERROR(`invalid projection number`) fi;  
    map(hompoint0,p,nr,dim)
  else
    dim:= nops(p);
    if nr > dim then ERROR(`invalid projection number`) fi; 
    hompoint0(p,nr,dim)
  fi
end:
    
    
      
# ___  AFFPOLY  ______________________________________________________

affpoly := proc (F)
local avars,hvars,nr,sublist,j;
  if type([args],[anything,list(name),list(name),nonnegint]) then
    hvars:= args[2];
    avars:= args[3];
    nr:= args[4]
  elif type([args],[anything,nonnegint]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= args[2]    
  elif type([args],[anything]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= 0
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,tpoly(hvars)) then ERROR(`illegal first argument`)  fi;
  if nr > nops(avars) then ERROR(`invalid projection number`) fi; 
  if nops(hvars) <> nops(avars)+1 then
    ERROR(`wrong number of affine variables`)
  fi;
  sublist := [seq(hvars[j]=avars[j],j=1..nr),hvars[nr+1]=1,
    seq(hvars[j]=avars[j-1],j=nr+2..nops(hvars))];
  subs(sublist,F)  
end:
  



# ___  AFFPOINT  ______________________________________________________

affpoint := proc(p)
local nr,dim,affpoint0;

    affpoint0 := proc(p,nr,dim) local i,t;
      if p[nr+1] = 0 then RETURN(NULL) fi;
      #scalarmul([p[1..nr],p[nr+2..dim]],1/p[nr+1])
      t := p[nr+1];
      [seq(p[i]/t,i=1..nr),seq(p[i]/t,i=nr+2..dim)]
    end:
  
  if type([args],[list,nonnegint]) then
    nr:= args[2]
  elif type ([args],[list]) then
    nr:= 0
  else
    ERROR(`wrong number or type of arguments`)  
  fi;
  if type(p,listlist) then
    dim:= nops(p[1]);
    if nr > dim-1 then ERROR(`invalid projection number`) fi;  
    map(affpoint0,p,nr,dim)
  else
    dim:= nops(p);
    if nr > dim-1 then ERROR(`invalid projection number`) fi; 
    affpoint0(p,nr,dim)
  fi
end:
 


# ___  POLY2COORD  ______________________________________________________

poly2coord := proc(F)
local vars,varset,lF,v,n,i,j,m;
  if type([args],[anything,list(name)])  then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= homvars
  else
    ERROR(` wrong number or type of arguments`) 
  fi;
  if not type(F,projpoly(vars)) then 
    ERROR(`first argument is not a homogeneous polynomial in `,eval(vars))
  fi;  
  lF:= collect(F,vars,'distributed');
  if nops(vars) <> 3 then
    ERROR(`number of variables  <> 3`)
  fi;  
  varset:= convert(vars,set);
  n:= degree(lF,varset);
  v:= array([seq(0,i=1..(n+1)*(n+2)/2)]);
  if type(lF,`+`) then lF:= [op(lF)] else lF:= [lF] fi;
  for m from 1 to nops(lF) do
    i:= degree(lF[m],vars[1]);
    j:= degree(lF[m],vars[2]);
    v[(n-i)*(n-i+1)/2 + 1 + n-i-j] := coeffs(lF[m],varset)
  od;  
  convert(v,list)
end:
   	    



# ___  COORD2POLY  ______________________________________________________

coord2poly := proc(C)
local vars,n,i,j,vind,F;
  if type([args],[list,list(name)])  then
    vars:= args[2]
  elif type([args],[list]) then
    vars:= homvars
  else
    ERROR(`wrong number or type of arguments`) 
  fi;
  if nops(vars) <> 3 then
    ERROR(`number of variables  <> 3`)
  fi;  
  n:= -3/2 + sqrt(1+8*nops(C))/2;
  if not type(n,posint) then 
    ERROR(`illegal dimension`)
  fi;  
  vind:= 0;
  F:= 0;
  for i from n by -1 to 0 do
    for j from n-i by -1 to 0 do
      vind:= vind+1;
      F:= F + C[vind]*vars[1]^i*vars[2]^j*vars[3]^(n-i-j)
    od
  od;
  eval(F)    
end:
    
macro (
  poly2coord = algcurve['poly2coord'],
  coord2poly = algcurve['coord2poly']
):



# ___  STANDARD  ______________________________________________________

standard := proc (p)
local i,j,k,tmp, ind,faclist,fac,intfac,comfac, denomj,denomlist,
      expo,exptable, lp,lpdim,ispoly,vars,dummy, polystandard;
      
    polystandard := proc(f,vars)
      sort(primpart(f,vars),vars)
    end:    
      
  if type([args],[list]) then
    ispoly:= false
  elif type([args],[anything,list(name)]) then  
    vars:= args[2];
    ispoly:= true    
  elif type([args],[anything]) then
    vars:= getindets(p);
    ispoly:= true  
  else  
    ERROR(` wrong number or type of arguments`) 
  fi;
  if ispoly then 
    if nops(vars) <> 3 or not type(p,projpoly(vars)) then
      RETURN(polystandard(p,vars))
    fi;
    lp:= poly2coord(p,vars) 
  else  
    lp:= p
  fi;  
  lpdim:= nops(lp);
  lp:= array(lp);
  for i from 1 to lpdim while lp[i] = 0 do od;
  if i > lpdim then ERROR(`argument is zero-tuple`) fi;
  for j from i+1 to lpdim do lp[j]:= normal (lp[j]/lp[i]*dummy) od;
  lp[i]:= dummy;
  denomlist:= []; exptable:= table();
  intfac:= 1;
  for j from i+1 to lpdim do
    tmp:= op(1,[op(lp[j])]);
    if type(tmp,fraction) then
      tmp:= denom(tmp);  k:= tmp/gcd(intfac,tmp); 
      intfac:= intfac*k;
      denomj:= denom(lp[j])/tmp
    else
      denomj:= denom(lp[j])
    fi;
    if denomj <> 1 then 
      if type(denomj,`*`) then faclist:=[op(denomj)] else faclist:=[denomj] fi;
      for k from 1 to nops(faclist) do
        if type(faclist[k],anything^integer) then
          expo:= op(2,faclist[k]);  fac:= op(1,faclist[k])
        else 
          expo:= 1; fac:= faclist[k]
        fi;	
        if member(fac,denomlist,'ind') then
          if exptable[ind] < expo then exptable[ind]:= expo fi
        else
          denomlist:= [op(denomlist),fac];
	  exptable[nops(denomlist)]:= expo
        fi	
      od
    fi
  od;  
  comfac:= convert([seq(denomlist[k]^exptable[k],k=1..nops(denomlist))],`*`);
  for k from i to lpdim do lp[k]:= intfac*lp[k]*comfac/dummy od;
  lp:= convert(lp,list);
  if ispoly then
    coord2poly(lp,vars)
  else
    eval(lp)
  fi    
end:

 
 


# ___  HOMEQUAL  ______________________________________________________

homequal := proc (p1,p2)
local cp,i,k;
  if not type([args],[list,list]) then
    ERROR(`wrong number or type of arguments`)  
  fi;
  if nops(p1) <> nops(p2) then
    ERROR(`dimension mismatch`)
  fi;
  if nops(p1) = 3 then
    iszerolist(convert(crossprod(p1,p2),list));
  else
    cp := { seq(p1[i] = k*p2[i],i=1..nops(p1)) };
    evalb(solve(cp,k) <> NULL)
  fi
end:
  
  
# ___  GRAD  ______________________________________________________
    
grad := proc (F)
local i,vars;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= getindets(F)
  else
    ERROR(`wrong number or type of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;
  [seq(diff(F,vars[i]),i=1..nops(vars))]
end:           


##
##    Title   :  algcurve,  the algebraic curves package  ( file 2/5)
##
##    Created :  Jul 24  1992
##
##    Author  :  Stefan Schwendimann
##               Institut fuer Informatik und 
##               angewandte Mathematik
##		 Laenggassstrasse 51 
##		 CH--3012 Bern
##
##		 <schwendi@iam.unibe.ch>
##
##    Documentation :   algcurve.tex (algcurve.ps)
##


macro ( 
  crossprod   =  linalg['crossprod'],
  genmatrix   =  linalg['genmatrix'],
  coldim      =  linalg['coldim'],
  transpose   =  linalg['transpose'],
  inverse     =  linalg['inverse'],
  multiply    =  linalg['multiply'],

  affvars     =  algcurve['affvars'],
  homvars     =  algcurve['homvars'],

  iszerolist  =  `algcurve/iszerolist`,
  getindets   =  `algcurve/getindets`,
  dotprod     =  `algcurve/dotprod`,  
  hompoly     =  algcurve['hompoly'],
  hompoint    =  algcurve['hompoint'],
  affpoly     =  algcurve['affpoly'],
  affpoint    =  algcurve['affpoint'],
  standard    =  algcurve['standard'],
  
  homtrans    =  `algcurve/homtrans`,
  afftrans    =  `algcurve/afftrans`,
  image2mat   =  `algcurve/image2mat`,
  mat2image   =  `algcurve/mat2image`,
  appoly      =  `algcurve/appoly`,
  appoly0     =  `algcurve/appoly0`,
  appolyE     =  `algcurve/appolyE`,
  appmat      =  `algcurve/appmat`,
  appimage    =  `algcurve/appimage`,
  NonCurvePt  =  `algcurve/NonCurvePt`,
  NonVertexTrans = `algcurve/NonVertexTrans`,
  PtTrans     =  `algcurve/PtTrans`,
  multcomp    =  `algcurve/multcomp`,
  commoncomp  =  `algcurve/commoncomp`,
  homxyfac    =  `algcurve/homxyfac`

):




# ___  HOMTRANS  ________________________________________________________

homtrans := proc (T)
local avars,hvars,nr;
  if type([args],[anything,list(name),list(name),nonnegint]) then
    avars:= args[2];
    hvars:= args[3];
    nr:= args[4]
  elif type([args],[anything]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= 0
  elif type([args],[anything,nonnegint]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= args[2]
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(T,list) or not type(T,tpoly(avars)) then
    ERROR(`illegal first argument`)
  fi;  	 
  if nr > nops(avars) then ERROR(`invalid projection number`) fi; 
  if nops(hvars) <> nops(avars)+1 then
    ERROR(`wrong number of homogeneous variables`)
  fi;
  hompoly(hompoint(T,nr),avars,hvars,nr)
end:


# ___  AFFTRANS  ________________________________________________________
  
afftrans := proc (T)
local avars,hvars,nr;
  if type([args],[anything,list(name),list(name),nonnegint]) then
    avars:= args[3];
    hvars:= args[2];
    nr:= args[4]
  elif type([args],[anything]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= 0
  elif type([args],[anything,nonnegint]) then
    avars:= affvars;
    hvars:= homvars;
    nr:= args[2]
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(T,list(projpoly(hvars))) then
    ERROR(`illegal first argument`)
  fi; 
  if nr > nops(avars) then ERROR(`invalid projection number`) fi; 
  if nops(hvars) <> nops(avars)+1 then
    ERROR(`wrong number of affine variables`)
  fi;
  affpoint(affpoly(T,hvars,avars,nr),nr)
end:




# ___  IMAGE2MAT  ________________________________________________________

image2mat := proc (homimage)
local hvars;
  if type([args],[anything,list(name)]) then
    hvars:= args[2]
  elif type([args],[anything]) then
    hvars:= homvars
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type (homimage, list(projpoly(hvars,1))) then
    ERROR(`first argument is not a list of linear homogeneous polynomials`)
  fi; 
  genmatrix(homimage,hvars)
end:          


# ___  MAT2IMAGE  ________________________________________________________

mat2image := proc (hommat)
local hvars;
  if type([args],[matrix,list(name)]) then
    hvars:= args[2]
  elif type([args],[matrix]) then
    hvars:= homvars
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if nops(hvars) <> coldim(hommat) then
    ERROR(`dimension mismatch`)
  fi;
  convert(multiply(hommat,hvars),list)
end:




# ___  APPOLY  ____________________________________________________________

appoly0 := proc(F,pt,vars)
local i;
  subs ( [seq(vars[i] = pt[i], i=1..nops(pt))] , F )
end:  

appolyE := proc(F,pt,vars)
  simplify(appoly0(F,pt,vars))
end:  


appoly := proc (F,pt)
local vars,i;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;  
  if not type(F,tpoly(vars)) then
    ERROR(`illegal first argument`)
  fi;  
  if type(pt,listlist) then 
    if nops(pt[1]) <> nops(vars) then ERROR(`dimension mismatch`) fi;
    RETURN( [seq( appoly0(F,pt[i],vars), i=1..nops(pt) )] )
  else 
    if nops(pt) <> nops(vars) then ERROR(`dimension mismatch`) fi;
    RETURN(appoly0(F,pt,vars))
  fi    
end:


# ___  APPIMAGE  __________________________________________________________

appimage := proc (im ,F)
local vars;
  if type([args],[list,anything,list(name)]) then
    vars:= args[3]
  elif type([args],[list,anything]) then
    vars:= getindets([im,F])
  else
    ERROR(`wrong type or number of arguments`)
  fi;  
  if not type(im,list(tpoly(vars))) then
    ERROR(`illegal first argument`)
  fi;
  if not type(F,tpoly(vars)) then
    ERROR(`illegal second argument`)
  fi;  
  appoly0(F,im,vars)
end:



  
# ___  APPMAT  ____________________________________________________________
  
appmat := proc (mat,F)
local vars,polycase,imlist,i;
  if type([args],[matrix,anything,list(name)]) then
    vars:= args[3];
    polycase:= true
  elif type([args],[matrix,list]) then
    polycase:= false  
  elif type([args],[matrix,anything]) then
    vars:= homvars;
    polycase:= true
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if polycase then
    if not type(F,projpoly(vars)) then
      ERROR(`second argument is not a homogeneous polynomial in`,vars)
    fi;  
    imlist:= convert(multiply(mat,vars),list);  
    appoly0 (F,imlist,vars)
  elif type(F,listlist) then
    [seq( convert(multiply(mat,F[i]),list), i=1..nops(F))]
  else
    convert(multiply(mat,F),list)  
  fi  
end:



# ___  NONCURVEPT  _________________________________________________________ 


NonCurvePt := proc (F)
local f,homcase, avars,hvars,nr, v1,v2,exlist, dir,left,right,up,down;
  if type([args],[anything,nonnegint,listlist,list(name)]) then
    nr:= args[2];
    exlist:= args[3];
    hvars:= args[4];
    homcase:= true
  elif type([args],[anything,nonnegint]) then
    nr:= args[2];
    exlist:= [];
    hvars:= homvars;
    homcase:= true  
  elif type([args],[anything,list(name)]) then
    nr:= 0;
    exlist:= [];
    avars:= args[2];
    homcase:= evalb(nops(avars)=3);  
    if homcase then hvars:= avars fi
  elif type([args],[anything]) then
    nr:= 0;
    exlist:= [];
    avars:= getindets(F);
    homcase:= evalb(nops(avars)=3);
    if homcase then hvars:= avars fi   
  else 
    ERROR(`wrong type or number of arguments`)
  fi; 
  if homcase then
    if nops(hvars) <> 3 then ERROR(`number of homogeneous variables <> 3`) fi;  
    if not type(F,projpoly(hvars)) then 
      ERROR(`first argument is not a homogeneous polynomial in`,hvars)
    fi;  
    if exlist <> [] then exlist:= affpoint(exlist,nr) fi;
    avars:= affvars;
    f:= affpoly(F,hvars,avars,nr)   
  else
    if nops(avars) <> 2 then ERROR(`number of affine variables <> 2`) fi;  
    if not type(F,polynom(algebraic,avars)) then
      ERROR(`first argument ist not a polynomial in`,avars)
    fi;
    f:= F
  fi;
  dir:= right;
  v1:=0; v2:= 0;
  while  appoly0(f,[v1,v2],avars) = 0   or  member([v1,v2],exlist) do
    if dir = right then
      v1:= v1+1;
      if v1 > -v2 then dir:= up fi
    elif dir = up then
      v2:= v2+1;
      if v2 = v1 then dir:= left fi
    elif dir = left then
      v1:= v1-1;
      if v1 = -v2 then dir:= down fi
    else # dir = down
      v2:= v2-1;
      if v2 = v1 then dir:= right fi
    fi;
  od;
  if homcase then
    hompoint([v1,v2],nr)
  else
    [v1,v2]
  fi
end:  # NonCurvePt

macro (NonCurvePt = algcurve['NonCurvePt']):




# ___  NONVERTEXTRANS  ______________________________________________________ 

NonVertexTrans := proc (F)
local vars, prelist, P, i, prenr, a;
  if type([args],[anything,listlist,list(name)]) then
    vars:= args[3];
    prelist:= args[2]
  elif type([args],[anything]) then
    vars:= homvars;
    prelist:= [];
  else
    ERROR(`wrong type or number of arguments`)
  fi; 
  if nops(vars) <> 3  or nops(prelist) > 3 then
    ERROR(`wrong number of variables or too long list`);
  fi;
  if not type(F,projpoly(vars)) then 
    ERROR(`arg is not a homogeneous polynomial in`,vars) 
  fi;
  prenr:= nops(prelist);
  for i from 1 to prenr do P[i]:= prelist[i] od;
  if prenr > 1 and iszerolist(convert(crossprod(P[1],P[2]),list)) then
    ERROR(`dependent tupels in list`);
  fi;  
  if prenr = 0 then
    P[1]:= NonCurvePt(F,0,[],vars)
  fi;
  if prenr <= 1 then
    a:= P[1][2];
    if a <> 0 then 
      P[2]:= NonCurvePt(F,1,[ [1/a,1,P[1][3]/a] ],vars)
    else
      P[2]:= NonCurvePt(F,1,[],vars)
    fi  
  fi;
  if prenr <= 2 then
    P[3]:= NonCurvePt(F*dotprod(crossprod(P[1],P[2]),vars),2,[],vars)
  fi;
  transpose(linalg['matrix'](3,3,[P[1],P[2],P[3]]))
end:


# ___  PTTRANS  ______________________________________________________ 

PtTrans := proc (L1,L2)
local A,B,BB;
  if type([args],[listlist,listlist]) then
    A:= L1;
    B:= L2
  elif type([args],[listlist]) then
    B:= L1
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  BB:= inverse(transpose(linalg['matrix'](B)));
  if nargs = 1 then RETURN(eval(BB)) fi;
  if nops(A) <> nops(B) then ERROR(`different length of lists`) fi;
  A:= transpose(linalg['matrix'](A));
  multiply(A,BB)
end:  



# ___  MULTCOMP  ______________________________________________________ 

multcomp := proc(F)
local vars, i;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;  
  for i from 1 to nops(vars) do
    if has(F,vars[i]) and simplify(discrim(F,vars[i])) = 0 then RETURN(true) fi
  od;
  RETURN(false) 
end:



# ___  COMMONCOMP  ______________________________________________________ 

commoncomp := proc(F,G)
local vars, i;
  if type([args],[anything,anything,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,anything]) then
    vars:= getindets([F,G])
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type([F,G],list(polynom(algebraic,vars))) then
    ERROR(`illegal first or second argument`)
  fi; 
  for i from 1 to nops(vars) do
    if has(F,vars[i]) and has(G,vars[i]) then
      if simplify(resultant(F,G,vars[i])) = 0 then RETURN(true) fi
    fi  
  od;
  RETURN(false) 
end:




# ___  HOMXYFAC  ______________________________________________________ 

homxyfac := proc (F)
local vars,G,S,i,k,r,sols,Grts,multtab;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= affvars
  else
    ERROR(`wrong type or number of arguments`)
  fi;    
  if nops(vars) <> 2  or  not type(F,projpoly(vars)) then
    ERROR(`number of variables <> 2  or polynomial is not homogeneous`)
  fi;
  S:= NULL;
  G:= F;
  for i from 1 to 2 do
    for k from 0 do
      r:= rem(G,vars[i],vars[i],'G');
      if r <> 0 then  G:= G*vars[i]+r; break fi
    od;
    if k > 0 then S:= S,vars[i]^k fi
  od;  
  sols:= [solve(subs(vars[1]=1,G),vars[2])]; Grts:= [];
  for i from 1 to nops(sols) do
    if not member(sols[i],Grts,'k') then
      Grts:= [op(Grts),sols[i]];
      multtab[nops(Grts)]:= 1
    else
      multtab[k]:= multtab[k]+1
    fi
  od;      
  [S,seq( (vars[1]*numer(Grts[i])-denom(Grts[i])*vars[2])^multtab[i],
          i=1..nops(Grts))]
end: 


  
 

##
##    Title   :  algcurve,  the algebraic curves package  ( file 3/5)
##
##    Created :  Jul 24  1992
##
##    Author  :  Stefan Schwendimann
##               Institut fuer Informatik und 
##               angewandte Mathematik
##		 Laenggassstrasse 51 
##		 CH--3012 Bern
##
##		 <schwendi@iam.unibe.ch>
##
##    Documentation :   algcurve.tex (algcurve.ps)
##


macro ( 
  nullspace   =  linalg['nullspace'],

  affvars     =  algcurve['affvars'],
  homvars     =  algcurve['homvars'],

# ---  alg1  ----
  iszerolist  =  `algcurve/iszerolist`,
  getindets   =  `algcurve/getindets`,
  dotprod     =  `algcurve/dotprod`,
  hompoly     =  algcurve['hompoly'],
  hompoint    =  algcurve['hompoint'],
  affpoly     =  algcurve['affpoly'],
  affpoint    =  algcurve['affpoint'],
  coord2poly  =  algcurve['coord2poly'],
  standard    =  algcurve['standard'],
  grad        =  algcurve['grad'],

# ---  alg2  ----
  appoly0     =  `algcurve/appoly0`,
  appolyE     =  `algcurve/appolyE`,
  appoly      =  algcurve['appoly'],
  multcomp    =  algcurve['multcomp'],
  homxyfac    =  `algcurve/homxyfac`,

# ---  alg3  ----
  singularities =  `algcurve/singularities`,
  isregular     =  `algcurve/isregular`,
  issingular    =  `algcurve/issingular`,
  isordinary    =  `algcurve/isordinary`,
  curvetaylor   =  `algcurve/curvetaylor`,
  multiplicity  =  `algcurve/multiplicity`,
  singtangent   =  `algcurve/singtangent`,
  tangent       =  `algcurve/tangent`,
  unityvec      =  `algcurve/unityvec`,
  filter        =  `algcurve/filter`,
  processmult   =  `algcurve/processmult`,
  linearsystem  =  `algcurve/linearsystem`,
  randsyspoly   =  `algcurve/randsyspoly`,
  iPoints       =  `algcurve/iPoints`,
  cPoints       =  `algcurve/cPoints`,
  getPoints     =  `algcurve/getPoints`,
  shorter       =  `algcurve/shorter`,
  RegCurvePts   =  `algcurve/RegCurvePts`
):


# ___  SINGULARITIES  ________________________________________________________

singularities := proc (F)
local vars,sols,t,oncurve,homcase,i;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;
  sols:= [solve(convert(grad(F,vars),set),convert(vars,set))];
  sols:= `algcurve/patchsolve`(sols):
  sols:= [seq(subs(sols[i],eval(vars)),i=1..nops(sols))];
  homcase:= evalb( nops(vars) = 3  and type(F,projpoly(vars) ));
  if homcase then
    oncurve:= unapply('evalb'('not iszerolist(t) and  appolyE'(F,t,vars)=0),t);
    RETURN (map(standard,select(oncurve,sols)))
  else
    oncurve:= unapply('evalb'('appolyE'(F,t,vars)=0),t);
    RETURN (select(oncurve,sols))        
  fi
end:  

`algcurve/patchsubs` := proc(L,r,sols) local s;
    seq(subs(r=s,L),s=sols)
end:
	
`algcurve/patchsolve` := proc(L) local Lup,r,poly,x;
    Lup := L:
    for r in indets(L,RootOf) do
        poly := op(1,r);
	poly := frontend( subs, [_Z=x,poly], [{`+`,`*`,`=`},{}] );
        if degree(poly,x)=2 then
	    Lup := map(`algcurve/patchsubs`,Lup,r,[solve(poly,x)]);
	fi;
    od;
    Lup
end:


# ___  ISREGULAR  ______________________________________________________

isregular := proc (F,pt)
local vars;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;
  if nops(vars) <> nops(pt) then
    ERROR(`dimension mismatch`)
  fi;  
  ( appolyE(F,pt,vars) = 0  or  indets(pt,name) <> {} )  and  
  not iszerolist(appoly0(grad(F,vars),pt,vars))
end:  

macro(isregular = algcurve['isregular']):




# ___  ISSINGULAR  ______________________________________________________

issingular := proc (F,pt)
local vars;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;
  if nops(vars) <> nops(pt) then
    ERROR(`dimension mismatch`)
  fi;  
  appolyE(F,pt,vars) = 0  and  iszerolist(appolyE(grad(F,vars),pt,vars))
end:  


# ___  CURVETAYLOR  ______________________________________________________

curvetaylor := proc (F,pt)
local vars,varset, tay, tmp,i;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;  
  if nops(vars) <> nops(pt) then
    ERROR(`dimension mismatch`)
  fi;
  varset:= convert(vars,set);  
  tay:= readlib(mtaylor) ( F, [ seq(vars[i]=pt[i],i=1..nops(pt)) ], 
                           degree(F,varset) + 1 );
  if indets(pt,name) <> {} then
    tmp:= subs( [ seq( vars[i]=vars[i]+pt[i], i=1..nops(pt) ) ], tay);
    if ldegree(tmp,varset) = 0 then
      RETURN(tay-tcoeff(tmp,varset))
    fi  
  fi;
  eval(tay)
end:

macro(curvetaylor = algcurve['curvetaylor']):




# ___  MULTIPLICITY  ______________________________________________________

multiplicity := proc (F,pt)
local vars,varset,tmp,i,k,lpt,isptlist,res;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;  
  if pt = [] then RETURN([]) fi;
  isptlist:= type(pt,listlist);
  if isptlist then lpt:= pt else lpt:= [pt] fi;
  if nops(lpt[1]) <> nops(vars) then
    ERROR(`dimension mismatch`)
  fi;
  res:= NULL;
  varset:= convert(vars,set);
  for k from 1 to nops(lpt) do
    tmp:= subs( [ seq( vars[i]=vars[i]+lpt[k][i], i=1..nops(lpt[k]) ) ],
                 curvetaylor(F,lpt[k],vars));
    res:= res, ldegree(expand(tmp),varset)
  od;
  if isptlist then RETURN([res]) else RETURN(eval(res)) fi 
end:




# ___  TANGENT  ______________________________________________________

singtangent := proc(f,pt,vars)
local tay,varset,lowterm,t,sfn,i;
  tay:= subs( [ seq( vars[i]=vars[i]+pt[i], i=1..nops(pt) ) ],
              curvetaylor(f,pt,vars));
  varset:= convert(vars,set);
  if not type(tay,`+`) then 
    lowterm:= tay 
  else 
    sfn:= unapply('evalb'('degree'(t,varset)=ldegree(tay,varset)),t);
    lowterm:= select(sfn,tay) 
  fi;
  subs( [ seq( vars[i]=vars[i]-pt[i], i=1..nops(pt) ) ],
        homxyfac(lowterm,vars) )
end:  
  	      
tangent := proc(F,pt)
local avars,vars, homcase,nr, gr,tmp,i;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;  
  if nops(vars) <> nops(pt) then
    ERROR(`dimension mismatch`)
  fi; 
  if not ( appolyE(F,pt,vars) = 0  or  indets(pt,name) <> {} ) then
    ERROR(`point is not on curve`)
  fi;
  homcase:= evalb( nops(vars) = 3  and type(F,projpoly(vars)) );
  if homcase and iszerolist(pt) then
    ERROR(`list was zero-tuple`)
  fi;  
  gr:= grad(F,vars);
  if not iszerolist(appolyE(gr,pt,vars)) then   # regular point
    if homcase then
      RETURN (dotprod ( vars, appoly(gr,pt,vars) ))
    else
      RETURN (dotprod ( [seq(vars[i]-pt[i],i=1..nops(vars))], 
                        appoly(gr,pt,vars) )) 
    fi
  fi;
  if nops(vars) > 2 and not homcase then RETURN('tangent(args)') fi;
  if homcase then
    for nr from 0 to nops(pt)-1 while pt[nr+1] = 0 do od;
    avars:= affvars;
    tmp:= singtangent(affpoly(F,vars,avars,nr),affpoint(pt,nr),avars);
    RETURN(hompoly(tmp,avars,vars,nr))
  else
    RETURN(singtangent(F,pt,vars))
  fi  
end:    

macro (tangent = algcurve['tangent']):



# ___  ISORDINARY  ______________________________________________________

isordinary := proc (F,pt)
local vars,varset, tay,i, sfn,t, lowterm;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;  
  if nops(vars) <> nops(pt) then
    ERROR(`dimension mismatch`)
  fi;  
  if isregular(F,pt) then RETURN(true)
  elif appolyE(F,pt,vars) <> 0 then RETURN(false) 
  else
    tay:= subs( [ seq( vars[i]=vars[i]+pt[i], i=1..nops(pt) ) ],
                curvetaylor(F,pt,vars));
    varset:= convert(vars,set);
    if not type(tay,`+`) then 
      lowterm:= tay 
    else 
      sfn:= unapply('evalb'('degree'(t,varset)=ldegree(tay,varset)),t);
      lowterm:= select(sfn,tay) 
    fi;
    not multcomp(lowterm,vars)
  fi
end:  




# ___  LINEARSYSTEM ______________________________________________________

unityvec := proc (n,vars)
local i,j,dim,vind,v;
  dim:= (n+1)*(n+2)/2; 
  vind:= 0;    
  v:= array([seq(0,i=1..dim)]);
  for i from n by -1 to 0 do
    for j from n-i by -1 to 0 do
      vind:= vind+1;
      v[vind]:= vars[1]^i*vars[2]^j*vars[3]^(n-i-j)
    od
  od;
  convert(v,list)
end:


filter := proc(pts,rest,mult) 
local resseq,complseq,i,lmult;
  if type (pts[1],[list,posint]) then
    lmult:= pts[1][2]
  else 
    lmult:= 1
  fi;  
  resseq:= NULL; complseq:= NULL;
  for i from 1 to nops(pts) do
    if type (pts[i],[list,posint]) then
      if pts[i][2] = lmult then
        resseq:= resseq,pts[i][1]
      else
      	complseq:= complseq,pts[i]
      fi	
    elif  lmult = 1 then
      resseq:= resseq,pts[i];
    else
      complseq:= complseq,pts[i]
    fi
  od;
  mult:= lmult;
  rest:= [complseq];
  RETURN([resseq])
end:       
  
processmult:= proc (pts,mult,unity,vars)
local lunity, s,len,tmp, i,j,k;
  len:= nops(pts);
  if mult = 1 then 
    RETURN([seq(appoly0(unity,pts[i],vars),i=1..len)])
  fi;  
  s:= mult-1;
  tmp:= NULL;
  for i from 0 to s do
    for j from 0 to s-i do
      lunity:= map(diff,unity,vars[1]$i,vars[2]$j,vars[3]$(s-i-j));
      tmp:= tmp,seq(appoly0(lunity,pts[k],vars),k=1..len)
    od
  od;
  [tmp]
end:




linearsystem := proc (pts,m)
local vars,unity,A,nspace,rowseq,restlist,mult,ptsofmult,i;
  if type([args],[list(list),posint,list(name)]) then
    vars:= args[3]
  elif type([args],[list(list),posint]) then 
    vars:= homvars
  else  
    ERROR(`wrong type or number of arguments`)
  fi;
  if nops(vars) <> 3 then ERROR(`dimension <> 3`) fi;
  for i from 1 to nops(pts) do
    if (type(pts[i],[list,posint]) and nops(pts[i][1]) <> 3) or
       (type(pts[i],list(algebraic)) and nops(pts[i]) <> 3) then
      ERROR(`dimension mismatch in point list`)
    fi
  od;
  unity:= unityvec(m,vars);
  rowseq:= NULL;
  restlist:= pts;
  while restlist <> [] do
    ptsofmult:= filter(restlist,'restlist','mult');
    rowseq:= rowseq,op(processmult(ptsofmult,mult,unity,vars))
  od;
  A:= linalg['matrix']([rowseq]);
  nspace:= map(convert,convert(nullspace(A),list),list);
  map(coord2poly,nspace,vars)
end:


# ___  RANDSYSPOLY  ______________________________________________________


randsyspoly := proc(L)
local vars,r,i;
  if type([args],[list,list(name)]) then
    vars:= args[2]
  elif type([args],[list]) then
    vars:= getindets(L)
  else  
    ERROR(`wrong type or number of arguments`)
  fi;
  r:= rand(-1..1);
  convert( [ seq( r()*L[i], i=1..nops(L) ) ], `+`)
end:




# ___  REGCURVEPTS  _________________________________________________________ 


iPoints := proc (f,oldptset,nrofpts,vars)
local ptset, sols,sols1,sols2, j,ii, isreg,t;
  ptset:= oldptset;
  isreg:= unapply('isregular'(f,t,vars),t);
  for ii from 0 to 50 while nops(ptset) < nrofpts do 
    sols1:= { isolve(subs(vars[1]=ii, f), vars[2]) };
    sols2:= { isolve(subs(vars[1]=-ii,f), vars[2]) };
    sols:= { seq([ ii,subs(sols1[j],vars[2])], j=1..nops(sols1)) } union
           { seq([-ii,subs(sols2[j],vars[2])], j=1..nops(sols2)) };
    sols1:= { isolve(subs(vars[2]=ii, f), vars[1]) };
    sols2:= { isolve(subs(vars[2]=-ii,f), vars[1]) };
    sols:= sols union { seq([subs(sols1[j],vars[1]), ii], j=1..nops(sols1)) } 
                union { seq([subs(sols2[j],vars[1]),-ii], j=1..nops(sols2)) };
    ptset:= ptset union select(isreg,sols)
  od;
  eval(ptset)
end:


cPoints := proc (f,oldptset,nrofpts,vars)
local ptset, sols,sols1,sols2, j,ii, isreg,t;
  ptset:= oldptset;
  isreg:= unapply('isregular'(f,t,vars),t);
  for ii from 0 to 10 while nops(ptset) < nrofpts do 
    sols1:= { solve(subs(vars[1]=ii, f), vars[2]) };
    sols2:= { solve(subs(vars[1]=-ii,f), vars[2]) };
    sols:= { seq([ ii,sols1[j] ], j=1..nops(sols1)) } union
           { seq([-ii,sols2[j] ], j=1..nops(sols2)) };
    sols1:= { solve(subs(vars[2]=ii, f), vars[1]) };
    sols2:= { solve(subs(vars[2]=-ii,f), vars[1]) };
    sols:= sols union { seq([sols1[j], ii], j=1..nops(sols1)) } 
                union { seq([sols2[j],-ii], j=1..nops(sols2)) };
    ptset:= ptset union select(isreg,sols)
  od;
  eval(ptset)
end:

getPoints := proc(F,hvars,avars,homcase,oldptset,nrofpts,pointproc)
local f,ptset,ptsetnr,nr,sel,sel0,t;
  ptset:= oldptset;
  sel0:= unapply('evalb'(t[1]=0),t );
  for nr from 0 to 2 while nops(ptset) < nrofpts do
    f:= affpoly(F,hvars,avars,nr);
    ptsetnr := map(affpoint,ptset,nr);
    ptsetnr := pointproc(f,ptsetnr,nrofpts,avars);
    ptsetnr := map(hompoint,ptsetnr,nr);
    if not homcase then ptsetnr := ptsetnr minus select(sel0,ptsetnr) fi;
    sel := unapply( 'evalb'(t[nr+1]=0),t );
    ptset:= select(sel,ptset) union ptsetnr
  od;
  eval(ptset)
end:


shorter := proc(t1,t2)
local l1,l2,test;
  l1:= length(t1); l2:= length(t2);
  if l1 < l2 then RETURN(true) fi;
  if l1 > l2 then RETURN(false) fi;
  test:= evalb( abs(t1[1]) <  abs(t2[1]) );
  if member(test,{true,false}) then
    if test then RETURN(true) fi;
    if abs(t1[1]) > abs(t2[1]) then RETURN(false) fi
  fi;
  test:= evalb(abs(t1[2]) < abs(t2[2]));
  if member(test,{true,false}) then RETURN(test) fi;
  false
end:


RegCurvePts := proc (G,nrofpts)
local homcase, ptset,ptlist, avars,hvars, F;
  if type([args],[anything,nonnegint,list(name)]) then
    avars:= args[3];
  elif type([args],[anything,nonnegint]) then
    avars:= `algcurve/getindets`(G);
  else 
    ERROR(`wrong type or number of arguments`)
  fi; 
  homcase:= evalb(nops(avars)=3);
  if homcase then
    hvars:= avars;
    if not type(G,projpoly(hvars)) then 
      ERROR(`first argument is not a homogeneous polynomial in`,hvars)
    fi;  
    avars:= affvars;
    F:= G
  else
    if nops(avars) <> 2 then ERROR(`number of affine variables <> 2`) fi;
    if not type(G,polynom(algebraic,avars)) then
      ERROR(`first argument ist not a polynomial in`,avars)
    fi;
    hvars:= homvars;
    F:= hompoly(G,avars,hvars,0)
  fi;
  ptset:= {};
  F:= standard(F,hvars);
  if type(F,polynom(rational,hvars)) then
    ptset:= getPoints(F,hvars,avars,homcase,ptset,nrofpts,iPoints)
  fi;
  if nops(ptset) < nrofpts then
    ptset:= getPoints(F,hvars,avars,homcase,ptset,nrofpts,cPoints)
  fi;
  ptlist:= convert(ptset,list);
  if homcase then
    [sort(map(standard,ptlist),shorter)[1..min(nrofpts,nops(ptlist))]]
  else
    ptlist:= affpoint(ptlist);
    [sort(ptlist,shorter)[1..min(nrofpts,nops(ptlist))]]
  fi
end: 



     

##
##    Title   :  algcurve,  the algebraic curves package  ( file 4/5)
##
##    Created :  Jul 24  1992
##
##    Author  :  Stefan Schwendimann
##               Institut fuer Informatik und 
##               angewandte Mathematik
##		 Laenggassstrasse 51 
##		 CH--3012 Bern
##
##		 <schwendi@iam.unibe.ch>
##
##    Documentation :   algcurve.tex (algcurve.ps)
##


macro ( 
  det         =  linalg['det'],
  hessian     =  linalg['hessian'],

  affvars     =  algcurve['affvars'],
  homvars     =  algcurve['homvars'],

# ---  alg1  ----
  iszerolist  =  `algcurve/iszerolist`,
  getindets   =  `algcurve/getindets`,
  dotprod     =  `algcurve/dotprod`,  
  hompoly     =  algcurve['hompoly'],
  hompoint    =  algcurve['hompoint'],
  affpoly     =  algcurve['affpoly'],
  affpoint    =  algcurve['affpoint'],
  standard    =  algcurve['standard'],
  grad        =  algcurve['grad'],

# ---  alg2  ----
  appoly0     =  `algcurve/appoly0`,
  appolyE     =  `algcurve/appolyE`,  
  appoly      =  algcurve['appoly'],
  commoncomp  =  algcurve['commoncomp'],

# ---  alg3  ----
  isregular   =  algcurve['isregular'],
  tangent     =  algcurve['tangent'],

# ---  alg4  ----
  intersection  =  `algcurve/intersection`,
  Polar         =  `algcurve/Polar`,
  tangentthrupt =  `algcurve/tangentthrupt`,
  Hessian       =  `algcurve/Hessian`,
  inflections   =  `algcurve/inflections`,
  intermultiplicity0 =  `algcurve/intermultiplicity0`,
  intermultiplicity  =  `algcurve/intermultiplicity`,
  newrootseq    =  `algcurve/newrootseq`,
  tryall        =  `algcurve/tryall`

):



# ___  INTERSECTION  ________________________________________________________

intersection := proc (F,G)
local vars,homcase, sols,i, sel,t;
  if type([args],[anything,anything,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,anything]) then
    vars:= getindets([F,G])
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type([F,G],list(polynom(algebraic,vars))) then
    ERROR(`illegal arguments`)
  fi;  
  if commoncomp(F,G,vars) then 
    ERROR(`polynomials have a common component`)
  fi;
  sols:= [solve({F,G},convert(vars,set))];
  sols:= `algcurve/patchsolve`(sols):
  sols:= convert( { seq(subs(sols[i],vars),i=1..nops(sols)) }, list);
  homcase:= evalb( nops(vars) = 3  and type(F,projpoly(vars) ));
  if homcase then
    sel:= unapply( 'evalb(not iszerolist(t))',t );
    sols:= select(sel,sols);
    RETURN (map(standard,sols))
  else
    RETURN (eval(sols))        
  fi
end:  


# ___  POLAR  ______________________________________________________

Polar:= proc(F,pt)
local vars, hvars, affcase, tmp;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi;  
  if nops(vars) <> nops(pt) then
    ERROR(`dimension mismatch`)
  fi; 
  affcase:= evalb(nops(pt) = 2);
  if not affcase and not type(F,projpoly(vars)) then
    ERROR(`first argument is not a homogeneous polynomial in`,vars)
  fi;
  if affcase then
    hvars:= homvars;
    tmp:= dotprod(hompoint(pt,0),grad(hompoly(F,vars,hvars,0),hvars));
    RETURN ( affpoly(standard(tmp,hvars),hvars,vars,0) )
  else
    RETURN ( standard(dotprod(pt,grad(F,vars)),vars) )
  fi  
end:  




# ___  TANGENTTHRUPT  ________________________________________________________

tangentthrupt := proc (F,pt)
local vars,polsec,tmp,i,t,sel;
  if type([args],[anything,list,list(name)]) then
    vars:= args[3]
  elif type([args],[anything,list]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(F,polynom(algebraic,vars)) then
    ERROR(`illegal first argument`)
  fi; 
  sel:= unapply('isregular'(F,t,vars),t);
  polsec := select(sel,intersection(F,Polar(F,pt,vars),vars));
  tmp:= NULL;
  for i from 1 to nops(polsec) do
    tmp:= tmp, standard(tangent(F,polsec[i],vars))
  od;
  [tmp]
end:


# ___  INTERMULTIPLICITY  ____________________________________________________

intermultiplicity0 := proc (f,g,pt,vars)
local lf,lg,k,fk,gk,fk0,gk0,v,R;
  if appolyE(f,pt,vars) <> 0  or  appolyE(g,pt,vars) <> 0 then  RETURN( 0 ) fi;
  v:= [vars[1]=vars[1]+pt[1], vars[2]=vars[2]+pt[2]];
  lf:= subs(v,f); 
  lg:= subs(v,g);
  v:=[];
  fk0:= simplify(expand(subs(vars[1]=0,lf)));  
  gk0:= simplify(expand(subs(vars[1]=0,lg)));
  fk0:= expand(fk0/vars[2]^ldegree(fk0,vars[2]));
  gk0:= expand(gk0/vars[2]^ldegree(gk0,vars[2]));
  R:= simplify(resultant(fk0,gk0,vars[2]));
  for k from 0 while R = 0 do
    v:= [vars[1]=k*vars[1]+vars[2], vars[2]=-vars[1]+ k*vars[2]];
    fk0:= simplify(expand(subs(v,vars[1]=0,lf))); 
    gk0:= simplify(expand(subs(v,vars[1]=0,lg)));
    fk0:= expand(fk0/vars[2]^ldegree(fk0,vars[2]));
    gk0:= expand(gk0/vars[2]^ldegree(gk0,vars[2]));
    R:= simplify(resultant(fk0,gk0,vars[2]));
  od;
  fk:= expand(subs(v,lf)); 
  gk:= expand(subs(v,lg));
  R:= simplify(resultant(fk,gk,vars[2]));
  ldegree(R,vars[1])
end:




intermultiplicity := proc(F,G,pt)
local vars,avars, f,g,lpt,actpt,i,nr,lastnr,isptlist,res;
  if type([args],[anything,anything,list,list(name)]) then
    vars:= args[4]
  elif type([args],[anything,anything,list]) then
    vars:= getindets([F,G])
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  isptlist:= type(pt,listlist);
  if isptlist then lpt:= pt else lpt:= [pt] fi;
  if nops(vars) <> nops(lpt[1]) then
    ERROR(`dimension mismatch`)
  fi;
  res:= NULL;
  if nops(vars) = 3 then
    if not type([F,G], list(projpoly(vars))) then
      ERROR(`arguments are not homogeneous polynomials in `,vars)
    fi;
    lastnr:= -1;
    avars:= affvars;
    for i from 1 to nops(lpt) do
      if iszerolist(lpt[i]) then ERROR(`zero coordinates`) fi;
      for nr from 0 to 2 while lpt[i][nr+1]=0 do od;
      if nr <> lastnr then
        f:= affpoly(F,vars,avars,nr); 
        g:= affpoly(G,vars,avars,nr); 
	lastnr:= nr
      fi;
      actpt:= affpoint(lpt[i],nr);
      res:= res, intermultiplicity0(f,g,actpt,avars)
    od
  elif nops(vars) <> 2 then
    ERROR(`illegal number of variables`)
  else
    if not type([F,G], list(polynom(algebraic,vars))) then
      ERROR(`arguments are not polynomials in`,vars)
    fi;
    f:= F;  g:= G; 
    res := seq(intermultiplicity0(f,g,lpt[i],vars), i=1..nops(lpt))
  fi;
  if isptlist then
    [res]
  else
    eval(res)
  fi
end:


      
# ___  HESSIAN  __________________________________________________

Hessian := proc(F)
local vars,hvars,affcase,lF,res;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  affcase:= evalb(nops(vars)=2);
  if affcase then
    if not type(F,polynom(algebraic,vars)) then
      ERROR(`illegal first argument`)
    fi;
    hvars:= homvars;
    lF:= hompoly(F,vars,hvars,0)
  else
    if not type(F,projpoly(vars)) then
      ERROR(`first argument is not a homogeneous polynomial in`,vars)
    fi;    
    hvars:= vars;
    lF:= F
  fi;  
  res:= standard(det(hessian(lF,hvars)),hvars);
  if affcase then
    affpoly(res,hvars,vars,0)
  else
    eval(res)
  fi
end:        

macro(Hessian = algcurve['Hessian']):


# ___  INFLECTIONS  __________________________________________________


inflections := proc (F)
local vars,sols,t,sel,homcase;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= getindets(F)
  else
    ERROR(`wrong type or number of arguments`)
  fi;
  sols:= intersection(F,Hessian(F,vars),vars);
  homcase:= evalb( nops(vars) = 3  and type(F,projpoly(vars) ));
  sel:= unapply('isregular'(F,t,vars),t);
  if homcase then
    map(standard,select(sel,sols))
  else
    select(sel,sols)     
  fi
end:  



# ___  TRYALL  __________________________________________________

newrootseq := proc(eq)
local x,xeq,roots;
options `Copyright 1990 by the University of Waterloo`;
    xeq := subs(_Z = x,eq);
    _EnvExplicit := true;
    roots := [solve(xeq,x)];
    op(roots)
end:

tryall := proc(L)
local lL, sols,i, oldrootseq, optd, optsimpl;
global `allvalues/rootseq`;
  if nargs > 3 then ERROR(`wrong number of arguments`) fi;
  if not type(L,list) then
    ERROR(`wrong type of first argument`)
  fi;
  lL:= L;
  optd:= false; optsimpl:= false;
  if nargs > 1 then
    if nargs = 2 and member(args[2],{'d','simplified'}) then
      if args[2] = 'd' then optd:= true else optsimpl:= true fi
    elif nargs = 3 and {args[2..3]} = {'d','simplified'} then
      optd:= true; optsimpl:= true
    else
      ERROR(`illegal option(s)`)
    fi
  fi;
  readlib(allvalues);
  oldrootseq:= eval(`allvalues/rootseq`);
  `allvalues/rootseq`:= eval(newrootseq);
  if optd then
    sols:= {seq(allvalues(lL[i],'d'),i=1..nops(lL))}
  else
    sols:= {seq(allvalues(lL[i]),i=1..nops(lL))}
  fi;
  `allvalues/rootseq`:= eval(oldrootseq);
  if optsimpl then sols:= map(simplify,sols) fi;
  convert(sols,list)
end:





##
##    Title   :  algcurve,  the algebraic curves package  ( file 5/5)
##
##    Created :  Jul 24  1992
##
##    Author  :  Stefan Schwendimann
##               Institut fuer Informatik und 
##               angewandte Mathematik
##		 Laenggassstrasse 51 
##		 CH--3012 Bern
##
##		 <schwendi@iam.unibe.ch>
##
##    Documentation :   algcurve.tex (algcurve.ps)
##


macro ( 
  affvars     =  algcurve['affvars'],
  homvars     =  algcurve['homvars'],

# ---  alg1  ----
  iszerolist  =  `algcurve/iszerolist`,
  getindets   =  `algcurve/getindets`,
  hompoly     =  algcurve['hompoly'],
  hompoint    =  algcurve['hompoint'],
  affpoly     =  algcurve['affpoly'],
  affpoint    =  algcurve['affpoint'],
  standard    =  algcurve['standard'],

# ---  alg2  ----
  appoly0     =  `algcurve/appoly0`,
  appolyE     =  `algcurve/appolyE`, 
  appoly      =  algcurve['appoly'],

# ---  alg3  ----
  singularities     =  algcurve['singularities'],
  multiplicity =  algcurve['multiplicity'],
  linearsystem =  algcurve['linearsystem'],

# ---  alg5  ----
  implicit    =  `algcurve/implicit`,
  expldeg1    =  `algcurve/expldeg1`,
  explmultnminus1 = `algcurve/explmultnminus1`,
  regcurvept  =  `algcurve/regcurvept`,
  explicit0   =  `algcurve/explicit0`,
  explicit    =  `algcurve/explicit`, 
  quadtrans   =  `algcurve/quadtrans`,
  extractfactors = `algcurve/extractfactors`,
  plotcurve   =  `algcurve/plotcurve`,
  plotcurve0  =  `algcurve/plotcurve0`
):



# ___  IMPLICIT  ________________________________________________________

implicit := proc (V)
local v, var,vars,avars, f,g,affcase,nr;
  if type ([args],[anything,name,list(name)]) then
    var:= args[2];
    vars:= args[3]
  elif type ([args],[anything]) then  
    var:= explvar;
    if nops(V) = 2 then vars:= affvars else vars:= homvars fi
  else  
    ERROR(`wrong type or number of arguments`)
  fi;
  if not type(V, list(ratpoly(algebraic,var))) then
    ERROR(`illegal first argument`)
  fi;
  if nops(vars) < 2 or nops(vars) > 3 then 
    ERROR(`illegal number of variables`) 
  fi;  
  affcase:= evalb(nops(vars) = 2);
  if affcase then 
    v:= V;
    avars:= vars 
  else 
    avars:= affvars;
    if V[1] <> 0 then nr:=0 else nr:=1 fi;
    v:= affpoint(V,nr)
  fi;  
  f:= denom(v[1])*avars[1] - numer(v[1]);
  g:= denom(v[2])*avars[2] - numer(v[2]);
  if affcase then
    standard(resultant (f,g,var),avars)
  else
    standard(hompoly(resultant(f,g,var),avars,vars,nr),vars)
  fi  
end:



# ___  QUADTRANS  ________________________________________________________

quadtrans := proc (F)
local vars,hvars, G,lF, i,k,r, affcase;
  if type([args],[anything,list(name)]) then
    vars:= args[2]
  elif type([args],[anything]) then
    vars:= getindets(F)
  else  
    ERROR(`wrong type or number of arguments`)
  fi;
  if nops(vars) > 3 then ERROR(`Too many variables`) fi;
  affcase:= evalb(nops(vars)=2);
  if affcase then
    if not type(F,polynom(algebraic,vars)) then
      ERROR(`illegal first argument`)
    fi;  
    hvars:= homvars;
    lF:= hompoly(F,vars,hvars,0)
  else
    if not affcase and not type(F,projpoly(vars)) then
      ERROR(`first argument is not a homogeneous polynomial in`,vars)
    fi; 
    hvars:= vars;
    lF:= F
  fi;    
  G:= subs( [ hvars[1]=hvars[2]*hvars[3],hvars[2]=hvars[1]*hvars[3],
              hvars[3]=hvars[1]*hvars[2] ], lF);
  for i from 1 to 3 do
    for k from 0 do
      r:= rem(G,hvars[i],hvars[i],'G');
      if r <> 0 then  G:= expand(G*hvars[i])+r; break fi
    od;
  od;
  if affcase then
    affpoly(G,hvars,vars,0)
  else    	
    eval(G)	
  fi  
end:




# ___  EXPLICIT  ________________________________________________________


expldeg1 := proc (f,avars,hvars,nr, var,invfun)
local sol;
  if has(f,avars[2]) then
    sol:=  solve(f,avars[2]);
    invfun:= hompoly(avars[1],avars,hvars,nr);
    RETURN( [var , subs(avars[1]=var,sol) ] )
  else
    sol:=  solve(f,avars[1]);
    invfun:= hompoly(avars[2],avars,hvars,nr);
    RETURN( [ subs(avars[2]=var,sol) , var] )
   fi
end:     


explmultnminus1 := proc (f,pt,r,avars,hvars,var,invfun)
local tmpnr,apt,G1,G2,g,R,N,phi,i;
  for tmpnr from 0 to 2  while pt[tmpnr+1]=0 do od;
  apt := affpoint(pt,tmpnr);
  G1:= hompoly(avars[2] - apt[2],avars,hvars,tmpnr);
  G2:= hompoly(avars[1] - apt[1],avars,hvars,tmpnr);
  invfun:= G1/G2; 
  g:= affpoly(G1 - var*G2,hvars,avars,0);
  phi:= array([0,0]);
  for i from 1 to 2 do
    R:= expand(resultant(f,g,avars[i mod 2 + 1]));
    N:= degree(R,avars[i]);
    phi[i]:=  -coeff(R,avars[i],N-1)/coeff(R,avars[i],N);
    if simplify(pt[1]) <> 0 then 
      phi[i]:= phi[i] - r*pt[1+i] 
    fi
  od;
  convert(phi,list)
end:  



explicit0 := proc (F,f,hvars,avars,nr,var,invfun)
local n,nL,L,Lpts,spts,r,extrapts,nrofextra,g,k,i,phi,R,N;
  n:= degree(F,convert(hvars,set));
  if n = 1 then RETURN ( expldeg1(f,avars,hvars,nr, var,'invfun') ) fi;
  spts:= singularities(F,hvars);
  r:= multiplicity(F,spts,hvars); 
  if sum('r[i]*(r[i]-1)','i'=1..nops(spts)) <> (n-1)*(n-2) then
    ERROR(`requested precondition not fulfilled`)
  fi;  
  if nops(spts)=1 and r[1] = n-1 then
    RETURN (explmultnminus1(f,spts[1],n-1,avars,hvars,var,'invfun'))
  fi;
  if n = 2 then  
    nrofextra:=   1; nL:= 1  
  else  
    nrofextra:= n-3; nL:= n-2 
  fi;
  extrapts:= RegCurvePts(F,nrofextra,hvars);
  if nops(extrapts) < nrofextra then RETURN(FAIL) fi;
  Lpts:=  [ seq([spts[i],r[i]-1],i=1..nops(spts)),op(extrapts) ];
  L:= linearsystem(Lpts, nL, hvars);
  invfun:= L[1]/L[2];
  extrapts:= affpoint(extrapts,0);
  g:=  affpoly( L[1]-var*L[2], hvars,avars,0); ;
  phi:= array([0,0]);
  for i from 1 to 2 do
    R:= expand(resultant(f,g,avars[i mod 2 + 1]));
    N:= degree(R,avars[i]);
    phi[i]:= -coeff(R,avars[i],N-1)/coeff(R,avars[i],N);
    for k from 1 to nops(spts) do
      if expand(spts[k][1]) <> 0 then 
        phi[i]:= phi[i]-r[k]*(r[k]-1)*spts[k][1+i] 
      fi
    od;
    for k from 1 to nrofextra do phi[i]:= phi[i] - extrapts[k][i] od
  od; 
  convert(phi,list)
end:  
 

explicit := proc (ff,invfun)
local vars,avars,var,affcase,F,f,res,invfun0,nr;
  if type([args],[anything,name,list(name),name]) then
    vars:= args[3];
    var:= args[4]
  elif type([args],[anything,name]) then
    vars:= getindets(ff);
    var:= explvar;
  elif type([args],[anything]) then
    vars:= getindets(ff);
    var:= explvar;
  else  
    ERROR(`wrong type or number of arguments`)
  fi;
  if nops(vars) < 2  or  nops(vars) > 3 then
    ERROR(`illegal number of variables`)
  fi; 
  affcase:= evalb(nops(vars) = 2);   
  nr:= 0;
  if affcase then
    if not type(ff,polynom(algebraic,vars)) then
      ERROR(`illegal first argument`)
    fi;  
    avars:= vars;
    vars:= homvars;
    F:= hompoly(ff,avars,vars,nr);
    f:= ff
  else
    if not type(ff,projpoly(vars)) then
      ERROR(`polynomial is not homogeneous`)
    fi; 
    avars:= affvars;
    F:= ff; 
    if not (has(F,vars[2]) or has(F,vars[3])) then nr:=1 fi;
    f:= affpoly(F,vars,avars,nr);
  fi;  
  res:= explicit0(F,f,vars,avars,nr,var,'invfun0');
  if res <> FAIL then
    if affcase then
      if nargs > 1 then 
        invfun:= affpoly(numer(invfun0),vars,avars,nr) / 
                 affpoly(denom(invfun0),vars,avars,nr)
      fi;
      RETURN(map(normal,res))
    else
      if nargs > 1 then invfun:= invfun0 fi;
      RETURN(standard(hompoint(res,nr)))
    fi
  else
    RETURN(FAIL)
  fi        
end:  



# ___  PLOTCURVE  ________________________________________________________

extractfactors := proc(flist)
local fset,i,j,res;
  readlib(factors);
  fset:= { seq( frontend(factors,[flist[i]]) , i=1..nops(flist) ) };
  res:= NULL;
  for i from 1 to nops(fset) do
    res:= res, [seq(fset[i][2][j][1], j=1..nops(fset[i][2]))]
  od;  
  [res]
end:  


plotcurve0 := proc(curvelist,nrofpts,vars,minx,miny,incrx,incry,rx,ry)
local pts,spts,singlist, ff,xx,yy,sols, curvenr,factornr,i,j, warn;
  pts:= array(1..nops(curvelist));  
  for i from 1 to nops(curvelist) do pts[i]:= NULL od;
  warn:= false;
  xx:= minx; yy:= miny;
  for i from 1 to nrofpts+1 do  
    for curvenr from 1 to nops(curvelist) do  
      for factornr from 1 to nops(curvelist[curvenr]) do
        ff:= subs(vars[1]=xx,curvelist[curvenr][factornr]);
        if has(ff,vars[2]) then 
	  sols:= traperror(fsolve(ff,vars[2],ry));
	  if sols <> lasterror then
	    sols:= [sols];
            pts[curvenr]:= pts[curvenr], seq(op([xx,sols[j]]),j=1..nops(sols))
	  else
	    warn:= true  
	  fi  
        fi;
        ff:= subs(vars[2]=yy,curvelist[curvenr][factornr]);
        if has(ff,vars[1]) then
	  sols:= traperror(fsolve(ff,vars[1],rx));
	  if sols <> lasterror then
	    sols:= [sols];
            pts[curvenr]:= pts[curvenr], seq(op([sols[j],yy]),j=1..nops(sols))
	  else
	    warn:= true  
	  fi  
        fi
      od
    od;      
    xx:= xx+incrx; yy:= yy+incry
  od;
  spts:= array[1..nops(curvelist)];
  for i from 1 to nops(curvelist) do spts[i]:= NULL od;
  for curvenr from 1 to nops(curvelist) do  
    for factornr from 1 to nops(curvelist[curvenr]) do
      sols:= traperror(singularities(curvelist[curvenr][factornr],vars));
      if sols <> lasterror then
        singlist:= map(convert,sols,list);
        for i from 1 to nops(singlist) do
          if not (has(singlist[i],RootOf)) then
            spts[curvenr]:= spts[curvenr], op(singlist[i])
          fi
        od
      else
        warn:= true	
      fi
    od  	
  od;    
  for curvenr from 1 to nops(curvelist) do
    if pts[curvenr] <> NULL then pts[curvenr] := [pts[curvenr]] fi;
    if spts[curvenr] <> NULL then  spts[curvenr]:= [spts[curvenr]] fi
  od;  
  pts:= op(convert(pts,list));  spts:= op(convert(spts,list));
  if warn then
    print(`WARNING: probably loss of some points`)
  fi;  
  RETURN ({pts,spts})
end:


plotcurve := proc (f)
local nrofpts, vars,varset, minx,miny,maxx,maxy, incrx,incry,i,
      drx,dry,rx,ry,curvelist, nonconstant,t ;
  if type([args],[anything,'range','range',posint,list(name)]) then
    nrofpts:= args[4];
    vars:= args[5]
  elif type([args],[anything,anything,anything,posint]) then
    nrofpts:= args[4];
    vars:= affvars
  elif type([args],[anything,anything,anything]) then
    nrofpts:= 40;
    vars:= affvars
  else
    ERROR(`wrong type or number of arguments`)
  fi;    
  
  if nops(vars) <> 2 then 
    ERROR(`illegal number of variables (<> 2)`)
  fi; 
  if type([args[2],args[3]],list('range')) then
    rx:= args[2]; ry:= args[3]
  elif type([args[2],args[3]],list(name='range')) then
    vars:= [ op(1,args[2]), op(1,args[3]) ];
    rx:= op(2,args[2]); ry:= op(2,args[3])
  else
    ERROR(`invalid ranges`)
  fi;
  if type(f,list) then curvelist:= f else curvelist:= [f] fi;  
  if not type(curvelist,list(polynom(algebraic,vars))) then
    ERROR(`illegal first argument`)
  fi;  
  
  minx:= evalf(op(1,rx)); maxx:= evalf(op(2,rx));
  miny:= evalf(op(1,ry)); maxy:= evalf(op(2,ry));
  if not type([minx,maxx],list(numeric)) then
    ERROR(`invalid horizontal range`)
  fi;
  if not type([miny,maxy],list(numeric)) then
    ERROR(`invalid vertical range`)
  fi;    
  drx:= maxx-minx; dry:= maxy-miny;
  rx:= (minx-0.05*drx)..(maxx+0.05*drx);
  ry:= (miny-0.05*dry)..(maxy+0.05*dry);
  incrx:= evalf((maxx-minx)/nrofpts); incry:= evalf((maxy-miny)/nrofpts);
  
  varset:= convert(vars,set);
  curvelist := extractfactors(curvelist);
  nonconstant:= unapply( 'evalb'('degree'( t, varset ) > 0), t );
  curvelist := [seq( select(nonconstant,t), t=curvelist )];
  #for i from 1 to nops(curvelist) do
  #  curvelist[i]:= select(nonconstant,curvelist[i])
  #od; 

  plot( plotcurve0(curvelist,nrofpts,vars,minx,miny,incrx,incry,rx,ry),
        vars[1]=rx,vars[2]=ry,style=POINT)
end:  

macro(
intermultiplicity0 = intermultiplicity0,
intermultiplicity = intermultiplicity,
scalarmul = scalarmul,
crossprod = crossprod,
getindets = getindets,
iszerolist = iszerolist,
hompoint = hompoint,
affpoint = affpoint,
poly2coord = poly2coord,
coord2poly = coord2poly,
standard = standard,
homequal = homequal,
genmatrix = genmatrix,
transpose = transpose,
multiply = multiply,
homtrans = homtrans,
afftrans = afftrans,
image2mat = image2mat,
mat2image = mat2image,
appimage = appimage,
NonCurvePt = NonCurvePt,
multcomp = multcomp,
commoncomp = commoncomp,
homxyfac = homxyfac,
isregular = isregular,
issingular = issingular,
isordinary = isordinary,
curvetaylor = curvetaylor,
singtangent = singtangent,
unityvec = unityvec,
processmult = processmult,
randsyspoly = randsyspoly,
getPoints = getPoints,
RegCurvePts = RegCurvePts,
inflections = inflections,
newrootseq = newrootseq,
implicit = implicit,
expldeg1 = expldeg1,
regcurvept = regcurvept,
explicit0 = explicit0,
explicit = explicit,
quadtrans = quadtrans,
plotcurve = plotcurve,
plotcurve0 = plotcurve0,
NonVertexTrans = NonVertexTrans,
singularities = singularities,
multiplicity = multiplicity,
linearsystem = linearsystem,
intersection = intersection,
tangentthrupt = tangentthrupt,
explmultnminus1 = explmultnminus1,
extractfactors = extractfactors,
affvars = affvars,
hompoly = hompoly,
homvars = homvars,
affpoly = affpoly,
grad = grad,
coldim = coldim,
inverse = inverse,
dotprod = dotprod,
appoly = appoly,
appoly0 = appoly0,
appolyE = appolyE,
appmat = appmat,
PtTrans = PtTrans,
tangent = tangent,
filter = filter,
iPoints = iPoints,
cPoints = cPoints,
shorter = shorter,
hessian = hessian,
Polar = Polar,
Hessian = Hessian,
tryall = tryall,
det = det);

#-----  library procedures ------------------------------------------------

algcurve[homvars] := [x0,x1,x2]:
algcurve[affvars] := [x,y]:
algcurve[explvar] := t:


#---  alg1  ---
algcurve[hompoly] := eval( `algcurve/hompoly` ):
algcurve[hompoint] := eval( `algcurve/hompoint` ):
algcurve[affpoly] := eval( `algcurve/affpoly` ):
algcurve[affpoint] := eval( `algcurve/affpoint` ):
algcurve[poly2coord] := eval( `algcurve/poly2coord` ):
algcurve[coord2poly] := eval( `algcurve/coord2poly` ):
algcurve[standard] := eval( `algcurve/standard` ):
algcurve[homequal] := eval( `algcurve/homequal` ):
algcurve[grad] := eval( `algcurve/grad` ):
  
  
#---  alg2  ---	          
algcurve[homtrans] := eval( `algcurve/homtrans` ):
algcurve[afftrans] := eval( `algcurve/afftrans` ):
algcurve[image2mat] := eval( `algcurve/image2mat` ):
algcurve[mat2image] := eval( `algcurve/mat2image` ):
algcurve[appoly] := eval( `algcurve/appoly` ):
algcurve[appimage] := eval( `algcurve/appimage` ):
algcurve[appmat] := eval( `algcurve/appmat` ):
algcurve[NonCurvePt] := eval( `algcurve/NonCurvePt` ):
algcurve[NonVertexTrans] := eval( `algcurve/NonVertexTrans` ):
algcurve[PtTrans] := eval( `algcurve/PtTrans` ):
algcurve[multcomp] := eval( `algcurve/multcomp` ):
algcurve[commoncomp] := eval( `algcurve/commoncomp` ):


    
#---  alg3  ---

algcurve[singularities] := eval( `algcurve/singularities` ):
algcurve[isregular] := eval( `algcurve/isregular` ):
algcurve[issingular] := eval( `algcurve/issingular` ):
algcurve[isordinary] := eval( `algcurve/isordinary` ):
algcurve[curvetaylor] := eval( `algcurve/curvetaylor` ):
algcurve[multiplicity] := eval( `algcurve/multiplicity` ):
algcurve[tangent] := eval( `algcurve/tangent` ):
algcurve[linearsystem] := eval( `algcurve/linearsystem` ):
algcurve[randsyspoly] := eval( `algcurve/randsyspoly` ):
algcurve[RegCurvePts] := eval( `algcurve/RegCurvePts` ):
  
#---  alg4  ---

algcurve[intersection] := eval( `algcurve/intersection` ):
algcurve[Polar] :=  eval( `algcurve/Polar` ):
algcurve[tangentthrupt] :=  eval( `algcurve/tangentthrupt` ):
algcurve[Hessian] :=  eval( `algcurve/Hessian` ):
algcurve[inflections] :=  eval( `algcurve/inflections` ):
algcurve[intermultiplicity] :=  eval( `algcurve/intermultiplicity` ):
algcurve[tryall] :=  eval( `algcurve/tryall` ):

#---  alg5  ---

algcurve[explicit] :=  eval( `algcurve/explicit` ):
algcurve[implicit] :=  eval( `algcurve/implicit` ):
algcurve[quadtrans] :=  eval( `algcurve/quadtrans` ):
algcurve[plotcurve] :=  eval( `algcurve/plotcurve` ):




`help/text/algcurve` := TEXT(
`   `,
`HELP FOR: The algebraic curves package`,
`      `,
`CALLING SEQUENCE:`,
`   <function>(args)`,
`   algcurve[<function>](args)`,
`      `,
`SYNOPSIS:    `,
`   `,
`- To use an algcurve function, either define that function alone using the`,
`  command with(algcurve, <function>), or define all algcurve functions using`,
`  the command with(algcurve).  Alternatively, invoke the function using the`,
`  long form algcurve[<function>].  This long form notation is necessary`,
`  whenever there is a conflict between a package function name and another `,
`  function used in the same session.`,
`      `,
`- The functions available are:`,
`      `,
`  hompoly	hompoint	affpoly		affpoint	poly2coord`,
`  coord2poly	standard	homequal	grad		appoly	`,
`   `,
`  homtrans	afftrans	image2mat	mat2image	quadtrans	`,
`  appmat	appimage	PtTrans		NonVertexTrans`,
`   `,
`  NonCurvePt	RegCurvePts	commoncomp	multcomp`,
`     `,
`  singularities	isregular	issingular	isordinary	curvetaylor`,
`  multiplicity	tangent		Polar 		linearsystem	randsyspoly`,
`  intersection	tryall		tangentthrupt	Hessian		inflections `,
`  explicit	implicit 	plotcurve	intermultiplicity		`,
`     `,
`      `,
`- For more information on a particular function see ?algcurve[<function>].`,
`      `,
`- Note that the algcurve functions for manipulating coordinates expect`,
`  as input the Maple type list, rather than more general arrays.`,
`  In particular, subscripts are indexed from 1.`,
`      `,
`SEE ALSO: linalg, projgeom, geometry`
):


`help/algcurve/text/Hessian` := TEXT(
`      `,
`FUNCTION: algcurve[Hessian] - Hessian curve of a curve `,
`      `,
`CALLING SEQUENCE:`,
`   Hessian( F, vars )`,
`   Hessian( F )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   vars -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- If F is a homogeneous polynomial in the variables x0,x1,x2 then the Hessian`,
`  curve of  F  is the curve with the equation `,
`   `,
`       det ( (diff(F,xi,xj)) ) = 0 `,
`   `,
`- If F is an affine polynomial in two variables then the Hessian curve of the`,
`  associated homogeneous polynomial is constructed and the result is transformed`,
`  into the affine plane.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  Hessian(..) only after performing the command with(algcurve) or `,
`  with(algcurve, Hessian). The function can always be accessed in the long `,
`  form algcurve[Hessian](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> Hessian ( y^2 + x^3 - x^2 );`,
`                                 2    2        2`,
`                                x  - y  + 3 x y`,
`   `,
`> Hessian ( x0*x2^2 + x1^3 - x0*x1^2 );`,
`                                2        2          2`,
`                           x0 x1  - x0 x2  + 3 x1 x2`,
`   `,
`> Hessian ( x1^3 + x0*x2^2 );`,
`                                          2`,
`                                     x1 x2`,
`   `,
`      `,
`SEE ALSO:  algcurve[Polar], algcurve[quadtrans], linalg[hessian]`
):
`help/algcurve/text/NonCurvePt` := TEXT(
`      `,
`FUNCTION: algcurve[NonCurvePt] - find a point not on the curve`,
`      `,
`CALLING SEQUENCE:`,
`   NonCurvePt(F, nr, exlist, vars)`,
`   NonCurvePt(F, nr)`,
`   NonCurvePt(F, vars)`,
`   NonCurvePt(F)`,
`      `,
`PARAMETERS:`,
`   F      -  multivariate polynomial in vars`,
`   nr     -  (optional) nonnegative integer`,
`   exlist -  (optional) list of lists`,
`   vars   -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The function NonCurvePt is searching for a simple point not lying on the`,
`  curve F and not being member of the exception list exlist. 'simple' means`,
`  that the point has integer coordinates and lies near the affine origin with`,
`  respect to the nr-th coordinate neighbourhood. If F is a homogeneous`,
`  polynomial in x0,x1,x2 and nr = 0 then the result is a tuple (1,a,b) where `,
`  a,b are relatively small integers.`,
`   `,
`- The function accepts both : homogeneous polynomials in 3 variables and`,
`  affine polynomials in 2 variables for F. In the latter case the result is a`,
`  list with affine coordinates.`,
`      `,
`- If nr is specified or vars has three elements then F must be a homogeneous`,
`  polynomial in vars. If nr is omitted then it defaults to 0.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or`,
`  algcurve[affvars]  (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  NonCurvePt(..) only after performing the command with(algcurve) or`,
`  with(algcurve, NonCurvePt). The function can always be accessed in the long`,
`  form algcurve[NonCurvePt](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> f:= y^2 + x^3 - x^2;   F:= hompoly( f );`,
`                                     2    3    2`,
`                               f := y  + x  - x`,
`   `,
`                                    2     3        2`,
`                          F := x0 x2  + x1  - x0 x1`,
`   `,
`> NonCurvePt( f );`,
`                                    [1, 1]`,
`   `,
`> NonCurvePt( F );`,
`                                   [1, 1, 1]`,
`   `,
`> NonCurvePt( F, 1 );  `,
`                                   [0, 1, 0]`,
`   `,
`> NonCurvePt( F, 2 );`,
`                                   [1, 0, 1]`,
`   `,
`> NonCurvePt( F, 1, [[0,1,0],[1,1,1]], [x0,x1,x2] );`,
`                                   [0, 1, 1]`,
`   `,
`      `,
`SEE ALSO:  algcurve[hompoint], algcurve[RegCurvePts]`
):
`help/algcurve/text/NonVertexTrans` := TEXT(
`      `,
`FUNCTION: algcurve[NonVertexTrans] - transform a curve away from the `,
`                                     fundamental points`,
`      `,
`CALLING SEQUENCE:`,
`   NonVertexTrans( F, prelist, vars )`,
`   NonVertexTrans( F )`,
`      `,
`PARAMETERS:`,
`   F       -  homogeneous polynomial in vars`,
`   prelist -  (optional) list of at most three lists `,
`   vars    -  (optional) list of three names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function NonVertexTrans computes a simple linear transformation, which, `,
`  applied to F yields a projective equivalent curve F' avoiding the`,
`  fundamental points (1,0,0), (0,1,0), (0,0,1) (also called 'vertices of`,
`  reference'). The result is an integer matrix of the projective linear group `,
`  PGL(3,C).`,
`      `,
`- If prelist is specified then (1,0,0) is mapped to prelist[1], (0,1,0) to`,
`  prelist[2] and (0,0,1) to prelist[3]. If prelist has less than three elements`,
`  then the image coordinates for the remaining vertices are chosen as described`,
`  above.   `,
`  Example : to transform a singularity (a0,a1,a2) of F into the affine`,
`  origin one has to call NonVertexTrans(F,[[a0,a1,a2]],vars) and apply the `,
`  the matrix to F. One gets a curve F' with a singularity in (1,0,0) and`,
`  which does not contain (0,1,0) and (0,0,1).`,
`   `,
`- If vars is omitted then it defaults to algcurve[homvars].`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  NonVertexTrans(..) only after performing the command with(algcurve) or`,
`  with(algcurve, NonVertexTrans). The function can always be accessed in the `,
`  long form algcurve[NonVertexTrans](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> F:= x0*x2^2 + x0*x1^2 + x1^3;`,
`                                    2        2     3`,
`                          F := x0 x2  + x0 x1  + x1`,
`> M:= NonVertexTrans( F );`,
`                                    [ 1  0  1 ]`,
`                                    [         ]`,
`                               M := [ 1  1  0 ]`,
`                                    [         ]`,
`                                    [ 0  0  1 ]`,
`> appmat ( M, F );`,
`                           2                      2            3`,
`               (x0 + x2) x2  + (x0 + x2) (x0 + x1)  + (x0 + x1)`,
`   `,
`> M:= NonVertexTrans( F, [[1,4,5]], [x0,x1,x2] );`,
`                                    [ 1  0  1 ]`,
`                                    [         ]`,
`                               M := [ 4  1  0 ]`,
`                                    [         ]`,
`                                    [ 5  0  1 ]`,
`      `,
`SEE ALSO:   algcurve[PtTrans], algcurve[appmat], linalg[matrix]`
):
`help/algcurve/text/Polar` := TEXT(
`      `,
`FUNCTION: algcurve[Polar] - Polar of a curve relative to a point`,
`      `,
`CALLING SEQUENCE:`,
`   Polar( F, pt, vars )`,
`   Polar( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- If F is a homogeneous polynomial in the variables x0,x1,x2 then the polar`,
`  relative to the point (a0,a1,a2) is the curve with the equation`,
`   `,
`       a0*diff(F,x0) + a1*diff(F,x1) + a2*diff(F,x2) = 0`,
`   `,
`- If F is an affine polynomial in two variables then the Polar of the`,
`  associated homogeneous polynomial is constructed and the result is transformed`,
`  into the affine plane.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  Polar(..) only after performing the command with(algcurve) or `,
`  with(algcurve, Polar). The function can always be accessed in the long `,
`  form algcurve[Polar](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> Polar ( x0*x2 - x1^2, [ 1, 0, -1 ] );`,
`                                    x0 - x2`,
`   `,
`> Polar ( x^2 + y^2 - 1, [ 1, 1 ] );`,
`                                   1 - x - y`,
`   `,
`> Polar ( x1^3 + x2^3 - 3*x0*x1*x2 , [ 0, 0, 1 ] );`,
`                                            2`,
`                                  x0 x1 - x2`,
`      `,
`SEE ALSO:  algcurve[Hessian], algcurve[quadtrans]`
):
`help/algcurve/text/PtTrans` := TEXT(
`      `,
`FUNCTION: algcurve[PtTrans] - transformation defined through points`,
`      `,
`CALLING SEQUENCE:`,
`   PtTrans( L1, L2 )`,
`   PtTrans( L2 )`,
`      `,
`PARAMETERS:`,
`   L1  -  (optional) list of lists`,
`   L2  -  list of lists`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function PtTrans computes a matrix M, which, applied to curve F  yields a`,
`  projective equivalent curve F' such that the points of L2 with respect to F'`,
`  correspond to the points of L1 with respect to F. For example if L1[1] lies on`,
`  F then L2[1] lies on F'. The result is the inverse of the matrix which maps `,
`  the points of L1 to the points of L2.`,
`      `,
`- L1 and L2 must have the same number of elements, and this number must be`,
`  equal to the dimension of the points of L1 and L2 (in general: a linear`,
`  mapping of dimension n is determined by n pairs of points of dimension n).`,
`   `,
`- If L1 is omitted then L1 is taken to be [ [1,0,0],[0,1,0],[0,0,1] ], i.e.`,
`  the fundamental points will be mapped to  L2[1] .. L2[3].`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  PtTrans(..) only after performing the command with(algcurve) or with(algcurve,`,
`  PtTrans). The function can always be accessed in the long form `,
`  algcurve[PtTrans](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> L1:= [ [1,2,3], [0,1,4], [2,2,1] ]:`,
`   `,
`> L2:= [ [1,1,2], [-1,0,1], [1,0,-2] ]:`,
`   `,
`> F:= x0*x2^2 + x0*x1^2 + x1^3:`,
`   `,
`> appoly ( F, L1 );`,
`                                   [0, 0, 5]`,
`> A:= PtTrans(L1,L2);`,
`                                  [ -3   8   -2 ]`,
`                                  [             ]`,
`                             A := [  6  -15   4 ]`,
`                                  [             ]`,
`                                  [ -1   -1   1 ]`,
`> G:= appmat( A, F );`,
`                                             2`,
` G := (- 3 x0 + 8 x1 - 2 x2) (- x0 - x1 + x2)`,
`   `,
`                                                    2                        3`,
`      + (- 3 x0 + 8 x1 - 2 x2) (6 x0 - 15 x1 + 4 x2)  + (6 x0 - 15 x1 + 4 x2)`,
`   `,
`> appoly ( G, L2 );`,
`                                   [0, 0, 5]`,
`   `,
`> appmat ( linalg[inverse]( A ), L1 );`,
`                      [[1, 1, 2], [-1, 0, 1], [1, 0, -2]]`,
`      `,
`SEE ALSO:  algcurve[NonVertexTrans], algcurve[appmat], algcurve[appoly],`,
`           linalg[inverse]`
):
`help/algcurve/text/RegCurvePts` := TEXT(
`      `,
`FUNCTION: algcurve[RegCurvePts] - find regular points on a curve`,
`      `,
`CALLING SEQUENCE:`,
`   RegCurvePts( F, nrofpts, vars )`,
`   RegCurvePts( F, nrofpts )`,
`      `,
`PARAMETERS:`,
`   F       -  multivariate polynomial in vars`,
`   nrofpts -  positive integer`,
`   vars    -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The function RegCurvePts looks for nrofpts simple regular points lying on`,
`  the curve F. 'simple' means points with integers or rationals or other short`,
`  expressions as coordinates.`,
`      `,
`- If F is a homogeneous polynomial in three variables then the result is a list`,
`  of nrofpts projective coordinates, and in the affine case a list of nrofpts`,
`  affine coordinates.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  RegCurvePts(..) only after performing the command with(algcurve) or`,
`  with(algcurve, RegCurvePts). The function can always be accessed in the long`,
`  form algcurve[RegCurvePts](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> RegCurvePts ( y^2 + x^3 - x^2, 4 );`,
`                     [[1, 0], [-3, 6], [-3, -6], [-8, 24]]`,
`   `,
`> f:= x^4 + x^2*y^2 - 2*x^2*y - x*y^2 + y^2;`,
`                            4    2  2      2        2    2`,
`                      f := x  + x  y  - 2 x  y - x y  + y`,
`   `,
`> RegCurvePts ( f, 4 ); `,
`                 [[1, 1], [1/2, 1/6], [1/2, 1/2], [1/5, 1/15]]`,
`   `,
`> RegCurvePts ( hompoly ( f ), 4 );`,
`                 [[1, 1, 1], [2, 1, 1], [6, 3, 1], [15, 3, 1]]`,
`   `,
`      `,
`SEE ALSO:  algcurve[singularities], algcurve[NonCurvePt], algcurve[isregular]`
):
`help/algcurve/text/algcurve` := TEXT(
`   `,
`HELP FOR: The algebraic curves package`,
`      `,
`CALLING SEQUENCE:`,
`   <function>(args)`,
`   algcurve[<function>](args)`,
`      `,
`SYNOPSIS:    `,
`   `,
`- To use an algcurve function, either define that function alone using the`,
`  command with(algcurve, <function>), or define all algcurve functions using`,
`  the command with(algcurve).  Alternatively, invoke the function using the`,
`  long form algcurve[<function>].  This long form notation is necessary`,
`  whenever there is a conflict between a package function name and another `,
`  function used in the same session.`,
`      `,
`- The functions available are:`,
`      `,
`  hompoly	hompoint	affpoly		affpoint	poly2coord`,
`  coord2poly	standard	homequal	grad		appoly	`,
`   `,
`  homtrans	afftrans	image2mat	mat2image	quadtrans	`,
`  appmat	appimage	PtTrans		NonVertexTrans`,
`   `,
`  NonCurvePt	RegCurvePts	commoncomp	multcomp`,
`     `,
`  singularities	isregular	issingular	isordinary	curvetaylor`,
`  multiplicity	tangent		Polar 		linearsystem	randsyspoly`,
`  intersection	tryall		tangentthrupt	Hessian		inflections `,
`  explicit	implicit 	plotcurve	intermultiplicity		`,
`     `,
`      `,
`- For more information on a particular function see algcurve[<function>].`,
`      `,
`- Note that the algcurve functions for manipulating coordinates expect`,
`  as input the Maple type list, rather than more general arrays.`,
`  In particular, subscripts are indexed from 1.`,
`      `,
`SEE ALSO: linalg, projgeom, geometry`
):
`help/algcurve/text/appimage` := TEXT(
`      `,
`FUNCTION: algcurve[appimage] - application of a transformation`,
`      `,
`CALLING SEQUENCE:`,
`   appimage( T, F, vars )`,
`   appimage( T, F )`,
`      `,
`PARAMETERS:`,
`   T     -  list of polynomials in vars`,
`   F     -  polynomial in vars`,
`   vars  -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function appimage performs an application of the transformation T to the `,
`  polynomial F. T must be given as a list of image coordinates of the `,
`  indeterminate coordinates,  The result is the image of T under the map  `,
`  vars -> F(vars).`,
`      `,
`- If vars is omitted, it is taken to be algcurve[homvars] or algcurve[affvars]`,
`  (depending on the variables in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  appimage(..) only after performing the command with(algcurve) or `,
`  with(algcurve,  appimage). The function can always be accessed in the long `,
`  form algcurve[appimage](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> f:= y^2 + x^3 - x^2;  F:= hompoly( f );`,
`                                     2    3    2`,
`                               f := y  + x  - x`,
`   `,
`                                    2     3        2`,
`                          F := x0 x2  + x1  - x0 x1`,
`   `,
`> t:= [ x + a , y + b ];  T:= homtrans( t );`,
`                              t := [x + a, y + b]`,
`   `,
`                        T := [x0, x1 + x0 a, x2 + x0 b]`,
`   `,
`> appimage ( t, f );`,
`                               2          3          2`,
`                        (y + b)  + (x + a)  - (x + a)`,
`   `,
`> appimage ( T, F );`,
`                             2              3                 2`,
`               x0 (x2 + x0 b)  + (x1 + x0 a)  - x0 (x1 + x0 a)`,
`   `,
`   `,
`      `,
`SEE ALSO:  algcurve[appoly], algcurve[appmat]`
):
`help/algcurve/text/appmat` := TEXT(
`      `,
`FUNCTION: algcurve[appmat] - application of a matrix to a curve/point`,
`      `,
`CALLING SEQUENCE:`,
`   appmat( M, F, vars )`,
`   appmat( M, F )`,
`   appmat( M, pt )`,
`      `,
`PARAMETERS:`,
`   M    -  matrix`,
`   F    -  homogeneous polynomial in vars`,
`   pt   -  list `,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- If the second argument is a homogeneous polynomial then the result is the `,
`  projective equivalent polynomial of F with respect to M.`,
`      `,
`- If the second argument is a point then the image of pt under the linear `,
`  transformation M is computed.`,
`   `,
`- If vars is omitted then vars is taken to be algcurve[homvars].`,
`   `,
`- The function accepts whole lists of points as second argument.`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  appmat(..) only after performing the command with(algcurve) or with(algcurve,`,
`  appmat). The function can always be accessed in the long form `,
`  algcurve[appmat](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> M:= linalg[matrix] ([ [1,0,0], [c,a,b], [f,d,e] ]);`,
`                                    [ 1  0  0 ]`,
`                                    [         ]`,
`                               M := [ c  a  b ]`,
`                                    [         ]`,
`                                    [ f  d  e ]`,
`   `,
`> appmat ( M, y^3 - x*z^2, [x,y,z] );`,
`                                    3                      2`,
`                   (c x + a y + b z)  - x (f x + d y + e z)`,
`   `,
`> appmat ( M, x1 );`,
`                              a x1 + b x2 + x0 c`,
`   `,
`> appmat ( M, [1,2,2] ); `,
`                       [1, c + 2 a + 2 b, f + 2 d + 2 e]`,
`   `,
`> appmat ( M, [ [1,0,0], [0,1,0], [0,0,1] ] );  `,
`                       [[1, c, f], [0, a, d], [0, b, e]]`,
`   `,
`      `,
`SEE ALSO:  algcurve[appoly], algcurve[appimage], linalg[matrix]`,
`   `,
`   `
):
`help/algcurve/text/appoly` := TEXT(
`      `,
`FUNCTION: algcurve[appoly] - application of a polynomial to a point `,
`      `,
`CALLING SEQUENCE:`,
`   appoly( F, pt, vars )`,
`   appoly( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- This function performs an application of a polynomial to a point, i.e `,
`  the result is the image of pt under the map  vars -> F(vars).`,
`   `,
`- The function accepts lists of polynomials as first argument and lists of `,
`  coordinates as second argument.`,
`      `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  appoly(..) only after performing the command with(algcurve) or with(algcurve,`,
`  appoly). The function can always be accessed in the long form `,
`  algcurve[appoly](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> f:= x^6 - x^2*y^3 - y^5;  `,
`                                   6    2  3    5`,
`                             f := x  - x  y  - y`,
`> appoly ( f, [0,0] );`,
`                                       0`,
`   `,
`> appoly ( f, [ [-2,2], [-3,3], [2,4] ] );`,
`                                [0, 243, -1216]`,
`   `,
`> appoly ( grad (f), [-2,2] );`,
`                                 [-160, -128]`,
`   `,
`> appoly ( x0 - 3*x1 + 5*x2, [0,a,b] ); `,
`                                  - 3 a + 5 b`,
`   `,
`      `,
`SEE ALSO:  algcurve[appmat], algcurve[appimage]`
):
`help/algcurve/text/commoncomp` := TEXT(
`      `,
`FUNCTION: algcurve[commoncomp] - check for a common component`,
`FUNCTION: algcurve[multcomp] - check for a multiple component`,
`      `,
`CALLING SEQUENCE:`,
`   commoncomp( F, G, vars )`,
`   commoncomp( F, G )`,
`   `,
`   multcomp( F, vars )`,
`   multcomp( F )`,
`      `,
`PARAMETERS:`,
`   F, G  -  multivariate polynomials in vars`,
`   vars  -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function commoncomp checks whether F and G have a common component or not.`,
`  The result is a boolean.`,
`      `,
`- The function multcomp checks whether F has a multiple component or not.`,
`  The result is a boolean.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- These functions are part of the algcurve package, and so can be used in the `,
`  form  commoncomp(..), multcomp(..) only after performing the command `,
`  with(algcurve) or with(algcurve, commoncomp, multcomp). The functions can `,
`  always be accessed in the long form algcurve[commoncomp](..), `,
`  algcurve[multcomp](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> multcomp(x^2);`,
`                                      true`,
`> multcomp(x*y);`,
`                                     false`,
`   `,
`> F:= (x0-x1)^2 * (2*x1*x0 + x2^2);`,
`                                      2              2`,
`                        F := (x0 - x1)  (2 x1 x0 + x2 )`,
`> multcomp( F );`,
`                                      true`,
`> multcomp( F, [x2] );`,
`                                     false`,
`   `,
`> G:= (x0 - x1)*(x0 + x2);`,
`                            G := (x0 - x1) (x0 + x2)`,
`   `,
`> commoncomp( F, G ); `,
`                                      true`,
`   `,
`> commoncomp( F, G, [x2] );`,
`                                     false`,
`   `,
`> commoncomp( x, y ); `,
`                                     false`,
`   `,
`   `,
`      `,
`SEE ALSO:  resultant, discrim`
):
`help/algcurve/text/curvetaylor` := TEXT(
`      `,
`FUNCTION: algcurve[curvetaylor] - complete taylor series expansion`,
`      `,
`CALLING SEQUENCE:`,
`   curvetaylor( F, pt, vars )`,
`   curvetaylor( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The complete multivariate taylor series expansion of the polynomial F in`,
`  vars at the point pt is computed. `,
`      `,
`- If pt contains indeterminates then pt is assumed to be a point on the curve `,
`  and the term of order 0 is removed from the expansion.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  curvetaylor(..) only after performing the command with(algcurve) or `,
`  with(algcurve, curvetaylor). The function can always be accessed in the long `,
`  form algcurve[curvetaylor](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> circle := x^2 + y^2 - 1; `,
`                                        2    2`,
`                             circle := x  + y  - 1`,
`   `,
`> curvetaylor ( circle, [0,-1] );`,
`                                        2          2`,
`                           - 2 y - 2 + x  + (y + 1)`,
`   `,
`> curvetaylor ( circle, [a,b] );`,
`                                                   2          2`,
`                2 a (x - a) + 2 b (y - b) + (x - a)  + (y - b)`,
`   `,
`> curvetaylor ( x1^3 - x0*x2^2, [1,0,0] );`,
`                               2     3              2`,
`                           - x2  + x1  - (x0 - 1) x2`,
`   `,
`      `,
`SEE ALSO:  algcurve[multiplicity], mtaylor, taylor`
):
`help/algcurve/text/explicit` := TEXT(
`      `,
`FUNCTION: algcurve[explicit] - explicit representation of a curve`,
`      `,
`CALLING SEQUENCE:`,
`   explicit( F, 'inv', vars, var )`,
`   explicit( F, 'inv' )`,
`   explicit( F )`,
`      `,
`PARAMETERS:`,
`   F     -  multivariate polynomial in vars`,
`   'inv' -  (optional) unevaluated name`,
`   var   -  (optional) name`,
`   vars  -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The function explicit computes the explicit representation of the curve F,`,
`  i.e a tuple of rational functions in the variable var. The length of the tuple`,
`  is equal to the length of vars. Actually, the function only accepts rational`,
`  curves fulfilling the condition `,
`   `,
`     (n-1)*(n-2)  =  sum ( ri*(ri-1) ) ,`,
`   `,
`  where n is the degree of F with respect to vars and the ri's are the `,
`  multiplicities of the singularities.`,
`   `,
`- The optional argument 'inv' is assigned the rational function in vars, which`,
`  gives for almost all points on the curve F the corresponding parameter value,`,
`  i.e. if (x,y) lies on the curve and phi is the resulting tuple of functions `,
`  then  (x,y) = ( phi[1](inv(x,y)), phi[2](inv(x,y)) ) .`,
`         `,
`- If var is omitted then it defaults to algcurve[explvar].`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars]  (depending on the length of phi).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  explicit(..) only after performing the command with(algcurve) or`,
`  with(algcurve, explicit). The function can always be accessed in the long`,
`  form algcurve[explicit](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> explicit ( x - y + c ); `,
`                                   [t, t + c]`,
`   `,
`> explicit ( x^2 + y^2 - 1, 'inv' ); `,
`                                                  2`,
`                                    t      - 1 + t`,
`                            [- 2 ------, - --------]`,
`                                      2          2`,
`                                 1 + t      1 + t`,
`   `,
`> inv;   `,
`                                     y - 1`,
`                                     -----`,
`                                       x`,
`   `,
`> F:= x1^4 + 2*x1^2*x2^2 + x2^4 + 3*x0*x1^2*x2 - x0*x2^3;`,
`                      4       2   2     4          2           3`,
`               F := x1  + 2 x1  x2  + x2  + 3 x0 x1  x2 - x0 x2`,
`   `,
`> explicit ( F, 'inv' );`,
`                          2    4            2    2         2`,
`                  [1 + 2 t  + t , t (- 3 + t ), t  (- 3 + t )]`,
`> inv;   `,
`                                       x2`,
`                                      ----`,
`                                       x1`,
`   `,
`> explicit ( x^6 - x^2*y^3 - y^5 );`,
`                                 3    5   6    4`,
`                               [t  + t , t  + t ]`,
`      `,
`SEE ALSO:  algcurve[implicit], algcurve[explvar]`
):
`help/algcurve/text/grad` := TEXT(
`   `,
`FUNCTION: algcurve[grad] - vector gradient of a polynomial`,
`      `,
`CALLING SEQUENCE:`,
`   grad(F, vars)`,
`   grad(F)   `,
`      `,
`PARAMETERS:`,
`   F     - polynomial in vars`,
`   vars  - (optional) list of names`,
`      `,
`SYNOPSIS:   `,
`- The function grad computes the gradient of F with respect to vars.`,
`      `,
`- That is, it computes the following list of partial derivatives:`,
`      `,
`      [ diff(F,vars[1]), diff(F,vars[2]), ... ] `,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`     `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  grad(..) only after performing the command with(algcurve) or with(algcurve,`,
`  grad). The function can always be accessed in the long form `,
`  algcurve[grad](..).`,
`      `,
`EXAMPLES:   `,
`> with (algcurve):`,
`> grad( y^2 + x^3 - x^2 );`,
`                                   2`,
`                               [3 x  - 2 x, 2 y]`,
`   `,
`> grad( hompoly( y^2 + x^3 - x^2 ) ); `,
`                        2     2      2`,
`                     [x2  - x1 , 3 x1  - 2 x0 x1, 2 x0 x2]`,
`   `,
`SEE ALSO: type[projpoly], algcurve[homvars]`
):
`help/algcurve/text/homequal` := TEXT(
`      `,
`FUNCTION: algcurve[homequal] - check for projective equivalent coordinates`,
`      `,
`CALLING SEQUENCE:`,
`   homequal(p1,p2)`,
`      `,
`PARAMETERS:`,
`   p1 - list (type projcoord)`,
`   p2 - list (type projcoord)`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function homequal checks whether the coordinates p1 and p2 are projective`,
`  equivalent or not. Result is one of the boolean values true or false.`,
`      `,
`- If n is the length of p1 and p2 then it is assumed that p1 and p2 are members`,
`  of a (n-1)-dimensional projective space.`,
`   `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  homequal(..) only after performing the command with(algcurve) or`,
`  with(algcurve, homequal). The function can always be accessed in the long`,
`  form algcurve[homequal](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> homequal( [1,2,3], [2,4,6] );`,
`                                     true`,
`> homequal( [1,2,3], [2,4,5] );`,
`                                     false`,
`   `,
`> homequal( [3,4,6,8], [3*I, 4*I, 6*I, 8*I] ); `,
`                                     true`,
`   `,
`> v:= [ a^3*(b-1)^d , a, a*b ]; `,
`                                 3        d`,
`                          v := [a  (b - 1) , a, a b]`,
`   `,
`> w:= standard( v );`,
`                                  2        d`,
`                           w := [a  (b - 1) , 1, b]`,
`   `,
`> homequal( v, w );`,
`                                     true`,
`   `,
`      `,
`SEE ALSO:  algcurve[standard], type[projcoord]`
):
`help/algcurve/text/hompoint` := TEXT(
`      `,
`FUNCTION: algcurve[hompoint] - homogeneous form of an affine point`,
`FUNCTION: algcurve[affpoint] - affine form of an projective point`,
`      `,
`CALLING SEQUENCE:`,
`   hompoint(pt, nr)`,
`   hompoint(pt)`,
`   `,
`   affpoint(Pt, nr)`,
`   affpoint(Pt)`,
`   `,
`      `,
`PARAMETERS:`,
`   pt  -  list`,
`   Pt  -  list `,
`   nr  -  (optional) nonnegative integer`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The function hompoint computes the corresponding projective coordinates of pt`,
`  with respect to the nr-th coordinate neighbourhood.`,
`      `,
`- The function affpoint computes the corresponding affine coordinates of Pt`,
`  with respect to the nr-th coordinate neighbourhood. If Pt[nr+1] = 0 then`,
`  the empty sequence NULL is returned.`,
`   `,
`- nr must be a nonnegative integer between 0 and the length of pt (or the length`,
`  of Pt minus 1 respectively). Default is 0.`,
`   `,
`- The functions accept lists of points as first argument.`,
`        `,
`- The functions are part of the algcurve package, and so can be used in the form`,
`  hompoint(..), affpoint(..) only after performing the command with(algcurve)`,
`  or with(algcurve, hompoint), with(algcurve, affpoint). The functions can`,
`  always be accessed in the long form algcurve[hompoint](..), `,
`  algcurve[affpoint](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> hompoint( [a,b] );`,
`                                   [1, a, b]`,
`   `,
`> hompoint( [a,b], 1 );`,
`                                   [a, 1, b]`,
`   `,
`> hompoint( [a,b] , 2 ); `,
`                                   [a, b, 1]`,
`   `,
`> affpoint( ", 2 );`,
`                                     [a, b]`,
`   `,
`> affpoint( [ 3, 1+I, 6/5 ] );`,
`                               [1/3 + 1/3 I, 2/5]`,
`   `,
`> affpoint( [ a, b, c ] ); `,
`                                   [b/a, c/a]`,
`      `,
`SEE ALSO:  type[projcoord], algcurve[homequal], algcurve[hompoly]`
):
`help/algcurve/text/hompoly` := TEXT(
`      `,
`FUNCTION: algcurve[hompoly] - homogeneous form of a polynomial`,
`FUNCTION: algcurve[affpoly] - affine form of a homogeneous polynomial`,
`      `,
`CALLING SEQUENCE:`,
`   hompoly(f, avars, hvars, nr)`,
`   hompoly(f, nr)`,
`   hompoly(f)`,
`   `,
`   affpoly(F, hvars, avars, nr)`,
`   affpoly(F, nr)`,
`   affpoly(F)`,
`      `,
`PARAMETERS:`,
`   f      -  multivariate polynomial in  avars`,
`   F      -  homogeneous polynomial in hvars`,
`   avars  -  (optional) list of names`,
`   hvars  -  (optional) list of names`,
`   nr     -  (optional) nonnegative integer`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function hompoly computes the associated homogeneous polynomial of f`,
`  with respect to the nr-th coordinate neighbourhood. If f(x,y) is an affine`,
`  polynomial with degree n in x,y then the result is`,
`   `,
`     F(x0,x1,x2) = x0^n * f(x1/x0,x2/x0)   (nr = 0),`,
`     F(x0,x1,x2) = x1^n * f(x0/x1,x2/x1)   (nr = 1),`,
`     F(x0,x1,x2) = x2^n * f(x0/x2,x1/x2)   (nr = 2).`,
`   `,
`- The function affpoly computes the associated affine polynomial of the`,
`  homogeneous polynomial F with respect to the nr-th coordinate neighbourhood.`,
`  If F(x0,x1,x2) is homogeneous in x0,x1,x2 then the result is`,
`   `,
`     f(x,y) = F(1,x,y)   (nr = 0),   `,
`     f(x,y) = F(x,1,y)   (nr = 1),`,
`     f(x,y) = F(x,y,1)   (nr = 2).`,
`   `,
`- nr must be a nonnegative integer between zero and the length of avars (i.e.`,
`  the dimension of the affine space). The default value of nr is 0.`,
`      `,
`- The lists avars/hvars contain the affine/homogeneous variable names. If they`,
`  are omitted then they are taken to be algcurve[affvars]/algcurve[homvars].`,
`        `,
`- The functions accept whole lists of polynomials as first argument.`,
`   `,
`- The functions are part of the algcurve package, and so can be used in the form`,
`  hompoly(..), affpoly(..) only after performing the command with(algcurve) or`,
`  with(algcurve,hompoly). The functions can always be accessed in the long form `,
`  algcurve[hompoly](..),algcurve[affpoly](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> f:= a*x + b*y + 1; `,
`                               f := a x + b y + 1`,
`   `,
`> F:= hompoly(f);`,
`                             F := a x1 + b x2 + x0`,
`   `,
`> affpoly(F);`,
`                                 a x + b y + 1`,
`   `,
`> hompoly(f,2);`,
`                                a x0 + b x1 + x2`,
`   `,
`> hompoly( y^2 + x^3 - x^2 ,[x,y], [u,v,w], 2 ); `,
`                                   2    3      2`,
`                                w v  + u  - w u`,
`> affpoly( " , [u,v,w], [x,y], 2 ); `,
`                                   2    3    2`,
`                                  y  + x  - x`,
`      `,
`SEE ALSO:  algcurve[affvars], algcurve[homvars], algcurve[hompoint]`
):
`help/algcurve/text/homtrans` := TEXT(
`      `,
`FUNCTION: algcurve[homtrans] - homogeneous form of an affine transformation`,
`FUNCTION: algcurve[afftrans] - affine form of a homogeneous transformation`,
`    `,
`CALLING SEQUENCE:  `,
`   homtrans(t, avars, hvars, nr)`,
`   homtrans(t, nr)`,
`   homtrans(t)`,
`   `,
`   afftrans(T, hvars, avars, nr)`,
`   afftrans(T, nr)`,
`   afftrans(T)`,
`      `,
`PARAMETERS:`,
`   t      -  list of polynomials in  avars`,
`   T      -  list of homogeneous polynomials in hvars`,
`   avars  -  (optional) list of names`,
`   hvars  -  (optional) list of names`,
`   nr     -  (optional) nonnegative integer`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The transformations t and T must be given as image coordinates of the in-`,
`  determinate point. That is, if A is a map or a coordinate transformation, `,
`  then t = A(avars) or T = A(hvars) respectively. t and T may also be `,
`  considered as images of the fundamental lines (i.e. in the homogeneous case `,
`  of the lines x0 = 0, x1 = 0, x2 = 0). `,
`   `,
`- The function homtrans computes the corresponding homogeneous transformation`,
`  of the affine transformation t with respect to the nr-th coordinate neigh-`,
`  bourhood. The result is the list of image coordinates in the variables`,
`  hvars.   `,
`   `,
`- The function afftrans computes the corresponding affine transformation`,
`  of the homogeneous transformation T with respect to the nr-th coordinate `,
`  neighbourhood. The result is the list of image coordinates in the variables`,
`  hvars.    `,
`   `,
`- nr must be a nonnegative integer between zero and the length of avars (i.e.`,
`  the dimension of the affine space). The default value for nr is 0.`,
`      `,
`- The lists avars/hvars contain the affine/homogeneous variable names. If they `,
`  are omitted then they are taken to be algcurve[affvars]/algcurve[homvars].`,
`   `,
`- Linear homogeneous transformations may be transformed into the matrix `,
`  representation  by the function algcurve[image2mat].`,
`        `,
`- These functions are part of the algcurve package, and so can be used in the`,
`  form homtrans(..), afftrans(..) only after performing the command  `,
`  with(algcurve) or with(algcurve, homtrans, afftrans). The functions can`,
`  always be accessed in the long form algcurve[homtrans](..), `,
`  algcurve[afftrans](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> t:=  [ a*x + b*y + c, d*x + e*y + f ] ;`,
`                      t := [a x + b y + c, d x + e y + f]`,
`> homtrans( t ); `,
`                 [x0, a x1 + b x2 + x0 c, d x1 + e x2 + x0 f]`,
`   `,
`> afftrans( " );`,
`                        [a x + b y + c, d x + e y + f]`,
`   `,
`> homtrans( t, [x,y], [u,v,w], 2 );  `,
`                     [a u + b v + w c, d u + e v + w f, w]`,
`   `,
`> afftrans( ", [u,v,w], [x,y], 2 );`,
`                        [a x + b y + c, d x + e y + f]`,
`   `,
`> homtrans ( [ y^2 + x^3 - x^2, x^3 - y^2 ] );`,
`                             2     3        2    3        2`,
`                   [x0, x0 x2  + x1  - x0 x1 , x1  - x0 x2 ]`,
`   `,
`> afftrans ( " );`,
`                              2    3    2   3    2`,
`                            [y  + x  - x , x  - y ]`,
`   `,
`      `,
`SEE ALSO:  algcurve[appimage], algcurve[image2mat], algcurve[hompoly], `,
`           algcurve[hompoint]`,
`   `
):
`help/algcurve/text/image2mat` := TEXT(
`      `,
`FUNCTION: algcurve[image2mat] - matrix form of a linear transformation`,
`FUNCTION: algcurve[mat2image] - image coordinate form of a linear transformation`,
`      `,
`CALLING SEQUENCE:`,
`   image2mat( T, hvars )`,
`   image2mat( T )`,
`   `,
`   mat2image( M, hvars )`,
`   mat2image( M )`,
`      `,
`PARAMETERS:`,
`   T      -  list of linear homogeneous polynomials in hvars`,
`   M      -  matrix`,
`   hvars  -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- If A is a linear transformation in the projective space then T must be the`,
`  list of the image coordinates of the indeterminate coordinates, i.e. A(hvars).`,
`  The function image2mat generates the corresponding matrix. The coefficient of`,
`  hvars[j] in T[i] gives the entry of the matrix at position (i,j).`,
`      `,
`- The function mat2image generates the corresponding list of image`,
`  coordinates, i.e. M*hvars (where '*' acts as matrix multiplication).`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars].`,
`        `,
`- The functions are part of the algcurve package, and so can be used in the form`,
`  image2mat(..), mat2image(..) only after performing the command with(algcurve)`,
`  or with(algcurve, image2mat, mat2image). The function can always be accessed`,
`  in the long form  algcurve[image2mat](..), algcurve[mat2image](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> t:=  [ a*x + b*y + c, d*x + e*y + f ] :`,
`> T:=  homtrans( t );`,
`               T := [x0, a x1 + b x2 + x0 c, d x1 + e x2 + x0 f]`,
`   `,
`> M:= image2mat( T );`,
`                                    [ 1  0  0 ]`,
`                                    [         ]`,
`                               M := [ c  a  b ]`,
`                                    [         ]`,
`                                    [ f  d  e ]`,
`   `,
`> mat2image ( M , [u0,u1,u2] ); `,
`                 [u0, c u0 + a u1 + b u2, f u0 + d u1 + e u2]`,
`   `,
`> image2mat ( homtrans( t, 1 ) ); `,
`                                  [ a  c  b ]`,
`                                  [         ]`,
`                                  [ 0  1  0 ]`,
`                                  [         ]`,
`                                  [ d  f  e ]`,
`   `,
`> afftrans ( mat2image( " ), 1 ); `,
`                        [a x + b y + c, d x + e y + f]`,
`      `,
`SEE ALSO:  linalg, linalg[matrix], algcurve[homtrans], algcurve[appmat]`
):
`help/algcurve/text/implicit` := TEXT(
`      `,
`FUNCTION: algcurve[implicit] - implicit representation of a curve`,
`      `,
`CALLING SEQUENCE:`,
`   implicit( phi, var, vars )`,
`   implicit( phi )`,
`      `,
`PARAMETERS:`,
`   phi   -  list of two or three rational functions in var`,
`   var   -  (optional) name`,
`   vars  -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function <implicit> computes the implicit representation (a polynomial in`,
`  vars) of the curve given by the tuple of rational functions phi. phi[i] `,
`  corresponds to vars[i]. If phi and vars have three elements then the `,
`  resulting polynomial is homogeneous in vars.`,
`      `,
`- If var is omitted then it defaults to algcurve[explvar].`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the length of phi). `,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  implicit(..) only after performing the command with(algcurve) or`,
`  with(algcurve, implicit). The function can always be accessed in the long`,
`  form algcurve[implicit](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> implicit ( [ 1-t^2 , t*(1-t^2) ] );`,
`                                   3    2    2`,
`                                  x  - x  + y`,
`   `,
`> implicit ( [ m^2 , m ], m, [ u, v ] ); `,
`                                       2`,
`                                    - v  + u`,
`   `,
`> phi:= [ 1 + 2*t^2 + t^4, t*(-3 + t^2), t^2*(-3 + t^2) ] ; `,
`                             2    4            2    2         2`,
`              phi := [1 + 2 t  + t , t (- 3 + t ), t  (- 3 + t )]`,
`   `,
`> implicit ( phi );`,
`                    4       2   2     4          2           3`,
`                  x1  + 2 x1  x2  + x2  + 3 x0 x1  x2 - x0 x2`,
`      `,
`SEE ALSO:  algcurve[explicit], algcurve[explvar]`
):
`help/algcurve/text/inflections` := TEXT(
`      `,
`FUNCTION: algcurve[inflections] - inflection points of a curve`,
`      `,
`CALLING SEQUENCE:`,
`   inflections( F, vars )`,
`   inflections( F )`,
`      `,
`PARAMETERS:`,
`   F     -  multivariate polynomial in vars`,
`   vars  -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function inflections computes the inflections points of the plane`,
`  algebraic curves F. The result is a list of points.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- In the solutions of inflections often appear RootOf-expressions. To eliminate`,
`  them (at least those of low order) use the function algcurve[tryall]. `,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  inflections(..) only after performing the command with(algcurve) or`,
`  with(algcurve, inflections). The function can always be accessed in the`,
`  long form algcurve[inflections](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> f:= x^3 - y^2;`,
`                                        3    2`,
`                                  f := x  - y`,
`   `,
`> inflections ( f );`,
`                                       []`,
`   `,
`> inflections ( hompoly( f ) );`,
`                                  [[0, 0, 1]]`,
`   `,
`> inflections ( x0*x2^2 + x0*x1^2 + x1^3 );`,
`                            1/2                 1/2`,
`               [[9, -12, 4 3   ], [9, -12, - 4 3   ], [0, 0, 1]]`,
`   `,
`   `,
`SEE ALSO:  algcurve[tryall], algcurve[intermultiplicity], algcurve[tangent]`
):
`help/algcurve/text/intermultiplicity` := TEXT(
`      `,
`FUNCTION: algcurve[intermultiplicity] - intersection multiplicity of two curves `,
`                                        at a point`,
`      `,
`CALLING SEQUENCE:`,
`   intermultiplicity( F, G, pt, vars )`,
`   intermultiplicity( F, G, pt )`,
`      `,
`PARAMETERS:`,
`   F, G  -  multivariate polynomials in vars`,
`   pt    -  list`,
`   vars  -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function intermultiplicity computes the intersection multiplicity of the`,
`  curves F and G at the point pt. If pt is not a point of F or G then the `,
`  intersection multiplicity is 0.`,
`   `,
`- F and G must not have a common component.`,
`   `,
`- The function accepts lists of points as third argument.`,
`      `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  intermultiplicity(..) only after performing the command with(algcurve) or`,
`  with(algcurve, intermultiplicity). The function can always be accessed in the`,
`  long form algcurve[intermultiplicity](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> F:= x2^2*x1 + x2*x0^2 - x0^3;  G:= x2*x1;`,
`                                     2     2        3`,
`                           F := x1 x2  + x0  x2 - x0`,
`   `,
`                                   G := x2 x1`,
`   `,
`> ipts:= intersection( F, G );`,
`                   ipts := [[1, 0, 1], [0, 0, 1], [0, 1, 0]]`,
`   `,
`> intermultiplicity( F, G, ipts );`,
`                                   [1, 2, 3]`,
`   `,
`> intermultiplicity( F, G, [ 1, 0, 0 ] );`,
`                                       0`,
`   `,
`> intermultiplicity( x^2 + y^2 - 1, y - 1, [ 0, 1 ] );`,
`                                       2`,
`      `,
`SEE ALSO:  algcurve[intersection], algcurve[multiplicity]`
):
`help/algcurve/text/intersection` := TEXT(
`      `,
`FUNCTION: algcurve[intersection] - intersection of curves`,
`      `,
`CALLING SEQUENCE:`,
`   intersection( F, G, vars )`,
`   intersection( F, G )`,
`      `,
`PARAMETERS:`,
`   F, G  -  multivariate polynomials in vars`,
`   vars  -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function intersection computes the intersection points of the plane`,
`  algebraic curves F and G. The result is a list of points.`,
`   `,
`- F and G must not have a common component.`,
`      `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- In the solutions of intersection often appear RootOf-expressions. To eliminate`,
`  them (at least those of low order) use the function algcurve[tryall]. `,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  intersection(..) only after performing the command with(algcurve) or`,
`  with(algcurve, intersection). The function can always be accessed in the`,
`  long form algcurve[intersection](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> intersection( x^2 + y^2 - 1, x - y );`,
`                         1/2         1/2         1/2       1/2`,
`                [[- 1/2 2   , - 1/2 2   ], [1/2 2   , 1/2 2   ]]`,
`   `,
`> F:= x0*x2^2 + x1^3 - x0*x1^2;`,
`                                     2     3        2`,
`                           F := x0 x2  + x1  - x0 x1`,
`   `,
`> G:= x1^3 - x0*x2^2;`,
`                                      3        2`,
`                               G := x1  - x0 x2`,
`   `,
`> intersection ( F, G );`,
`                                             1/2             1/2`,
`              [[1, 0, 0], [0, 0, 1], [4, 2, 2   ], [4, 2, - 2   ]]`,
`   `,
`      `,
`SEE ALSO:  algcurve[tryall], algcurve[intermultiplicity]`
):
`help/algcurve/text/isregular` := TEXT(
`      `,
`FUNCTION: algcurve[isregular]  - check if a point is regular`,
`FUNCTION: algcurve[issingular] - check if a point is singular`,
`FUNCTION: algcurve[isordinary] - check if a point is ordinary `,
`      `,
`CALLING SEQUENCE:`,
`   isregular( F, pt, vars )`,
`   isregular( F, pt )`,
`   `,
`   issingular( F, pt, vars )`,
`   issingular( F, pt )`,
`   `,
`   isordinary( F, pt, vars )`,
`   isordinary( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The functions isregular, issingular, isordinary check if the point pt is a `,
`  regular, singular or ordinary point of the plane algebraic curve given by F. `,
`  The result is a boolean.`,
`   `,
`- If the point pt does not lie on the curve F then the result is in all three `,
`  cases false.`,
`      `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- These functions are part of the algcurve package, and so can be used in the`,
`  form isregular(..), issingular(..), isordinary(..) only after performing the`,
`  command with(algcurve) or with(algcurve, isregular, issingular, isordinary).`,
`  The functions can always be accessed in the long form algcurve[isregular](..),`,
`  algcurve[issingular], algcurve[isordinary].`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> f:=  x^3 - y^2;   `,
`                                        3    2`,
`                                  f := x  - y`,
`   `,
`> isregular(f,[0,0]);`,
`                                     false`,
`   `,
`> issingular(f,[0,0]);`,
`                                      true`,
`   `,
`> isordinary(f,[0,0]);`,
`                                     false`,
`   `,
`> F:= x0*x2^2 + x1^3 - x0*x1^2;   pt:= [1,0,0];`,
`                                     2     3        2`,
`                           F := x0 x2  + x1  - x0 x1`,
`   `,
`                                pt := [1, 0, 0]`,
`   `,
`> isregular ( F, pt ); issingular ( F, pt ); isordinary ( F, pt );`,
`                                     false`,
`   `,
`                                      true`,
`   `,
`                                      true`,
`   `,
`   `,
`> isregular ( F, [1,-3, 6] );  issingular ( F, [1,-3, 6] );`,
`                                      true`,
`   `,
`                                     false`,
`   `,
`      `,
`SEE ALSO:  algcurve[singularities], algcurve[tangent], algcurve[RegCurvePts]`
):
`help/algcurve/text/linearsystem` := TEXT(
`      `,
`FUNCTION: algcurve[linearsystem] - linear system of curves`,
`      `,
`CALLING SEQUENCE:`,
`   linearsystem( pts, deg, vars )`,
`   linearsystem( pts, deg )`,
`      `,
`PARAMETERS:`,
`   pts  -  list of { list, [list,positive integer] }`,
`   deg  -  positive integer`,
`   vars -  (optional) list of three names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function linearsystem computes a base for the linear system of curves `,
`  of degree deg going through the points pts with the given multiplicity.`,
`  The result is a list of homogeneous polynomials in vars.`,
`      `,
`- The points must have dimension 3. If an element of pts is of type `,
`  [list, posint] then the positive integer denotes the multiplicity. `,
`  Otherwise the multiplicity defaults to 1.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars].`,
`   `,
`- The resulting curves of linearsystem are often reducible. One can try`,
`  to get an irreducible curve by the call algcurve[randsyspoly](..), which`,
`  simply combines the curves in a random way.`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  linearsystem(..) only after performing the command with(algcurve) or `,
`  with(algcurve, linearsystem). The function can always be accessed in the `,
`  long form algcurve[linearsystem](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> linearsystem ( [ [ 1, 4, 5 ] ], 1 );`,
`                           [- 5 x0 + x2, - 4 x0 + x1]`,
`   `,
`   `,
`> v1 := [ 1, 0, 0 ]:  v2 := [ 1, 1, 1 ]:  v3 := [ 1, 0, 1 ]: `,
`   `,
`> pts:= [ v1, [v2,2], v3 ];`,
`                 pts := [[1, 0, 0], [[1, 1, 1], 2], [1, 0, 1]]`,
`   `,
`> L:= linearsystem ( pts, 3 );`,
`            2        2                      2    2             2     3`,
`    L := [x0  x1 - x0  x2 - x0 x1 x2 + x0 x2 , x0  x1 - 2 x0 x1  + x1 ,`,
`   `,
`          2                        2    2           2                2`,
`        x0  x1 - 2 x0 x1 x2 + x1 x2 , x0  x1 - x0 x1  - x0 x1 x2 + x1  x2,`,
`   `,
`            2        2                     3`,
`        2 x0  x1 - x0  x2 - 2 x0 x1 x2 + x2 ]`,
`   `,
`> F:= randsyspoly ( L );`,
`             2                        2          2     3        2     2`,
`      F := x0  x2 + 2 x0 x1 x2 - x0 x2  - 3 x0 x1  + x1  - x1 x2  + x1  x2`,
`   `,
`> appoly ( F, [v1,v2,v3] );`,
`                                   [0, 0, 0]`,
`   `,
`> singularities ( F );`,
`                                  [[1, 1, 1]]`,
`   `,
`> multiplicity ( F , " );`,
`                                      [2]`,
`   `,
`     `,
`SEE ALSO:  algcurve[multiplicity], algcurve[singularities], algcurve[appoly]`
):
`help/algcurve/text/multiplicity` := TEXT(
`      `,
`FUNCTION: algcurve[multiplicity] - multiplicity of a curve at a point`,
`      `,
`CALLING SEQUENCE:`,
`   multiplicity( F, pt, vars )`,
`   multiplicity( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The multiplicity of a plane algebraic curve at the point pt is computed.`,
`  It is the order of the lowest non-vanishing term in the Taylor expansion of`,
`  F at pt.   `,
`      `,
`- If pt contains indeterminates then pt is assumed to be an indeterminate`,
`  point on the curve and the multiplicity is in most cases 1.`,
`   `,
`- If pt does not lie on the curve then the multiplicity is 0.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- The function multiplicity accepts whole lists of points as second argument.`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  multiplicity(..) only after performing the command with(algcurve) or `,
`  with(algcurve, multiplicity). The function can always be accessed in the long `,
`  form algcurve[multiplicity](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> multiplicity( x^2 + y^2 - 1 , [0,1] );`,
`                                       1`,
`> multiplicity( x^2 + y^2 - 1 , [1,1] );`,
`                                       0`,
`   `,
`> F:= 2*x1^4  - 3*x0*x1^2*x2 + x0^2*x2^2  - 2*x0*x2^3  + x2^4; `,
`                       4          2        2   2          3     4`,
`              F := 2 x1  - 3 x0 x1  x2 + x0  x2  - 2 x0 x2  + x2`,
`   `,
`> spts := singularities ( F );`,
`                         spts := [[1, 0, 0], [1, 0, 1]]`,
`   `,
`> multiplicity( F , spts );`,
`                                     [2, 2]`,
`   `,
`> multiplicity( (x^2 + y^2)^3 - 4*x^2*y^2, [ 0, 0 ] );`,
`                                       4`,
`      `,
`SEE ALSO:  algcurve[curvetaylor], algcurve[singularities], algcurve[isregular]`
):
`help/algcurve/text/plotcurve` := TEXT(
`      `,
`FUNCTION: algcurve[plotcurve] - plot of a plane curve`,
`      `,
`CALLING SEQUENCE:`,
`   plotcurve( f, r1, r2, numpts, vars )`,
`   plotcurve( f, r1, r2, numpts )`,
`   plotcurve( f, r1, r2 )`,
`      `,
`PARAMETERS:`,
`   f      -  multivariate polynomial in vars`,
`   r1,r2  -  ranges`,
`   numpts -  (optional) positive integer`,
`   vars   -  (optional) list of two names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function plotcurve displays the curve f in the horizontal range r1`,
`  (vars[1]) and the vertical range r2 (vars[2]). No interpolation takes place,`,
`  only a lot of points are plotted.`,
`      `,
`- For both ranges nrofpts points are numerically computed. If nrofpts is`,
`  omitted then it defaults to 40.`,
`   `,
`- The singularities of f are displayed always and in a different colour.`,
`   `,
`- plotcurve accepts lists of polynomials as first argument. Each curve is`,
`  then displayed in a different colour.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[affvars].`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  plotcurve(..) only after performing the command with(algcurve) or`,
`  with(algcurve, plotcurve). The function can always be accessed in the long`,
`  form algcurve[plotcurve](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> plotcurve( y^2 + x^3 - x^2, -1..1, -1..1, 50 );`,
`   `,
`> plotcurve( 2*x^4 - 3*x^2*y + y^2 - 2*y^3 + y^4, -1.5..1.5, 0..3 ); `,
`   `,
`> plotcurve( (x^2 + y^2)^2 + 3*x^2*y - y^3, -1..1, -0.8..1.2 ); `,
`   `,
`> f:= x*y^2 + 3*x^2*y - 5*x*y - 10*y + x; `,
`                             2      2`,
`                     f := x y  + 3 x  y - 5 x y - 10 y + x`,
`   `,
`> plotcurve( [ f, Hessian( f ) ], -6..6, -6..6 );`,
`   `,
`> plotcurve( [ f, Polar( f, [2,2] ) ], -2..2, -2..2 );`,
`   `,
`      `,
`SEE ALSO:  plot`
):
`help/algcurve/text/poly2coord` := TEXT(
`      `,
`FUNCTION: algcurve[poly2coord] - coefficient extraction`,
`FUNCTION: algcurve[coord2poly] - conversion of a coefficient list `,
`                                 to a polynomial`,
`      `,
`CALLING SEQUENCE:`,
`   poly2coord(F, vars)`,
`   poly2coord(F)`,
`   `,
`   coord2poly(C, vars)`,
`   coord2poly(C)`,
`      `,
`PARAMETERS:`,
`   F     -  homogeneous polynomial in vars`,
`   C     -  list`,
`   vars  -  (optional) list of three names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- If n = degree(F,vars) then the result of poly2coord is a list of length`,
`  (n+1)(n+2)/2 with the coefficients of F as entries. The order is determined by`,
`  the degrees in the single variables of vars. That is, the first entry `,
`  corresponds to the coefficient of vars[1]^n, the second to the coefficient`,
`  of vars[1]^(n-1)*vars[2] etc. It is the same order as in sort(F,vars).`,
`      `,
`- If C is a list of length (n+1)(n+2)/2 (n a positive integer) then coord2poly`,
`  computes the homogeneous polynomial of degree n in vars with the coefficients`,
`  corresponding to the entries of C as above.`,
`   `,
`- vars must contain three variable names. If vars is omitted then it is taken`,
`  to be algcurve[homvars].`,
`        `,
`- The functions are part of the algcurve package, and so can be used in the form`,
`  poly2coord(..), coord2poly only after performing the command with(algcurve) or`,
`  with(algcurve, poly2coord, coord2poly). The functions can always be accessed`,
`  in the long form algcurve[poly2coord](..), algcurve[coord2poly](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> poly2coord( a*x0 + c*x2 + b*x1 );`,
`                                   [a, b, c]`,
`   `,
`> coord2poly( " ); `,
`                               a x0 + c x2 + b x1`,
`   `,
`> conic := a*x^2 + b*y^2 + c*z^2 + d*x*y + e*x*z + f*y*z:`,
`   `,
`> sort( conic, [x,y,z] );`,
`                      2                      2              2`,
`                   a x  + d x y + e x z + b y  + f y z + c z`,
`   `,
`> poly2coord( conic, [x,y,z] );`,
`                               [a, d, e, b, f, c]`,
`   `,
`> coord2poly( " ); `,
`                  2                           2                 2`,
`              a x0  + d x0 x1 + e x0 x2 + b x1  + f x1 x2 + c x2`,
`   `,
`> poly2coord ( v^3 + u*v^2 - u*w^2 , [u,v,w] );`,
`                        [0, 0, 0, 1, 0, -1, 1, 0, 0, 0]`,
`   `,
`      `,
`SEE ALSO:  type[projcoord], type[projpoly], algcurve[hompoint], sort`
):
`help/algcurve/text/projcoord` := TEXT(
`      `,
`FUNCTION: type/projcoord - check for homogeneous coordinates`,
`      `,
`CALLING SEQUENCE:`,
`   type(expr, projcoord)`,
`   type(expr, projcoord(n))`,
`      `,
`PARAMETERS:`,
`   expr - any expression`,
`   n    - positive integer`,
`      `,
`SYNOPSIS:  `,
`- In the first form  (where n is not specified) the function checks if expr`,
`  is a valid Maple list. It returns true if expr is a list and not all entries`,
`  of expr are zero. It returns false otherwise.`,
`   `,
`- In the second form, where n is a positive integer, the function checks`,
`  if expr is a list of length n+1 with not all entries zero.  That is, it tests`,
`  if expr can be a member of a n-dimensional projective space.`,
`   `,
`EXAMPLES:  `,
`> with(algcurve):`,
`> v:= [ 0, 1, 0 ]:`,
`> type(v, projcoord);`,
`                                    true`,
`   `,
`> type(v, projcoord(2));`,
`                                    true`,
`   `,
`> type(v, projcoord(3));`,
`                                    false`,
`   `,
`> type([0,0,0,0], projcoord);`,
`                                    false`,
`   `,
`> type( [ [0,0,1],[I,0,0],[1,a,c] ] , list(projcoord(2)) );`,
`                                    true`,
`   `,
`SEE ALSO:  list, type, type[projpoly]`
):
`help/algcurve/text/projpoly` := TEXT(
`      `,
`FUNCTION: type/projpoly - check for a homogeneous polynomial`,
`      `,
`CALLING SEQUENCE:`,
`   type(F, projpoly)`,
`   type(F, projpoly(vars))`,
`   type(F, projpoly(deg))`,
`   type(F, projpoly(vars, deg))`,
`      `,
`PARAMETERS:`,
`   F      - any expression`,
`   vars   - (optional) list of names `,
`   deg    - (optional) nonnegative integer `,
`      `,
`SYNOPSIS:    `,
`   `,
`- The call type(F, projpoly(vars,deg)) checks if F is a homogeneous`,
`  polynomial in the variables vars with degree deg.`,
`      `,
`- The variable(s) vars must be a list of names. Default is algcurve[homvars].`,
`      `,
`- If deg is omitted then F can be of any degree.`,
`   `,
`- The coefficients of F must be of type algebraic.`,
`   `,
`    `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> type( x0*x1^2 + a*x1*x2^2 + b*x1^3, projpoly ); `,
`                                      true`,
`   `,
`> F:= a*x*y + y^2;`,
`                                              2`,
`                                F := a x y + y`,
`   `,
`> type( F, projpoly );`,
`                                     false`,
`   `,
`> type( F, projpoly([x,y]) );`,
`                                      true`,
`   `,
`> type( F, projpoly([x,y],2) ); `,
`                                      true`,
`   `,
`> type( F, projpoly([x,y],3) ); `,
`                                     false`,
`     `,
`   `,
`SEE ALSO:  indets, type, polynom, type[algebraic], type[projcoord],`,
`           algcurve[homvars]`,
`   `,
`   `,
`   `
):
`help/algcurve/text/quadtrans` := TEXT(
`      `,
`FUNCTION: algcurve[quadtrans] - transform of a curve by quadratic transformation`,
`      `,
`CALLING SEQUENCE:`,
`   quadtrans( F, vars )`,
`   quadtrans( F )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   vars -  (optional) list of two or three names`,
`   `,
`      `,
`SYNOPSIS:  `,
`- The standard quadratic transformation is defined as~:`,
`   `,
`     T :  (x0,x1,x2)  ->  ( x1*x2, x0*x2, x0*x1 )`,
`    `,
`- If F is a homogeneous polynomial in three variables then the algebraic`,
`  transform  G(x0,x1,x2) := F(x1*x2,x0*x2,x0*x1) is computed first. Then G `,
`  is divided by the highest possible powers of x0,x1 and x2 and the result `,
`  is called transform of F by T.`,
`      `,
`- If F is an affine polynomial in two variables then the associated`,
`  homogeneous polynomial is transformed and the result is converted into the `,
`  affine form.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  quadtrans(..) only after performing the command with(algcurve) or`,
`  with(algcurve, quadtrans). The function can always be accessed in the long`,
`  form algcurve[quadtrans](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> quadtrans(x0+x1+x2);`,
`                             x1 x2 + x0 x2 + x0 x1`,
`   `,
`> quadtrans( " );`,
`                                  x0 + x1 + x2`,
`   `,
`   `,
`> f:= y^2 + x^3 - x^2;`,
`                                     2    3    2`,
`                               f := y  + x  - x`,
`> quadtrans( f ); `,
`                                  2      2    3`,
`                                 y  - x y  + x`,
`   `,
`> quadtrans( " );`,
`                                   2    3    2`,
`                                  y  + x  - x`,
`      `,
`SEE ALSO:  algcurve[NonVertexTrans], algcurve[PtTrans]`
):
`help/algcurve/text/singularities` := TEXT(
`      `,
`FUNCTION: algcurve[singularities] - determination of singularities`,
`      `,
`CALLING SEQUENCE:`,
`   singularities( F, vars )`,
`   singularities( F )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The function determines the singularities of the plane algebraic curve F.`,
`  The result is a list of coordinates. If F is an affine polynomial in two`,
`  variables then the singularities lying in the affine plane are computed only.`,
`      `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`      `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  singularities(..) only after performing the command with(algcurve) or `,
`  with(algcurve, singularities). The function can always be accessed in the `,
`  long form algcurve[singularities](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`   `,
`> f:= 2*x^4 - 3*x^2*y + y^2 - 2*y^3 + y^4:`,
`   `,
`> singularities ( f );`,
`                                [[0, 0], [0, 1]]`,
`   `,
`> singularities ( hompoly(f) );`,
`                             [[1, 0, 0], [1, 0, 1]]`,
`   `,
`> singularities ( x^2 + c*y^2*x - b*x ); `,
`                                    1/2        1/2`,
`                                   b          b`,
`                            [[0, - ----], [0, ----]]`,
`                                    1/2        1/2`,
`                                   c          c`,
`   `,
`> singularities ( y^3 - (x^2+1)^2 );`,
`                               [[- I, 0], [I, 0]]`,
`   `,
`> f:= x*y^2 - x - 1:`,
`   `,
`> singularities ( f );`,
`                                       []`,
`   `,
`> singularities ( hompoly(f) );`,
`                                  [[0, 1, 0]]`,
`   `,
`      `,
`SEE ALSO:  algcurve[grad], algcurve[intersection], algcurve[multiplicity]`
):
`help/algcurve/text/standard` := TEXT(
`      `,
`FUNCTION: algcurve[standard] - standard form of projective coordinates and`,
`                               polynomials`,
`      `,
`CALLING SEQUENCE:`,
`   standard( pt )`,
`   standard( F, vars )`,
`   standard( F )`,
`      `,
`PARAMETERS:`,
`   pt   -  list (type projcoord)`,
`   F    -  polynomial in vars`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- If the first argument is a list then a projective equivalent coordinate pt'`,
`  (list) is computed with the following properties :`,
`    - the elements of pt' do not contain quotient,`,
`    - the first element of pt' different from 0 is positive, `,
`    - the elements of pt' have no common polynomial over the rationals as`,
`      divisor; many other common divisors are recognized and eliminated, too.`,
`      `,
`- If the first argument is a homogeneous polynomial in three variables (vars)`,
`  the simplifications are performed on the coefficients of F. If F is not`,
`  homogeneous with respect to vars then the function primpart is used.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  standard(..) only after performing the command with(algcurve) or`,
`  with(algcurve, standard). The function can always be accessed in the long form`,
`  algcurve[standard](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> standard( [ 0, -x^2, x*(1-x) ] );`,
`                                [0, x, - 1 + x]`,
`> standard( [ 0, 1 - x + I - I*x, 1 + I ] );`,
`                                [0, - 1 + x, -1]`,
`   `,
`> standard(  [ 25, 16/3*5*(x-1)*(z-1), 4/9*5*(x-1) ] ) ;`,
`                     [45, 48 (- 1 + x) (z - 1), - 4 + 4 x]`,
`   `,
`> standard( [ 0, -5, 25/3 ] ); `,
`                                   [0, 3, -5]`,
`   `,
`> standard ( -a^2*x1 + a*(1-a)*x2 );`,
`                              a x1 + (- 1 + a) x2`,
`   `,
`> standard ( b*x + b*y + 5*b );`,
`                                   x + y + 5`,
`   `,
`      `,
`SEE ALSO:  type[projcoord], algcurve[homequal], primpart, content`
):
`help/algcurve/text/tangent` := TEXT(
`      `,
`FUNCTION: algcurve[tangent] - tangent to a curve at a point`,
`      `,
`CALLING SEQUENCE:`,
`   tangent( F, pt, vars )`,
`   tangent( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:    `,
`- The tangent to the plane algebraic curve F at the point pt is computed.`,
`  If r is the multiplicity of F at pt then there exist exactly r (not`,
`  necessarily distinct) tangents to F at pt. That is, if pt is a regular point`,
`  then the result is the only tangent to F at pt, and if pt is a singular`,
`  point then the result is the list of the tangents to F at pt, where multiple`,
`  tangents appear in the '^'-notation. `,
`   `,
`- If pt contains indeterminates then pt is assumed to be a point on the curve `,
`  and so in most cases the result will be exactly one tangent.`,
`   `,
`- If pt does not lie on the curve, then an error occurs.`,
`   `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`   `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  tangent(..) only after performing the command with(algcurve) or `,
`  with(algcurve, tangent). The function can always be accessed in the long `,
`  form algcurve[tangent](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> tangent ( x^2 + y^2 - 1, [ a,b ] ); `,
`                           2 (x - a) a + 2 (y - b) b`,
`   `,
`> standard ( " );`,
`                                           2    2`,
`                              a x + b y - a  - b`,
`   `,
`> f:= y^2 + x^3 - x^2:`,
`> tangent ( f, [ 0, 0 ] );`,
`                                [x - y, - x - y]`,
`   `,
`> tangent ( f, [ 1, 0 ] );`,
`                                     x - 1`,
`   `,
`> F:= 2*x1^4  - 3*x0*x1^2*x2 + x0^2*x2^2  - 2*x0*x2^3  + x2^4; `,
`                       4          2        2   2          3     4`,
`              F := 2 x1  - 3 x0 x1  x2 + x0  x2  - 2 x0 x2  + x2`,
`   `,
`> tangent ( F , [ 1, 0, 1 ] ); `,
`                         1/2                  1/2`,
`                    [x1 3    - x2 + x0, - x1 3    - x2 + x0]`,
`   `,
`> tangent ( x^6 - x^2*y^3 - y^5, [ 0, 0 ] );`,
`                              3`,
`                            [y , - x I - y, x I - y]`,
`   `,
`      `,
`SEE ALSO:  algcurve[curvetaylor], algcurve[singularities], algcurve[isregular]`
):
`help/algcurve/text/tangentthrupt` := TEXT(
`      `,
`FUNCTION: algcurve[tangentthrupt] - tangents to a curve going through a point`,
`      `,
`CALLING SEQUENCE:`,
`   tangentthrupt( F, pt, vars )`,
`   tangentthrupt( F, pt )`,
`      `,
`PARAMETERS:`,
`   F    -  multivariate polynomial in vars`,
`   pt   -  list`,
`   vars -  (optional) list of names`,
`   `,
`      `,
`SYNOPSIS:   `,
`- The function tangentthrupt computes the list of all tangents to regular `,
`  points of the curve F, which contain the point pt.`,
`      `,
`- If vars is omitted then it is taken to be algcurve[homvars] or `,
`  algcurve[affvars] (depending on the variables occurring in F).`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  tangentthrupt(..) only after performing the command with(algcurve) or`,
`  with(algcurve, tangentthrupt). The function can always be accessed in the`,
`  long form algcurve[tangentthrupt](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> tangentthrupt ( x^2 + y^2 - 1, [ 1, 1 ] );`,
`                                 [x - 1, y - 1]`,
`   `,
`> F:= x1^3 - x0*x2^2;`,
`                                      3        2`,
`                               F := x1  - x0 x2`,
`   `,
`> tangentthrupt ( F, [ 1, 1, 0 ] );`,
`                                 1/2                      1/2`,
`               [9 x0 - 9 x1 + 2 3    x2, 9 x0 - 9 x1 - 2 3    x2]`,
`   `,
`> tangentthrupt ( x0*x2^2 + x1^3 - x0*x1^2 , [ 0, 1, 0 ] );`,
`                               1/2               1/2`,
`                    [2 x0 - 3 3    x2, 2 x0 + 3 3    x2, x0]`,
`   `,
`      `,
`SEE ALSO:  algcurve[tryall], algcurve[tangent], algcurve[Polar]`
):
`help/algcurve/text/tryall` := TEXT(
`      `,
`FUNCTION: algcurve[tryall] - evaluate all possible polynomials or lists`,
`                             involving RootOf's`,
`      `,
`CALLING SEQUENCE:`,
`   tryall( L, 'd', 'simplified' )`,
`   tryall( L, 'simplified' )`,
`   tryall( L, 'd' )`,
`   tryall( L )`,
`      `,
`PARAMETERS:`,
`   L   -  list of polynomials or list of lists`,
`   'd' -  option`,
`   'simplified' - option `,
`      `,
`SYNOPSIS:   `,
`- The function tryall tries to eliminate all RootOf's in the elements of L.`,
`  Result is the list L where all solvable RootOf expressions are replaced by the`,
`  corresponding roots.`,
`      `,
`- The procedure tryall will attempt to evaluate expressions exactly using`,
`  solve. The roots of nth degree polynomial equations where n <= 4 can be`,
`  obtained exactly. Where roots cannot be obtained exactly, tryall will let the`,
`  RootOf expression unchanged. Use allvalues to obtain numerical solutions in `,
`  this case.`,
`   `,
`- The option 'd' is used to specify that RootOf's of the same equation `,
`  represent the same value and they should not be evaluated independently of `,
`  one another.`,
`   `,
`- If the option 'simplified' is used then all elements are simplified by the`,
`  function simplify.`,
`        `,
`- This function is part of the algcurve package, and so can be used in the form`,
`  tryall(..) only after performing the command with(algcurve) or with(algcurve,`,
`  tryall). The function can always be accessed in the long form `,
`  algcurve[tryall](..).`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> intersection( x^2 + y^2 - 1, y - x^2 );`,
`                          2         4            2         4 2`,
`               [[RootOf(_Z  - 1 + _Z ), RootOf(_Z  - 1 + _Z ) ]]`,
`   `,
`> tryall( " ,'d','simplified' );`,
`                            1/2 1/2  1/2               1/2`,
`              [[1/2 I (1 + 5   )    2   , - 1/2 - 1/2 5   ],`,
`   `,
`                               1/2 1/2  1/2               1/2`,
`                  [1/2 (- 1 + 5   )    2   , - 1/2 + 1/2 5   ],`,
`   `,
`                                 1/2 1/2  1/2               1/2`,
`                  [- 1/2 (- 1 + 5   )    2   , - 1/2 + 1/2 5   ],`,
`   `,
`                                 1/2 1/2  1/2               1/2`,
`                  [- 1/2 I (1 + 5   )    2   , - 1/2 - 1/2 5   ]]`,
`   `,
`      `,
`SEE ALSO:  allvalues`
):
`help/algcurve/text/vars` := TEXT(
`      `,
`HELP FOR: algcurve[homvars], algcurve[affvars], algcurve[explvar] `,
`          - default variable names`,
`      `,
`CALLING SEQUENCE:`,
`   homvars   `,
`   affvars   `,
`   explvar   `,
`      `,
`SYNOPSIS:   `,
`- homvars and affvars are Maple lists with the default variable names for`,
`  homogeneous and affine variables. explvar is the (single) default name for `,
`  the function variable in the explicit representation of curves (see `,
`  algcurve[explicit]).`,
`      `,
`- If the variable list is omitted in the calling sequence of an algcurve`,
`  function then the variable names are taken from homvars, affvars or`,
`  explvar.   `,
`   `,
`- It is possible to redefine homvars, affvars and explvar by assigning`,
`  a new value to them in the following way :`,
`   `,
`     algcurve['homvars'] := ...`,
`   `,
`  The names in homvars, affvars and explvar must be all different, and`,
`  homvars must contain one name more than affvars.`,
`        `,
`- homvars, affvars, explvar are part of the algcurve package, and so can`,
`  be used in the form homvars, affvars, explvar only after performing the`,
`  command with(algcurve) or with(algcurve,homvars,affvars,explvar). It can`,
`  always be accessed in the long form algcurve[homvars], algcurve[affvars],`,
`  algcurve[explvar].`,
`      `,
`EXAMPLES:   `,
`> with(algcurve):`,
`> homvars;   `,
`                                  [x0, x1, x2]`,
`   `,
`> affvars;   `,
`                                     [x, y]`,
`   `,
`> explvar;   `,
`                                       t`,
`   `,
`> algcurve['homvars'] := [ u, v, w ];`,
`                         algcurve[homvars] := [u, v, w]`,
`   `,
`> hompoly ( 4*x + 3*y + 15 );`,
`                                4 v + 3 w + 15 u`,
`   `,
`   `,
`SEE ALSO: type[projpoly], algcurve[hompoly], algcurve[affpoly]`,
`   `
):

#--- Aliases for help files
`help/algcurve/text/affpoly`:= `help/algcurve/text/hompoly`:
`help/algcurve/text/affpoint`:= `help/algcurve/text/hompoint`:
`help/algcurve/text/coord2poly`:= `help/algcurve/text/poly2coord`:
`help/algcurve/text/afftrans`:= `help/algcurve/text/homtrans`:
`help/algcurve/text/mat2image`:= `help/algcurve/text/image2mat`:
`help/algcurve/text/multcomp`:= `help/algcurve/text/commoncomp`:
`help/algcurve/text/issingular`:= `help/algcurve/text/isregular`:
`help/algcurve/text/isordinary`:= `help/algcurve/text/isregular`:
`help/algcurve/text/randsyspoly`:= `help/algcurve/text/linearsystem`:
`help/algcurve/text/affvars`:= `help/algcurve/text/vars`:
`help/algcurve/text/homvars`:= `help/algcurve/text/vars`:
`help/algcurve/text/explvar`:= `help/algcurve/text/vars`:
`help/type/text/projpoly`:= `help/algcurve/text/projpoly`:
`help/type/text/projcoord`:= `help/algcurve/text/projcoord`:

#save `algcurve.m`;
#quit
