123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- module hille; % Hillebrand decomposition of a zero - dimensional polynomial
- % ideal following
- % D. Hillebrand: Triangulierung nulldimensionaler Ideale - Implementierung und
- % Vergleich zweier Algorithmen. Diplomarbeit im Studiengang Mathematik
- % der Universit"at Dortmund. Betreuer: Prof. Dr. H. M. M"oller, 1999
- % Dasi: hille.sav7
- % triang4: groeposthillebrand: interface for the solver (for zero -
- % dimensional polynomial ideals).
- symbolic procedure groeposthillebrand(u,v);
- % Solve - interface for the module 'hille' (for:Hillebrand);
- % ' u ' is the (partial) basis in external form (the first word is 'list);
- % ' v ' is the total list of variables (the first word is 'list);
- % the routine returns a list of solutions, if 'u' is zero-dimensional;
- % else it returns 'nil'.
- begin scalar a,d,e;u:=cdr u;
- vdpinit groebnervars(u,nil);groedomainmode();
- a:=for each uu in u collect numr simp uu;
- vars!*:=dipvars!*:=vdpvars!*:=cdr v;
- if null hillebrandtriangular(cdr v,a,nil)then return nil;
- % From now on, the zero-dimensionality has been assured.
- !*groebopt:=nil;
- a:=hillebrand(a,nil);
- for each b in a do
- <<d:='list.for each c in b collect prepf c;
- e:=append(e,groepostfastsolve(d,v))>>;
- return groesolvearb(e,v) end; %%%AENDERUNG 18.9.00
- % triang3: saturation of a basis and a polynomial.
- symbolic procedure hillebrandstdsat(g,p);
- % Compute the basis of the saturation ideal ' g ' and polynomial ' p ' .
- begin scalar a,b,c,e;
- if cdr g then go to a ;
- % ' g ' is a one - polynomial list .
- p:=p./ 1;g:=car g ./ 1;a:=t;
- while a do<<a:=hillebrandquot(g,p);if a then g:=a>>;
- e:=if not domainp numr g then{numr g}else nil;return e;
- a: % The list 'g' has more than one polynomial.
- p:=prepf p;a:='list.for each gg in g collect prepf gg;
- b:=saturationeval{a,p};
- if b='(list 1)then return'(1);
- c:=for each bb in cdr b collect numr simp bb;
- return sort(c,function hillebrandcompare)end;
- symbolic procedure hillebrandquot(g,p);
- % Compute the quotient of 'g' and 'p', if 'p' divides 'g' as a
- % polynomial (if 'p' is a polynomial divisor of 'g', ignoring the
- % quotients of coefficients).
- (if hillebrandvar(denr a , vars!*)then numr a ./ 1 else nil)
- where a=quotsq(g,p);
- symbolic procedure hillebrandvar(p,m);
- % Tests, if the variables of 'p' are contained in 'm' ; 'nil'
- % if a variable of 'p' is part of 'm' ; else return 't'.
- if domainp p then t else if mvar p member m then nil else
- hillebrandvar(lc p,m)and hillebrandvar(red p,m);
-
- % triang2: the main routine 'hillebrand1'.
- symbolic procedure hillebrand(g,fact);
- % 'g' ist an untagged list of standard polynomials, a Groebner basis,
- % 'fact' is a swich which involves faczorization (if set).
- begin scalar a ; vars!*:=dipvars!*;!*trgroesolv and hillebrandmsg1 g;
- a:=hillebrand1(sort(g,function hillebrandcompare),fact);
- !*trgroesolv and hillebrandmsg2 a;return a end;
- % The sorting is inverse to the normal sorting (polynomial with the
- % highest leading term (normally) is the last one).
- symbolic procedure hillebrandcompare(a,b);
- % Comparison of 'a' and 'b' (standard polynomials) after inverse 'lex' principle.
- hillebrandcompare1(a,b,vars!*);
- symbolic procedure hillebrandcompare1(a,b,v);
- % If the result is 't', 'a' and 'b' are sorted 'a'<'b'; if the result
- % is 'nil', they are ordered 'b'<'a'.
- begin scalar aa,bb,c;
- aa:=a;bb:=b;
- if domainp aa or not(mvar aa member v) then return t else
- if domainp bb or not(mvar bb member v) then
- (if mvar aa member v then return nil else return t);
- aa: if domainp bb or not(mvar bb member v)then
- (if domainp aa or not(mvar aa member v)then
- return hillebrandcompare1(red a,red b,v)else return t) else
- if mvar aa member v and mvar aa=mvar bb then
- (if ldeg aa=ldeg bb then<<aa:=lc aa;bb:=lc bb;go to aa>>else
- if ldeg aa #< ldeg bb then return t else return nil)else
- if(c:=mvar bb member v)then
- (if domainp aa or not(mvar aa member c)or mvar aa member cdr c then return t else
- if mvar aa member v then return nil);
- return hillebrandcompare1(red a,red b,v)end;
-
- % The routine HILLEBRAND1: the main(recursive) routine.
- symbolic procedure hillebrand1(g,fact);
- % Input: 'g' : a (reduced ) lexicographical groebner basis,
- % fact: a switch, which involves factorization (if set);
- % output: a list of bases (a decomposition of 'g' in triangular bases),
- % internal form.
- if hillebrandtriangular(vars!*,g,t)then hillebrandfactorizelast(g,fact)else
- begin scalar a,aa,b,c,r,f,ff,fh,g2,g3,h,l,o;
- % first part of the split.
- g3:=g;while cdr g3 do g3:=cdr g3;
- a:=hillebranddecompose(g,mvar car g3);
- c:=for each aa in cdr a collect lc aa ;
- r:=hillebrandgroebner hillebrandjoin(car a,c);
- f:=hillebrand1(r,fact); % Recursive call with reduced basis.
- aa:=hillebrandlast g;
- for each tt in f do
- <<b:=hillebrandnormalform(aa,tt);
- ff:=hillebrandappend1(ff,tt,b)>> ; % append(tt,{b}).ff
- f:=reversip ff;
- % second part of the split.
- h:=car a; % H := { g_1 1, ... , g_n-1 c_n-1 }
- o:=length c;
- for k := 1:o do
- <<l:=nth(c,k);
- g2:=hillebrandstdsat(h,l);
- if not(car g2=1)then
- <<fh:=hillebrand1(g2,fact);
- fh:=for each tt in fh collect
- hillebrandgroebner hillebrandappend(tt,{car cdr a});
- f:=hillebrandappend(f,fh)>>;
- h:=append(h,{nth(c,o)})>>;
- f:=for each ff in f collect sort(ff,function hillebrandcompare);
- return f end;
- % Append a basis, (if that is not empty).
- symbolic procedure hillebrandappend(a,b);
- if null car b then a else append(a,b);
- symbolic procedure hillebrandappend1(ff,tt,b);
- % append(tt,{b}).ff.
- <<if b then tt:=append(tt,{b});tt.ff>>;
- % Detect, if 'g' is already triangular.
- symbolic procedure hillebrandtriangular(a,g,m);
- % 'a' is the list of variables, 'g' is the Groebner basis. If m='t',
- % a basis with a mixed leading term is rejected. If m='nil', only the
- % zero - dimensionality is tested (that each variable occurs once isolated).
- begin scalar b,c;
- for each gg in g do
- if domainp lc gg or not(mvar lc gg member a)then b:=mvar gg.b else c:=t;
- if m and c then return nil;
- c:=t;for each gg in g do c and(c:=hillebrandtriangular1(a,gg,b));
- return c end;
- symbolic procedure hillebrandtriangular1(a,g,b);
- % Test, if all variables of 'g' occur in 'b'; return
- % 't' then; return 'nil' if that is not the case. 'g'
- % is a standard polynomial ; the 'variables' are the leading ones.
- if domainp g or not(mvar g member a)then t else
- if not(mvar g member b)then nil else
- hillebrandtriangular1(a,lc g,b)and hillebrandtriangular1(a,red g,b);
- symbolic procedure hillebrandfactorizelast(g,f);
- % Factorize the last polynomial of 'g' if 'f' is non-nil.
- if null f then {g} else
- begin scalar a,b,c,d;
- aa: if cdr g then<<a:=car g.a;g:=cdr g>>;if cdr g then go to aa;
- b:=fctrf car g;if domainp car b then b:=cdr b;
- c:=for each bb in b collect
- <<d:={car bb};for each aa in a do d:=aa.d;d>>;
- return if null cdr c then c else
- for each cc in c collect sort(cc,function hillebrandcompare)end ;
- % Decompose 'g' wrt'n'-th variable 'v'.
- symbolic procedure hillebranddecompose(g,v);
- begin scalar a,b,c,d;
- while g do
- <<c:=car g;d:=hillebranddecompose1(c,v,vars!*,0);
- if d=1 then a:=c.a else if d=2 then b:=c.b;g:=cdr g>>;
- return reversip a.reversip cdr b end;
- symbolic procedure hillebranddecompose1(p,v,vv,m);
- % 'p' is a polynomial; look, if it is a product of the
- % variable 'v'; return '1' if the leading factor is not a product of
- % variable 'v', '2' if it is.
- if domainp p or not(mvar p member vv)then m else
- hillebranddecompose1(lc p,v,vv,n)
- where n=if mvar p=v then 2 else if m #< 1 and mvar p member vv then 1 else m;
- % Join 2 lists.
- symbolic procedure hillebrandjoin(a,b);
- % Join 'a' and 'b' if 'b' is not 'nil'.
- if null b then a else append(a,b);
- % Last polynomial of a list.
- symbolic procedure hillebrandlast g;
- <<while cdr g do g:=cdr g; car g>>;
- % Compute a Groebner basis .
- symbolic procedure hillebrandgroebner g;
- % Compute the Groebner basis of 'g'; return the Groebner basis as a sorted
- % list of standard polynomials sorted descending.
- begin scalar a,b,c,d;
- for each gg in g do
- <<d:=prepf gg;if not(d=0)then a:=d.a>>;
- b:=groebnereval{'list.a,'list.vars!*}
- where dipvars!*=dipvars!*,vdpvars!*=vdpvars!*;
- c:=for each x in cdr b collect numr simp x;
- return sort(c,function hillebrandcompare)end;
- % Compute the normal form of a polynomial.
- symbolic procedure hillebrandnormalform(p,g);
- % Compute 'p' modulo Groebner basis 'g'.
- <<p:=hillebrandf2vdp p;
- g:=for each x in g collect hillebrandf2vdp x;
- vdp2f groebnormalform(p,g,'sort)>>;
- symbolic procedure hillebrandf2vdp p;
- gsetsugar(a,nil)where a=f2vdp p;
- % General .
- symbolic procedure hillebrandmsg1 g;
- if !*trgroesolv then
- <<writepri(" ",'only);writepri(" Hillebrand routine;solve{",'only);
- while g do<<writepri(mkquote prepf car g,'first);g:=cdr g;
- if g then writepri(" , ",'last)>>;
- writepri(" } with respect to ",nil);
- writepri(mkquote('list.vars!*),'last);
- writepri(" ",'only);>>;
- symbolic procedure hillebrandmsg2 a;
- if !*trgroesolv then
- <<writepri(" Decomposition by Hillebrand : ",'only);
- for each aa in a do
- <<writepri(" { ",'only);
- while aa do<<writepri(mkquote prepf car aa,'first);
- aa:=cdr aa;
- if aa then writepri(" , ",'last)>>;
- writepri(" } ",'last)>>;
- writepri(" ",'only);>>;
- endmodule;;end;
|