source: git/Singular/LIB/primitiv.lib @ d2b2a7

spielwiese
Last change on this file since d2b2a7 was d2b2a7, checked in by Kai Krüger <krueger@…>, 26 years ago
Modified Files: libparse.l utils.cc LIB/classify.lib LIB/deform.lib LIB/elim.lib LIB/factor.lib LIB/fastsolv.lib LIB/finvar.lib LIB/general.lib LIB/hnoether.lib LIB/homolog.lib LIB/inout.lib LIB/invar.lib LIB/makedbm.lib LIB/matrix.lib LIB/normal.lib LIB/poly.lib LIB/presolve.lib LIB/primdec.lib LIB/primitiv.lib LIB/random.lib LIB/ring.lib LIB/sing.lib LIB/standard.lib LIB/tex.lib LIB/tst.lib Changed help section o procedures to have an quoted help-string between proc-definition and proc-body. git-svn-id: file:///usr/local/Singular/svn/trunk@1601 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 10.1 KB
Line 
1// $Id: primitiv.lib,v 1.5 1998-05-05 11:55:35 krueger Exp $
2// author:  Martin Lamm,  email: lamm@mathematik.uni-kl.de
3// last change:           11.3.98
4///////////////////////////////////////////////////////////////////////////////
5version="$Id: primitiv.lib,v 1.5 1998-05-05 11:55:35 krueger Exp $";
6info="
7LIBRARY:    primitiv.lib    PROCEDURES FOR FINDING A PRIMITIVE ELEMENT
8
9 primitive(ideal i);   finds minimal polynomial for a primitive element
10 splitring(f,R[,L]);   define ring extension with name R and switch to it
11 randomLast(b);        random transformation of the last variable
12";
13
14///////////////////////////////////////////////////////////////////////////////
15LIB "random.lib";
16///////////////////////////////////////////////////////////////////////////////
17
18proc randomLast(int b)
19"USAGE:   randomLast
20RETURN:  ideal = maxideal(1) but the last variable exchanged by
21         a sum of it with a linear random combination of the other
22         variables
23EXAMPLE: example randomLast; shows an example
24"
25{
26  ideal i=maxideal(1);
27  int k=size(i);
28  i[k]=0;
29  i=randomid(i,size(i),b);
30  ideal ires=maxideal(1);
31  ires[k]=i[1]+var(k);
32  return(ires);
33}
34example
35{ "EXAMPLE:"; echo = 2;
36   ring  r = 0,(x,y,z),lp;
37   ideal i = randomLast(10);
38   i;
39}
40///////////////////////////////////////////////////////////////////////////////
41
42proc primitive(ideal i)
43"USAGE:  primitive(i); i ideal of the following form:
44 Let k be the ground field of your basering, a_1,...,a_n algebraic over k,
45 m_1(x1), m_2(x_1,x_2),...,m_n(x_1,...,x_n) polynomials in k such that
46 m_j(a_1,...,a_(j-1),x_j) is minimal polynomial for a_j over k(a_1,...,a_(j-1))
47                                                        for all j=1,...,n.
48 Then i has to be generated by m_1,...,m_n.
49
50RETURN:  ideal j in k[x_n] such that
51 j[1] is minimal polynomial for a primitive element b of k(a_1,...,a_n)=k(b)
52         over k
53 j[2],...,j[n+1] polynomials in k[x_n] : j[i+1](b)=a_i for i=1,...,n
54NOTE:    the number of variables in the basering has to be exactly the number n
55         of given algebraic elements (and minimal polynomials)
56EXAMPLE: example primitive;  shows an example
57"
58{
59 def altring=basering;
60 execute("ring deglexring=("+charstr(altring)+"),("+varstr(altring)+"),dp;");
61 ideal j;
62 execute("ring lexring=("+charstr(altring)+"),("+varstr(altring)+"),lp;");
63 ideal i=fetch(altring,i);
64
65 int k,schlecht;
66 int nva = nvars(basering);
67 ideal jmap,j;
68 map phi;
69 option(redSB);
70 int Fehlversuche;
71 //-------- Mache so lange Random-Koord.wechsel, bis letztes Poly -------------
72 //--------------- das Minpoly eines primitiven Elements ist : ----------------
73 for (Fehlversuche=0; 1; Fehlversuche++) {
74   schlecht=0;
75   if (Fehlversuche==0) { jmap=maxideal(1);}
76   else {
77     if (Fehlversuche<3) { jmap=randomLast(10);}
78     else                { jmap=randomLast(100);}
79   }
80   phi=lexring,jmap;
81   j=phi(i);
82   setring deglexring;
83 //--------------- Berechne reduzierte Standardbasis mit fglm: ----------------
84   j=std(fetch(lexring,j));
85   setring lexring;
86   j=fglm(deglexring,j);
87 //-- teste, ob SB n Elemente enthaelt (falls ja, ob lead(Fi)=xi i=1... n-1): -
88   if (size(j)==nva) {
89     for (k=1; k<nva; k++) {
90       j[k+1]=j[k+1]/leadcoef(j[k+1]);        // normiere die Erzeuger
91       if (lead(j[k+1]) != var(nva-k)) { schlecht=1;}
92     }
93     if (schlecht==0) {
94 //--- Random-Koord.wechsel war gut: Berechne das zurueckzugebende Ideal: -----
95       ideal erg;
96       for (k=1; k<nva; k++) { erg[k]=var(k)-j[nva-k+1]; }
97                               // =g_k(x_n) mit a_k=g_k(a_n)
98       erg[nva]=var(nva);
99       map chi=lexring,erg;
100       ideal extra=maxideal(1);extra=phi(extra);
101                               // sonst: "argument of a map must have a name"
102       erg=j[1]+chi(extra);    // j[1] = Minimalpolynom
103       setring altring;
104       return(fetch(lexring,erg));
105     }
106   }
107   "The random coordinate change was bad!";
108 }
109}
110example
111{ "EXAMPLE:"; echo = 2;
112 ring exring=0,(x,y),dp;
113 ideal i=x2+1,y2-x;                  // compute Q(i,i^(1/2))=:L
114 ideal j=primitive(i);               // -> we have L=Q(a):
115 "minimal polynomial of a:",j[1];    // => a=(-1)^(1/4)
116 "polynomial for i:       ",j[2];    // => i=a^2
117 "polynomial for i^(1/2): ",j[3];    // => i^(1/2)=a
118 // ==> the 2nd element was already primitive!
119 j=primitive(ideal(x2-2,y2-3));      // compute Q(sqrt(2),sqrt(3))
120 "minimal polynomial:",j[1];
121 "polynomial p s.t. p(a)=sqrt(2):",j[2];
122 "polynomial r s.t. r(a)=sqrt(3):",j[3];
123 // ==> no element was primitive -- the calculation of a is based on a random
124 //     choice.
125}
126///////////////////////////////////////////////////////////////////////////////
127
128proc splitring
129"USAGE:  splitring(f,R[,L]);  f poly, univariate, irreducible(!), R string,
130                     L list of polys and/or ideals (optional)
131ACTION: defines a ring with name R, in which f is reducible, and changes to it
132        If the old ring has no parameter, the name 'a' is chosen for the
133        parameter of R (if a is no variable; if it is, the proc takes 'b',
134        etc.; if a,b,c,o are variables of the ring, produce an error message),
135        otherwise the name of the parameter is kept and only the
136        minimal polynomial is changed.
137        The names of variables and orderings are not affected.
138
139        It is also allowed to call splitring with R==\"\". Then the old basering
140        will be REPLACED by the new ring (with the same name as the old ring).
141
142RETURN: list L mapped into the new ring R, if L is given; else nothing
143ASSUME: the active ring must allow an algebraic extension
144         (e.g. it cannot be a transcendent ring extension of Q or Z/p)
145EXAMPLE: example splitring;  shows an example
146"
147{
148 //----------------- split ist bereits eine proc in 'inout.lib' ! -------------
149 poly f=#[1]; string @R=#[2];
150 if (size(#)>2) {
151    list L=#[3];
152    int L_groesse=size(L);
153 }
154 else { int L_groesse=-1; }
155 //-------------- ermittle das Minimalpolynom des aktuellen Rings: ------------
156 string minp=string(minpoly);
157
158 if (@R=="") {
159  string altrname=nameof(basering);
160  @R="splt_temp";
161 }
162
163 def altring=basering;
164 string charakt=string(char(altring));
165 string varnames=varstr(altring);
166 string algname;
167 int i;
168 int anzvar=size(maxideal(1));
169 //--------------- Fall 1: Bisheriger Ring hatte kein Minimalpolynom ----------
170 if (minp=="0") {
171  if (find(varnames,"a")==0)        { algname="a";}
172  else { if (find(varnames,"b")==0) { algname="b";}
173         else { if (find(varnames,"c")==0)
174                                    { algname="c";}
175         else { if (find(varnames,"o")==0)
176                                    { algname="o";}
177         else {
178           "** Sorry -- could not find a free name for the primitive element.";
179           "** Try e.g. a ring without 'a' or 'b' as variable.";
180           return();
181         }}
182       }
183  }
184 //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: --
185  execute("ring splt1="+charakt+","+algname+",dp;");
186  ideal abbnach=var(1);
187  for (i=1; i<anzvar; i++) { abbnach=abbnach,var(1); }
188  map nach_splt1=altring,abbnach;
189  execute("poly mipol="+string(nach_splt1(f))+";");
190  string Rminp=string(mipol);
191 //--------------------- definiere den neuen Ring: ----------------------------
192  execute("ring "+@R+" = ("+charakt+","+algname+"),("+varnames+"),("
193           +ordstr(altring)+");");
194  execute("minpoly="+Rminp+";");
195  execute("export "+@R+";");
196  def neuring=basering;
197 //---------------------- Berechne die zurueckzugebende Liste: ----------------
198  list erg;
199  if (L_groesse>0) {
200 // L ist ja nicht in 'neuring' def., daher merke man sich die Groesse als int
201   map take=altring,maxideal(1);
202   erg=take(L);
203  }            // take(empty list) gibt nicht empty list, sondern Fehlermeldung
204 }
205 else {
206 //------------- Fall 2: Bisheriger Ring hatte ein Minimalpolynom: ------------
207  algname=parstr(altring);           // Name des algebraischen Elements
208  if (size(algname)>1) {"only one Parameter is allowed!!"; return();}
209 //---------------- Minimalpolynom in ein Polynom umwandeln: ------------------
210  execute("ring splt2="+charakt+","+algname+",dp;");
211  execute("poly mipol="+minp+";");
212 // f ist Polynom in algname und einer weiteren Variablen --> mache f bivariat:
213  execute("ring splt3="+charakt+",("+algname+","+varnames+"),dp;");
214  poly f=imap(altring,f);
215 //-------------- Vorbereitung des Aufrufes von primitive: --------------------
216  execute("ring splt1="+charakt+",(x,y),dp;");
217  ideal abbnach=x;
218  for (i=1; i<=anzvar; i++) { abbnach=abbnach,y; }
219  map nach_splt1_3=splt3,abbnach;
220  map nach_splt1_2=splt2,x;
221  ideal maxid=nach_splt1_2(mipol),nach_splt1_3(f);
222  ideal primit=primitive(maxid);
223  "new minimal polynomial:",primit[1];
224 //-- erzeuge einen String, der das Minimalpolynom des neuen Rings enthaelt: --
225  setring splt2;
226  map nach_splt2=splt1,0,var(1);     // x->0, y->a
227  minp=string(nach_splt2(primit)[1]);
228 //--------------------- definiere den neuen Ring: ----------------------------
229  execute("ring "+@R+" = ("+charakt+","+algname+"),("+varnames+"),("
230          +ordstr(altring)+");");
231  execute("minpoly="+minp+";");
232  execute("export "+@R+";");
233  def neuring=basering;
234
235 //--------------- Uebersicht: wenn altring=(p,a),(x,y),dp; dann: -------------
236 //------------ splt1=p,(x,y),dp;  splt2=p,a,dp;  splt3=p,(a,x,y),dp; ---------
237
238  list erg;
239  if (L_groesse>0) {
240 //---------------------- Berechne die zurueckzugebende Liste: ----------------
241    setring splt3;
242    list zwi=imap(altring,L);
243    map nach_splt3_1=splt1,0,var(1);  // x->0, y->a
244 //----- rechne das primitive Element von altring in das von neuring um: ------
245    ideal convid=maxideal(1);
246    convid[1]=nach_splt3_1(primit)[2];
247    map convert=splt3,convid;
248    zwi=convert(zwi);
249    setring neuring;
250    erg=imap(splt3,zwi);
251  }
252 }
253 if (defined(altrname)) {
254   execute("kill "+altrname+";");
255   execute("def "+altrname+" = splt_temp;");
256   @R=altrname;
257   execute("export "+altrname+";");
258   kill splt_temp;
259 }
260
261 execute("keepring "+@R+";");
262 if (L_groesse >= 0) {return(erg);}
263}
264example
265{ "EXAMPLE:"; echo = 2;
266 ring r=0,(x,y),dp;
267 splitring(x2-2,"r1");   // change to Q(sqrt(2))
268 splitring(x2-a,"r2",a); // change to Q(sqrt(2),sqrt(sqrt(2)))=Q(a)
269                         // and return the transformed old parameter
270 // the result is (a2) == (sqrt(sqrt(2)))^2
271 nameof(basering);
272 r2;
273 kill r1; kill r2;
274}
Note: See TracBrowser for help on using the repository browser.