1 | /////////////////////////////////////////////////////////////////////////////// |
---|
2 | version="$Id: center.lib,v 1.14 2005-05-06 14:38:08 hannes Exp $"; |
---|
3 | category="Noncommutative"; |
---|
4 | info=" |
---|
5 | LIBRARY: center.lib computation of central elements of G-algebras and Q-algebras. |
---|
6 | AUTHOR: Oleksandr Motsak, motsak@mathematik.uni-kl.de. |
---|
7 | OVERVIEW: |
---|
8 | This is a library for computing the central elements and centralizers of elements in various noncommutative algebras. |
---|
9 | Implementation is based on algorithms, written in the frame of the diploma thesis by O. Motsak (advisor: Prof. S.A. Ovsienko, support: V. Levandovskyy), at Kyiv Taras Shevchenko University (Ukraine) with the title 'An algorithm for the computation of the center of noncommutative polynomial algebra'. |
---|
10 | |
---|
11 | SUPPORT: Forschungsschwerpunkt 'Mathematik und Praxis' |
---|
12 | |
---|
13 | PROCEDURES: |
---|
14 | center(MaxDeg[,N]); computes the generators of the center of a basering, |
---|
15 | centralizer(f, MaxDeg[,N]); computes the generators of the centralizer of f in a basering, |
---|
16 | inCenter(l); checks the centrality of elements of list/ideal/poly l |
---|
17 | inCentralizer(l, f); checks the commutativity wrt polynomial f of polynomials of list/ideal/poly l |
---|
18 | |
---|
19 | KEYWORDS: inCenter; inCentralizer; center; centralizer |
---|
20 | "; |
---|
21 | |
---|
22 | /******************************************************/ |
---|
23 | // stuff |
---|
24 | |
---|
25 | /******************************************************/ |
---|
26 | static proc myValue ( def s, list # ) |
---|
27 | " |
---|
28 | return s or (typeof(s))(#) |
---|
29 | " |
---|
30 | { |
---|
31 | def @p = s; |
---|
32 | if ( size(#) > 0 ) |
---|
33 | { |
---|
34 | if ( typeof( #[1] ) == typeof(s) ) |
---|
35 | { |
---|
36 | @p = #[1]; |
---|
37 | }; |
---|
38 | }; |
---|
39 | return (@p); |
---|
40 | }; |
---|
41 | |
---|
42 | /******************************************************/ |
---|
43 | static proc myInt ( list # ) |
---|
44 | " |
---|
45 | return 0 or int(#) |
---|
46 | " |
---|
47 | { |
---|
48 | int @p = 0; |
---|
49 | return (myValue ( @p, # )); |
---|
50 | }; |
---|
51 | |
---|
52 | /******************************************************/ |
---|
53 | static proc myPoly ( list # ) |
---|
54 | " |
---|
55 | return 0 or poly(#) |
---|
56 | " |
---|
57 | { |
---|
58 | poly @p = 0; |
---|
59 | return (myValue( @p, # )); |
---|
60 | }; |
---|
61 | |
---|
62 | /******************************************************/ |
---|
63 | static proc myRing ( list # ) |
---|
64 | " |
---|
65 | return basring or ring(#) |
---|
66 | " |
---|
67 | { |
---|
68 | def @p = basering; |
---|
69 | return (myValue ( @p, # )); |
---|
70 | }; |
---|
71 | |
---|
72 | /******************************************************/ |
---|
73 | static proc myString ( list # ) |
---|
74 | " |
---|
75 | return basring or ring(#) |
---|
76 | " |
---|
77 | { |
---|
78 | string @p = ""; |
---|
79 | return (myValue ( @p, # )); |
---|
80 | }; |
---|
81 | |
---|
82 | /******************************************************/ |
---|
83 | static proc myIdeal ( list # ) |
---|
84 | " |
---|
85 | return 0 or ideal(#) |
---|
86 | " |
---|
87 | { |
---|
88 | ideal @p; |
---|
89 | return (myValue ( @p, # )); |
---|
90 | }; |
---|
91 | |
---|
92 | /******************************************************/ |
---|
93 | // for debug |
---|
94 | |
---|
95 | /******************************************************/ |
---|
96 | static proc toprint() |
---|
97 | { |
---|
98 | return (0); |
---|
99 | }; |
---|
100 | |
---|
101 | /******************************************************/ |
---|
102 | static proc Print( list # ) |
---|
103 | { |
---|
104 | if ( toprint() ) |
---|
105 | { |
---|
106 | print (#); |
---|
107 | }; |
---|
108 | }; |
---|
109 | |
---|
110 | /******************************************************/ |
---|
111 | static proc BCall(string Name, list #) |
---|
112 | { |
---|
113 | if( toprint() ) |
---|
114 | { |
---|
115 | "CALL: ", Name, "( ", string(#), " )"; |
---|
116 | }; |
---|
117 | }; |
---|
118 | |
---|
119 | /******************************************************/ |
---|
120 | static proc ECall(string Name, list #) |
---|
121 | { |
---|
122 | if( toprint() ) |
---|
123 | { |
---|
124 | "RET : ", Name, "(...)={ ", string(#), " }"; |
---|
125 | }; |
---|
126 | }; |
---|
127 | |
---|
128 | |
---|
129 | /******************************************************/ |
---|
130 | // "my" degres functions and lie procedures... |
---|
131 | |
---|
132 | /******************************************************/ |
---|
133 | static proc maxDeg( def z ) |
---|
134 | " |
---|
135 | returns: int : max of givendeg( z_i ), among all z_i \in z |
---|
136 | returns -1 if z is empty or contain only 0 polynomial |
---|
137 | " |
---|
138 | { |
---|
139 | int max = -1; |
---|
140 | int d; |
---|
141 | |
---|
142 | for(int i=size(z); i>0; i-- ) |
---|
143 | { |
---|
144 | d = deg(z[i]); |
---|
145 | if( d > max ) |
---|
146 | { |
---|
147 | max = d; |
---|
148 | }; |
---|
149 | }; |
---|
150 | |
---|
151 | return(max); |
---|
152 | }; |
---|
153 | |
---|
154 | /******************************************************/ |
---|
155 | // some business for my_var |
---|
156 | |
---|
157 | /******************************************************/ |
---|
158 | static proc myCoeff ( poly f, poly m ) |
---|
159 | " |
---|
160 | input: poly f, |
---|
161 | return: coeff at m |
---|
162 | " |
---|
163 | { |
---|
164 | m = leadmonom(m); |
---|
165 | |
---|
166 | int i = size(f); |
---|
167 | |
---|
168 | while ( (i>0) and (leadmonom(f[i])<m) ) |
---|
169 | { |
---|
170 | i--; |
---|
171 | }; |
---|
172 | if( i == 0 ) |
---|
173 | { |
---|
174 | return ( 0 ); |
---|
175 | }; |
---|
176 | |
---|
177 | if(leadmonom(f[i]) == m) |
---|
178 | { |
---|
179 | return ( leadcoef(f[i]) ); |
---|
180 | }; |
---|
181 | |
---|
182 | return ( 0 ); |
---|
183 | }; |
---|
184 | |
---|
185 | /******************************************************/ |
---|
186 | static proc my_vars () |
---|
187 | { |
---|
188 | int N = nvars( basering ); |
---|
189 | list V = list(); |
---|
190 | |
---|
191 | for ( int k = 1; k <= N; k++ ) |
---|
192 | { |
---|
193 | V[k] = var(k); |
---|
194 | }; |
---|
195 | |
---|
196 | return (V); |
---|
197 | }; |
---|
198 | |
---|
199 | /******************************************************/ |
---|
200 | static proc my_commutators () |
---|
201 | { |
---|
202 | list V = my_vars(); |
---|
203 | int N = size( V ); |
---|
204 | |
---|
205 | matrix M[N][N] = 0; |
---|
206 | |
---|
207 | poly v, d; int i; |
---|
208 | |
---|
209 | for ( int k = 2; k <= N; k++ ) |
---|
210 | { |
---|
211 | v = V[k]; |
---|
212 | for ( i = 1; i < k; i++ ) |
---|
213 | { |
---|
214 | d = V[i]; |
---|
215 | M[k,i] = v*d - d*v; // [var(k),var(i)] |
---|
216 | M[i,k] = -M[k,i]; // [var(i),var(k)] == -[var(k),var(i)] |
---|
217 | }; |
---|
218 | }; |
---|
219 | |
---|
220 | return (M); |
---|
221 | }; |
---|
222 | |
---|
223 | /******************************************************/ |
---|
224 | static proc my_associated () |
---|
225 | " |
---|
226 | return list of records: |
---|
227 | [1] - poly: variable, |
---|
228 | [2] - bool: isCartan |
---|
229 | [3] - matrix: associated matrix (basering should be compatible) |
---|
230 | " |
---|
231 | { |
---|
232 | int i, j; poly a; poly d; |
---|
233 | |
---|
234 | int N = nvars( basering ); |
---|
235 | list V = my_vars(); |
---|
236 | matrix M = my_commutators(); |
---|
237 | |
---|
238 | matrix A[N][N]; |
---|
239 | |
---|
240 | int cartan; |
---|
241 | |
---|
242 | list RESULT = list(); |
---|
243 | int r_begin = 1; |
---|
244 | int r_end = N; |
---|
245 | |
---|
246 | |
---|
247 | for ( int k = 1; k <= N; k++ ) |
---|
248 | { |
---|
249 | A = 0; |
---|
250 | cartan = 1; |
---|
251 | for ( i = 1; i <= N; i++ ) |
---|
252 | { |
---|
253 | d = M[k,i]; |
---|
254 | for ( j = 1; j <= N; j++ ) |
---|
255 | { |
---|
256 | a = myCoeff( d, V[j] ); |
---|
257 | A[i,j] = a; |
---|
258 | |
---|
259 | if( (i!=j) and (a!=0) ) |
---|
260 | { |
---|
261 | cartan = 0; |
---|
262 | }; |
---|
263 | }; |
---|
264 | }; |
---|
265 | |
---|
266 | if ( cartan ) |
---|
267 | { |
---|
268 | RESULT[r_begin] = list( V[k], cartan, A ); |
---|
269 | r_begin++; |
---|
270 | } else |
---|
271 | { |
---|
272 | RESULT[r_end] = list( V[k], cartan, A ); |
---|
273 | r_end--; |
---|
274 | }; |
---|
275 | |
---|
276 | }; |
---|
277 | |
---|
278 | return (RESULT); |
---|
279 | |
---|
280 | }; |
---|
281 | |
---|
282 | /******************************************************/ |
---|
283 | static proc my_var_init() |
---|
284 | " |
---|
285 | must be called once before using my_var!!! |
---|
286 | " |
---|
287 | { |
---|
288 | if( defined( @@@SORTEDVARARRAY ) ) |
---|
289 | { |
---|
290 | kill ( @@@SORTEDVARARRAY ); |
---|
291 | }; |
---|
292 | |
---|
293 | list @@@SORTEDVARARRAY; |
---|
294 | list V = my_associated(); |
---|
295 | |
---|
296 | // cartans - first then others... |
---|
297 | |
---|
298 | for ( int i = 1; i<= size(V); i++ ) |
---|
299 | { |
---|
300 | @@@SORTEDVARARRAY[i] = V[i][1]; |
---|
301 | }; |
---|
302 | |
---|
303 | Print( "@@@SORTEDVARARRAY: " + string(@@@SORTEDVARARRAY) ); |
---|
304 | |
---|
305 | export(@@@SORTEDVARARRAY); |
---|
306 | }; |
---|
307 | |
---|
308 | /******************************************************/ |
---|
309 | static proc my_var(int @number ) |
---|
310 | " |
---|
311 | 'my' var (with my order of variables), |
---|
312 | before use call my_var_init() |
---|
313 | " |
---|
314 | { |
---|
315 | if( defined( @@@SORTEDVARARRAY ) ) |
---|
316 | { |
---|
317 | return( @@@SORTEDVARARRAY[@number] ); |
---|
318 | }; |
---|
319 | |
---|
320 | Print( "Error: my_var_init() was not called before this..." ); |
---|
321 | return( var(@number) ); |
---|
322 | |
---|
323 | }; |
---|
324 | |
---|
325 | /******************************************************/ |
---|
326 | static proc my_var_done() |
---|
327 | " |
---|
328 | this procedure should be called after finishing using my_var in order to clean up. |
---|
329 | " |
---|
330 | { |
---|
331 | if( defined( @@@SORTEDVARARRAY ) ) |
---|
332 | { |
---|
333 | kill ( @@@SORTEDVARARRAY ); |
---|
334 | }; |
---|
335 | }; |
---|
336 | |
---|
337 | |
---|
338 | /******************************************************/ |
---|
339 | // QNF stuff |
---|
340 | |
---|
341 | /******************************************************/ |
---|
342 | static proc myBitParam( int param, int n ) |
---|
343 | " |
---|
344 | return: string: param in bin within no less then n digits (adding zeroes) |
---|
345 | " |
---|
346 | { |
---|
347 | string s = ""; |
---|
348 | |
---|
349 | while ( param != 0 ) |
---|
350 | { |
---|
351 | s = string ( param % 2 ) + s; |
---|
352 | param = param / 2; |
---|
353 | n --; |
---|
354 | }; |
---|
355 | while ( n > 0 ) |
---|
356 | { |
---|
357 | s = "0" + s; |
---|
358 | n --; |
---|
359 | }; |
---|
360 | return ( s ); |
---|
361 | }; |
---|
362 | |
---|
363 | /******************************************************/ |
---|
364 | static proc QNF_init(list #) |
---|
365 | { |
---|
366 | if( defined(@@@MY_QIDEAL) ) |
---|
367 | { |
---|
368 | kill (@@@MY_QIDEAL); |
---|
369 | }; |
---|
370 | |
---|
371 | if( typeof(basering) == "qring" ) |
---|
372 | { |
---|
373 | ideal @@@MY_QIDEAL = twostd(myIdeal(#)); |
---|
374 | // setup redSB, redTail options |
---|
375 | export(@@@MY_QIDEAL); |
---|
376 | |
---|
377 | option(redSB); |
---|
378 | option(redTail); |
---|
379 | |
---|
380 | }; |
---|
381 | }; |
---|
382 | |
---|
383 | /******************************************************/ |
---|
384 | static proc QNF_done() |
---|
385 | { |
---|
386 | if( defined(@@@MY_QIDEAL) ) |
---|
387 | { |
---|
388 | kill (@@@MY_QIDEAL); |
---|
389 | }; |
---|
390 | }; |
---|
391 | |
---|
392 | /******************************************************/ |
---|
393 | static proc QNF_poly ( poly p, list # ) |
---|
394 | { |
---|
395 | if( defined(@@@MY_QIDEAL) ) |
---|
396 | { |
---|
397 | /* |
---|
398 | int param = 1 ; // by def: reduce both 1st and 2nd entries |
---|
399 | param = myValue(param, #); |
---|
400 | string bits = myBitParam( param, 8 ); |
---|
401 | */ |
---|
402 | BCall( "QNF_poly", p ); |
---|
403 | |
---|
404 | p = NF( p, @@@MY_QIDEAL ); |
---|
405 | |
---|
406 | ECall( "QNF_poly", p ); |
---|
407 | }; // QRing |
---|
408 | |
---|
409 | return(p); |
---|
410 | }; |
---|
411 | |
---|
412 | |
---|
413 | /******************************************************/ |
---|
414 | static proc QNF_list ( list l, list # ) |
---|
415 | " |
---|
416 | expects list of records with two polynomial entries |
---|
417 | and in case of Qring allpies NF( * , std(0) ) to entries (depends on parameter) |
---|
418 | |
---|
419 | 1234 5678 |
---|
420 | |
---|
421 | +1 8 => reduce every 1st entry |
---|
422 | +2 7 => reduce every 2nd entry |
---|
423 | |
---|
424 | --- (for PBW in qrings) --- |
---|
425 | |
---|
426 | +4 6 => kill out pbw entries where pbw monom (1) was affected |
---|
427 | |
---|
428 | //?? wofuer? |
---|
429 | +8 5 => reduce every 3rd entry |
---|
430 | |
---|
431 | " |
---|
432 | { |
---|
433 | |
---|
434 | if( defined(@@@MY_QIDEAL) ) |
---|
435 | { |
---|
436 | |
---|
437 | int param = 1 + 2; // by def: reduce both 1st and 2nd entries |
---|
438 | param = myValue(param, #); |
---|
439 | |
---|
440 | string bits = myBitParam( param, 8 ); |
---|
441 | |
---|
442 | BCall( "QNF_list", "list, " + bits ); |
---|
443 | |
---|
444 | poly temp; |
---|
445 | |
---|
446 | for ( int i = size(l); i>0 ; i -- ) |
---|
447 | { |
---|
448 | |
---|
449 | if ( typeof( l[i] ) == "poly" ) |
---|
450 | { |
---|
451 | |
---|
452 | if ( (bits[8] == "1") or (bits[6] == "1") ) |
---|
453 | { |
---|
454 | temp = NF( l[i], @@@MY_QIDEAL ); |
---|
455 | |
---|
456 | if ( bits[6] == "1" ) |
---|
457 | {// for PBW in qrings: kill out pbw entries where pbw monom was reduced |
---|
458 | |
---|
459 | if( temp != l[i] ) |
---|
460 | { |
---|
461 | l = delete( l, i ); |
---|
462 | i --; |
---|
463 | continue; |
---|
464 | }; |
---|
465 | }; |
---|
466 | |
---|
467 | if ( bits[8] == "1" ) |
---|
468 | { |
---|
469 | l[i] = temp; |
---|
470 | }; |
---|
471 | }; |
---|
472 | }; |
---|
473 | |
---|
474 | if ( typeof( l[i] ) == "list" ) |
---|
475 | { |
---|
476 | // 1st |
---|
477 | |
---|
478 | if ( size(l[i])>0 ) |
---|
479 | { |
---|
480 | if ( (bits[8] == "1") or (bits[6] == "1") ) |
---|
481 | { |
---|
482 | if( typeof( l[i][1] ) == "poly" ) |
---|
483 | { |
---|
484 | |
---|
485 | temp = NF( l[i][1], @@@MY_QIDEAL ); |
---|
486 | |
---|
487 | if ( bits[6] == "1" ) |
---|
488 | {// for PBW in qrings: kill out pbw entries where pbw monom was reduced |
---|
489 | |
---|
490 | if( temp != l[i][1] ) |
---|
491 | { |
---|
492 | l = delete( l, i ); |
---|
493 | i --; |
---|
494 | continue; |
---|
495 | }; |
---|
496 | }; |
---|
497 | |
---|
498 | if ( bits[8] == "1" ) |
---|
499 | { |
---|
500 | l[i][1] = temp; |
---|
501 | }; |
---|
502 | |
---|
503 | }; |
---|
504 | }; |
---|
505 | }; |
---|
506 | |
---|
507 | // 2nd |
---|
508 | |
---|
509 | if ( size(l[i])>1 ) |
---|
510 | { |
---|
511 | if ( bits[7] == "1" ) |
---|
512 | { |
---|
513 | if( typeof( l[i][2] ) == "poly" ) |
---|
514 | { |
---|
515 | temp = NF( l[i][2], @@@MY_QIDEAL ); |
---|
516 | |
---|
517 | l[i][2] = temp; |
---|
518 | }; |
---|
519 | }; |
---|
520 | }; |
---|
521 | }; |
---|
522 | }; |
---|
523 | |
---|
524 | ECall( "QNF_list", "list" ); |
---|
525 | |
---|
526 | }; // Qring |
---|
527 | |
---|
528 | return ( l ); |
---|
529 | }; |
---|
530 | |
---|
531 | /******************************************************/ |
---|
532 | // things for zCommon |
---|
533 | |
---|
534 | /******************************************************/ |
---|
535 | static proc index( int i ) |
---|
536 | " |
---|
537 | i need indexing of arrays from 0 => ARRAY[ index(i) ] - everywhere... |
---|
538 | " |
---|
539 | { |
---|
540 | return (i + 1); |
---|
541 | }; |
---|
542 | |
---|
543 | /******************************************************/ |
---|
544 | static proc uni_poly( poly p ) |
---|
545 | " |
---|
546 | returns polynomial with the same monomials but without coefficients. |
---|
547 | " |
---|
548 | { |
---|
549 | poly @tt = poly(0); |
---|
550 | for ( int @k = size(p); @k > 0; @k -- ) |
---|
551 | { |
---|
552 | @tt = @tt + leadmonom(p[@k]); |
---|
553 | }; |
---|
554 | return (@tt); |
---|
555 | }; |
---|
556 | |
---|
557 | /******************************************************/ |
---|
558 | static proc get_max ( poly @t, number @def ) |
---|
559 | { |
---|
560 | int @n = size( @t ); |
---|
561 | |
---|
562 | if ( @n == 0 ) |
---|
563 | { |
---|
564 | return (@def); |
---|
565 | }; |
---|
566 | |
---|
567 | number @max = leadcoef(@t[1]); |
---|
568 | number @mm; |
---|
569 | |
---|
570 | if ( @n > 1) |
---|
571 | { |
---|
572 | for ( int @i = 2; @i <= @n ;@i ++ ) |
---|
573 | { |
---|
574 | @mm = leadcoef ( @t[@i] ); |
---|
575 | if ( @mm < 0 ) |
---|
576 | { |
---|
577 | @mm = -@mm; |
---|
578 | }; |
---|
579 | |
---|
580 | if( @mm > @max ) |
---|
581 | { |
---|
582 | @max = @mm; |
---|
583 | }; |
---|
584 | }; |
---|
585 | }; |
---|
586 | |
---|
587 | @max = @max + 1; |
---|
588 | if ( @max == 0 ) |
---|
589 | { |
---|
590 | @max = @max + 1; |
---|
591 | }; |
---|
592 | return ( 1/@max ); |
---|
593 | }; |
---|
594 | |
---|
595 | |
---|
596 | /******************************************************/ |
---|
597 | static proc get_uni_sum(list @given, int @num) |
---|
598 | { |
---|
599 | int @l, @k; |
---|
600 | |
---|
601 | poly @t, @tt; |
---|
602 | |
---|
603 | @l = size (@given); |
---|
604 | |
---|
605 | @t = poly(0); |
---|
606 | for ( @k = @l; @k > 0; @k -- ) |
---|
607 | { |
---|
608 | if (@num == 1) |
---|
609 | { |
---|
610 | @tt = @given[@k]; |
---|
611 | } else |
---|
612 | { |
---|
613 | @tt = @given[@k][2]; |
---|
614 | }; |
---|
615 | |
---|
616 | @t = @t + uni_poly( @tt ); |
---|
617 | }; |
---|
618 | |
---|
619 | return ( uni_poly(@t) ); |
---|
620 | }; |
---|
621 | |
---|
622 | |
---|
623 | |
---|
624 | /******************************************************/ |
---|
625 | static proc LM ( intvec exp ) |
---|
626 | " |
---|
627 | input : given exponent |
---|
628 | return: monom with this exponent... |
---|
629 | " |
---|
630 | { |
---|
631 | poly @f = 1; int @deg; |
---|
632 | for( int @i = 1; @i <= size(exp); @i ++ ) |
---|
633 | { |
---|
634 | @deg = exp[@i]; |
---|
635 | if ( @deg > 0 ) |
---|
636 | { |
---|
637 | @f = @f * (var(@i)^(@deg)); |
---|
638 | }; |
---|
639 | }; |
---|
640 | |
---|
641 | return (@f); |
---|
642 | }; |
---|
643 | |
---|
644 | /******************************************************/ |
---|
645 | // reduced centers - computation of "minimal" set of generators |
---|
646 | |
---|
647 | LIB "general.lib"; // for sort |
---|
648 | |
---|
649 | /******************************************************/ |
---|
650 | static proc zSort ( list @z ) |
---|
651 | " |
---|
652 | Sort elements of a list of polynoms, |
---|
653 | and normalize |
---|
654 | " |
---|
655 | { |
---|
656 | int n = size(@z); |
---|
657 | if ( n < 1 ) |
---|
658 | {// empty list |
---|
659 | return( @z ); |
---|
660 | }; |
---|
661 | |
---|
662 | if ( n == 1 ) |
---|
663 | { |
---|
664 | if ( @z[1] == 0 ) // if zero => empty list |
---|
665 | { |
---|
666 | return(list()); |
---|
667 | }; |
---|
668 | |
---|
669 | @z[1] = @z[1] * ( 1/leadcoef(@z[1]) ) ; |
---|
670 | |
---|
671 | return( @z ); |
---|
672 | }; |
---|
673 | |
---|
674 | int i = 1; |
---|
675 | |
---|
676 | while ( i<=n ) |
---|
677 | { |
---|
678 | if (size( @z[i] ) != 0) |
---|
679 | { |
---|
680 | break; |
---|
681 | }; |
---|
682 | i++; |
---|
683 | }; |
---|
684 | |
---|
685 | if ( i > n ) |
---|
686 | { // all zeroes |
---|
687 | return(list()); |
---|
688 | }; |
---|
689 | |
---|
690 | ideal id = @z[i]; |
---|
691 | i++; |
---|
692 | |
---|
693 | while ( i<= n ) |
---|
694 | { |
---|
695 | if( @z[i] != 0 ) |
---|
696 | { |
---|
697 | id=@z[i],id; |
---|
698 | }; |
---|
699 | i++; |
---|
700 | }; |
---|
701 | |
---|
702 | // can sort only ideal generators:-( |
---|
703 | list srt = sort(id); |
---|
704 | |
---|
705 | poly p; |
---|
706 | // convert srt[1]:ideal to result:list. |
---|
707 | list result = list(); |
---|
708 | for ( i = size(srt[1]); i>0; i-- ) |
---|
709 | { |
---|
710 | p = srt[1][i]; |
---|
711 | if ( p == 0 ) |
---|
712 | { |
---|
713 | i --; |
---|
714 | continue; |
---|
715 | }; |
---|
716 | p = p* (1/leadcoef(p)); // normalize |
---|
717 | result = list(p) + result; |
---|
718 | }; |
---|
719 | |
---|
720 | // "OUT SORT::"; |
---|
721 | // result; |
---|
722 | |
---|
723 | return ( result ); |
---|
724 | }; |
---|
725 | |
---|
726 | |
---|
727 | |
---|
728 | /******************************************************/ |
---|
729 | static proc zRefine ( list @z ) |
---|
730 | " |
---|
731 | kill terms by leading monomials... |
---|
732 | Note: based on myCoeff |
---|
733 | " |
---|
734 | { |
---|
735 | BCall("zRefine", "list"); |
---|
736 | |
---|
737 | int @i, @j; |
---|
738 | |
---|
739 | poly @f = 0; // leadmonom |
---|
740 | |
---|
741 | poly @ff = 0; // polyes |
---|
742 | poly @gg = 0; |
---|
743 | number @nf, @ng; |
---|
744 | |
---|
745 | int flag = 1; |
---|
746 | |
---|
747 | while ( flag == 1 ) |
---|
748 | { |
---|
749 | flag = 0; |
---|
750 | |
---|
751 | @z = zSort(@z); // sort out, < ... |
---|
752 | |
---|
753 | if( size(@z) < 2 ) |
---|
754 | { |
---|
755 | return (@z); |
---|
756 | }; |
---|
757 | |
---|
758 | for ( @i = size(@z); @i > 0; @i -- ) // at 1st the biggest ... then smallest... |
---|
759 | { |
---|
760 | |
---|
761 | @ff = @z[@i]; |
---|
762 | |
---|
763 | if( size(@ff) == 0 ) |
---|
764 | { |
---|
765 | @z = delete ( @z , @i ); |
---|
766 | @i --; |
---|
767 | continue; |
---|
768 | }; |
---|
769 | |
---|
770 | @ff = @ff*(1/leadcoef(@ff)); |
---|
771 | @z[@i] = @ff; |
---|
772 | @f = leadmonom(@ff); |
---|
773 | |
---|
774 | for ( @j = (@i-1); (@j>0); @j -- ) |
---|
775 | { |
---|
776 | @gg = @z[@j]; |
---|
777 | @ng = myCoeff(@gg, @f); // leads? |
---|
778 | if( @ng!=0 ) |
---|
779 | { |
---|
780 | @z[@j] = @gg - @ng * @ff; |
---|
781 | flag = 1; |
---|
782 | }; |
---|
783 | }; |
---|
784 | for ( @j = (@i+1); (@j<=size(@z)); @j ++ ) |
---|
785 | { |
---|
786 | @gg = @z[@j]; |
---|
787 | @ng = myCoeff(@gg, @f); |
---|
788 | if( @ng!=0 ) |
---|
789 | { |
---|
790 | @z[@j] = @gg - @ng * @ff; |
---|
791 | flag = 1; |
---|
792 | }; |
---|
793 | }; |
---|
794 | |
---|
795 | }; |
---|
796 | }; |
---|
797 | |
---|
798 | ECall("zRefine", "list"); |
---|
799 | |
---|
800 | return ( @z ); |
---|
801 | |
---|
802 | }; |
---|
803 | |
---|
804 | |
---|
805 | /******************************************************/ |
---|
806 | // procedures for building "bad leadmonomials" set |
---|
807 | |
---|
808 | |
---|
809 | /******************************************************/ |
---|
810 | static proc checkPolyUniq( list l, poly p ) |
---|
811 | " |
---|
812 | check whether p sits already in l, assume l to be size-sorted < |
---|
813 | return: -1 if present |
---|
814 | 1 if we need to add |
---|
815 | " |
---|
816 | { |
---|
817 | BCall( "checkPolyUniq", "{ " + string(l) + " }, " + string(p) ); |
---|
818 | int n = size(l); |
---|
819 | int i = 1; |
---|
820 | |
---|
821 | int s = size(p); |
---|
822 | |
---|
823 | while( i<= n ) |
---|
824 | { |
---|
825 | if ( size(l[i]) >= s ) |
---|
826 | { |
---|
827 | break; |
---|
828 | }; |
---|
829 | |
---|
830 | i ++; |
---|
831 | }; |
---|
832 | |
---|
833 | // now: size(l[i]) >= s |
---|
834 | while( i<= n ) |
---|
835 | { |
---|
836 | if ( size(l[i]) == s ) |
---|
837 | { |
---|
838 | break; |
---|
839 | |
---|
840 | }; |
---|
841 | if ( l[i] == p ) |
---|
842 | { |
---|
843 | ECall( "checkPolyUniq", -1 ); |
---|
844 | return (-1); |
---|
845 | }; |
---|
846 | i ++; |
---|
847 | }; |
---|
848 | |
---|
849 | ECall( "checkPolyUniq", 1 ); |
---|
850 | return ( 1 ); |
---|
851 | |
---|
852 | }; |
---|
853 | |
---|
854 | /******************************************************/ |
---|
855 | static proc addPolyUniq( list l, poly p ) |
---|
856 | " |
---|
857 | add p into l uniquely, and keep l size-sorted < |
---|
858 | " |
---|
859 | { |
---|
860 | BCall( "addPolyUniq", " { " + string(l) + " }, " + string(p) ); |
---|
861 | |
---|
862 | int n = size(l); |
---|
863 | |
---|
864 | if ( n == 0 ) |
---|
865 | { |
---|
866 | l = list(p); |
---|
867 | |
---|
868 | ECall( "addPolyUniq", l ); |
---|
869 | |
---|
870 | return (l); |
---|
871 | }; |
---|
872 | |
---|
873 | int s = size(p); |
---|
874 | |
---|
875 | int i = 1; |
---|
876 | while( i<= n ) |
---|
877 | { |
---|
878 | if( size(l[i]) > s ) |
---|
879 | { |
---|
880 | l = insert( l, p, i-1 ) ; |
---|
881 | break; |
---|
882 | }; |
---|
883 | |
---|
884 | if( size(l[i]) == s ) |
---|
885 | { |
---|
886 | if ( l[i] == p ) |
---|
887 | { |
---|
888 | break; |
---|
889 | }; |
---|
890 | }; |
---|
891 | |
---|
892 | i++; |
---|
893 | }; |
---|
894 | |
---|
895 | if( i > n ) |
---|
896 | { |
---|
897 | l = l + list(p); |
---|
898 | }; |
---|
899 | |
---|
900 | ECall( "addPolyUniq", l ); |
---|
901 | return(l); |
---|
902 | }; |
---|
903 | |
---|
904 | |
---|
905 | /******************************************************/ |
---|
906 | static proc mergePolysUniq( list a, list b ) |
---|
907 | " |
---|
908 | merge lists uniq |
---|
909 | " |
---|
910 | { |
---|
911 | BCall( "mergePolysUniq", "{ " + string(a) + " }, { " + string(b) + "} " ); |
---|
912 | |
---|
913 | for( int i = 1; i <= size(b); i ++ ) |
---|
914 | { |
---|
915 | a = addPolyUniq(a, b[i]); |
---|
916 | }; |
---|
917 | |
---|
918 | ECall( "mergePolysUniq", a ); |
---|
919 | |
---|
920 | return (a); |
---|
921 | }; |
---|
922 | |
---|
923 | |
---|
924 | /******************************************************/ |
---|
925 | static proc sortPolysUniq( list a ) |
---|
926 | " |
---|
927 | sort list uniq |
---|
928 | " |
---|
929 | { |
---|
930 | BCall( "sortPolysUniq", a ); |
---|
931 | |
---|
932 | if( size(a) < 2 ) |
---|
933 | { |
---|
934 | ECall( "sortPolysUniq", a ); |
---|
935 | return(a); |
---|
936 | }; |
---|
937 | |
---|
938 | list b = list(a[1]); |
---|
939 | |
---|
940 | for( int i = 2; i <= size(a); i ++ ) |
---|
941 | { |
---|
942 | b = addPolyUniq(b, a[i]); |
---|
943 | }; |
---|
944 | |
---|
945 | ECall( "sortPolysUniq", b ); |
---|
946 | |
---|
947 | return (b); |
---|
948 | }; |
---|
949 | |
---|
950 | /******************************************************/ |
---|
951 | static proc addRecordUniq ( list leadD, list newD, intvec texp, poly tm, int kind, list prs ) |
---|
952 | " |
---|
953 | if kind = 0 => for PBW - no products |
---|
954 | if kind = 1 => with products |
---|
955 | " |
---|
956 | { |
---|
957 | BCall ("addRecordUniq", "{old leads}, {new lead}, [" + string(texp) + "], " + string(tm) + ", " + string(kind) + ", {" + string(prs) + "}"); |
---|
958 | |
---|
959 | int i; |
---|
960 | int f_add = 0; |
---|
961 | |
---|
962 | prs = sortPolysUniq(prs); |
---|
963 | |
---|
964 | // trick: |
---|
965 | // check for presens of a monomial @tm in current index poly of @leads (=> in list @leads) |
---|
966 | // if char = 0 then new_size > (if not present) or = (if already present) |
---|
967 | // if char > 0 then new_size > (if not present) or =< (if already present) |
---|
968 | // !!!!! |
---|
969 | if( size(tm + leadD[2]) > size(leadD[2]) ) |
---|
970 | { |
---|
971 | f_add = 1; |
---|
972 | } else |
---|
973 | { |
---|
974 | if ( kind != 0 ) |
---|
975 | { |
---|
976 | for ( i = 1; i<= size(leadD[1]); i++ ) |
---|
977 | { |
---|
978 | if ( leadD[1][i][2] == tm ) |
---|
979 | { |
---|
980 | for ( i = size(prs); i>0; i-- ) |
---|
981 | { |
---|
982 | f_add = checkPolyUniq( leadD[1][i][3], prs[i] ); |
---|
983 | if( f_add == -1 ) |
---|
984 | { |
---|
985 | prs = delete(prs, i); |
---|
986 | }; |
---|
987 | }; |
---|
988 | |
---|
989 | break; |
---|
990 | }; |
---|
991 | }; |
---|
992 | }; |
---|
993 | }; |
---|
994 | |
---|
995 | if ( f_add == 1 ) |
---|
996 | { |
---|
997 | |
---|
998 | list newlist ; |
---|
999 | if ( kind != 0 ) |
---|
1000 | { |
---|
1001 | newlist = list ( list ( texp, tm, prs ) ); |
---|
1002 | } else |
---|
1003 | { |
---|
1004 | newlist = list ( list ( texp, tm ) ); |
---|
1005 | }; |
---|
1006 | |
---|
1007 | |
---|
1008 | if ( size(newD[1]) == 0 ) |
---|
1009 | { |
---|
1010 | newD[1] = newlist; |
---|
1011 | newD[2] = tm; |
---|
1012 | } else |
---|
1013 | { |
---|
1014 | |
---|
1015 | if( size(tm + newD[2]) > size(newD[2]) ) |
---|
1016 | { |
---|
1017 | newD[1] = newD[1] + newlist; |
---|
1018 | newD[2] = newD[2] + tm; |
---|
1019 | } else |
---|
1020 | { |
---|
1021 | if ( kind != 0 ) |
---|
1022 | { |
---|
1023 | for ( i = 1; i<= size(newD[1]); i++ ) |
---|
1024 | { |
---|
1025 | if ( newD[1][i][2] == tm ) |
---|
1026 | { |
---|
1027 | newD[1][i][3] = mergePolysUniq( newD[1][i][3], prs ); |
---|
1028 | break; |
---|
1029 | }; |
---|
1030 | }; |
---|
1031 | }; |
---|
1032 | }; |
---|
1033 | }; |
---|
1034 | }; |
---|
1035 | |
---|
1036 | ECall("addRecordUniq", "{new leads}"); |
---|
1037 | return (newD); |
---|
1038 | }; |
---|
1039 | |
---|
1040 | |
---|
1041 | /******************************************************/ |
---|
1042 | static proc mergeRecordsUniq ( list old, list new, int kind ) |
---|
1043 | { |
---|
1044 | BCall ("mergeRecordsUniq", "{old leads}, {new leads}, " + string(kind) ); |
---|
1045 | |
---|
1046 | if( size(new[1]) > 0 ) |
---|
1047 | { |
---|
1048 | if ( size (old[1]) == 0 ) |
---|
1049 | { |
---|
1050 | old = new; |
---|
1051 | } else |
---|
1052 | { |
---|
1053 | if ( kind != 0 ) |
---|
1054 | { |
---|
1055 | int io; |
---|
1056 | for ( int in = 1; in <= size( new[1] ); in ++ ) |
---|
1057 | { |
---|
1058 | if( size( new[1][in][2] + old[2] ) > size( old[2] ) ) |
---|
1059 | { |
---|
1060 | old[1] = old[1] + list(new[1][in]); |
---|
1061 | old[2] = old[2] + new[1][in][2]; |
---|
1062 | } else |
---|
1063 | { |
---|
1064 | for( io = 1; io <= size( old[1] ); io ++ ) |
---|
1065 | { |
---|
1066 | if( old[1][io][2] == new[1][in][2] ) |
---|
1067 | { |
---|
1068 | old[1][io][3] = mergePolysUniq( old[1][io][3], new[1][in][3] ); |
---|
1069 | break; |
---|
1070 | }; |
---|
1071 | }; |
---|
1072 | }; |
---|
1073 | }; |
---|
1074 | } else |
---|
1075 | { |
---|
1076 | old[1] = old[1] + new[1]; |
---|
1077 | old[2] = old[2] + new[2]; |
---|
1078 | }; |
---|
1079 | }; |
---|
1080 | }; |
---|
1081 | |
---|
1082 | ECall ("mergeRecordsUniq", "{new leads}"); |
---|
1083 | return (old); |
---|
1084 | }; |
---|
1085 | |
---|
1086 | |
---|
1087 | |
---|
1088 | /******************************************************/ |
---|
1089 | static proc init_bads(int @deg) |
---|
1090 | " |
---|
1091 | initialization of an empty 'badleads' list |
---|
1092 | " |
---|
1093 | { |
---|
1094 | list @l = list(); |
---|
1095 | for( int @i = 0; @i <= @deg; @i ++ ) |
---|
1096 | { |
---|
1097 | @l[index(@i)] = list( list() , 0); |
---|
1098 | // new items: |
---|
1099 | // { |
---|
1100 | // list of leads, - empty list |
---|
1101 | // sum poly "index", - poly(0) |
---|
1102 | // } |
---|
1103 | }; |
---|
1104 | return (@l); |
---|
1105 | }; |
---|
1106 | |
---|
1107 | /******************************************************/ |
---|
1108 | static proc zAddBad ( list @leads, list @newz, int @maxDeg, int kind ) |
---|
1109 | " |
---|
1110 | input: |
---|
1111 | @leads: graded by deg list of |
---|
1112 | rec: |
---|
1113 | { |
---|
1114 | [1] - list of |
---|
1115 | rec: |
---|
1116 | { |
---|
1117 | [1] - leadexp. |
---|
1118 | [2] - leadmonom([1]) |
---|
1119 | if kind != 0 (for zReduce) => |
---|
1120 | [3] - !list! of all possible products which give this leadexp |
---|
1121 | }, |
---|
1122 | [2] - summ of all in [1] ('index' poly) |
---|
1123 | } |
---|
1124 | @newz: new elements for adding to @leads |
---|
1125 | @maxDeg: maximal degree |
---|
1126 | |
---|
1127 | if kind != 0 => keeps also list of all possible products which give leadexp of a record |
---|
1128 | |
---|
1129 | return: |
---|
1130 | updated @leads list |
---|
1131 | |
---|
1132 | " |
---|
1133 | { |
---|
1134 | BCall ("zAddBad", "{old leads}, { " + string(@newz) + " }, " + string(@maxDeg) + ", " + string(kind) + ""); |
---|
1135 | |
---|
1136 | int @newSize = size(@newz); |
---|
1137 | if ( @newSize < 1 ) |
---|
1138 | { |
---|
1139 | return (@leads); |
---|
1140 | }; |
---|
1141 | |
---|
1142 | int @i, @j, @k, @dd, @deg; |
---|
1143 | |
---|
1144 | |
---|
1145 | poly @m, @tm, @ttm; |
---|
1146 | intvec @exp, @texp, @ttexp; |
---|
1147 | |
---|
1148 | list @newzz; |
---|
1149 | int @size, @newdeg, @mydeg; |
---|
1150 | |
---|
1151 | poly @sum_old, @sum_new; |
---|
1152 | |
---|
1153 | poly a, b, @temp; |
---|
1154 | |
---|
1155 | /* |
---|
1156 | if kind = 0 => for PBW - no products |
---|
1157 | if kind = 1 => for zReduce - with products |
---|
1158 | */ |
---|
1159 | |
---|
1160 | poly pr = 0; int pri; list prs; |
---|
1161 | |
---|
1162 | for ( @i = @newSize; @i > 0; @i -- ) |
---|
1163 | {// for every new poly (@newz[@i]) do |
---|
1164 | |
---|
1165 | @m = leadmonom( @newz[@i] ); |
---|
1166 | @deg = deg(@m); |
---|
1167 | @exp = leadexp(@m); |
---|
1168 | |
---|
1169 | // newzz void new list |
---|
1170 | @newzz = init_bads(@maxDeg ); |
---|
1171 | |
---|
1172 | for( @mydeg = @deg; @mydeg <= @maxDeg; @mydeg = @mydeg + @deg ) |
---|
1173 | {// adding all possiblities for @newz[@i]^@j; |
---|
1174 | |
---|
1175 | if ( @mydeg > @deg ) |
---|
1176 | { |
---|
1177 | @texp = @texp + @exp; |
---|
1178 | @tm = LM ( @texp ); |
---|
1179 | if ( kind != 0) |
---|
1180 | { |
---|
1181 | pr = QNF_poly( pr * @newz[@i] ); // degrees must be there!!! |
---|
1182 | }; |
---|
1183 | } else |
---|
1184 | { |
---|
1185 | @texp = @exp; |
---|
1186 | @tm = @m; |
---|
1187 | if ( kind != 0) |
---|
1188 | { |
---|
1189 | pr = @newz[@i]; |
---|
1190 | }; |
---|
1191 | }; |
---|
1192 | |
---|
1193 | @temp = QNF_poly(@tm); |
---|
1194 | if( @temp != @tm ) |
---|
1195 | { |
---|
1196 | break; |
---|
1197 | }; |
---|
1198 | |
---|
1199 | /*!!*/ @newzz[index(@mydeg)] = |
---|
1200 | /*!!*/ addRecordUniq( @leads[index(@mydeg)], @newzz[index(@mydeg)], @texp, @tm, kind, list(pr) ); |
---|
1201 | |
---|
1202 | for ( @dd = 1; (@dd <= @maxDeg) and ((@dd + @mydeg) <= @maxDeg ); @dd ++ ) |
---|
1203 | { // for every good "deg" |
---|
1204 | |
---|
1205 | @newdeg = @dd + @mydeg; // any deg should be additive!!! |
---|
1206 | |
---|
1207 | for ( @k = size(@leads[index(@dd)][1]); @k > 0; @k -- ) |
---|
1208 | { |
---|
1209 | |
---|
1210 | @ttexp = (@leads[index(@dd)][1][@k][1]) + @texp; |
---|
1211 | @ttm = LM (@ttexp); |
---|
1212 | |
---|
1213 | if ( kind != 0 ) |
---|
1214 | { |
---|
1215 | prs = list(); |
---|
1216 | |
---|
1217 | for( pri = 1; pri <= size(@leads[index(@dd)][1][@k][3]); pri++) |
---|
1218 | { |
---|
1219 | // to do products into list and add one list !!! |
---|
1220 | a = QNF_poly( pr*@leads[index(@dd)][1][@k][3][pri]); |
---|
1221 | b = QNF_poly( @leads[index(@dd)][1][@k][3][pri]*pr); |
---|
1222 | |
---|
1223 | prs= prs + list(a); |
---|
1224 | |
---|
1225 | if ( a!=b ) |
---|
1226 | { |
---|
1227 | prs= prs + list(b); |
---|
1228 | }; |
---|
1229 | }; |
---|
1230 | |
---|
1231 | } else |
---|
1232 | { |
---|
1233 | prs = list(pr); |
---|
1234 | }; |
---|
1235 | |
---|
1236 | @temp = QNF_poly(@ttm); |
---|
1237 | if( @temp == @ttm ) |
---|
1238 | { |
---|
1239 | |
---|
1240 | /*!!*/ @newzz[index(@newdeg)] = |
---|
1241 | /*!!*/ addRecordUniq( @leads[index(@newdeg)], @newzz[index(@newdeg)], @ttexp, @ttm, kind, prs ); |
---|
1242 | }; |
---|
1243 | |
---|
1244 | |
---|
1245 | }; |
---|
1246 | }; // for |
---|
1247 | |
---|
1248 | if ( @deg == 0 ) |
---|
1249 | { |
---|
1250 | break; |
---|
1251 | }; |
---|
1252 | }; |
---|
1253 | |
---|
1254 | for ( @mydeg = 0; @mydeg <= @maxDeg; @mydeg ++ ) |
---|
1255 | { // adding currently generated to result |
---|
1256 | @leads[index(@mydeg)] = mergeRecordsUniq ( @leads[index(@mydeg)], @newzz[index(@mydeg)], kind ); |
---|
1257 | }; |
---|
1258 | |
---|
1259 | }; |
---|
1260 | |
---|
1261 | ECall ("zAddBad", "{new leads}"); |
---|
1262 | |
---|
1263 | return (@leads); |
---|
1264 | }; |
---|
1265 | |
---|
1266 | |
---|
1267 | /******************************************************/ |
---|
1268 | // procedure for reducing a given poly wrt already calculated "badleadings" |
---|
1269 | |
---|
1270 | /******************************************************/ |
---|
1271 | static proc zReducePoly ( list leads, poly new, poly anfang ) |
---|
1272 | " |
---|
1273 | reduce poly new wrt found leads, |
---|
1274 | return: list of all possible reductions... |
---|
1275 | " |
---|
1276 | { |
---|
1277 | poly temp = new; |
---|
1278 | poly rest = anfang; |
---|
1279 | |
---|
1280 | poly lm; |
---|
1281 | number lc; |
---|
1282 | |
---|
1283 | list LEADS; |
---|
1284 | |
---|
1285 | int i, n; |
---|
1286 | list prs; |
---|
1287 | |
---|
1288 | while ( size(temp) > 0 ) |
---|
1289 | { |
---|
1290 | // do for every term... beginning with leading... 'till smallest |
---|
1291 | lm = leadmonom( temp ); |
---|
1292 | |
---|
1293 | LEADS = leads[index(deg( lm ))]; // currently users bad leading products... |
---|
1294 | |
---|
1295 | if( size(LEADS[2] + lm ) <= size(LEADS[2]) ) |
---|
1296 | { // need to reduce, since leacmonom already in LEADS |
---|
1297 | |
---|
1298 | for ( i = 1; i <= size(LEADS[1]); i++ ) |
---|
1299 | { |
---|
1300 | if( LEADS[1][i][2] == lm ) |
---|
1301 | { |
---|
1302 | |
---|
1303 | lc = leadcoef( temp ); // no need be the unit |
---|
1304 | |
---|
1305 | prs = LEADS[1][i][3]; // shouldbe generated by zAddBad with kind == 1 |
---|
1306 | n = size(prs) ; |
---|
1307 | |
---|
1308 | if ( n == 1 ) |
---|
1309 | { // no recursion |
---|
1310 | |
---|
1311 | temp = leadcoef(prs[1]) * temp - lc * prs[1]; // leadmonom goes down |
---|
1312 | |
---|
1313 | } else |
---|
1314 | { // do recursion |
---|
1315 | |
---|
1316 | list result = list(); |
---|
1317 | poly newnew; |
---|
1318 | int f_addrest = 0; |
---|
1319 | |
---|
1320 | for( int pri = 1; pri <= n ; pri ++ ) |
---|
1321 | { |
---|
1322 | newnew = leadcoef(prs[pri]) * temp - lc * prs[pri]; // leadmonom goes down |
---|
1323 | |
---|
1324 | if( size( newnew ) > 0 ) |
---|
1325 | { |
---|
1326 | result = result + zReducePoly(leads, newnew, rest); |
---|
1327 | } else |
---|
1328 | { |
---|
1329 | f_addrest = 1; |
---|
1330 | }; |
---|
1331 | }; |
---|
1332 | |
---|
1333 | if ( f_addrest == 1 ) |
---|
1334 | { |
---|
1335 | result = result + list(rest); |
---|
1336 | }; |
---|
1337 | return ( result ); |
---|
1338 | |
---|
1339 | }; |
---|
1340 | break; |
---|
1341 | }; |
---|
1342 | }; |
---|
1343 | |
---|
1344 | } else |
---|
1345 | { // no such leadmonom in leads |
---|
1346 | |
---|
1347 | rest = rest + lead ( temp ); |
---|
1348 | temp = temp - lead ( temp ); // leadcoeff goes down |
---|
1349 | }; |
---|
1350 | }; |
---|
1351 | |
---|
1352 | return (list(rest)); |
---|
1353 | |
---|
1354 | }; |
---|
1355 | |
---|
1356 | |
---|
1357 | /******************************************************/ |
---|
1358 | static proc zCancel ( list @tt, list @leads ) |
---|
1359 | " |
---|
1360 | just kill entries of plane PBW base with leading monomials in @leads... |
---|
1361 | " |
---|
1362 | { |
---|
1363 | int @i; |
---|
1364 | |
---|
1365 | if ( (size(@tt) == 0) ) |
---|
1366 | { |
---|
1367 | return (@tt); |
---|
1368 | }; |
---|
1369 | |
---|
1370 | list result = list(); |
---|
1371 | poly g, f; |
---|
1372 | |
---|
1373 | for ( @i = size(@tt); @i > 0 ; @i -- ) |
---|
1374 | // for all PBW entries: |
---|
1375 | { |
---|
1376 | g = leadmonom(@tt[@i][1]); // pbw entry |
---|
1377 | f = @leads[index(deg(g))][2]; // 'index' poly from @leads |
---|
1378 | |
---|
1379 | if ( size(f + g) > size(f) ) // if g not in @leads (works only for monomials) |
---|
1380 | { |
---|
1381 | result = list( @tt[@i] ) + result; |
---|
1382 | }; |
---|
1383 | }; |
---|
1384 | |
---|
1385 | return (result); |
---|
1386 | |
---|
1387 | }; |
---|
1388 | |
---|
1389 | /******************************************************/ |
---|
1390 | // procedure for computing "minimal" set of generators... |
---|
1391 | |
---|
1392 | /******************************************************/ |
---|
1393 | static proc zReduce( list @z ) |
---|
1394 | " |
---|
1395 | reduce a set @z - base of Center as V.S. |
---|
1396 | into a minimal set!! |
---|
1397 | " |
---|
1398 | { |
---|
1399 | BCall( "zReduce", @z ); |
---|
1400 | |
---|
1401 | @z = zRefine ( @z ); |
---|
1402 | int n = size( @z ); |
---|
1403 | |
---|
1404 | if ( n < 2 ) |
---|
1405 | { |
---|
1406 | return (@z); |
---|
1407 | }; |
---|
1408 | |
---|
1409 | int d = maxDeg( @z ); |
---|
1410 | |
---|
1411 | if( d== -1 ) |
---|
1412 | { |
---|
1413 | return (@z); |
---|
1414 | }; |
---|
1415 | |
---|
1416 | list leads = init_bads( d ); |
---|
1417 | |
---|
1418 | list @red; |
---|
1419 | |
---|
1420 | int f_add; int j; |
---|
1421 | |
---|
1422 | list result = list(); |
---|
1423 | |
---|
1424 | poly p; |
---|
1425 | |
---|
1426 | for ( int i = 1; i <= n ; i++ ) |
---|
1427 | {// in this order... from least to maximal... |
---|
1428 | |
---|
1429 | p = @z[i]; |
---|
1430 | |
---|
1431 | @red = zReducePoly ( leads, p, 0 ); |
---|
1432 | |
---|
1433 | f_add = 1; |
---|
1434 | |
---|
1435 | for( j = 1; j <= size(@red); j++ ) |
---|
1436 | { |
---|
1437 | if ( @red[j] == 0 ) |
---|
1438 | { |
---|
1439 | f_add = 0; |
---|
1440 | break; // nothing new.... |
---|
1441 | }; |
---|
1442 | }; |
---|
1443 | |
---|
1444 | @red = zRefine( @red ); // there will be no zeroes after ??? |
---|
1445 | |
---|
1446 | if( size(@red) > 0 ) |
---|
1447 | { |
---|
1448 | leads = zAddBad( leads, @red, d, 1); |
---|
1449 | }; |
---|
1450 | |
---|
1451 | if ( f_add == 1 ) |
---|
1452 | { |
---|
1453 | // we got something new.... |
---|
1454 | result = result + list(@red); // ??? which one to add? => trying to add all |
---|
1455 | }; |
---|
1456 | }; |
---|
1457 | |
---|
1458 | ECall( "zReduce", result ); |
---|
1459 | |
---|
1460 | return (result); |
---|
1461 | }; |
---|
1462 | |
---|
1463 | |
---|
1464 | /******************************************************/ |
---|
1465 | // PBW procedures .... |
---|
1466 | |
---|
1467 | /* |
---|
1468 | PBW: graded by deg list of lists of PBW terms. |
---|
1469 | PBW term: list of 2 polynoms: [1] = PBW monom, [2] = Ad_p( [1] ), [3] = last variable in [1] (for speed) |
---|
1470 | */ |
---|
1471 | |
---|
1472 | /******************************************************/ |
---|
1473 | static proc PBW_init() |
---|
1474 | " |
---|
1475 | PBW[ index(0) ] = PBW part of degree 0: |
---|
1476 | record: |
---|
1477 | [1] : 1 // var(0) ;-) |
---|
1478 | [2] : 0 |
---|
1479 | [3] : 1 |
---|
1480 | " |
---|
1481 | { |
---|
1482 | BCall( "PBW_init" ); |
---|
1483 | return (list(list(1, 0, 1))); |
---|
1484 | }; |
---|
1485 | |
---|
1486 | |
---|
1487 | /******************************************************/ |
---|
1488 | static proc PBW_sys(list VARS, poly p) |
---|
1489 | " |
---|
1490 | calculate the array [1..NVARS] of records: |
---|
1491 | record[i] = |
---|
1492 | [1] = var(i) // i^{th} variable |
---|
1493 | [2] = p*[1]-[1]*p // [ p, var(i) ] |
---|
1494 | [3] = deg(var(i)) // i^{th} variable's deg |
---|
1495 | |
---|
1496 | ?? need debug ?? |
---|
1497 | " |
---|
1498 | { |
---|
1499 | |
---|
1500 | BCall( "PBW_sys" ); |
---|
1501 | |
---|
1502 | poly t; |
---|
1503 | for (int v = size(VARS); v>0; v -- ) |
---|
1504 | { |
---|
1505 | t = VARS[v]; |
---|
1506 | VARS[v] = list( t, QNF_poly( p*t - t*p ), deg(t) ) ; |
---|
1507 | }; |
---|
1508 | |
---|
1509 | return (VARS); |
---|
1510 | }; |
---|
1511 | |
---|
1512 | /******************************************************/ |
---|
1513 | static proc PBW_done( list PBW ) |
---|
1514 | " |
---|
1515 | collects all together, from graded lists into plane list. |
---|
1516 | |
---|
1517 | Note: also the last vars... |
---|
1518 | " |
---|
1519 | { |
---|
1520 | BCall( "PBW_done" ); |
---|
1521 | |
---|
1522 | list result = list(); |
---|
1523 | |
---|
1524 | int n = size(PBW); |
---|
1525 | for ( int i = 1; i <= n; i++) |
---|
1526 | { |
---|
1527 | result = result + PBW[i]; |
---|
1528 | }; |
---|
1529 | |
---|
1530 | return (result); |
---|
1531 | }; |
---|
1532 | |
---|
1533 | /******************************************************/ |
---|
1534 | static proc PBW_next ( list PBW, int k, list sys) |
---|
1535 | { |
---|
1536 | BCall( "PBW_next", k ); |
---|
1537 | |
---|
1538 | list temp; |
---|
1539 | int kk, nn, ii; |
---|
1540 | list result = list(); // PBW[ index(k) ] ought to be empty ?? |
---|
1541 | int N = size(sys); |
---|
1542 | |
---|
1543 | for ( int i = 1; i <= N; i ++ ) // for all vars |
---|
1544 | { |
---|
1545 | kk = (k - sys[i][3]); // any deg should be additive function wrt multiplication |
---|
1546 | if ( kk >= 0 ) |
---|
1547 | { |
---|
1548 | nn = size( PBW[ index(kk) ] ); |
---|
1549 | for ( ii = 1; ii <= nn; ii ++ ) |
---|
1550 | { |
---|
1551 | temp = PBW[ index(kk) ][ii]; |
---|
1552 | |
---|
1553 | if ( temp[3] <= i ) |
---|
1554 | { |
---|
1555 | temp[2] = temp[2]*sys[i][1] + temp[1]*sys[i][2]; // recursive [,] |
---|
1556 | temp[1] = temp[1]*sys[i][1]; |
---|
1557 | temp[3] = i; |
---|
1558 | |
---|
1559 | result = result + list ( temp ); |
---|
1560 | }; |
---|
1561 | }; |
---|
1562 | }; |
---|
1563 | }; |
---|
1564 | |
---|
1565 | result = QNF_list( result, 2 + 4); |
---|
1566 | ECall( "PBW_next", "list result" ); |
---|
1567 | return (result); |
---|
1568 | |
---|
1569 | }; |
---|
1570 | |
---|
1571 | /******************************************************/ |
---|
1572 | static proc PBW_base( int MaxDeg, poly p ) |
---|
1573 | { |
---|
1574 | BCall( "PBW_base", MaxDeg, p ); |
---|
1575 | |
---|
1576 | list PBW = list(); |
---|
1577 | list SYS = PBW_sys( my_vars(), p ); |
---|
1578 | |
---|
1579 | PBW[index(0)] = PBW_init(); |
---|
1580 | |
---|
1581 | for (int k = 1; k <= MaxDeg; k ++ ) |
---|
1582 | { |
---|
1583 | PBW[index(k)] = PBW_next( PBW, k, SYS ); |
---|
1584 | }; |
---|
1585 | |
---|
1586 | return (PBW_done( PBW )); |
---|
1587 | }; |
---|
1588 | |
---|
1589 | |
---|
1590 | /******************************************************/ |
---|
1591 | // standard center procedures... |
---|
1592 | |
---|
1593 | /******************************************************/ |
---|
1594 | static proc FSS (list @given, poly @BASE_POLY) |
---|
1595 | " |
---|
1596 | Gauss with computation of kernel v.s basis |
---|
1597 | to be optimized |
---|
1598 | " |
---|
1599 | { |
---|
1600 | BCall( "FSS", "list", "basepoly: ", @BASE_POLY); |
---|
1601 | |
---|
1602 | list @nums = list (); |
---|
1603 | intvec @ones; |
---|
1604 | int @j, @k, |
---|
1605 | @n, @v, |
---|
1606 | @a, @nn; |
---|
1607 | |
---|
1608 | @n = size( @BASE_POLY ); |
---|
1609 | @v = size( @given ); |
---|
1610 | |
---|
1611 | if ( (@v == 0) or (@n == 0) ) |
---|
1612 | { |
---|
1613 | return (@given); |
---|
1614 | }; |
---|
1615 | |
---|
1616 | matrix MD[@n][@v]; |
---|
1617 | |
---|
1618 | number @max; |
---|
1619 | poly @test; |
---|
1620 | poly @t; |
---|
1621 | |
---|
1622 | list LM = list(); // rec: { exp, poly } |
---|
1623 | |
---|
1624 | for( @k = @v; @k > 0; @k -- ) |
---|
1625 | { |
---|
1626 | LM[@k] = list(); |
---|
1627 | @t = @given[@k][2]; |
---|
1628 | LM[@k][2]= @t; |
---|
1629 | LM[@k][1]= leadexp( @t ); |
---|
1630 | }; |
---|
1631 | |
---|
1632 | |
---|
1633 | intvec @w; |
---|
1634 | for ( @a = 1 ; @a <= @n ; @a ++ ) |
---|
1635 | { |
---|
1636 | @w = leadexp(@BASE_POLY[@a]); |
---|
1637 | for( @k = @v; @k > 0; @k -- ) |
---|
1638 | { |
---|
1639 | if( @w == LM[@k][1] ) |
---|
1640 | { |
---|
1641 | @t = LM[@k][2]; |
---|
1642 | MD[@a, @k] = leadcoef( @t ); |
---|
1643 | @t = @t - lead ( @t ); |
---|
1644 | LM[@k][2] = @t; |
---|
1645 | |
---|
1646 | LM[@k][1] = leadexp(@t); |
---|
1647 | }; |
---|
1648 | }; |
---|
1649 | |
---|
1650 | }; |
---|
1651 | |
---|
1652 | int @x, @y; |
---|
1653 | number @min; |
---|
1654 | |
---|
1655 | number @div; |
---|
1656 | // @nums = list(); |
---|
1657 | |
---|
1658 | // Gauss |
---|
1659 | // print("Before Gauss, Matrix: "); |
---|
1660 | // print( MD ); |
---|
1661 | |
---|
1662 | |
---|
1663 | @x = 1; |
---|
1664 | @y = 1; |
---|
1665 | while ( (@y <= @n) && (@x <= @v)) |
---|
1666 | // main Gauss loop... |
---|
1667 | { |
---|
1668 | @min = leadcoef( MD[@y, @x] ); // curr diag. |
---|
1669 | |
---|
1670 | if ( @min == 0 ) |
---|
1671 | // if zero on diag... |
---|
1672 | { |
---|
1673 | @j = 0; |
---|
1674 | |
---|
1675 | // let's find the minimal |
---|
1676 | for ( @k = @y+1; @k <= @n; @k ++ ) |
---|
1677 | { |
---|
1678 | @max = leadcoef( MD[ @k, @x ] ); |
---|
1679 | if ( @max != 0 ) |
---|
1680 | { |
---|
1681 | @j = @k; |
---|
1682 | @min = @max; |
---|
1683 | // @k ++; |
---|
1684 | break; // this pure for |
---|
1685 | // continue; |
---|
1686 | // for find min |
---|
1687 | }; |
---|
1688 | }; // for (@k) // found minimal |
---|
1689 | |
---|
1690 | if ( @j == 0 ) |
---|
1691 | { |
---|
1692 | // das ist gut! // |
---|
1693 | @nums = @nums + list ( list ( @x, @y ) ); |
---|
1694 | @x ++; |
---|
1695 | continue; // while |
---|
1696 | } ; |
---|
1697 | |
---|
1698 | for ( @k = @x ; @k <= @v ; @k ++ ) |
---|
1699 | { |
---|
1700 | @t = MD[ @j, @k ]; |
---|
1701 | MD[ @j, @k ] = MD[ @y, @k ]; |
---|
1702 | MD[ @y, @k ] = @t; |
---|
1703 | }; |
---|
1704 | |
---|
1705 | }; // if diag === zero. |
---|
1706 | @ones[@y] = @x; |
---|
1707 | |
---|
1708 | if ( @min == 0 ) |
---|
1709 | { |
---|
1710 | // write_latex_str ( " ******************* ERROR ******************* " ); |
---|
1711 | quit; |
---|
1712 | }; |
---|
1713 | |
---|
1714 | |
---|
1715 | if ( @min != 1) // let's norm the row... to make the '1' ! |
---|
1716 | { |
---|
1717 | @min = 1 / @min; |
---|
1718 | for ( @k = @x; @k <= @v; @k++ ) |
---|
1719 | { |
---|
1720 | @max = leadcoef( MD[@y, @k] ); |
---|
1721 | |
---|
1722 | if ( @max == 0) |
---|
1723 | { |
---|
1724 | @k ++ ; |
---|
1725 | continue; // for : norming the row... |
---|
1726 | }; |
---|
1727 | |
---|
1728 | MD[@y, @k] = @max * @min; // here must be Field ... |
---|
1729 | }; |
---|
1730 | |
---|
1731 | // @min = 1; |
---|
1732 | |
---|
1733 | }; |
---|
1734 | |
---|
1735 | // here must be @min != 0; |
---|
1736 | for ( @k = 1; @k <= @n; @k++ ) |
---|
1737 | { |
---|
1738 | @max = leadcoef( MD[@k, @x] ); |
---|
1739 | |
---|
1740 | if ( ( @k == @y) || (@max == 0) ) |
---|
1741 | { |
---|
1742 | @k ++ ; |
---|
1743 | continue; |
---|
1744 | }; |
---|
1745 | |
---|
1746 | for ( @j = @x; @j <= @v ; @j ++ ) |
---|
1747 | { |
---|
1748 | MD[ @k, @j ] = MD[ @k, @j ] - @max * MD[ @y, @j ]; |
---|
1749 | }; |
---|
1750 | |
---|
1751 | }; //killing |
---|
1752 | |
---|
1753 | @x ++; |
---|
1754 | @y ++; |
---|
1755 | }; //main while. |
---|
1756 | /******************************************************/ |
---|
1757 | |
---|
1758 | // print("Gaussed Matrix: "); |
---|
1759 | // print( MD ); |
---|
1760 | |
---|
1761 | // computation of kernel's basis |
---|
1762 | |
---|
1763 | if ( @x <= @v ) |
---|
1764 | { |
---|
1765 | for ( @k = @x; @k <= @v ; @k ++ ) |
---|
1766 | { |
---|
1767 | @nums = @nums + list ( list ( @k, @n+1 ) ); |
---|
1768 | } |
---|
1769 | } |
---|
1770 | |
---|
1771 | // print("Nums: " ); |
---|
1772 | // print (@nums); |
---|
1773 | |
---|
1774 | list result = list(); |
---|
1775 | |
---|
1776 | // real calculations of the Base of a Ker as V.S. |
---|
1777 | |
---|
1778 | for ( @k = 1; @k <= size(@nums) ; @k ++ ) |
---|
1779 | { |
---|
1780 | @x = @nums[@k][1]; |
---|
1781 | @j = @nums[@k][2]; |
---|
1782 | |
---|
1783 | @t = @given[@x][1]; |
---|
1784 | |
---|
1785 | for ( @y = 1; @y < @j ; @y ++ ) |
---|
1786 | // for every "@x" column |
---|
1787 | { |
---|
1788 | @max = leadcoef( MD[@y, @x] ); |
---|
1789 | if ( (@max != 0) ) |
---|
1790 | { |
---|
1791 | @a = @ones[@y]; |
---|
1792 | @t = @t - @max * @given[@a][1]; |
---|
1793 | }; |
---|
1794 | }; |
---|
1795 | |
---|
1796 | result[@k] = @t; |
---|
1797 | }; |
---|
1798 | |
---|
1799 | ECall( "FSS", "list" ); |
---|
1800 | return ( result ); |
---|
1801 | }; |
---|
1802 | |
---|
1803 | /******************************************************/ |
---|
1804 | static proc reduce_one_per_row(list @given) |
---|
1805 | { |
---|
1806 | BCall( "reduce_one_per_row" ); |
---|
1807 | |
---|
1808 | int @k; |
---|
1809 | int @l = size (@given); |
---|
1810 | |
---|
1811 | if( @l == 0 ) |
---|
1812 | { |
---|
1813 | return (@given); |
---|
1814 | }; |
---|
1815 | |
---|
1816 | int @char = char(basering); |
---|
1817 | |
---|
1818 | intvec @marks; |
---|
1819 | |
---|
1820 | if ( @char == 0 ) |
---|
1821 | { |
---|
1822 | poly @t = poly(0); |
---|
1823 | }; |
---|
1824 | |
---|
1825 | list @unis = list (); |
---|
1826 | poly p; |
---|
1827 | |
---|
1828 | for ( @k = @l; @k > 0; @k -- ) |
---|
1829 | { |
---|
1830 | p = uni_poly( @given[@k][2] ); |
---|
1831 | @unis[@k] = p; |
---|
1832 | |
---|
1833 | if( p == 0 ) |
---|
1834 | { |
---|
1835 | @marks[@k] = 2; |
---|
1836 | } else |
---|
1837 | { |
---|
1838 | @marks[@k] = 1; |
---|
1839 | if ( @char == 0 ) |
---|
1840 | { |
---|
1841 | @t = @t + p; |
---|
1842 | }; |
---|
1843 | }; |
---|
1844 | }; |
---|
1845 | |
---|
1846 | if ( @char != 0 ) |
---|
1847 | { |
---|
1848 | def save = basering; |
---|
1849 | execute( "ring NewRingWithGoodField = (0), (" + varstr(save) + "), (" + ordstr(save) + "); "); |
---|
1850 | poly @t = 0; |
---|
1851 | |
---|
1852 | if(! defined (@unis) ) |
---|
1853 | { |
---|
1854 | list @unis = imap( save, @unis ); |
---|
1855 | }; |
---|
1856 | |
---|
1857 | for ( @k = @l; @k > 0; @k -- ) |
---|
1858 | { |
---|
1859 | if( @marks[@k] == 1 ) |
---|
1860 | { |
---|
1861 | @t = @t + @unis[@k]; |
---|
1862 | }; |
---|
1863 | }; |
---|
1864 | }; |
---|
1865 | |
---|
1866 | int @loop_size = size(@t); |
---|
1867 | poly @for_delete, @tt; |
---|
1868 | int @ll; |
---|
1869 | |
---|
1870 | while( @loop_size > 0 ) |
---|
1871 | { |
---|
1872 | @for_delete = poly(0); |
---|
1873 | @ll = size(@t); |
---|
1874 | |
---|
1875 | for ( @k = @ll; @k > 0; @k -- ) |
---|
1876 | { |
---|
1877 | if ( leadcoef(@t[@k]) == 1 ) |
---|
1878 | { |
---|
1879 | @for_delete = @for_delete + @t[@k]; |
---|
1880 | }; |
---|
1881 | }; |
---|
1882 | |
---|
1883 | @loop_size = size( @for_delete ); |
---|
1884 | |
---|
1885 | if ( @loop_size>0 ) |
---|
1886 | { |
---|
1887 | for( @k = @l ; @k > 0 ; @k -- ) |
---|
1888 | { |
---|
1889 | if ( @marks[@k] == 1) |
---|
1890 | { |
---|
1891 | @tt = @unis[@k]; |
---|
1892 | |
---|
1893 | if( size( @for_delete + @tt ) != ( size( @for_delete ) + size( @tt ) ) ) |
---|
1894 | { |
---|
1895 | @t = @t - @tt; |
---|
1896 | @marks[@k] = 0; |
---|
1897 | }; |
---|
1898 | }; |
---|
1899 | }; |
---|
1900 | }; |
---|
1901 | }; |
---|
1902 | |
---|
1903 | if ( @char != 0 ) |
---|
1904 | { |
---|
1905 | setring(save); |
---|
1906 | kill(NewRingWithGoodField); |
---|
1907 | }; |
---|
1908 | |
---|
1909 | list @reduced = list(); |
---|
1910 | |
---|
1911 | for ( @k = @l ; @k>0 ; @k --) |
---|
1912 | { |
---|
1913 | if (@marks[@k]==2) |
---|
1914 | { |
---|
1915 | @reduced = list ( @given[@k] ) + @reduced ; |
---|
1916 | } else |
---|
1917 | { |
---|
1918 | if (@marks[@k]==1) |
---|
1919 | { |
---|
1920 | @reduced = @reduced + list ( @given[@k] ); |
---|
1921 | }; |
---|
1922 | }; |
---|
1923 | }; |
---|
1924 | |
---|
1925 | ECall( "reduce_one_per_row", "structured list" ); |
---|
1926 | return (@reduced); |
---|
1927 | }; |
---|
1928 | |
---|
1929 | |
---|
1930 | |
---|
1931 | /******************************************************/ |
---|
1932 | static proc calc_base (list @AD_GIVEN) |
---|
1933 | " |
---|
1934 | sort out given 'pbw' into groups due to common monoms in images = ([2])s |
---|
1935 | " |
---|
1936 | { |
---|
1937 | BCall( "calc_base" ); |
---|
1938 | |
---|
1939 | list @AD_CALC = list(); |
---|
1940 | int @ll, @k, @j, @loop_size; |
---|
1941 | |
---|
1942 | poly @t = poly(0); |
---|
1943 | poly @tt, @for_delete; |
---|
1944 | |
---|
1945 | int @t_size; |
---|
1946 | |
---|
1947 | list @GR, @GR_TEMP; |
---|
1948 | |
---|
1949 | int @number = size(@AD_GIVEN); |
---|
1950 | |
---|
1951 | while ( @number > 0 ) |
---|
1952 | { |
---|
1953 | @tt = @AD_GIVEN[@number][2]; |
---|
1954 | if ( size (@tt) == 0) |
---|
1955 | { |
---|
1956 | @AD_CALC = @AD_CALC + list ( @AD_GIVEN[@number][1] ); |
---|
1957 | } else |
---|
1958 | { |
---|
1959 | @t = uni_poly( @tt ); |
---|
1960 | @t_size = size(@t); |
---|
1961 | |
---|
1962 | @GR_TEMP = list (); |
---|
1963 | @GR_TEMP[1] = @t; |
---|
1964 | @GR_TEMP[2] = list ( @AD_GIVEN[@number] ); |
---|
1965 | |
---|
1966 | @loop_size = size(@GR); |
---|
1967 | if ( @loop_size == 0 ) |
---|
1968 | { |
---|
1969 | @GR = list(@GR_TEMP); |
---|
1970 | } else |
---|
1971 | { |
---|
1972 | for ( @k = @loop_size; @k > 0 ; @k -- ) |
---|
1973 | { |
---|
1974 | @tt = @GR[@k][1]; |
---|
1975 | if ( size( @t + @tt ) != ( @t_size + size(@tt) ) ) |
---|
1976 | // whether @tt and @i intersencts? ( will not work in char == 2 !!!) |
---|
1977 | { |
---|
1978 | |
---|
1979 | if ( char(basering) == 0 ) |
---|
1980 | { |
---|
1981 | @GR_TEMP[1] = @GR_TEMP[1] + @tt; |
---|
1982 | } else |
---|
1983 | { |
---|
1984 | @GR_TEMP[1] = uni_poly( @GR_TEMP[1] + @tt ); |
---|
1985 | }; |
---|
1986 | |
---|
1987 | @GR_TEMP[2] = @GR_TEMP[2] + @GR[@k][2]; |
---|
1988 | @GR = delete ( @GR, @k ); |
---|
1989 | }; |
---|
1990 | }; |
---|
1991 | @GR = @GR + list(@GR_TEMP); |
---|
1992 | }; |
---|
1993 | }; |
---|
1994 | @number --; |
---|
1995 | }; // main while |
---|
1996 | |
---|
1997 | list @res; |
---|
1998 | |
---|
1999 | for ( @k = size(@GR); @k > 0 ; @k -- ) |
---|
2000 | { |
---|
2001 | if ( size (@GR[@k][2]) > 1 ) // ! zeroes in AD_CALC so here must be non zero |
---|
2002 | { |
---|
2003 | @res = FSS ( @GR[@k][2], uni_poly(@GR[@k][1])); |
---|
2004 | |
---|
2005 | if ( size (@res) > 0 ) |
---|
2006 | { |
---|
2007 | @AD_CALC = @AD_CALC + @res; |
---|
2008 | }; |
---|
2009 | }; |
---|
2010 | }; |
---|
2011 | |
---|
2012 | ECall( "calc_base" ); |
---|
2013 | return (@AD_CALC); |
---|
2014 | |
---|
2015 | }; |
---|
2016 | |
---|
2017 | |
---|
2018 | /******************************************************/ |
---|
2019 | static proc ApplyAd( list l, list # ) |
---|
2020 | " |
---|
2021 | Apply Ad_{#} to every element of a list of polynomils |
---|
2022 | " |
---|
2023 | { |
---|
2024 | BCall( "ApplyAd", l, # ); |
---|
2025 | |
---|
2026 | if( (size(l) == 0) or (size(#) == 0) ) |
---|
2027 | { |
---|
2028 | return (l); |
---|
2029 | }; |
---|
2030 | |
---|
2031 | poly f, t; |
---|
2032 | |
---|
2033 | if ( typeof(#[1]) == "int") |
---|
2034 | { |
---|
2035 | int next = #[1]; |
---|
2036 | f = my_var (next); |
---|
2037 | } else |
---|
2038 | { |
---|
2039 | if ( typeof(#[1]) == "poly") |
---|
2040 | { |
---|
2041 | f = #[1]; |
---|
2042 | } else |
---|
2043 | { |
---|
2044 | print("Error: cannot differentiate with '" + string(#)+"'"); |
---|
2045 | return (); |
---|
2046 | }; |
---|
2047 | }; |
---|
2048 | |
---|
2049 | for ( int k = size(l); k > 0; k --) |
---|
2050 | { |
---|
2051 | t = l[k]; |
---|
2052 | l[k] = list( t, f * t - t * f ); |
---|
2053 | }; |
---|
2054 | |
---|
2055 | ECall("ApplyAd", l ); |
---|
2056 | return (l); |
---|
2057 | }; |
---|
2058 | |
---|
2059 | |
---|
2060 | /******************************************************/ |
---|
2061 | static proc calc_k_base (list l, list #) |
---|
2062 | " |
---|
2063 | calculation of Kernel of an Ad operator as a K-Vector Space |
---|
2064 | " |
---|
2065 | { |
---|
2066 | BCall( "calc_k_base", "list, " + string(#) ); |
---|
2067 | |
---|
2068 | list t = reduce_one_per_row( l, 0); // optimization (a1) |
---|
2069 | return( QNF_list ( ApplyAd( calc_base(t), # ), 2) ); // calculation of groupps (a2) + gauss. |
---|
2070 | |
---|
2071 | }; |
---|
2072 | |
---|
2073 | LIB "poly.lib"; // for content in proc makeIdeal |
---|
2074 | |
---|
2075 | /******************************************************/ |
---|
2076 | static proc makeIdeal ( list l ) |
---|
2077 | " |
---|
2078 | return: ideal: where the generators are polynomials from list, without 1 and zeroes |
---|
2079 | " |
---|
2080 | { |
---|
2081 | ideal I; poly p; |
---|
2082 | |
---|
2083 | for( int i = 1; i <= size(l); i++ ) |
---|
2084 | { |
---|
2085 | if ( typeof( l[i] ) == "list" ) |
---|
2086 | { |
---|
2087 | p = l[i][1]; // just take the 1st polynom... |
---|
2088 | } else |
---|
2089 | { |
---|
2090 | p = l[i]; |
---|
2091 | }; |
---|
2092 | |
---|
2093 | p = cleardenom( p* (1/content(p)) ); |
---|
2094 | if ( (p != 1) and (p != 0) ) |
---|
2095 | { |
---|
2096 | I = I, p; |
---|
2097 | }; |
---|
2098 | }; |
---|
2099 | |
---|
2100 | I = simplify ( I, 2 ); // no zeroes |
---|
2101 | |
---|
2102 | return(I); |
---|
2103 | }; |
---|
2104 | |
---|
2105 | /******************************************************/ |
---|
2106 | static proc inCenter_poly( poly p ) |
---|
2107 | " |
---|
2108 | if p in center => return 1 |
---|
2109 | otherwise return 0 |
---|
2110 | " |
---|
2111 | { |
---|
2112 | poly t; |
---|
2113 | for (int k = nvars(basering); k>0; k-- ) |
---|
2114 | { |
---|
2115 | t = var(k); |
---|
2116 | if ( QNF_poly(t * p - p * t) != 0 ) |
---|
2117 | { |
---|
2118 | if( toprint() ) |
---|
2119 | { |
---|
2120 | "POLY: ", string (p), " is NOT in center"; |
---|
2121 | }; |
---|
2122 | return (0); |
---|
2123 | }; |
---|
2124 | }; |
---|
2125 | |
---|
2126 | if( toprint() ) |
---|
2127 | { |
---|
2128 | "POLY: ", string (p), " is in center"; |
---|
2129 | }; |
---|
2130 | return (1); |
---|
2131 | }; |
---|
2132 | |
---|
2133 | /******************************************************/ |
---|
2134 | static proc inCenter_list(def l) |
---|
2135 | { |
---|
2136 | for ( int @i = 1; @i <= size(l); @i++ ) |
---|
2137 | { |
---|
2138 | if ( typeof(l[@i])=="poly" ) |
---|
2139 | { |
---|
2140 | if (! inCenter_poly(l[@i]) ) |
---|
2141 | { |
---|
2142 | return(0); |
---|
2143 | }; |
---|
2144 | |
---|
2145 | } else |
---|
2146 | { |
---|
2147 | if ( (typeof(l[@i])=="list") or (typeof(l[@i])=="ideal") ) |
---|
2148 | { |
---|
2149 | if (! inCenter_list(l[@i]) ) |
---|
2150 | { |
---|
2151 | return(0); |
---|
2152 | }; |
---|
2153 | }; |
---|
2154 | }; |
---|
2155 | }; |
---|
2156 | return(1); |
---|
2157 | }; |
---|
2158 | |
---|
2159 | /******************************************************/ |
---|
2160 | static proc inCentralizer_poly( poly p, poly f ) |
---|
2161 | " |
---|
2162 | if p in centralizer(f) => return 1 |
---|
2163 | otherwise return 0 |
---|
2164 | " |
---|
2165 | { |
---|
2166 | if ( QNF_poly(f * p - p * f) != 0 ) |
---|
2167 | { |
---|
2168 | if( toprint() ) |
---|
2169 | { |
---|
2170 | "POLY: ", string (p), " is NOT in centralizer(f)"; |
---|
2171 | }; |
---|
2172 | return (0); |
---|
2173 | }; |
---|
2174 | |
---|
2175 | if( toprint() ) |
---|
2176 | { |
---|
2177 | "POLY: ", string (p), " is in centralizer(f)"; |
---|
2178 | }; |
---|
2179 | return (1); |
---|
2180 | }; |
---|
2181 | |
---|
2182 | /******************************************************/ |
---|
2183 | static proc inCentralizer_list( def l, poly f ) |
---|
2184 | { |
---|
2185 | for ( int @i = 1; @i <= size(l); @i++ ) |
---|
2186 | { |
---|
2187 | if ( typeof(l[@i])=="poly" ) |
---|
2188 | { |
---|
2189 | if (! inCentralizer_poly(l[@i], f) ) |
---|
2190 | { |
---|
2191 | return(0); |
---|
2192 | }; |
---|
2193 | |
---|
2194 | } else |
---|
2195 | { |
---|
2196 | if ( (typeof(l[@i])=="list") or (typeof(l[@i])=="ideal") ) |
---|
2197 | { |
---|
2198 | if (! inCentralizer_list(l[@i], f) ) |
---|
2199 | { |
---|
2200 | return(0); |
---|
2201 | }; |
---|
2202 | }; |
---|
2203 | }; |
---|
2204 | }; |
---|
2205 | return(1); |
---|
2206 | }; |
---|
2207 | |
---|
2208 | |
---|
2209 | /******************************************************/ |
---|
2210 | /******************************************************/ |
---|
2211 | // main algorithms |
---|
2212 | |
---|
2213 | |
---|
2214 | /******************************************************/ |
---|
2215 | /******************************************************/ |
---|
2216 | // center's computation |
---|
2217 | |
---|
2218 | /******************************************************/ |
---|
2219 | /* static */ proc center_min_iterative( int MaxDeg, list # ) |
---|
2220 | " |
---|
2221 | computes the 'minimal' set of central elements (of deg <= MaxDeg) in iterative way |
---|
2222 | Note: based on calc_k_base, zAddBad, zRefine, zCancel, PBW_* |
---|
2223 | " |
---|
2224 | { |
---|
2225 | BCall("center_min_iterative", MaxDeg, #); |
---|
2226 | |
---|
2227 | int n = myInt(#); |
---|
2228 | int m = ( MaxDeg < 0 ); // no bound on Degree |
---|
2229 | |
---|
2230 | int MinDeg = 6; // starting guess for MaxDeg |
---|
2231 | int Delta = 4; // increment of MaxDeg |
---|
2232 | |
---|
2233 | if( m ) |
---|
2234 | { |
---|
2235 | // minimal guess |
---|
2236 | MaxDeg = MinDeg; |
---|
2237 | }; |
---|
2238 | |
---|
2239 | list @q; int @i; int N = nvars(basering); |
---|
2240 | |
---|
2241 | my_var_init(); // setup for my_var(n) |
---|
2242 | QNF_init(); |
---|
2243 | |
---|
2244 | list PBW = list(); |
---|
2245 | list PBW_PLAIN = list(); |
---|
2246 | |
---|
2247 | PBW[ index(0) ] = PBW_init(); |
---|
2248 | |
---|
2249 | list SYS = PBW_sys( my_vars(), my_var(1) ); |
---|
2250 | |
---|
2251 | |
---|
2252 | list @z = list (); // center list |
---|
2253 | list @l = init_bads( MaxDeg ); // verbotten leadexps... |
---|
2254 | |
---|
2255 | @q = PBW[ index(0) ]; |
---|
2256 | |
---|
2257 | int k = 1; |
---|
2258 | while( k <= ( MaxDeg+1 ) ) |
---|
2259 | { |
---|
2260 | for ( @i = 2; @i <= N; @i ++ ) |
---|
2261 | { |
---|
2262 | @q = calc_k_base (@q, my_var(@i)); |
---|
2263 | }; |
---|
2264 | |
---|
2265 | @q = zRefine (calc_k_base(@q)); // new center! |
---|
2266 | |
---|
2267 | |
---|
2268 | if ( size(@q) > 0 ) |
---|
2269 | { |
---|
2270 | @z = @z + @q; // computed central elements |
---|
2271 | |
---|
2272 | if( (n > 0) and (size(@z) > n) ) |
---|
2273 | { |
---|
2274 | break; // found all central elements |
---|
2275 | }; |
---|
2276 | }; |
---|
2277 | |
---|
2278 | if( k == ( MaxDeg+1 ) ) |
---|
2279 | { |
---|
2280 | if( (n == 0) and ( !m ) ) |
---|
2281 | { |
---|
2282 | break; // that's all |
---|
2283 | }; |
---|
2284 | |
---|
2285 | MaxDeg = MaxDeg + Delta; |
---|
2286 | |
---|
2287 | // renew bad list |
---|
2288 | @l = init_bads( MaxDeg ); |
---|
2289 | @l = zAddBad( @l, @z, MaxDeg, 0 ); |
---|
2290 | |
---|
2291 | } else |
---|
2292 | { |
---|
2293 | |
---|
2294 | if ( size(@q) > 0 ) |
---|
2295 | { |
---|
2296 | @l = zAddBad( @l, @q, MaxDeg, 0 ); // add all possible 'leadexps' ! |
---|
2297 | }; |
---|
2298 | |
---|
2299 | }; |
---|
2300 | |
---|
2301 | PBW[index(k)] = PBW_next( PBW, k, SYS ); |
---|
2302 | |
---|
2303 | PBW_PLAIN = PBW_PLAIN + zCancel( PBW[index(k-1)] , @l ); |
---|
2304 | |
---|
2305 | @q = PBW_PLAIN + zCancel( PBW[index(k)] , @l ); // kill from @tt all entries with leadexp in @l[@d] |
---|
2306 | |
---|
2307 | k ++; |
---|
2308 | }; |
---|
2309 | |
---|
2310 | QNF_done(); |
---|
2311 | my_var_done(); |
---|
2312 | |
---|
2313 | return (makeIdeal(@z)); |
---|
2314 | }; |
---|
2315 | |
---|
2316 | /******************************************************/ |
---|
2317 | static proc center_vectorspace( int MaxDeg ) |
---|
2318 | " |
---|
2319 | pure calculation of center as a finitely dimensional Vector Space (deg <= MaxDeg ) |
---|
2320 | " |
---|
2321 | { |
---|
2322 | my_var_init(); |
---|
2323 | |
---|
2324 | int N = nvars( basering ); |
---|
2325 | list P = PBW_base( MaxDeg, my_var(1) ); |
---|
2326 | |
---|
2327 | for( int v = 2; v <= N; v++ ) |
---|
2328 | { |
---|
2329 | P = calc_k_base( P, my_var(v) ); |
---|
2330 | }; |
---|
2331 | |
---|
2332 | my_var_done(); |
---|
2333 | |
---|
2334 | return( calc_k_base ( P ) ); |
---|
2335 | }; |
---|
2336 | |
---|
2337 | /******************************************************/ |
---|
2338 | /* static */ proc center_min_vectorspace( int MaxDeg ) |
---|
2339 | " |
---|
2340 | computes the 'minimal' set of central elements (of deg <= MaxDeg) |
---|
2341 | by reducing the set of it's generators as vector space |
---|
2342 | |
---|
2343 | Note: based on center_vectorspace. |
---|
2344 | Note: reduction by zReduce. |
---|
2345 | " |
---|
2346 | { |
---|
2347 | |
---|
2348 | QNF_init(); |
---|
2349 | ideal res = makeIdeal( zReduce( center_vectorspace( MaxDeg))); |
---|
2350 | QNF_done(); |
---|
2351 | |
---|
2352 | return( res ); |
---|
2353 | }; |
---|
2354 | |
---|
2355 | |
---|
2356 | /******************************************************/ |
---|
2357 | /******************************************************/ |
---|
2358 | // centralizer's computations |
---|
2359 | |
---|
2360 | /******************************************************/ |
---|
2361 | static proc centralizer_vectorspace( poly p, int MaxDeg ) |
---|
2362 | { |
---|
2363 | return( calc_k_base( PBW_base( MaxDeg, p ))); |
---|
2364 | }; |
---|
2365 | |
---|
2366 | /******************************************************/ |
---|
2367 | /* static */ proc centralizer_min_vectorspace( poly p, int MaxDeg ) |
---|
2368 | { |
---|
2369 | |
---|
2370 | QNF_init(); |
---|
2371 | ideal res = makeIdeal( zReduce( centralizer_vectorspace( p, MaxDeg))); |
---|
2372 | QNF_done(); |
---|
2373 | |
---|
2374 | return( res ); |
---|
2375 | }; |
---|
2376 | |
---|
2377 | /******************************************************/ |
---|
2378 | /* static */ proc centralizer_min_iterative( poly p, int MaxDeg, list # ) |
---|
2379 | " |
---|
2380 | computes the 'minimal' set of elements (of deg <= MaxDeg) generating centralizer of p in iterative way |
---|
2381 | Note: based on calc_k_base |
---|
2382 | |
---|
2383 | !!! NEED DEBUG !!! |
---|
2384 | Note: no proof that it is really centralizer and moreover 'minimal' centralizer |
---|
2385 | " |
---|
2386 | { |
---|
2387 | QNF_init(); |
---|
2388 | |
---|
2389 | int n = myInt(#); |
---|
2390 | int m = (MaxDeg < 0); |
---|
2391 | |
---|
2392 | int MinDeg = 6; // starting guess for MaxDeg |
---|
2393 | int Delta = 4; // increment of MaxDeg |
---|
2394 | |
---|
2395 | if( m ) |
---|
2396 | { |
---|
2397 | // minimal guess |
---|
2398 | MaxDeg = MinDeg; |
---|
2399 | }; |
---|
2400 | |
---|
2401 | list @q; |
---|
2402 | |
---|
2403 | list PBW = list(); |
---|
2404 | list PBW_PLAIN = list(); |
---|
2405 | |
---|
2406 | PBW[ index(0) ] = PBW_init(); |
---|
2407 | |
---|
2408 | list SYS = PBW_sys( my_vars(), p ); |
---|
2409 | |
---|
2410 | list @z = list (); // result list |
---|
2411 | list @l = init_bads( MaxDeg ); // verbotten loeadexps... |
---|
2412 | |
---|
2413 | @q = PBW[ index(0) ]; |
---|
2414 | |
---|
2415 | for (int k = 1; k <= ( MaxDeg+1 ); k ++ ) |
---|
2416 | { |
---|
2417 | @q = zRefine( calc_k_base(@q), 1 ); |
---|
2418 | |
---|
2419 | if ( size(@q) > 0 ) |
---|
2420 | { |
---|
2421 | @z = @z + @q; // computed desired elements |
---|
2422 | |
---|
2423 | if( (n > 0) and (size(@z) > n) ) |
---|
2424 | { |
---|
2425 | break; // found needed elements |
---|
2426 | }; |
---|
2427 | }; |
---|
2428 | |
---|
2429 | if( k == ( MaxDeg+1 ) ) |
---|
2430 | { |
---|
2431 | if( (n == 0) or ( !m ) ) |
---|
2432 | { |
---|
2433 | break; // that's all |
---|
2434 | }; |
---|
2435 | |
---|
2436 | MaxDeg = MaxDeg + Delta; |
---|
2437 | |
---|
2438 | // renew bad list |
---|
2439 | @l = init_bads( MaxDeg ); |
---|
2440 | @l = zAddBad( @l, @z, MaxDeg, 0 ); |
---|
2441 | |
---|
2442 | } else |
---|
2443 | { |
---|
2444 | |
---|
2445 | if ( size(@q) > 0 ) |
---|
2446 | { |
---|
2447 | @l = zAddBad( @l, @q, MaxDeg, 0 ); // add all possible 'leadexps' ! |
---|
2448 | }; |
---|
2449 | |
---|
2450 | }; |
---|
2451 | |
---|
2452 | PBW[index(k)] = PBW_next( PBW, k, SYS ); |
---|
2453 | PBW_PLAIN = PBW_PLAIN + zCancel( PBW[index(k-1)] , @l ); |
---|
2454 | @q = PBW_PLAIN + zCancel( PBW[index(k)] , @l ); // kill from @tt all entries with leadexp in @l[@d] |
---|
2455 | |
---|
2456 | }; |
---|
2457 | |
---|
2458 | QNF_done(); |
---|
2459 | return (makeIdeal(@z)); |
---|
2460 | }; |
---|
2461 | |
---|
2462 | |
---|
2463 | |
---|
2464 | /******************************************************/ |
---|
2465 | /******************************************************/ |
---|
2466 | // main aliases |
---|
2467 | |
---|
2468 | /******************************************************/ |
---|
2469 | proc inCenter( def a ) |
---|
2470 | "USAGE: inCenter(a); a poly/list/ideal |
---|
2471 | RETURN: integer (1 if a in the center, 0 otherwise) |
---|
2472 | EXAMPLE: example inCenter; shows examples" |
---|
2473 | { |
---|
2474 | QNF_init(); |
---|
2475 | def res; |
---|
2476 | |
---|
2477 | if ( typeof(a) == "poly" ) |
---|
2478 | { |
---|
2479 | res = inCenter_poly(a); |
---|
2480 | } else |
---|
2481 | { |
---|
2482 | if ( (typeof(a)=="list") or (typeof(a)=="ideal") ) |
---|
2483 | { |
---|
2484 | res = inCenter_list(a); |
---|
2485 | } else |
---|
2486 | { |
---|
2487 | res = a; |
---|
2488 | }; |
---|
2489 | }; |
---|
2490 | |
---|
2491 | QNF_done(); |
---|
2492 | return (res); |
---|
2493 | } |
---|
2494 | example |
---|
2495 | { |
---|
2496 | "EXAMPLE:";echo=2; |
---|
2497 | ring r=0,(x,y,z),dp; |
---|
2498 | matrix D[3][3]=0; |
---|
2499 | D[1,2]=-z; |
---|
2500 | D[1,3]=2*x; |
---|
2501 | D[2,3]=-2*y; |
---|
2502 | ncalgebra(1,D); // this is U(sl_2) |
---|
2503 | poly p=4*x*y+z^2-2*z; |
---|
2504 | inCenter(p); |
---|
2505 | poly f=4*x*y; |
---|
2506 | inCenter(f); |
---|
2507 | list l= list( 1, p, p^2, p^3); |
---|
2508 | inCenter(l); |
---|
2509 | ideal I= p, f; |
---|
2510 | inCenter(I); |
---|
2511 | }; |
---|
2512 | |
---|
2513 | |
---|
2514 | /******************************************************************************/ |
---|
2515 | proc inCentralizer( def a, poly f ) |
---|
2516 | "USAGE: inCentralizer(a, f); a poly/list/ideal, f poly |
---|
2517 | RETURN: integer (1 if a in the centralizer(f), 0 otherwise) |
---|
2518 | EXAMPLE: example inCentralizer; shows examples" |
---|
2519 | { |
---|
2520 | QNF_init(); |
---|
2521 | def res; |
---|
2522 | |
---|
2523 | if ( typeof(a) == "poly" ) |
---|
2524 | { |
---|
2525 | res = inCentralizer_poly(a, f); |
---|
2526 | } else |
---|
2527 | { |
---|
2528 | if ( (typeof(a)=="list") or (typeof(a)=="ideal") ) |
---|
2529 | { |
---|
2530 | res = inCentralizer_list(a, f); |
---|
2531 | } else |
---|
2532 | { |
---|
2533 | res = a; |
---|
2534 | }; |
---|
2535 | }; |
---|
2536 | |
---|
2537 | QNF_done(); |
---|
2538 | return (res); |
---|
2539 | } |
---|
2540 | example |
---|
2541 | { |
---|
2542 | "EXAMPLE:";echo=2; |
---|
2543 | ring r=0,(x,y,z),dp; |
---|
2544 | matrix D[3][3]=0; |
---|
2545 | D[1,2]=-z; |
---|
2546 | ncalgebra(1,D); // the Heisenberg algebra |
---|
2547 | poly f = x^2; |
---|
2548 | poly a = z; // lies in center |
---|
2549 | poly b = y^2; |
---|
2550 | inCentralizer(a, f); |
---|
2551 | inCentralizer(b, f); |
---|
2552 | list l = list(1, a); |
---|
2553 | inCentralizer(l, f); |
---|
2554 | ideal I = a, b; |
---|
2555 | inCentralizer(I, f); |
---|
2556 | }; |
---|
2557 | |
---|
2558 | /******************************************************/ |
---|
2559 | proc center(int MaxDeg, list # ) |
---|
2560 | "USAGE: center(MaxDeg[, N]); int MaxDeg, int N |
---|
2561 | RETURN: ideal generated by found elements |
---|
2562 | NOTE: computes the 'minimal' set of central elements. |
---|
2563 | Since in general algorithms knows nothing about the number and degrees of |
---|
2564 | desired polynomials one have to specify any kind of termination condition: |
---|
2565 | 1. MaxDeg - maximal degree of desired elements or/and |
---|
2566 | 2. n - the minimal number of desired elements to find. |
---|
2567 | SEE ALSO: centralizer; inCenter |
---|
2568 | EXAMPLE: example center; shows an example |
---|
2569 | " |
---|
2570 | { |
---|
2571 | if ( myInt(#) > 0 ) // given a number of central elements to compute |
---|
2572 | { |
---|
2573 | return ( center_min_iterative( MaxDeg, # ) ); |
---|
2574 | }; |
---|
2575 | |
---|
2576 | if( MaxDeg >= 0 ) // standard computation - the fastest one (often) |
---|
2577 | { |
---|
2578 | // return ( center_min_iterative( MaxDeg, # ) ); |
---|
2579 | return ( center_min_vectorspace ( MaxDeg ) ); |
---|
2580 | }; |
---|
2581 | |
---|
2582 | print( "Error: wrong arguments." ); |
---|
2583 | return(); |
---|
2584 | |
---|
2585 | } |
---|
2586 | example |
---|
2587 | { "EXAMPLE:"; echo = 2; |
---|
2588 | ring a=0,(x,y,z),dp; |
---|
2589 | matrix D[3][3]=0; |
---|
2590 | D[1,2]=-z; |
---|
2591 | D[1,3]=2*x; |
---|
2592 | D[2,3]=-2*y; |
---|
2593 | ncalgebra(1,D); // this is U(sl_2) |
---|
2594 | ideal Z = center(2); // find all central elements of degree <= 2 |
---|
2595 | Z; |
---|
2596 | inCenter(Z); |
---|
2597 | ideal ZZ = center(-1, 1 ); // find the first non trivial central element |
---|
2598 | ZZ; ""; |
---|
2599 | inCenter(ZZ); |
---|
2600 | }; |
---|
2601 | |
---|
2602 | |
---|
2603 | /******************************************************/ |
---|
2604 | proc centralizer( poly p, int MaxDeg, list # ) |
---|
2605 | "USAGE: centralizer(F, MaxDeg[, N]); poly F, int MaxDeg, int N |
---|
2606 | RETURN: ideal generated by found elements |
---|
2607 | NOTE: computes the 'minimal' set of elements of centralizer(F). |
---|
2608 | Since in general algorithms knows nothing about the number and degrees of |
---|
2609 | desired polynomials one have to specify any kind of termination condition: |
---|
2610 | 1. MaxDeg - maximal degree of desired elements or/and |
---|
2611 | 2. n - the minimal number of desired elements to find. |
---|
2612 | SEE ALSO: center; inCentralizer |
---|
2613 | EXAMPLE: example centralizer; shows an example" |
---|
2614 | { |
---|
2615 | |
---|
2616 | if( myInt(#) > 0 ) |
---|
2617 | { |
---|
2618 | return( centralizer_min_iterative( p, MaxDeg, # ) ); |
---|
2619 | }; |
---|
2620 | |
---|
2621 | if( MaxDeg >= 0 ) |
---|
2622 | { |
---|
2623 | // return( centralizer_min_iterative( p, MaxDeg, # ) ); |
---|
2624 | return( centralizer_min_vectorspace( p, MaxDeg ) ); |
---|
2625 | }; |
---|
2626 | |
---|
2627 | print( "Error: wrong arguments." ); |
---|
2628 | return(); |
---|
2629 | |
---|
2630 | } |
---|
2631 | example |
---|
2632 | { "EXAMPLE:"; echo = 2; |
---|
2633 | ring a=0,(x,y,z),dp; |
---|
2634 | matrix D[3][3]=0; |
---|
2635 | D[1,2]=-z; |
---|
2636 | D[1,3]=2*x; |
---|
2637 | D[2,3]=-2*y; |
---|
2638 | ncalgebra(1,D); // this is U(sl_2) |
---|
2639 | poly f = 4*x*y+z^2-2*z; // central polynomial |
---|
2640 | f; |
---|
2641 | ideal c = centralizer(f, 2); // find all elements of degree <= 2 which lies in centralizer of f |
---|
2642 | c; |
---|
2643 | inCentralizer(c, f); |
---|
2644 | ideal cc = centralizer(f, -1, 2 ); // find at least first two non trivial elements of the centralizer of f |
---|
2645 | cc; |
---|
2646 | inCentralizer(cc, f); |
---|
2647 | poly g = z^2-2*z; // any polynomial |
---|
2648 | g; ""; |
---|
2649 | c = centralizer(g, 2); // find all elements of degree <= 2 which lies in centralizer of g |
---|
2650 | c; ""; |
---|
2651 | inCentralizer(c, g); |
---|
2652 | cc = centralizer(g, -1, 2 ); // find at least first two non trivial elements of the centralizer of g |
---|
2653 | cc; ""; |
---|
2654 | inCentralizer(cc, g); |
---|
2655 | }; |
---|