######################################################### #11111111111111111111111111111111111111111111111111111111 # #Part I: The basic functions # Class, Leader, Initial ######################################################### readlib(factors): with(Groebner): _field_characteristic_:=0; # the class of poly f wrt variable ordering ord Class := proc(dp,ord) local i,idt; options remember,system; idt:=dIndets(dp); for i to nops(ord) do if member(ord[i], idt) then RETURN(nops(ord)-i+1) fi od; 0 end: # the highest order of the indeterminate var in dp # INPUT: # dp : a diff pol # var: an indeterminate # OUTPUT: the order # dOrder:=proc(dp,var) local idt,i,dvar; options remember,system; idt:=indets(dp); dvar:=-1; for i in idt do if has(i,var) then if dvar=-1 or type(dvar,symbol) or ( ( not type(i,symbol) ) and ( op(1,i) > op(1,dvar) ) ) then dvar:=i ; fi fi; od; if dvar=-1 then -1 elif type(dvar,symbol) then 0 else if nops(dvar) =1 then op(1,dvar) else [op(1..nops(dvar),dvar)] fi; fi; end: dIndets:=proc(dp) local i,indet_d,idt; options remember,system; idt:={}; indet_d:=indets(dp); if POLY_MODE='Algebraic' then RETURN(indet_d) fi; for i in indet_d do if type(i,symbol) then idt:={op(idt),i} else idt:={op(idt),op(0,i)} fi; od; idt end: # the initial of poly f wrt ord Initial := proc(f,ord) options remember,system; if Class(f,ord) = 0 then 1 else lcoeff(f,Leader(f,ord)); fi end: # the separant of poly f wrt ord Separant := proc(f,ord) options remember,system; if Class(f,ord) = 0 then 1 else diff(f,Leader(f,ord)); fi end: Sept:=proc(p,ord) local pol; options remember,system; pol:=Separant(p,ord); if Class(pol,ord)=0 then RETURN(1) fi; pol end: # the set of all nonconstant factors of separants of polys in as Septs:=proc(bset,ord) local i,list; options remember,system; list:={}; for i in bset do list:=list union Factorlist(Sept(i,ord)) od; for i in list do if Class(i,ord)=0 then list:=list minus {i} fi od; list end: Lessp:= proc(f,g,ord) local cf,cg,cmp,df,dg,leadf,leadg; options remember,system; cf := Class(f,ord); cg := Class(g,ord); if type(f,integer) then true elif type(g,integer) then false elif cf = 0 then true elif cg = 0 then false else leadf:=Leader(f,ord); leadg:=Leader(g,ord); cmp:=dercmp(leadf,leadg,ord); if cmp = 1 then true elif cmp=-1 then false else df := degree(f,leadf); dg := degree(g,leadg); if df < dg then true elif df = dg then Lessp(Initial(f,ord),Initial(g,ord),ord) else false fi fi fi end: Least:= proc(ps,ord) local i,lpol; options remember,system; lpol:=op(1,ps); for i from 2 to nops( ps ) do if Lessp(op(i,ps),lpol,ord) then lpol:=op(i,ps) fi; od; lpol end: #############################################4 Reduced Definitions########################3 Reducedp:= proc(p,q,ord,T) local mvar,var,idt; options remember,system; mvar:=Leader(q,ord); if type(mvar,symbol) then var:=mvar else var:=op(0,mvar) fi; if POLY_MODE='Algebraic' then ###############Algebraic mode################################# if nargs <4 or T='std_asc' then if Class(p,ord) > Class(q,ord) and degree(p,mvar) < degree(q,mvar) then 1 else 0 fi; elif T='wu_asc' then if Class(p,ord) > Class(q,ord) and degree(Initial(p,ord),mvar) < degree(q,mvar) then 1 else 0 fi; elif T='gao_asc' then ###########################in the following case , q is a list################# if Class(p,ord) > Class(op(1,q),ord) and Premas(Initial(p,ord),q,ord,'std_asc') <>0 then 1 else 0 fi; elif T='tri_asc' then if Class(p,ord) > Class(q,ord) then 1 else 0 fi; fi; ###############Algebraic mode################################# elif POLY_MODE='Ordinary_Differential' then ###############ODE mode################################# if nargs <4 or T='std_asc' then if Class(p,ord) > Class(q,ord) and degree(p,mvar) < degree(q,mvar) and dOrder(p,var) <= dOrder(q,var) then 1 else 0 fi; elif T='wu_asc' then if Class(p,ord) > Class(q,ord) and degree(Initial(p,ord),mvar) < degree(q,mvar) then 1 else 0 fi; elif T='gao_asc' then ###########################in the following case , q is a list################# if Class(p,ord) > Class(op(1,q),ord) and Premas(Initial(p,ord),q,ord,'std_asc') <>0 then 1 else 0 fi; elif T='tri_asc' then if Class(p,ord) > Class(q,ord) then 1 else 0 fi; fi; ###############ODE mode################################# elif POLY_MODE='Partial_Differential' then ###############PDE mode################################# if nargs <4 or T='std_asc' then idt:=indets(p); if dercmp(Leader(p,ord), mvar, ord)=-1 and degree(p,mvar) < degree(q,mvar) and (not member(true, map(Is_proper_derivative,idt,mvar)) ) then 1 else 0 fi; elif T='wu_asc' then if Class(p,ord) > Class(q,ord) and degree(Initial(p,ord),mvar) < degree(q,mvar) then 1 else 0 fi; elif T='gao_asc' then ###########################in the following case , q is a list################# if Class(p,ord) > Class(op(1,q),ord) and Premas(Initial(p,ord),q,ord,'std_asc') <>0 then 1 else 0 fi; elif T='tri_asc' then if Class(p,ord) > Class(q,ord) then 1 else 0 fi; fi; ###############PDE mode################################# fi; end: ############################# # # Name: Reducedset # Input: ps: a poly set # p: a polynomial # OUTPUT: redset:={q | q is in ps, q is rReduced to p } ############################# Reducedset:= proc(ps,p,ord,T) local i, redset; options remember,system; redset:={}; for i in ps do if Reducedp(i,p,ord,T)=1 then redset:={i,op(redset)} fi; od; redset end: ############################################################################## ############################################################################## # the basic set of polyset ps Basicset:= proc(ps,ord,T) local qs,b,bs; options remember,system; if nops(ps) < 2 then [op(ps)] else qs:=ps; bs:=[]; while (nops(qs) <>0) do b:=Least(qs,ord); bs:=[b,op(bs)]; if T='gao_asc' then qs :=Reducedset(qs,bs,ord,T); else qs :=Reducedset(qs,b,ord,T); fi; od; bs fi end: ############################################################## # modified pseudo division: I1^s1...Ir^sr*uu = q*vv + r, # where I1, ..., I_r are all distinct factors of lcoeff(vv,x) # and s1, ..., sr are chosen to be the smallest ############################################################## NPrem := proc(uu,vv,x) local r,v,dr,dv,l,t,lu,lv,gcd0; options remember,system; if type(vv/x,integer) then subs(x = 0,uu) else r := expand(uu); dr := degree(r,x); v := expand(vv); dv := degree(v,x); if dv <= dr then l := coeff(v,x,dv); v := expand(v-l*x^dv) else l := 1 fi; while dv <= dr and r <> 0 do # gcd0:=gcd(l,coeff(r,x,dr),'lu','lv'); gcd0:=gcd(l,coeff(r,x,dr)); lu:=simplify(l/gcd0); lv:=simplify(coeff(r,x,dr)/gcd0); lu:=l; lv:=coeff(r,x,dr); t := expand(x^(dr-dv)*v*lv); if dr = 0 then r := 0 else r := subs(x^dr = 0,r) fi; r := expand(lu*r)-t; dr := degree(r,x) od; r fi end: ################################################################################### ############################################################## # modified pseudo division: I1^s1...Ir^sr*uu = q*vv + r, # where I1, ..., I_r are all distinct factors of lcoeff(vv,x) # and s1, ..., sr are chosen to be the smallest ############################################################## NPremfinite := proc(uu,vv,x,ord) local r,v,dr,dv,l,t,lu,lv,gcd0; options remember,system; global _field_characteristic_; if type(vv/x,integer) then subs(x = 0,uu) else r := expand(uu); dr := degree(r,x); v := expand(vv); dv := degree(v,x); if dv <= dr then l := coeff(v,x,dv); v := expand(v-l*x^dv) else l := 1 fi; while dv <= dr and r <> 0 do # gcd0:=gcd(l,coeff(r,x,dr),'lu','lv'); gcd0:=gcd(l,coeff(r,x,dr)); lu:=simplify(l/gcd0); lv:=simplify(coeff(r,x,dr)/gcd0); lu:=l; lv:=coeff(r,x,dr); t := expand(x^(dr-dv)*v*lv) mod _field_characteristic_; if dr = 0 then r := 0 else r := subs(x^dr = 0,r) mod _field_characteristic_ fi; r := expand(lu*r)-t mod _field_characteristic_; # r :=finite_simplify(r,ord,_field_characteristic_); dr := degree(r,x) od; r fi end: ################################################# finite_simplify:=proc(r,ord,p) local i,res; res:=r; for i to nops(ord) do res:=subs(ord[i]^p=ord[i],res) mod p; od; res: end: ################################################################################### ################################################################################### # # pseudo remainder of poly f wrt ascending set as Premas := proc(f,as,ord,T) local r0,r1,asc; options remember,system; if nargs < 4 then asc:='std_asc' else asc:=T fi; r0:=Premas_a(f,as,ord,asc); if POLY_MODE <> 'Partial_Differential' then RETURN(r0) fi; r1:=Premas_a(r0,as,ord,asc); while(r1 <> r0) do r0:=r1; r1:=Premas_a(r0,as,ord,asc); od; r1: end: Premas_a := proc(f,as,ord,T) local remd,i,degenerate; options remember,system; global _field_characteristic_ ; remd := f; #################下面专门处理有限域的情形############ if (_field_characteristic_ <> 0) then for i to nops(as) do remd := NPremfinite(remd,as[i],Leader(as[i],ord),ord); od; fi; ####################################################### if nargs <4 then for i to nops(as) do remd := NewPrem(remd,as[i],Leader(as[i],ord)); od; elif T='std_asc' then for i to nops(as) do remd := NewPrem(remd,as[i],Leader(as[i],ord)); od; elif T='tri_asc' then for i to nops(as) do if Class(remd,ord) = Class(as[i],ord) then remd := NewPrem(remd,as[i],Leader(as[i],ord)); fi od; ###########for wu ascending set############# elif T='wu_asc' then for i to nops(as) do remd := WuPrem(remd,as[i],Leader(as[i],ord),ord,'degenerate'); if degenerate=1 then RETURN( Premas(remd,as,ord,T)) fi; od; ################################################## elif T='gao_asc' then if Premas( Initial(remd,ord), as,ord,'std_asc' ) =0 then RETURN( Premas(remd,as,ord,'std_asc') ) fi; for i to nops(as) do if Class(remd,ord) = Class(as[i],ord) then remd := NewPrem(remd,as[i],Leader(as[i],ord)); if Premas( Initial(remd,ord), as,ord,'std_asc' ) =0 then RETURN( Premas(remd,as,ord,'std_asc') ) fi; fi od; fi; if remd <> 0 then numer(remd/lcoeff(remd)) else 0 fi end: ################################################################################### ################################################################################### # set of non-zero remainders of polys in ps wrt ascending set as Remset := proc(ps,as,ord,T) local i,set,pset,r; options remember,system; set:={}; pset:={op(ps)} minus {op(as)}; if POLY_MODE='Partial_Differential' then pset := pset union spolyset(as,ord) fi; # print("pset=",pset); for i in pset do r:=Premas(i,as,ord,T); if r <>0 and Class(r,ord) =0 then RETURN({1}) else set:=set union {r} fi od; set minus {0} end: ###############################misc procedures########### Reverse:=proc(list) local i,n,list1; n := nops(list); list1 := [seq(list[n-i+1],i = 1 .. n)]; list1 end: ################ ################################################################################### # Factor the polynomials in Remaider set ################################################################################### Produce:=proc(rs,ord,test) global remfac; options remember,system; local i,j,list1,list2; list2 := {}; for i in rs do list1 := Nonumber(Factorlist(i),ord); remfac := remfac union (list1 intersect test); list1 := list1 minus test; for j in list1 do if Class(j,ord) = 0 then list1 := list1 minus {j} fi od; list2 := list2 union {list1} od; for j in list2 do if j = {} then RETURN({}) fi od; list2 end: Nonumber:=proc(list,ord) local i,ls; options remember,system; ls := {}; for i in list do if 0 < Class(i,ord) then ls := ls union {i} fi od; ls end: Factorlist:=proc(pol) local i,list1,list2; options remember,system; if (_field_characteristic_ <>0) then list1:=(Factors(pol) mod _field_characteristic_)[2]; else list1 := factors(pol)[2]; fi; list2 := {}; for i in list1 do list2 := list2 union {numer(i[1])} od; list2 end: #input two poly set set1,set2 #output Ltl:=proc(list1,list2) local set,i,j; options remember,system; set := {}; for i in list1 do for j in list2 do set := set union {{j,i}} od od end: Lltl:=proc(llist1,list2) local set,i,j; options remember,system; set := {}; for i in llist1 do for j in list2 do set := set union {i union {j}} od od end: # Procedure Nrs: #input a polynomial set RS:={R1,R2,...,Rn} #output a set in which every element is a poly set. set:={set1,set2,...,sets} Nrs:=proc(rs,ord,test) local rm,rss,l1,i,j,rset; options remember,system; rss := Produce(rs,ord,test); if rss={} then RETURN({}) fi; # print("rss=");print(rss); rset:=LProduct(rss); rset end: LProduct:=proc(inlist) # 输入是集合的集合,输出也是集合的集合 local i,j,k,m,n,B,C,D,T; options remember,system; B:=[]; for i from 1 to nops(op(1,inlist)) do B:=[op(B),{op(i,op(1,inlist))}]; end: for i from 2 to nops(inlist) do C:=[];D:=[]; for j from 1 to nops(B) do if ((B[j] intersect op(i,inlist))<>{}) then C:=[op(C),B[j]]; else D:=[op(D),B[j]]; end: end: B:=C; for m from 1 to nops(D) do T:=op(i,inlist); for n from 1 to nops(C) do if (nops(C[n] minus D[m])=1) then T:=T minus (C[n] minus D[m]); end: end: for k from 1 to nops(T) do B:= [op(B),D[m] union {op(k,T)}]; end : end: end: B:={op(B)}; end: LProduct_wdk:=proc(list1) local len,lls,i,j; options remember,system; len:=nops(list1); if len=0 then RETURN(list1) fi; lls:={}; for i in op(1,list1) do lls:=lls union { {i} } od; if len=1 then RETURN (lls) fi; for j from 2 to len do lls:=Lltl(lls, op(j,list1)); od; lls; end: Lltl:=proc(lls,ls) local res,i,j,l1,rm; options remember,system; res:={}; for i in lls do if i intersect ls ={} then for j in ls do res:= res union { i union {j} }; od; else res:=res union {i}; fi; od; l1 := nops(res); rm := {}; for i to l1-1 do for j from i+1 to l1 do if op(i,res) minus op(j,res) = {} then rm := rm union {op(j,res)} fi; if op(j,res) minus op(i,res) = {} then rm := rm union {op(i,res)} fi od od; res := res minus rm; res end: ####################################################### # Aux functions: # # ###################################################### Nums:=proc(ps,ord) local i,n; options remember,system; n:=0; for i in ps do if Class(i,ord)=1 and POLY_MODE='Algebraic' then n:=n+1 fi ; if Class(i,ord)=1 and (POLY_MODE='Partial_Differential' or POLY_MODE='Ordinary_Differential') and torder(Leader(i,ord))=0 then n:=n+1 fi; od; n end: Emptyset:=proc(ds,as,ord) local i; options remember,system; if {op(ds)} intersect {op(as)} <> {} then RETURN(1) fi; # for i in ds do if grobner[normalf](i,as,tdeg(op(ord)))=0 then RETURN(1) fi od; 0; end: Non0Constp:=proc(ps,ord) local i; options remember,system; for i in ps do if Class(i,ord)=0 and i <> 0 then RETURN(1) fi od; 0; end: TestQ:=proc(ps,as,ord) global remfac; local i; options remember,system; for i in ps do if grobner[normalf](i,as,ord) = 0 then remfac:=remfac union {i};RETURN(1) fi od; 0 end: Init:=proc(p,ord) local pol; options remember,system; pol:=Initial(p,ord); if Class(pol,ord)=0 then RETURN(1) fi; pol end: JInitials:=proc(bset,ord) local pol, product; options remember,system; product:=1; for pol in bset do product:=product*Initial(pol,ord); od; product; end: Inits:=proc(bset,ord) local i,list; options remember,system; list:={}; for i in bset do list:=list union Factorlist(Init(i,ord)) od; for i in list do if Class(i,ord)=0 then list:=list minus {i} fi od; list end: #The following will be used in algebraci case ONLY!!! Inits1:=proc(bset,ord) local i,list; options remember,system; list:={}; for i in bset do if Class(Init(i,ord),ord)>1 then list:=list union Factorlist(Init(i,ord)) fi od; ### remove the the factors with class <2 for i in list do if Class(i,ord) < 2 then list:=list minus {i} fi od; list end: ####################################################################### ####################################################################### # Compute the Characteristic set with FACTORIZATION ####################################################################### ####################################################################### # # NAME: Cs_a # INPUT: ps: a polynomial set, Suppose each pol in ps is irreducible over Q. # ord: indeterminate ordering. if ord:=[z,y,x] means z>y>x; # nzero: a polynomial set. Each pol in nzero is NOT equal to 0 # # test: a polynomial set, which is NOT equal to 0. # T: a symbol to decide to use which kind of ascending set # T: r_asc, w_asc,g_asc,q_asc=t_asc # OUTPUT: a list of ascending set ##################################################################### Cs_a:=proc(ps,ord,nzero,test,T) global asc_set,INDEX,time_bs,time_rs, time_f,__testp__; local asc,i,j,rm,cset,test1,ps1,bset,rset, ltime_b,ltime_r,ltime_f; options remember,system; if Nums(ps,ord)>1 then RETURN({}) fi; rm := {}; cset := {}; if {op(ps)} intersect nzero <> {} then RETURN({}) fi; if POLY_MODE='Algebraic' then if nops(nzero) <> 0 and Emptyset(nzero,ps,ord) = 1 then print("An empty set");RETURN({}) fi; if __testp__= 1 and nops(test) <> 0 and TestQ(test ,ps,ord) = 1 then print("One factor of an initial has been found and it will be appended to the original polynomial set "); # print("remfac=",remfac); RETURN({}) fi; fi; # print("ps=",ps); ltime_b:=time(); bset := Basicset(ps,ord,T); # print("bset=",bset); time_bs:=time_bs+time()-ltime_b; ltime_r:=time(); rset := Remset([op(ps)],bset,ord,T); # print("rset=",rset); time_rs:=time_rs+time()-ltime_r; if rset={1} then RETURN({}) fi; # for i in rset do if Class(i,ord)=0 then RETURN({}) fi od; if rset = {} then INDEX:= INDEX+1; asc_set[INDEX] := bset; print(`A New Component`); RETURN({bset}) fi; # for i in rset do # if (Class(i,ord) = 0) and (i <> 0) then RETURN({}) fi # od; ############## if POLY_MODE='Algebraic' and __testp__= 1 then test1 := test union Inits(bset,ord); else test1:=test; fi; ############## ltime_f:=time(); rset := Nrs(rset,ord,nzero union test1); time_f:=time_f+time()-ltime_f; if rset = {} then RETURN({}) fi; cset:=map(Cs_a,map(`union`,rset,{op(bset)}),ord,nzero,test1,T); map(op,cset); end: ####################################################################### ####################################################################### # # NAME: charset_a # INPUT: ps: a polynomial set, Suppose each pol in ps is irreducible over Q. # ord: indeterminate ordering. if ord:=[z,y,x] means z>y>x; # nzero: a polynomial set. Each pol in nzero is NOT equal to 0 # # T: a symbol to decide to use which kind of ascending set # T: r_asc, w_asc,g_asc,q_asc=t_asc # OUTPUT: a list of ascending set ##################################################################### charset_a:=proc(ps,ord,nzero,T) global asc_set,INDEX,time_bs,time_rs, time_f; local asc,i,j,rm,cset,test1,ps1,bset,rset, ltime_b,ltime_r,ltime_f; options remember,system; # if Nums(ps,ord)>1 then RETURN({}) fi; rm := {}; cset := {}; if {op(ps)} intersect nzero <> {} then RETURN({}) fi; if nops(nzero) <> 0 and Emptyset(nzero,ps,ord) = 1 then print("An empty set");RETURN({}) fi; # print("ps=",ps); ltime_b:=time(); bset := Basicset(ps,ord,T); # print("bset=",bset); time_bs:=time_bs+time()-ltime_b; ltime_r:=time(); rset := Remset([op(ps)],bset,ord,T); rset := map(primpart,rset,ord); # print("rset=",rset); time_rs:=time_rs+time()-ltime_r; if rset={1} or Non0Constp(rset,ord)=1 then RETURN([]) fi; # for i in rset do if Class(i,ord)=0 then RETURN({}) fi od; if rset = {} then INDEX:= INDEX+1; asc_set[INDEX] := bset; print(`A New Component`); RETURN(bset) fi; # for i in rset do # if (Class(i,ord) = 0) and (i <> 0) then RETURN({}) fi # od; # test1 := test union Inits(bset,ord); ltime_f:=time(); # rset := Nrs(rset,ord,nzero union test1); time_f:=time_f+time()-ltime_f; # if rset = {} then RETURN({}) fi; cset:=charset_a({op(bset)} union rset,ord,nzero,T); cset; end: charset_b:=proc(ps,ord,nzero,T) local cset,rs; options remember,system; cset := charset_a(ps,ord,nzero,T); rs:=Remset([op(ps)],cset,ord,T); # rs:=map(primpart,rs,ord); if rs={} then RETURN(cset) fi; if rs={1} then RETURN([]) fi; if cset=[] then RETURN([]) fi; # #lprint("kkkkkkkkkkkkk"); # cset:=charset_b({op(ps)} union {op(cset)} union rs,ord,nzero,T); while rs<> {} do cset:=charset_a({op(cset)} union rs, ord,nzero,T); #####we should consider the the following special case which cset=[] if nops(cset)=0 then RETURN(cset) fi; rs:=Remset(ps,cset,ord,T); od; cset end: CS_a:=proc(ps,ord,nzero,T) local pset,cset,order,nonzero,asc; options remember, system; if nargs < 1 then ERROR(`too few arguments`) elif nargs>4 then ERROR(`too many arguments`) fi; if nargs<2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; if nargs<3 then nonzero:={} else nonzero:=nzero fi; if nargs<4 then asc:=`` else asc:=T fi; cset:={}; pset:=Nrs(ps,order,nonzero); cset:=map(Cs_a,pset,order,nonzero,{},asc); [op(map(op,cset))]; end: ####################################################################### # # NAME: Cs_b # INPUT: ps: a polynomial set, Suppose each pol in ps is irreducible over Q. # ord: indeterminate ordering. if ord:=[z,y,x] means z>y>x; # nzero: a polynomial set. Each pol in nzero is NOT equal to 0 # # test: a polynomial set, which is NOT equal to 0. # T: a symbol to decide to use which kind of ascending set # T: r_asc, w_asc,g_asc,q_asc=t_asc # OUTPUT: a list of ascending set ##################################################################### Cs_b:=proc(ps,ord,nzero,test,T) local cset,cset1,i,j,rs,rs1; options remember,system; if Nums(ps,ord)>1 then RETURN({}) fi; rs1:={}; cset := Cs_a(ps,ord,nzero,test,T); cset1:=cset; for i in cset1 do rs:=Remset([op(ps)],i,ord,'std_asc'); # for i in cset1 do rs:=Remset([op(ps)],i,ord,T); # if rs<>{} then if rs <> {1} then rs1:=rs1 union {rs union {op(i)} } fi; if rs<>{} then if rs <> {1} then rs:=Nrs(rs,ord,nzero union test); rs1:=rs1 union map(`union`,rs , {op(i)} ) fi; cset:=cset minus {i} fi od; if rs1={} then RETURN(cset) fi; for j in rs1 do cset:=cset union Cs_b(ps union j,ord,nzero,test,T) od; cset end: ####################################################################### # # NAME: Cs_c # INPUT: ps: a polynomial set, Suppose each pol in ps is irreducible over Q. # ord: indeterminate ordering. if ord:=[z,y,x] means z>y>x; # nzero: a polynomial set. Each pol in nzero is NOT equal to 0 # # test: a polynomial set, which is NOT equal to 0. # T: a symbol to decide to use which kind of ascending set # T: r_asc, w_asc,g_asc,q_asc=t_asc # OUTPUT: a list of ascending set ##################################################################### Cs_c:=proc(ps,ord,nzero,T) local cset,remf,ps1,i,nzeros; global remfac; options remember,system; if Nums(ps,ord)>1 then RETURN({}) fi; remfac:={}; cset:=Cs_b({op(ps)},ord,{op(nzero)},{},T); remf:=remfac minus {op(nzero)}; # print(remf); # print(remf); for i to nops(remf) do # print(remf[i]); # print(ps); ps1 := {op(ps)} union {remf[i]}; if i = 1 then nzeros := {op(nzero)} else nzeros := nzeros union {remf[i-1]} fi; cset := cset union Cs_c(ps1,ord,nzeros,T) od; cset end: CS:=proc(ps,ord,nzero,T) local i,pset,cset,order,nonzero,asc; options remember, system; if nargs < 1 then ERROR(`too few arguments`) elif nargs > 4 then ERROR(`too many arguments`) fi; if nargs < 2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; if nargs < 4 then asc:='std_asc' else asc:=T fi; cset:={}; pset:=Nrs(ps,order,nonzero); for i to nops(pset) do cset:=cset union Cs_c(pset[i],order,nonzero,asc) od; [op(cset)] end: checknum:=0: Css:=proc(ps,ord,nzero,T) global remfac,checknum; local cset1,cset,i,j,nzero1, ps1,ps2,Is,Ninits; options remember,system; checknum:=checknum+1; remfac := {}; cset1 := Cs_c(ps,ord,nzero,T); cset := cset1; # nn:=0; for i in cset1 do # print(nops(cset1)); # nn:=nn+1; # print(nn); if Class(i[nops(i)],ord)=1 and POLY_MODE='Algebraic' then Is:=Inits1(i,ord) else Is := Inits(i,ord) fi; if POLY_MODE='Partial_Differential' or POLY_MODE='Ordinary_Differential' then Is := Is union Septs(i,ord) fi; Ninits := Is minus {op(nzero)}; # print("checknum=",checknum, "Ninits=",Ninits); for j to nops(Ninits) do ps1 := ({op(ps)} union {op(i)}) union {Ninits[j]}; if j = 1 then nzero1 := {op(nzero)} else nzero1 := nzero1 union {Ninits[j-1]} fi; cset := cset union Css(ps1,ord,nzero1,T) od od; cset end: realfac:=proc(ps,ord) local s,res,i; options remember,system; s:=Produce(ps,ord,{}); res:={}; for i in s do res:=res union i; od; res; end: Degenerate:=proc(ds,as,ord) local i,r; options remember,system; for i in ds do r:=Premas(i,as,ord,'std_asc'); if r =0 then return 1 fi; od; 0; end: ### POLY_MODE:= one of ['Algebraic','Ordinary_Differential','Partial_Differential'] ### depend_relation is like : [[x,y],[t]]; #### T:= one of ['std_asc','norm_asc','wu_asc','gao_asc','tri_asc'] CSS:=proc(ps,ord,nzero,T) global factor_time,prem_time, t_time,time_bs,time_rs,time_f; local asc,i,pset,cset,nonzero,order,result,wm; options remember,system; if nargs < 2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; if nargs < 4 then asc:='std_asc' else asc:=T fi; if asc='norm_asc' then return Dec({op(ps)},order,nonzero,'std_asc');fi; cset:={}; factor_time:=0; prem_time:=0; time_bs:=0; time_rs:=0; time_f:=0; t_time:=time(); pset:=Nrs(ps,order,nonzero); if asc='norm_asc' then for i to nops(pset) do cset:=cset union Dec(pset[i],order,nonzero,'std_asc') od; else for i to nops(pset) do cset:=cset union Css(pset[i],order,nonzero,asc) od; fi; result:=[]; for i in cset do if Degenerate(nonzero,i,order)<>1 then result:=[op(result),i]; fi od; #lprint("Timing","Total", time()-t_time, "Factoring", factor_time,"Prem",prem_time); #lprint("BasicSet",time_bs,"RS",time_rs,"factor",time_f); result; end: charset:=proc(ps,ord,nzero,T) global factor_time,prem_time, t_time,time_bs,time_rs,time_f; local asc,nonzero,order,result,cm; options remember,system; if nargs < 2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; if nargs < 4 then asc:='std_asc' else asc:=T fi; prem_time:=0; time_bs:=0; t_time:=time(); result:=charset_b({op(ps)}, order,nonzero,asc); # result:=charset_b(map(primpart,{op(ps)},order),order,nonzero,asc); #lprint("Timing","Total", time()-t_time, "BasicSet",time_bs,"Prem",prem_time); result; end: Css1:=proc(ps,ord,test,type) local cset,i,j,septs,cset1,nonzero,vv; options remember,system; cset:=CSS(ps,ord,test,type); # septs:={}; cset1:=cset; nonzero:={op(test)}; for i in cset1 do septs:=Septs(i,ord) minus Inits(i,ord); if septs<>{} then for j in septs do vv:= {op(Css1(ps union {op(i)} union {j},ord,nonzero,type))}; nonzero:={op(nonzero),j}; cset:={op(cset)} union vv ; od fi od; [op(cset)] end: Gsolve:=proc(ps,ord,test) gsolve(ps,ord,test) end: e_val:=proc(ps,ord,test,T) global factor_time,prem_time, t_time,time_bs,time_rs,time_f; local asc,nonzero,order,result,cm; options remember,system; if nargs < 2 then error("The input should have at least 2 parameters") fi; if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; if nargs < 4 then asc:='std_asc' else asc:=T fi; prem_time:=0; time_bs:=0; t_time:=time(); nonzero:=test; result:=Css1({op(ps)}, ord,nonzero,asc); #lprint("Timing","Total", time()-t_time, "BasicSet",time_bs,"Prem",prem_time); result; end: wsolve:=proc() local rt; global POLY_MODE; POLY_MODE:='Algebraic'; rt:=CSS(args); rt; end: od_wsolve:=proc() local rt; global POLY_MODE,depend_relation; POLY_MODE:='Ordinary_Differential'; if type(depend_relation,'list') and nops(depend_relation) >1 and type(depend_relation[2],'list') and nops(depend_relation[2])=1 then rt:=CSS(args); else #lprint("Please set depend_relation:=[[x,y,...],[t]] first, if x,y,... depend on t"); rt:=0; fi; rt; end: pd_wsolve:=proc() local rt; global POLY_MODE,depend_relation; POLY_MODE:='Partial_Differential'; if type(depend_relation,'list') and nops(depend_relation) >1 and type(depend_relation[2],'list') and nops(depend_relation[2])>1 then rt:=CSS(args); else #lprint("Please set depend_relation:=[[x1,x2,...],[t1,t2,...]] first, if x1,x2,... depend on t1,t2,..."); rt:=0; fi; rt; end: INDEX:=0: __testp__:=0: remfac:={}: prem_time:=0: factor_time:=0: time_bs:=0: time_rs:=0: time_f:=0: POLY_MODE:=Algebraic: RANKING_MODE:='cls_ord_var': # Test Program for Differentiation #---------------------------------------- # Global dependence #---------------------------------------- ######################################################### #11111111111111111111111111111111111111111111111111111111 # #Part IV: The basic functions for differential poly # ######################################################### #Diff_Var:=[u,v,w]; # Declare variables; #Diff_Indets:=[X1,X2,X3]; # Declare Diff ndeterminates; #Lvar:=nops(Diff_Var); #---------------------------------------------------------- # main function #---------------------------------------------------------- dDiff:=proc(dp,var,n) local df,i; options remember,system; df:=dp; if nargs=2 then RETURN (DF(dp,var)) fi; for i to n do df:=DF(df,var); od; df; end: #========================================================== # # dq <- DF(dp, var) # # (differetiating a diff polynomial) # # # Input: dp, a diff polynomial; # var, the variable w.r.t which to be differentiate # # Output: dq, the result after differentiating dp w.r.t var; # #=========================================================== DF:=proc(dp, var) local dq, dp1, dp2; options remember,system; #Step1 [Recursive base] if op(0,dp) <> `+` then dq:=DF_prod(dp,var); RETURN(dq); fi; #Step2 [Recursion] dp1:=op(1,dp); dp2:=normal(dp-dp1); dq:=normal(DF_prod(dp1,var)+DF(dp2,var)); #Step3 [Prepare for return] RETURN(dq); end: #------------------------------------------ # subroutines #------------------------------------------ #========================================================= # # # der <- DF_indet(indet, var) # # (differentiate a differential indeterminante) # # Input: indet, a differential indeterminate which is a # derivative of symobls in Diff_Indets w.r.t # some variables in Diff_Var; # # var, the variable w.r.t which to be differeniated # # Output: der, the derivative of indet w.r.t var # #=========================================================== DF_indet:=proc(indet, var) local der, p, i, index, j,Diff_Var,Diff_Indets,Lvar; global depend_relation; options remember,system; #STEP0 [Initiation diffs]; Diff_Var:=depend_relation[2]; Diff_Indets:=depend_relation[1]; Lvar:=nops(Diff_Var); #STEP1 [Special cases] if not member(var, Diff_Var, 'p') then der := diff(indet, var); RETURN(der); fi; if not member(indet, Diff_Indets) and not member(op(0,indet), Diff_Indets) then der := diff(indet, var); RETURN(der); fi; #STEP2 [Compute] index:=NULL; #Initialization if member(indet, Diff_Indets) then # build a derivative from a diff indet for i from 1 to Lvar do if i = p then index:=index,1; else index:=index,0; fi; od; der:=indet[index]; else # modify a derivative from a given one for i from 1 to Lvar do j:=op(i,indet); if i = p then index:=index,(j+1); else index:=index,j; fi; od; der:=op(0,indet)[index] fi; #STEP3 [Prepare for return] RETURN(der); end: #======================================================== # # dq <- DF_power(dp, var) # # (differentiating a power of a drivative of a diff indet) # # input: dp, a power of a diff indet # var, the variable w.r.t which to be differentiated # # output: dq, the result after differentiating dp w.r.t var # #========================================================= DF_power:=proc(dp, var) local dq, indet, expon; options remember,system; #Step1 [Special cases] # constant case if dp = 1 then dq := 0; RETURN(dq); fi; # indeterminate case if op(0,dp) <> `^` then dq := DF_indet(dp, var); RETURN(dq); fi; #Step2 [Compute] indet:=op(1,dp); expon:=op(2,dp); dq:=expon*indet^(expon-1)*DF_indet(indet,var); #Step3 [Prepare for return] RETURN(dq); end: #========================================================= # # dq <- DF_prod(dp, var) # # (differentiating a product of derivatives of some diff indets) # # input: dp, a product of derivatives of some diff indets # var, the variable w.r.t which to be differentiated # # output: dq, the result after differentiating dp w.r.t var; # #========================================================== DF_prod:=proc(dp, var) local dq, dp1, dp2; options remember,system; #Step1 [Recursive base] if op(0,dp) <> `*` then dq := DF_power(dp, var); RETURN(dq); fi; #Step2 [Recursion] dp1:=op(1,dp); dp2:=normal(dp/dp1); dq:=normal(DF_power(dp1,var)*dp2+dp1*DF_prod(dp2,var)); #Step3 [Prepare for return] RETURN(dq); end: #=============================================================== # # ord <- torder(der) # # computing the order of a derivative of a diff indet # # input: der, a derivative of a diff indet # # output: ord, ord is the order of der. # #================================================================= torder:=proc(der) local ord,i,Diff_Var,Lvar; global depend_relation; options remember,system; #STEP1 [Initialize] if type(der,symbol) then RETURN(0) fi; ord := 0; #STEP2 [Compute] for i from 1 to nops(der) do ord := ord + op(i, der); od; ord; end: #================================================================== # # lead <- Leader(dp, ranking,ord, _cls, _ord) # # Input: dp, a nonzero diff poly; # ranking, a specified ranking; # # Output: the Leader w.r.t. ranking; # # Option: _cls, the class of the lead; # _ord,, the order of the lead; # #=================================================================== Mainvar:=proc(p,ord) options remember,system; Leader(p,ord); end: Leader := proc(dp, ord, _cls, _ord) local lead, cls, order, L, l, der, clsord, i, j, cls1, ord1,Diff_Var,Lvar; global depend_relation; options remember,system; #Step1 [Initialize] Diff_Var:=depend_relation[2]; Lvar:=nops(Diff_Var); L:=indets(dp); l:=nops(L); lead := 1; cls := 0; order := 0; #Step 2 [Algebraic mode] if POLY_MODE='Algebraic' then for i to nops(ord) do if member(ord[i],L) then RETURN(ord[i]) fi od; fi; #Step2 [cls_ord_var case] if RANKING_MODE = cls_ord_var then for i from 1 to l do der := L[i]; cls1:=Class(der,ord); ord1:=torder(der); if cls1 > cls or (cls1 = cls and ord1 > order) then lead := der; cls := cls1; order := ord1 else if cls1 = cls and ord1 = order and ord1 > 0 then for j from 1 to Lvar do if op(j, lead) < op(j, der) then lead := der; cls := cls1; order := ord1; break; else if op(j, lead) > op(j, der) then; break; fi; fi; od; fi; fi; od; fi; #Step3 [ord_cls_var case] if RANKING_MODE = ord_cls_var then for i from 1 to l do der := L[i]; cls1:=Class(der,ord); ord1:=torder(der); if ord1 > order or (ord1 = order and cls1 > cls) then lead := der; cls := cls1; order := ord1 elif ord1 = order and cls1 = cls and ord1 > 0 then for j from 1 to Lvar do if op(j, lead) < op(j, der) then lead := der; cls := cls1; order := ord1; break; elif op(j, lead) > op(j, der) then; break; fi; od; fi; od; fi; #STEP3 [Prepare for return] if nargs > 2 then _cls := cls; fi; if nargs > 3 then _ord := order; fi; RETURN(lead); end: depend:=proc(l1,l2) global depend_relation; depend_relation:=[l1,l2]; 1: end: #============================================================ # # {1,-1,0} <- dercmp(der1, der2) # # input: der1, der2, two derivatives; # # # output: 0 if der1 = der2 # 1 if der1 < der2 # -1 if der1 > der2 # #============================================================ dercmp:=proc(der1, der2,ord) local dp, lead; options remember,system; if der1=der2 then RETURN(0) fi; dp := der1 + der2; lead:=Leader(dp,ord); if lead = der1 then RETURN(-1); else RETURN(1); fi; end: #if der1 is a derivative of der2 then return true else false Is_derivative:=proc(der1, der2) local dt1,dt2,i, l1,l2; options remember,system; if type(der1,symbol) then dt1:=der1 else dt1:=op(0,der1) fi; if type(der2,symbol) then dt2:=der2 else dt2:=op(0,der2) fi; if dt1<>dt2 then RETURN(false) fi; if der1=der2 then RETURN(true) fi; if torder(der2)=0 then RETURN(true) elif torder(der1)=0 then RETURN(false) ; else l1:=dOrder(der1,dt1); l2:=dOrder(der2,dt1); for i to nops(l1) do if op(i,l1) < op(i,l2) then RETURN(false) fi; od; fi; true; end: #if der1 is a proper derivative of der2 then return true else false Is_proper_derivative:=proc(der1, der2) local dt1,dt2,i, l1,l2; options remember,system; if type(der1,symbol) then dt1:=der1 else dt1:=op(0,der1) fi; if type(der2,symbol) then dt2:=der2 else dt2:=op(0,der2) fi; if dt1<>dt2 then RETURN(false) fi; if der1=der2 then RETURN(false) fi; if torder(der2)=0 then RETURN(true) elif torder(der1)=0 then RETURN(false) ; else l1:=dOrder(der1,dt1); l2:=dOrder(der2,dt1); for i to nops(l1) do if op(i,l1) < op(i,l2) then RETURN(false) fi; od; fi; true; end: #return all the derivatives in dp of der proper_derivatives:=proc(dp,der) local i,idt,dets; options remember,system; idt:=indets(dp); dets:={}; for i in idt do if Is_proper_derivative(i,der) then dets:={i,op(dets)}; fi; od; dets; end: #sometimes, Maple's GCD is NOT valid for parameters which has indexes such a[1],a[2]; NPremO := proc(uu,vv,xx) local r,v,dr,dv,lcv,rtv,g,lu,lv; options remember,system; if degree(vv,xx)=0 then RETURN(0) fi; if type(vv/xx,integer) then coeff(uu,xx,0) else r := expand(uu); dr := degree(r,xx); v := expand(vv); dv := degree(v,xx); lcv:=lcoeff(v,xx); # rtv:=sterm(v,xx); rtv:=v-expand(lcoeff(v,xx)*xx^degree(v,xx)); while dv <= dr and r <> 0 do # g:=gcd(lcv,coeff(r,xx,dr)); lu:=lcv; lv:=coeff(r,xx,dr); r:=expand(lu*(r-expand(lcoeff(r,xx)*xx^degree(r,xx)))-lv*rtv*xx^(dr-dv)); dr := degree(r,xx) od; r fi end: #######变量y有两种情形.y and y[1]所以要小心. ODPrem:= proc(uu,vv,y) local u,x,dv,du,d,t,var; global depend_relation; options remember,system; t:=depend_relation[2][1]; var:=depend_relation[1]; # if dClass(uu,var)=0 then RETURN(uu) fi; u:=uu; if type(y,symbol) then x:=y else x:=op(0,y) fi; dv:=dOrder(vv,x); du:=dOrder(u,x); d:=du-dv; if d<0 then RETURN(uu) fi; #the following program is for ordinary differential case while d>0 do u:=NPremO(u,dDiff(vv,t,d), x[du]); du:=dOrder(u,x); d:=du-dv; od; # if dv =0 then NPremO(u,vv,x) else NPremO(u,vv,x[dv]) fi; end: NewPrem:= proc(uu,vv,y) local u,x,dv,du,d,t,var; global depend_relation; options remember,system; if POLY_MODE='Algebraic' then NPrem(uu,vv,y); elif POLY_MODE='Ordinary_Differential' then ODPrem(uu,vv,y); elif POLY_MODE='Partial_Differential' then PDPrem(uu,vv,y); fi; end: Headder:=proc(idts) local hder,i,j; options remember,system; hder:=op(1,idts); # if type(hder,symbol) then var:=hder else var:=op(0,hder) fi; for i in idts do if torder(i) > torder(hder) then hder:=i ; elif torder(i)=torder(her) then for j to nops(hder) do if op(j,i) > op(j,hder) then hder:=i;break; elif op(j,i) < op(j,hder) then break; fi; od; fi; od; hder: end: PDPrem:=proc(dp, dq, y) local Diff_Indets,Diff_Var, var,dr, idt,l2,lder,da,l1,i,s; options remember,system; #Step1 [Special case] Diff_Indets:=depend_relation[1]; Diff_Var:=depend_relation[2]; if y=1 then RETURN(0) fi; if type(y,symbol) then var:=y else var:=op(0,y) fi; dr:=dp; idt:=proper_derivatives(dr,y); l2:=dOrder(y,var); #Step2 [Recursive base] while nops(idt)<>0 do lder:=Headder(idt); da := dq; l1:=dOrder(lder,var); for i to nops(l1) do if l2=0 then s:=op(i,l1) else s:=op(i,l1) -op(i,l2) fi; da := dDiff(da, Diff_Var[i],s); od; dr := NPremO(dr, da, lder); idt:=proper_derivatives(dr,y); od; dr:=NPremO(dr,dq,y) ; #Step4 [Prepare for return] dr; end: # # set: A set; cmb:=proc(set0) local p,q, ls,set1; options remember,system; ls:={}; set1:=set0; for p in set0 do set1:=set1 minus {p}; for q in set1 do ls:={op(ls),[p,q]} od; od; ls; end: ######## modified Nov.6 ######## spolyset:=proc(as,ord) local res,bs,l,p,cls,i,poly; options remember,system; res:={}; bs:={op(as)}; l:=nops(bs); if l <= 1 then RETURN(res) fi; p:=op(1,bs); cls:=Class(Leader(p,ord),ord); bs:=bs minus {p}; while nops(bs) <>0 do for i in bs do if Class(Leader(i,ord),ord) = cls then poly:=PD_spoly(i,p,ord); res:=res union {poly} fi; od; p:=op(1,bs); cls:=Class(Leader(p,ord),ord); bs:=bs minus {p}; od; res minus {0}; end: PD_spoly:=proc(p,q,ord) local leadp,leadq,var,l1,l2,ml,dp,dq,i,Diff_Var; global depend_relation; options remember,system; leadp:=Leader(p,ord); leadq:=Leader(q,ord); var:=op(0,leadp); Diff_Var:=depend_relation[2]; l1:=dOrder(leadp,var); l2:=dOrder(leadq,var); ml:=maxlist(l1,l2); dp:=p; dq:=q; for i to nops(ml) do dp:=dDiff(dp,Diff_Var[i],ml[i]-l1[i]); dq:=dDiff(dq,Diff_Var[i],ml[i]-l2[i]); od; ######直觉觉得可以直接用PDPrem(dp,q,Leader(q,ord)) 更好。而这里用的是标准的方法。 NPremO(dp,dq, Leader(dq,ord)); end: maxlist:=proc(l1,l2) local i,list; options remember,system; list:=[]; for i to nops(l1) do list:=[op(list), max(l1[i],l2[i])]; od: list end: #torder Is_deriv Reducedp Leader Head Leader PDE map Num spoly NewPrem # the class of poly f wrt variable ordering ord MainVariables := proc(ps,ord) local i,set; options remember,system; set:={}; for i in ps do set:=set union {Leader(i,ord)}; od; set end: PNormalp:=proc(p,as,ord) local i,idts,mvs,initp; options remember,system; initp:=Initial(p,ord); idts:=indets(initp); if idts={} then RETURN(true) fi; mvs:=MainVariables(as,ord); for i in idts do if member(i,mvs) then RETURN(false) fi; od; true end: ASNormalp:=proc(ps,ord) local i,l,as,p; options remember,system; l:=nops(ps); if l=1 then RETURN(true) fi; as:=[ps[l]]; for i from l-1 to 1 by -1 do p:=ps[i]; if not PNormalp(p,as,ord) then RETURN(false) fi; as:=[p,op(as)]; od; true end: Dec:=proc(ps,ord,nzero,T) global remfac,checknum; local i,cset1,cset; options remember,system; cset1:=Cs_c(ps,ord,nzero,T); cset:={}; for i in cset1 do if ASNormalp(i,ord) then cset:=cset union NormDec1(ps,i,ord,nzero,T); else cset:=cset union NormDec2(ps,i,ord,nzero,T); fi; od; cset end: NormDec1:=proc(ps,as,ord,nzero,T) local cset,j,nzero1, ps1,ps2,Is,Ninits; options remember,system; cset:= {as}; if Class(as[nops(as)],ord)=1 then Is:=Inits1(as,ord) else Is := Inits(as,ord) fi; Ninits := Is minus {op(nzero)}; for j to nops(Ninits) do ps1 := ({op(ps)} union {op(as)}) union {Ninits[j]}; if j = 1 then nzero1 := {op(nzero)} else nzero1 := nzero1 union {Ninits[j-1]} fi; cset := cset union Dec(ps1,ord,nzero1,T) od; cset end: NormDec2:=proc(ps,as,ord,nzero,T) local cset,i,j,l,regas,p,initp,lp,pol,r1,r2,Is,Ninits,l2,ps1,nzero1,mvar,vars,mv,d,f,g; options remember,system; cset:={}; l:=nops(as); regas:=[as[l]]; for i from 2 to l do p:=as[l-i+1]; mvar:=Leader(p,ord); d:=degree(p,mvar); if PNormalp(p,regas,ord) then regas:= [p,op(regas)] else initp:=Initial(p,ord); vars:=indets(initp); lp:=nops(regas); ###1 开始111 for j to lp do pol:=regas[j]; mv:=Leader(pol,ord); if member(mv,vars) then # 注意Resultant函数 r1:=NResultantE(initp,pol, Leader(pol,ord),'f','g'); r2:=Premas(r1,regas,ord,'std_asc'); if r2=0 then if Class(as[nops(regas)],ord)=1 then Is:=Inits1(regas,ord) else Is := Inits(regas,ord) fi; Ninits := Is minus {op(nzero)}; l2:=nops(Ninits); nzero1:={op(nzero)}; for j to l2 do ps1 := ({op(ps)} union {op(as)}) union {Ninits[j]}; if j <> 1 then nzero1 := nzero1 union {Ninits[j-1]} fi; cset := cset union Dec(ps1,ord,nzero1,T) od; print("kkkkkkkkkk"); if l2 <> 0 then nzero1:=nzero1 union {Ninits[l2]} fi; # f;g; # print("cset=",cset); # print("ps=",ps); # print("as=", as); # print("regas=",regas); cset:=cset union Dec(ps union {op(as)} union {op(regas)} union {f},ord,nzero1,T) union Dec(ps union {op(as)} union {op(regas)} union {initp},ord,nzero1,T); RETURN(cset); else # p 变形成新的p p:=expand(f*p+g*pol*mvar^d); p:=Premas(p,regas,ord,'std_asc'); initp:=Initial(p,ord); vars:=indets(initp); fi; fi; od; ###1 结束111 regas:=[p,op(regas)] fi; od; cset:=NormDec1(ps,regas,ord,nzero,T); cset end: #如果首项系数变成0,而余式不是0则置degenerate为1否则为0。 WuPrem:= proc(uu,vv,x,ord,degenerate) local r,init,lead,lmono,red,init_r,s,t; options remember,system; degenerate:=0; if uu=0 then RETURN(0) fi; r:=uu; if Class(uu,ord) = Class(vv,ord) then r:= NPrem(uu,vv,x); elif Class(uu,ord) > Class(vv,ord) then init:=Initial(uu,ord); if degree(init,x) >0 and Reducedp(init, vv,ord,'std_asc') = 0 then lead:=Leader(uu,ord); # collect(uu,lead); lmono:=lead^degree(uu,lead); red:=expand(uu-init*lmono); init_r:=NPremE(init,vv,x,'s','t'); r:=expand(init_r*lmono+s*red); if init_r=0 and r <>0 then degenerate:=1 fi; # collect(r,lead); fi; fi; r; end: NPremE := proc(uu,vv,x,s1,t1) local r,v,dr,dv,l,t,lu,lv,s0,t0; options remember,system; s0:=1; t0:=0; r := expand(uu); dr := degree(r,x); v := expand(vv); dv := degree(v,x); if dv <= dr then l := coeff(v,x,dv); v := expand(v-l*x^dv) else l := 1 fi; while dv <= dr and r <> 0 do gcd(l,coeff(r,x,dr),'lu','lv'); s0:=lu*s0; t0:=lu*t0+lv*x^(dr-dv); t := expand(x^(dr-dv)*v*lv); if dr = 0 then r := 0 else r := subs(x^dr = 0,r) fi; r := expand(lu*r)-t; dr := degree(r,x) od; s1:=expand(s0); t1:=expand(t0); r end: #This function is for ascending set normalization. #in fact, it is not a resultant for 2 pols with indeterminate x. #for two polys uu,vv with indeterminate x #it has the property m*uu+n*vv=r with degree(r,x)=0; NResultantE := proc(uu,vv,x,m,n) local r,s,t,r0,s0,t0,r1,s1,t1,tmpr,tmps,tmpt; options remember,system; r0:=uu; s0:=1; t0:=0; r1:=vv; s1:=0; t1:=1; if degree(r0,x)=0 then m:=1;n:=0;RETURN(r0) fi; if degree(r1,x)=0 then m:=0;n:=1;RETURN(r1) fi; while degree(r1,x) >= 1 do r:=NPremE(r0,r1,x,'s','t'); tmpr:=r1; tmps:=s1; tmpt:=t1; r1:=r; s1:=s*s0-t*s1; t1:=s*t0-t*t1; r0:=tmpr; s0:=tmps; t0:=tmpt; od; m:=s1; n:=t1; r end: ############################################################################## # Name: SylvesterResultant # Calling sequence: SylvesterResultant(f, g, x, u, v) # Input: f, g two polynomials in x with positive degrees # x, a name # Output: the Sylvester resultant of f and g with respect to x # Optional: u, v, such that # u*f+v*g = resultant ############################################################################### #SylvesterResultant := proc(f, g, x, u, v) NResultantE := proc(f, g, x, u, v) local df, dg, deg, A, a, b, U, V, i, m, Q, l, e, s, us, vs; #------------------------------------------- # check input #------------------------------------------- (df, dg) := degree(f, x), degree(g, x); if df = 0 or dg = 0 then error "input polynomials should be of positive degrees"; end if; #--------------------------------------------- # initialize data #--------------------------------------------- if df >= dg then (A[1], A[2]) := f, g; (deg[1], deg[2]) := df, dg; else (A[1], A[2]) := g, f; (deg[1], deg[2]) := dg, df; end if; if nargs > 3 then (U[1], U[2]) := 1, 0; if nargs > 4 then (V[1], V[2]) := 0, 1; end if; end if; (a[1], b[1], a[2], b[2]) := (1, 1, lcoeff(A[2],x), lcoeff(A[2], x)^(deg[1]-deg[2])); i := 2; l[i] := deg[i-1]-deg[i]+1; #---------------------------------------------- # compute #---------------------------------------------- while true do i := i + 1; #------------------------------- # form extraneous factor #------------------------------- e[i] := (-1)^l[i-1]*a[i-2]*b[i-2]; #-------------------------------- # compute remainder #-------------------------------- if nargs = 3 then A[i] := evala(Simplify(prem(A[i-2], A[i-1], x)/e[i])); else A[i] := evala(Simplify(prem(A[i-2], A[i-1], x, 'm', 'Q')/e[i])); U[i] := evala(Simplify((m*U[i-2] - Q*U[i-1])/e[i])); if nargs = 5 then V[i] := evala(Simplify((m*V[i-2] - Q*V[i-1])/e[i])); end if; end if; #----------------------------------- # Resultant is zero #----------------------------------- if A[i] = 0 then if nargs > 3 then u := U[i]; if nargs > 4 then v := V[i]; end if; end if; return A[i]; end if; #------------------------------------ # update auxiliary sequences #------------------------------------ deg[i] := degree(A[i], x); l[i] := deg[i-1]-deg[i]+1; a[i] := lcoeff(A[i], x); b[i] := evala(Simplify(a[i]^(l[i]-1)/b[i-1]^(l[i]-2))); #------------------------------------------- # Resultant is nonzero #------------------------------------------- if deg[i] = 0 then if nargs > 3 then s := evala(Simplify(b[i]/a[i])); us := evala(Simplify(U[i]*s)); if nargs > 4 then vs := evala(Simplify(V[i]*s)); end if; if df >= dg then u := us; if nargs > 4 then v := vs; end if; else u := (-1)^(df*dg)*vs; if nargs > 4 then v := (-1)^(df*dg)*us; end if; end if; end if; if df >= dg then return b[i]; else return (-1)^(df*dg)*b[i]; end if; end if; end do; end proc: #printf(" Pls type 'with(linalg)' firstly before calling function 'Resultant_E' "); ##The following is to compute the resultant of 2 pols via computing the determinant directly. # input: M is a list of lists , whereby to denote a matrix; # i,j are two integer numbers; # output:sM is a new list of lists, obtained by removing # the ith row and jth column of L, SubM:=proc(M,i,j) local row,tmp,sM; if i<1 or i>nops(M) then error "Input row index %1 broke bounds",i;fi; if j<1 or j>nops(M[1]) then error "Input column index %1 broke bounds",j;fi; sM:=[]; tmp:=subsop(i=NULL,M); for row in tmp do row:=subsop(j=NULL,row); sM:=[op(sM),row]; od; sM; end: # with(linalg) firstly # input: A,B are two polynomials, v is a variable; # output:[R,T,U]; R,T,U are three polynomials, where R is the resultant # of A,B w.r.t v, so that A*T+B*U=R #with(linalg); NResultantE_Matrix:=proc(A,B,v,TA,UB) local m,n,d1,d2,cA,cB,row,i,j,syl,msyl,sM,sign,R,T,U,result; # #lprint("nargs=",nargs); if (nargs <> 3) and (nargs <> 5) then error "Number of parameters should be 3 or 5" fi; m:=degree(A,v); n:=degree(B,v); if m=0 then error "InPut Polynomial %1 Has No Variable %2",A,v;fi; if n=0 then error "InPut Polynomial %1 Has No Variable %2",B,v;fi; # to get coefficients of A and B cA:=[]; for d1 from 0 to m do cA:=[coeff(A,v,d1),op(cA)]; od; cB:=[]; for d2 from 0 to n do cB:=[coeff(B,v,d2),op(cB)]; od; # initialize sylvester matrix syl:=[]; for i from 1 to n do row:=cA; for j from 1 to i-1 do row:=[0,op(row)];od; for j from 1 to n-i do row:=[op(row),0];od; syl:=[op(syl),row]; od; for i from 1 to m do row:=cB; for j from 1 to i-1 do row:=[0,op(row)];od; for j from 1 to m-i do row:=[op(row),0];od; syl:=[op(syl),row]; od; msyl:=linalg[matrix](m+n,m+n,syl); # to get resultant of A,B w.r.t v R:=linalg[det](msyl); R:=expand(R); if nargs=3 then RETURN(R) fi; # to get T T:=0; for d1 from 1 to n do sign:=(-1)^(d1+m+n mod 2); sM:=SubM(syl,d1,m+n); T:=T+(v^(n-d1))*expand(sign*linalg[det](linalg[matrix](m+n-1,m+n-1,sM))); T:=expand(T); od; # to get U U:=0; for d2 from 1 to m do sign:=(-1)^(d2+m mod 2); sM:=SubM(syl,d2+n,m+n); U:=U+(v^(m-d2))*expand(sign*linalg[det](linalg[matrix](m+n-1,m+n-1,sM))); U:=expand(U); od; if nargs=5 then TA:=T; UB:=U fi; R; end: ########################################################################################### ########################################################################################### ############## computing partioned-parametric Grobner basis 2005.11.4################### ##需要 “wsolve” 和 “project” ##文后付有主要函数调用的例子 ########################################################################################### ########################################################################################### ########################################################################################### interface(warnlevel=0); with(Groebner): ########p在约束Zero(a11/a12)下一定不为0,ord是参变元########## NotZeroUnderCons:=proc(a11,a12,p,ord) option remember; RETURN(IsEmpty({op(a11),p},a12,ord)); end: ########p在约束Zero(a11/a12)下一定为0,ord是参变元########## IsZeroUnderCons:=proc(a11,a12,p,ord) option remember; RETURN(IsEmpty(a11,{op(a12),p},ord)); end: ########约束多项式conspolyset形式:[[{a11},{a12}],[{a21},{a22}]]## UnAmbiguous:=proc(conspolyset,var_para::list,term_order) local p,vp,result,a11,a12,a21,a22,newa11,newa22,lc,vars,paras,reduct; vars:=var_para[1]; paras:=var_para[2]; a11:=conspolyset[1][1]; a12:=conspolyset[1][2]; a21:=conspolyset[2][1]; a22:=conspolyset[2][2]; if a22={} then RETURN ({conspolyset}); fi; p:=a22[1]; newa22:=a22 minus {p}; if nops(a21) <>0 then p:=numer(normalf(p,a21,term_order(op(vars)))); fi; ##########AAA if (_field_characteristic_ <>0 ) then p :=expand(p) mod _field_characteristic_ fi; if nops(a11) <>0 then p:=numer(normalf(p,a11,term_order(op(paras)))); fi; if (_field_characteristic_ <>0 ) then p :=expand(p) mod _field_characteristic_ fi; #########如果p是0多项式############ if p=0 then result:=UnAmbiguous([[a11,a12],[a21,newa22]],var_para,term_order); RETURN(result); fi; ##########如果p是非0常数############## if (p <> 0) and ( type(p,'constant') ) then RETURN ( {[conspolyset[1],[{1},{} ] ]}); fi; #lprint("p="); #lprint(p); lc:=leadcoeff(p,term_order(op(vars))); #lprint("lc="); #lprint(lc); reduct:=expand(p-lc*leadterm(p,term_order(op(vars)))); vp:=indets(p); #######如果p含有变元############ if (vp intersect {op(vars)}) <> {} then if(type(lc,'constant')=true) then result:=UnAmbiguous([[a11,a12],[a21 union {p}, newa22]],var_para,term_order); elif NotZeroUnderCons(a11,a12,lc,paras) then result:=UnAmbiguous([[a11,a12],[a21 union {p}, newa22]],var_para,term_order); elif IsZeroUnderCons(a11,a12,lc,paras) then result:=UnAmbiguous([[a11,a12],[a21,newa22 union {reduct}]],var_para,term_order); else lc:=CutNozeroFactors(lc,a12); newa11:=CutPolyByFactor(a11,lc); result:=UnAmbiguous([[{op(newa11),lc},a12],[a21,newa22 union {reduct}]],var_para,term_order) union UnAmbiguous([[a11,a12 union FactorList(lc)],[a21 union {p}, newa22]],var_para,term_order); fi; else #######如果p不含变元,只含参数############ ##modify if NotZeroUnderCons(a11,a12,p,paras) then result:={[conspolyset[1],[{1},{} ]]}; elif IsZeroUnderCons(a11,a12,p,paras) then result:=UnAmbiguous([[a11,a12],[a21,newa22]],var_para,term_order) ; else lc:=CutNozeroFactors(lc,a12); newa11:=CutPolyByFactor(a11,lc); result:=UnAmbiguous([[{op(newa11),lc},a12],[a21,newa22]],var_para,term_order) union UnAmbiguous([[a11,a12 union FactorList(lc)],[{1}, {}]],var_para,term_order); fi; fi; result: end: ######pol对list1中的多项式逐个做除法,返回商####### DivideList:=proc(pol,list1) local i,q,rt; rt:=pol; for i in list1 do if divide(rt,i,'q') then rt:=q; fi; od; rt; end: ###<1>list1中的多项式已不可约 ###<2>去掉pol中在list1里列出的因子且忽略重数 CutNozeroFactors:=proc(pol,list1) local i,q,sqf_pol,rt; sqf_pol:=sqrfree(pol); sqf_pol:=sqf_pol[2]; for i from 1 to nops(sqf_pol) do sqf_pol[i][1]:=DivideList(sqf_pol[i][1],list1); od; rt:=1; for i from 1 to nops(sqf_pol) do rt:=rt*(sqf_pol[i][1]); od; rt; end: ###去掉list1中以pol为因子的多项式 CutPolyByFactor:=proc(list1,pol) local p,rt,q; rt:={}; for p in list1 do if not divide(p,pol,'q') then rt:={op(rt),p};fi; od; rt; end: ##<1>通过gb对等于零的约束部分做normalform来化简 ##<2>因为gb的首系数一定不为零,通过对gb做primpart来化简 SimplifyConsgb:=proc(consgb,var_para,term_order) local rt,i,temp,paras,vars; vars:=var_para[1]; paras:=var_para[2]; rt:={}; for i in consgb do temp:=map(normalf,i[2],i[1][1],term_order(op(paras))); temp:=map(primpart,map(numer,temp),vars); rt:={op(rt),[i[1],temp]}; od; rt; end: FactorList:=proc(pol) local i,list1,list2; list1 := factors(pol)[2]; list2 := {}; for i in list1 do list2 := {op(list2),i[1]}; od; list2 end: #######如果p在constrain的条件下为0在返回1,np=0 #######如果p在constrain的条件下为非0的常数返回10,np=10 #######如果p在constrain的条件下首项系数一定不是0则返回-1 #######其他情形返回0。np=pol ########paracons=[ [part=0 ],[part <>0]] 是参数的约束; nonzerolc:=proc(pol,paracons,var_para,np,term_order) local lc,vars,paras,cons1,cons2,np0,t,pol2; global _field_characteristic_ ; vars:=var_para[1]; paras:=var_para[2]; cons1:=paracons[1]; cons2:=paracons[2]; lc:=leadcoeff(pol,term_order(op(vars))); if pol=0 then np:=0; RETURN(1); fi; if type(pol,'constant') then np:=10; RETURN(10); fi; if type(lc,'constant') then np:=pol; RETURN(-1); fi; ##########lc在约束下一定为0####### if IsZeroUnderCons(cons1,cons2,lc,paras) then pol2:=reductum(pol,term_order(op(vars))); if (_field_characteristic_ <>0 ) then pol2:=pol2 mod _field_characteristic_ fi; t:=nonzerolc(pol2,paracons,var_para,'np0',term_order); np:=np0; RETURN(t); ##########lc在约束下一定不为0####### elif NotZeroUnderCons(cons1,cons2,lc,paras) then if lc=pol then np:=10; RETURN(10); else np:=pol; RETURN(-1); fi; else np:=pol; RETURN(0); fi; end: reductum:=proc(p,ord) local res; expand(p-leadcoeff(p,ord)*leadterm(p,ord)); end: gb:=proc(ps,var_para,term_order) local res; res:=gb0([[{},{}],[{},{op(ps)}]],var_para,term_order); res:=SimplifyConsgb(res,var_para,term_order); end: gb0:=proc(conspolyset,var_para,term_order) local i,branches, res,temp; res:={}; branches:=UnAmbiguous(conspolyset,var_para,term_order); for i in branches do temp:=gb1(i,var_para,term_order); res:=res union temp; od; res; end: #################Step 1######################## gb1:=proc(conspolyset,var_para,term_order) local i,j,T,paracons,pset,pset0,pset1,pol,pset3,l,nonzerosp,sp,bs2,vars,newpol,cr,nf,np; global _field_characteristic_; T:={}; vars:=var_para[1]; paracons:=conspolyset[1]; pset:=conspolyset[2][1]; pset0:=pset; pset1:={}; if nops(pset)=0 then RETURN({[paracons,[0]]}) fi; if nops(pset) =1 then RETURN({[paracons,[op(pset)]]}) fi; #################Step 2----- Normalization------##################### for i in pset do pset0:=pset0 minus {i}; nf:=normalf(i,pset0 union pset1,term_order(op(vars))); pol:=expand(numer(nf )); cr:=nonzerolc(pol,paracons,var_para,'newpol',term_order); newpol:=numer(normalf(newpol,pset0 union pset1,term_order(op(vars)))); if (_field_characteristic_ <>0 ) then newpol :=expand(newpol) mod _field_characteristic_ fi; #lprint("newpol=");#lprint(newpol); if cr=1 then ; elif cr=10 then RETURN( { [paracons,[1]] }); elif cr=-1 then if newpol <>0 then pset1:=pset1 union {newpol} fi; else pset3:=[paracons,[ pset0 union pset1 ,{newpol} ]]; RETURN( gb0(pset3,var_para,term_order) ); fi; od; ##############Step 3----- S-polynomial------#################################### l:=nops(pset1); if l=1 then RETURN( {[paracons,[op(pset1)]] }) fi; nonzerosp:={}; for i to l do for j from i+1 to l do sp:=expand(numer(normalf(spoly(pset1[i],pset1[j],term_order(op(vars))),pset1,term_order(op(vars))))); if( _field_characteristic_ <>0) then sp:= expand(sp) mod _field_characteristic_ fi; #lprint("sp="); #lprint(sp); if (nonzerolc(sp,paracons,var_para,'np',term_order)<>1) then nonzerosp:=nonzerosp union {np} fi; od; od; if nonzerosp={} then RETURN( {[paracons,inter_reduce([op(pset1)],term_order(op(vars)) )] } ) ; else bs2:=[paracons,[{op(pset1)},nonzerosp ]]; T:=T union gb0(bs2,var_para,term_order); fi; T: end: ############################# ### solution number #### ############################# basis:=proc(a,b,ord) local i,j,k1,k;k:={}; for i in a do k1:=normalf(i,b,ord); if(k1<>0) then k:=k union {k1}; end if; end do; return k; end: mulset:=proc(a,b) local i,j,k; k:={}; if b={} then return a; fi; for i in a do for j in b do k:=k union {i*j}; od; od; return k; end: create:=proc(a,b,num) local i,j,k,k1,b1; b1:=b union {1}; k1:=b1 union mulset(a,b1); if num=0 then return k1;fi; k:=create(a,k1,num-1); end: havefinitesolution:=proc(l,var) local i,lvs,lv1; lv1:={}; for i in l do lvs:=indets(i) intersect {op(var)}; if nops(lvs)=1 then lv1:=lv1 union lvs; fi; od; if ({op(var)} minus lv1 )={} then return true; else return false; fi; end: comp:=proc(a,b) local i,j,k,l;k:={}; for i in b do for j in a do if j=i then k:=k union {j}; fi; od; od; return k; end: getmostdegree:=proc(l) local i,j,k1,k2; k2:={}; k1:={}; for i in l do k1:={op(i)}; for j in k1 do k2:=k2 union {op(j)}; od; od; return k2; end: ltt:=proc(l,vorder) local i,k; k:={}; for i to nops(l) do k:={leadterm(l[i],vorder)} union k; end do; return k; end: GetDim:=proc(lts,vars) local i,branch,l,rt; rt:=nops(lts); branch:=Nrs(lts,[op(vars)],{}); branch:=[op(branch)]; for i to nops(branch) do l:=nops(branch[i]); if l{0} then j:=j+1; rt:=gb[2]; fi; od; if j<>1 then print("ambiguous occur!");fi; rt; end: EvalAll:=proc(op,vars,vals) local i,rt; rt:=op; for i to nops(vars) do rt:=eval(rt,vars[i]=vals[i]); od; rt; end: #把ps中的多项式设成首项系数为1 SetLC1:=proc(ps) local i,p,rt; rt:={}; for i to nops(ps) do p:=expand(ps[i]); if p=0 then rt:={op(rt),p}; else p:=p/lcoeff(p); rt:={op(rt),p}; fi; od; rt; end: ###检验约束groebnerbasis程序的正确性 check:=proc(paravalue,paragb,ps,ord,term_order) local i,gb,gb1,spec_paragb,spec_ps; if nops(paravalue)<>nops(ord[2]) then return "Error in parameter assignment: parameter number is NOT matched!" fi; spec_ps:=EvalAll(ps,ord[2],paravalue); spec_ps:={op(spec_ps)} minus {0}; spec_ps:=[op(spec_ps)]; gb1:=gbasis(spec_ps,term_order(op(ord[1]))); spec_paragb:=EvalAll(paragb,ord[2],paravalue); gb:=FindRightGB(spec_paragb); if SetLC1(gb)=SetLC1(gb1) then print( "two results are the same polynomial set!"); else print("two results are NOT the same polynomial set!"); fi; print("greobner basis gotten by parameter assignment at begin:"); print(gb1); print("greobner basis gotten by CGB method:"); gb; end: ######## 例子 ###################### #参数: #ps:=[a*x^2-b*x,b*y^2-c*x,c*z^2-a*x+b]; #ord:=[[x,y,z],[a,b,c]]; #termord:=tdeg; #'pgb'; 是一个变量名,该参数可缺省 #调用1: #gb(ps,ord,termord) #返回: #ps的约束GroebnerBasis #调用2: #solution(ps,ord,termord,'pgb');  #返回: #ps的不同约束下解的个数。 #pgb为ps的约束GroebnerBasis #调用3: #solution1(ps,ord,termord);  #返回: #ps的约束GroebnerBasis及相应解的个数(若有限,还列出不属于首理想的单项式)。 #参数: #paraval:=[1,2,3]; 是参数[a,b,c]的特定值 #pgb; ps的约束GroebnerBasis #调用4: # check(paraval,pgb,ps,ord,termord); #该函数比较pgb在特定参数值paraval下的GroebnerBasis与先对参数取值后再求的GroebnerBasis是否相同。 #同时也列出这两个GroebnerBasis。此函数可做为全文的测试函数。 #返回: #pgb在特定参数值paraval下的GroebnerBasis ########################################################################################### ########################################################################################### ############## computing partioned-parametric Grobner basis 2005.11.4 ##################### ############## END END END END END END END END END END END END END END##################### ########################################################################################### ########################################################################################### ########################################################################################### ########################for computing the projection of quasi-variety 2005.11.4############### ### read "wsolve.txt" firstly ### if not type(wsolve,procedure) then #lprint(" Warning: please read 'wsolve.txt' firstly ! "): fi: ##-----main function------------------------------------------------ ##Project(ps,ds,ord,pord) //old main function ##Sproject(result_of_project,pord) //no component is redundant ##Example: [[ASC,[a,b]],...] == (ASC=0 and a*b<>0 ) or ... ##Proj(ps,ds,ord,pord) //new main function ##Sproj(result_of_project,pord) //no component is redundant ##Example: [[ASC,[a,b]],...] == (ASC=0 and ( a<>0 or b<>0) ) or ... ##------------------------------------------------------------------- #-----------Part1--------------------- # project(ps,ds,ord,pord) # ord:= all variables (descending order list) # pord:=variables to eliminate (as above) #----------------------------------------------------- #QV (QuasiVariety) ; ASC (ascendant characteristic set) # get the product of the initials of cs Mainvar := proc(f,ord) local i; options remember,system; for i to nops(ord) do if has(f,ord[i]) then RETURN(ord[i]) fi od; #lprint(`Warning: lvar is called with constant`); 0 end: GetIP:=proc(cs,ord) local i,rt; rt:=1; for i from 1 to nops(cs) do rt:=rt*Initial(cs[i],ord); od; rt; end: # get the product of the polys in ds. GetProduct:=proc(ds) local jds,d; jds:=1; for d in ds do jds:=jds*d; od; jds; end: #get the union of two lists, denoted as list also. ListUnion:=proc(list1,list2) local rt; rt:={op(list1)} union {op(list2)}; rt:=[op(rt)]; end: # inverse a list Inverse:=proc(lis) local i,result; result:=[]; for i from nops(lis) to 1 by -1 do result:=[op(result),lis[i]]; od; result; end: # inverse every list in a list. InverseAll:=proc(lislis) local rt,l; rt:=[]; for l in lislis do rt:=[op(rt),Inverse(l)]; od; end: # eliminate such ASC in cslist that Premas(jds,ASC,ord)=0 Newcslist:=proc(cslist,jds,ord) local rt,cs; rt:=[]; for cs in cslist do if Premas(jds,cs,ord)<>0 then rt:=[op(rt),cs] fi; od; rt; end: # factors of a polynomial w.r.t ord; # facts(x^2*y+x*y-x,[x,y]); [x,x*y+y-1] # facts(x^2*y+x*y-x,[y]); [x*y+y-1] # facts(x^2*y+x*y-x,[u,v,w]); [] Ordfacts:=proc(pol,ord) local i,temp,facl,result; if type(pol,polynom) then result:=[]; facl:=factors(pol); facl:=facl[2]; if facl=[] then RETURN([]) fi; for i from 1 to nops(facl) do temp:=facl[i]; if dClass(temp[1],ord)<>0 then result:=[op(result),temp[1]]; fi; od; RETURN(result); else #lprint(`Warning: facts is called with no polynomial`); RETURN(pol); fi; end: # put p to proper position in notzerolist s.t. MV(ASC[i-1])<=MV(p) p in fpolys and <2> MV(ASC[i-1])<=MV(p)2 then rt:=3; elif not type(qv[2],polynom) then rt:=3; elif Class(qv[2],ord)<>0 then rt:=3; elif qv[2]=0 then rt:=0; else rt:=1; fi; RETURN(rt); end: # get variables of pol which are of higher order then the highest # polynomial in asc. HigherOrdVars:=proc(pol,mvl,len,ord) local vl,rt,var,index; vl:=indets(pol) intersect {op(pord)}; rt:=[]; if len<=1 then RETURN(rt);fi; for var in vl do index:=Class(var,ord); if index>mvl[len-1] then rt:=[op(rt),var]; fi; od; rt; end: # decompose the pol in [[ASC],pol] to ['UN',[[ASC],pol1],...] # so as to eliminate variables in varl. DecompList:=proc(qv,subasc,notzerolist,varList,ord) local i,flag,lenasc,rt,pol,coeffsList,coeff; if varList=[] then RETURN(qv);fi; pol:=qv[2]; if pol=0 then rt:=[subasc,pol]; else flag:=0; lenasc:=nops(qv[1]); for i from 1 to lenasc do if notzerolist[i]!=1 then flag:=1; break;fi; od; coeffsList:=[coeffs(expand(pol),varList)]; if nops(coeffsList)>1 then rt:=["UN"]; else rt:=[]; fi; for coeff in coeffsList do if Class(coeff,ord)=0 and flag=0 then RETURN([subasc,1]); else rt:=[op(rt),[qv[1],coeff]]; fi; od; fi; if nops(rt)=1 then rt:=rt[1];fi; rt; end: #when ASC has no variables in varl . # decompose the pol in [[ASC],pol] to ['UN',[[ASC],pol1],...] # so as to eliminate variables in varl DecompList1:=proc(qv,subasc,notzerolist,varList,ord) local i,flag,lenasc,rt,pol,coeffsList,coeff; if varList=[] then RETURN(qv);fi; pol:=qv[2]; if pol=0 then rt:=[subasc,pol]; else flag:=1; lenasc:=nops(qv[1]); for i from 1 to lenasc do flag:=flag*notzerolist[i] ; od; coeffsList:=[coeffs(expand(pol),varList)]; if nops(coeffsList)>1 then rt:=["UN"]; else rt:=[]; fi; for coeff in coeffsList do if Class(coeff,ord)=0 and flag=1 then RETURN([subasc,1]); else rt:=[op(rt),[qv[1],coeff*flag]]; fi; od; fi; if nops(rt)=1 then rt:=rt[1];fi; rt; end: # eliminate the highest polynomial in ASC, within [[ASC],pol] ElimPoly:=proc(qv,notzerolist,mvl,subasc,ord,pord) local rt,newasc,asc,pol,hPol,hVar,hDeg,rem,newPol,tempList,varList,len; asc:=qv[1]; len:=nops(asc); newasc:=subsop(len=NULL,asc); pol:=qv[2]; hPol:=asc[len]; hVar:=Mainvar(hPol,ord); hDeg:=degree(hPol,hVar); if degree(pol,hVar)=0 then rt:=[newasc,pol*notzerolist[len]]; RETURN(rt); else rem:=sprem(pol^hDeg,hPol,hVar); if rem=0 then rt:=[subasc,0]; RETURN(rt); fi; newPol:=rem*notzerolist[len]; tempList:=[newasc,newPol]; varList:=HigherOrdVars(newPol,mvl,len,ord,pord); rt:=DecompList(tempList,subasc,notzerolist,varList,ord); RETURN(rt); fi; end: # project wth one QV formed by one ASC(prepair share done by ProjASC) ProjectASC:=proc(qv,notzerolist,mvl,subasc,lensub,ord,pord) local pol,asc,nproj,tempList,sign,rt,nozero,i; pol:=qv[2]; asc:=qv[1]; # get the nonzero polynomial to prject with here. nozero:=pol; for i from 1 to nops(asc) do nozero:=nozero*notzerolist[i]; od; # recursion ending conditions if nops(asc)=0 or nops(asc)=lensub then if Class(nozero,pord)>0 then rt:=DecompList1(qv,subasc,notzerolist,pord,ord); elif Class(nozero,ord)>0 then rt:=[asc,nozero]; else rt:=[asc,Get1or0(nozero)]; fi; RETURN(rt); elif Class(nozero,pord)=0 then if Class(nozero,ord)>0 then rt:=[subasc,nozero]; else rt:=[subasc,Get1or0(nozero)]; fi; RETURN(rt); fi; # eliminate the highest polynomial in asc of QV. tempList:=ElimPoly(qv,notzerolist,mvl,subasc,ord,pord); # whether have many branchs in the result of ElimPoly. if not type(tempList[1],string) then rt:=ProjectASC(tempList,notzerolist,mvl,subasc,lensub,ord,pord); else rt:=[tempList[1]]; for i from 2 to nops(tempList) do nproj:=ProjectASC(tempList[i],notzerolist,mvl,subasc,lensub,ord,pord); # deal with trival cases. sign:=IsTrival(nproj,ord); if sign=0 then next; elif sign=1 then rt:= [subasc,1];break; else rt:=[op(rt),nproj]; fi; od: # rt:=["UN"] if nops(rt)=1 then rt:=[subasc,0]; fi; # rt:=["UN",[...]] if nops(rt)=2 and type(rt[2],list) then rt:=rt[2];fi; fi; rt; end: # project with one QV formed by one ASC ProjASC:=proc(cs,ds,ord,pord) local mvl,notzerolist,p,qv,subasc,lensub,rt; # mainvars order list mvl:=[]; for p in cs do mvl:=[op(mvl),Class(p,ord)]; od; # notzerolist notzerolist:=CreatNotZeroList(cs,ds,mvl,ord); qv:=[cs,notzerolist[-1]]; subasc:=SubASC(cs,pord); lensub:=nops(subasc); rt:=ProjectASC(qv,notzerolist,mvl,subasc,lensub,ord,pord); rt:=Format1(rt); end: #whether input QuasiVariety is [[[],[1]]] QVIsTruth:=proc(qv) if qv=[[[],[1]]] then RETURN(true); else RETURN(false); fi; end: #----main func.------- # project with the QV [ps,ds], eliminate variables in pord # return [] if zero(ps) is empty # return [[[],[0]]] if zero(ps/ds) is empty # else return [ [[ASC],[p1,p2,...]] , ...] Project:=proc(ps,ds,ord,pord) local jds,cslist,cs,p,ini,qvs,newds,subasc,rt; jds:=GetProduct(ds); cslist:=wsolve(ps,ord); #printf("The characteristic sets are:"); ##lprint(cslist); rt:=[]; if nops(cslist)<>0 then cslist:=Newcslist(cslist,jds,ord); if nops(cslist)=0 then RETURN([]); fi; cslist:=InverseAll(cslist); for cs in cslist do #add initials to ds newds:={op(ds)}; for p in cs do ini:=Initial(p,ord); if Class(ini,ord)>0 then newds:={op(newds),ini}; fi; od; newds:=[op(newds)]; qvs:=ProjASC(cs,newds,ord,pord); subasc:=qvs[1][1]; qvs:=Simplify1(qvs,subasc,ord); if QVIsTruth(qvs) then rt:=qvs; RETURN(rt); else rt:=ListUnion(qvs,rt); fi; od; fi; if nops(rt)=0 then RETURN([[[],[0]]]); fi; rt; end: ## the subasc in qvs is the same one AddQVS:=proc(rt,qvs) local newrt,i,j,subasc; newrt:=rt; subasc:=qvs[1]; j:=0; for i from 1 to nops(newrt) do if subasc=newrt[i][1] then newrt[i][2]:=ListUnion(qvs[2],newrt[i][2]); j:=1; break;fi; od; if j=0 then newrt:=[op(newrt),qvs];fi; newrt; end: SqfreeList:=proc(plist) local j,p,q,rt,sq; rt:=[]; for p in plist do j:=1; sq:=sqrfree(p); sq:=sq[2]; for q in sq do j:=j*q[1]; od; rt:=[op(rt),j]; od; rt; end: SqfreeGB:=proc(plist,ord) local rt,gb1,gb2; gb1:=plist; gb2:=Groebner[gbasis](gb1,plex(op(ord))); gb2:=SqfreeList(gb2); while(gb1<>gb2) do gb1:=gb2; gb2:=Groebner[gbasis](gb1,plex(op(ord))); gb2:=SqfreeList(gb2); od; gb2; end: GBsimplify:=proc(qvs,ord) local qv,rt; rt:=[]; for qv in qvs do rt:=[op(rt),[qv[1],SqfreeGB(qv[2],ord) ] ]; od; rt; end: Congre:=proc(qvs) local rt,qv,notzero; notzero:=[]; for qv in qvs do notzero:=[op(notzero),qv[2]]; od; notzero:={op(notzero)}; notzero:=[op(notzero)]; rt:=[qvs[1][1],notzero]; end: #new project Proj:=proc(ps,ds,ord,pord) local jds,cslist,cs,p,ini,qvs,newds,subasc,rt; jds:=GetProduct(ds); cslist:=wsolve(ps,ord); #printf("The characteristic sets are:"); ##lprint(cslist); rt:=[]; if nops(cslist)<>0 then cslist:=Newcslist(cslist,jds,ord); if nops(cslist)=0 then RETURN("Characteristic Set is empty set"); fi; cslist:=InverseAll(cslist); for cs in cslist do #add initials to ds newds:={op(ds)}; for p in cs do ini:=Initial(p,ord); if Class(ini,ord)>0 then newds:={op(newds),ini}; fi; od; newds:=[op(newds)]; qvs:=ProjASC(cs,newds,ord,pord); subasc:=qvs[1][1]; qvs:=Simplify2(qvs,subasc,ord); if qvs=[[[],1]] then RETURN([[[],[1]]]); else qvs:=Congre(qvs); rt:=AddQVS(rt,qvs); fi; od; fi; if nops(rt)=0 then RETURN([[[],[0]]]); fi; rt:=GBsimplify(rt,ord); end: # return 1 if zero(ps,ds)=empty # else return 0 IsEmpty:=proc(ps,ds,ord) local jds,cslist,cs,p,ini,qvs,newds,subasc; if nops(ps)=0 then RETURN(false);fi; jds:=GetProduct(ds); cslist:=wsolve(ps,ord); #printf("The characteristic sets are:"); ##lprint(cslist); if nops(cslist)<>0 then cslist:=Newcslist(cslist,jds,ord); if nops(cslist)=0 then RETURN(true); fi; cslist:=InverseAll(cslist); for cs in cslist do #add initials to ds newds:=ds; for p in cs do ini:=Initial(p,ord); if Class(ini,ord)>0 then newds:=[op(ds),ini]; fi; od; qvs:=ProjASC(cs,newds,ord,ord); subasc:=qvs[1][1]; qvs:=Simplify1(qvs,subasc,ord); if QVIsTruth(qvs) then RETURN(false); fi; od; fi; RETURN(true) end: #return -1 if zero([ ps, [op(ds),p] ])=empty #return 1 if zero([ [op(ps),p],ds ])=empty #else return 0 whichcase:=proc(ps0,ds0,p,ord) local ps,ds; ps:=[op(ps0)]; ds:=[op(ds0)]; if IsEmpty(ps,[op(ds),p],ord,ord) then RETURN(-1) fi; if IsEmpty([op(ps),p],ds,ord,ord) then RETURN(1) fi; RETURN(0); end: #---------------- Format1(qvs)----------------- #when the input is as:["UN",...] #step1: formated all the branchs of "UN". #step2: Union all the branchs. FormatUN:=proc(qvs) local i,temp,rt; rt:=[]; for i from 2 to nops(qvs) do temp:=Format1(qvs[i]); rt:=ListUnion(rt,temp); od; rt; end: # when the input is as:[[ASC],pol] # output [[[ASC],pol]] FormatList:=proc(qv) RETURN([qv]); end: # format the result of ProjectASC() # to the form: [[[ASC],pol1],[[ASC],pol2],...]; Format1:=proc(qvs) local rt; if type(qvs[1],string) then rt:=FormatUN(qvs); else rt:=FormatList(qvs); fi; rt; end: #-----------------Simplify1(qvs)--------------- #for every qausi variety in the result of Project() call doRem1 #for empty set , return []; the result form: [[[ASC],[p1,p2,...]],...] #p1<>0 and p2<>0 and ... Simplify1:=proc(qvs,subasc,ord) local qv,rt,newqv; rt:=[]; for qv in qvs do newqv:=doRem1(qv,subasc,ord); if newqv<>[] then if member(1,newqv[2]) then RETURN([[subasc,[1]]]);fi; fi; rt:=[op(rt),newqv]; od; rt; end: # a qausi variety is denoted as: [[asc],pol] # rem=premas(pol,asc,ord) # notZero:= all factors of rem of dClass w.r.t ord zero. # return [[asc], [notZero]] doRem1:=proc(qv,subasc,ord) local pol,rem,notZero,rt; pol:=qv[2]; # modified 2003.3.21 # if nops(subasc)=0 or Class(pol,ord)=0 then # if pol=0 then rt:=[]; # else rt:=[subasc,[1]]; # fi; # RETURN(rt); # fi; rem:=Premas(pol,Inverse(subasc),ord); if rem=0 then rt:=[]; else notZero:=Factorlist_chen(rem,ord); rt:=[subasc,notZero]; fi; rt; end: #-----------------Simplify2(qvs)--------------- #for every qausi variety in the result of Project() call doRem2 #for empty set , return []; the result form: [[[ASC],[p1,p2,...]],...] #p1<>0 or p2<>0 or ... #for every qausi variety in the result of Project() call doRem #for empty set , return []; the result form: [[[ASC],[p1,p2,...]],...] Simplify2:=proc(qvs,subasc,ord) local qv,rt,newqv; rt:=[]; for qv in qvs do newqv:=doRem2(qv,subasc,ord); if newqv<>[] then if newqv[2]=1 then RETURN([[subasc,1]]);fi; fi; rt:=[op(rt),newqv]; od; rt; end: # a qausi variety is denoted as: [[asc],pol] # rem=premas(pol,asc,ord) # return [[asc], rem] doRem2:=proc(qv,subasc,ord) local pol,rem,notZero,rt; pol:=qv[2]; rem:=Premas(pol,Inverse(subasc),ord); if rem=0 then rt:=[]; else notZero:=Factorlist_chen(rem,ord); rt:=[subasc,GetProduct(notZero)]; fi; rt; end: # if 0 return 0 else return 1 Get1or0:=proc(p) local rt; if p=0 then rt:=0; else rt:=1; fi; rt; end: # p=3*(x+y)^2*(x-y)*u; ord=[x,y]; result=[x+y,x-y]; # p=2; result=[1]; p=0; result=[0] Factorlist_chen:=proc(p,ord) local i,j,fl,pair,fact,rt; if Class(p,ord)=0 then rt:=[Get1or0(p)]; else rt:=[]; fl:=factors(p); fl:=fl[2]; for pair in fl do fact:=pair[1]; if Class(fact,ord)<>0 then rt:=[op(rt),fact]; fi; od; fi; rt; end: #########----------Simplify----------########### ###----- computation of QV---------- ############ # judge whether or not Zero(ps/ds) is empty # judge whether or not Zero(ps1/ds1) is included in Zero(ps2/ds2) # QVInclude:=proc(ps1,ds1,ps2,ds2) #------Simplify the output of Project--------# # whether or not QV is included in the union of QVS # output: 1(yes), 0(not included) QVSInclude:=proc(QV,QVS,ord) local D,newQVS,rt,temp,i,ass,proj,ps,ds,newucs; #if QVS=[] then return 0;fi; D:=GetProduct(QV[2]); newQVS:=QVS; for i from 1 to nops(QVS) do newQVS[i]:=[op(newQVS[i][1]),GetProduct(newQVS[i][2])]; od; ass:=AllSorts(newQVS,ord); for i from 1 to nops(ass) do temp:=ass[i]; ds:=[D,op(temp[2])]; if temp[1]<>[] then ps:=[op(QV[1]),op(temp[1])]; proj:=Project(ps,ds,ord,ord); # case :not empty set if proj<>[] and proj[1][2][1]<>0 then RETURN(0);fi; else proj:=ProjASC(QV[1],ds,ord,ord); # case: not empty set if proj[1][2]<>0 then RETURN(0);fi; fi; od; RETURN(1); end: # if every QV in QVS is included in the union of the others # then expunge it. Sproject:=proc(QVS,ord) local i,rt,UQV,len; rt:=[]; len:=nops(QVS); for i from 1 to len do if i=len then UQV:=[]; fi; UQV:=QVS[i+1..len]; UQV:=[op(rt),op(UQV)]; if UQV=[] then rt:=[QVS[i]];break ;fi; if QVSInclude(QVS[i],UQV,ord)=0 then rt:=[op(rt),QVS[i]]; fi; od; rt; end: Sproj:=proc(qvs,ord) local temprt,rt, tempqvs,qv,nozerop; tempqvs:=[]; #change to old form for qv in qvs do for nozerop in qv[2] do tempqvs:=[op(tempqvs), [ qv[1],[nozerop] ] ]; od; od; temprt:=Sproject(tempqvs,ord); rt:=[]; #return to new form for qv in temprt do rt:=AddQVS(rt,qv); od; rt; end: #------Simplify the output of wsolve--------# #AllSort([[a1,a3],[c1,c2,c3]]); #output:[ [[],[c1,a1]], [[],[c2,a1]], [[c3],[a1]], [[a3],[c1]], # [[a3],[c2]], [[c3,a3],[]] ] AllSorts:=proc(lists,ord) local ls,C,ls_len,p,i,reculist,list,onesort,rt; rt:=[]; ls:=lists[1]; ls_len:=nops(lists[1]); C:=Class(ls[ls_len],ord); if nops(lists)=1 then for i from 1 to ls_len-1 do p:=[[],[ls[i]]]; rt:=[op(rt),p ]; od; if C<>0 then rt:=[op(rt),[[ls[ls_len]],[]]]; fi; RETURN(rt); fi; reculist:=AllSorts(subsop(1=NULL,lists),ord); for i from 1 to ls_len-1 do for list in reculist do onesort:=list; onesort[2]:=[op(onesort[2]),ls[i]]; rt:=[op(rt),onesort]; od; od; if C<>0 then for list in reculist do onesort:=list; onesort[1]:=[op(onesort[1]),ls[ls_len]]; rt:=[op(rt),onesort]; od; fi; rt; end: # whether or not cs is included in the union of ucs # output: 1(yes), 0(not included) CSSInclude:=proc(cs,ucs,ord) local proj,IP,ass,rt,temp,i,ps,ds,newucs; if ucs=[] then return 0;fi; IP:=GetIP(cs,ord); newucs:=ucs; for i from 1 to nops(ucs) do newucs[i]:=[op(newucs[i]),GetIP(newucs[i],ord)]; od; ass:=AllSorts(newucs,ord); for i from 1 to nops(ass) do temp:=ass[i]; ds:=[IP,op(temp[2])]; if temp[1]<>[] then ps:=[op(cs),op(temp[1])]; proj:=Project(ps,ds,ord,ord); # case :not empty set if proj<>[] and proj[1][2][1]<>0 then RETURN(0);fi; else proj:=ProjASC(cs,ds,ord,ord); # case: not empty set if proj[1][2]<>0 then RETURN(0);fi; fi; od; RETURN(1); end: # if every cs in css is included in the union of the others # then expunge it. Swsolve:=proc(css,ord) local i,rt,newcss,UCS,len; rt:=[]; newcss:=InverseAll(css); len:=nops(newcss); for i from 1 to len do UCS:=newcss[i+1..len]; UCS:=[op(rt),op(UCS)]; if CSSInclude(newcss[i],UCS,ord)=0 then rt:=[op(rt),newcss[i]]; fi; od; InverseAll(rt); end: