001 /*
002 * $Id: SolvableGroebnerBaseSeq.java 3652 2011-06-02 18:17:04Z kredel $
003 */
004
005 package edu.jas.gb;
006
007 import java.util.ArrayList;
008 import java.util.List;
009 import java.util.ListIterator;
010
011 import org.apache.log4j.Logger;
012
013 import edu.jas.structure.RingElem;
014 import edu.jas.poly.ExpVector;
015 import edu.jas.poly.GenPolynomial;
016 import edu.jas.poly.GenSolvablePolynomial;
017 import edu.jas.poly.GenSolvablePolynomialRing;
018 import edu.jas.poly.PolynomialList;
019
020
021 /**
022 * Solvable Groebner bases sequential algorithms.
023 * Implements common left, right and twosided Groebner bases
024 * and left, right and twosided GB tests.
025 * @param <C> coefficient type
026 * @author Heinz Kredel.
027 */
028
029 public class SolvableGroebnerBaseSeq<C extends RingElem<C>>
030 extends SolvableGroebnerBaseAbstract<C> {
031
032 private static final Logger logger = Logger.getLogger(SolvableGroebnerBaseSeq.class);
033
034 private final boolean debug = logger.isDebugEnabled();
035
036
037 /**
038 * Constructor.
039 */
040 public SolvableGroebnerBaseSeq() {
041 super();
042 }
043
044
045 /**
046 * Constructor.
047 * @param sred Solvable reduction engine
048 * @param pl pair selection strategy
049 */
050 public SolvableGroebnerBaseSeq(SolvableReduction<C> sred,
051 PairList<C> pl) {
052 super(sred,pl);
053 }
054
055
056 /**
057 * Left Groebner base using pairlist class.
058 * @param modv number of module variables.
059 * @param F solvable polynomial list.
060 * @return leftGB(F) a left Groebner base of F.
061 */
062 public List<GenSolvablePolynomial<C>>
063 leftGB(int modv,
064 List<GenSolvablePolynomial<C>> F) {
065 List<GenSolvablePolynomial<C>> G
066 = new ArrayList<GenSolvablePolynomial<C>>();
067 PairList<C> pairlist = null;
068 int l = F.size();
069 // ListIterator it = F.listIterator();
070 for ( GenSolvablePolynomial<C> p: F ) {
071 // p = (SolvablePolynomial) it.next();
072 if ( p.length() > 0 ) {
073 p = (GenSolvablePolynomial<C>)p.monic();
074 if ( p.isONE() ) {
075 G.clear(); G.add( p );
076 return G; // since no threads are activated
077 }
078 G.add( p );
079 if ( pairlist == null ) {
080 //pairlist = new OrderedPairlist<C>( modv, p.ring );
081 pairlist = strategy.create( modv, p.ring );
082 }
083 // putOne not required
084 pairlist.put( p );
085 } else {
086 l--;
087 }
088 }
089 if ( l <= 1 ) {
090 return G; // since no threads are activated
091 }
092
093 GenSolvablePolynomial<C> pi, pj, S, H;
094 Pair<C> pair;
095 while ( pairlist.hasNext() ) {
096 pair = pairlist.removeNext();
097 if ( pair == null ) {
098 continue;
099 }
100 pi = (GenSolvablePolynomial<C>)pair.pi;
101 pj = (GenSolvablePolynomial<C>)pair.pj;
102 if ( false && debug ) {
103 logger.info("pi = " + pi );
104 logger.info("pj = " + pj );
105 }
106
107 S = sred.leftSPolynomial( pi, pj );
108 if ( S.isZERO() ) {
109 pair.setZero();
110 continue;
111 }
112 if ( false && debug ) {
113 logger.info("ht(S) = " + S.leadingExpVector() );
114 }
115
116 H = sred.leftNormalform( G, S );
117 if ( H.isZERO() ) {
118 pair.setZero();
119 continue;
120 }
121 if ( false && debug ) {
122 logger.info("ht(H) = " + H.leadingExpVector() );
123 }
124
125 H = (GenSolvablePolynomial<C>)H.monic();
126 if ( H.isONE() ) {
127 G.clear(); G.add( H );
128 return G; // since no threads are activated
129 }
130 if ( debug ) {
131 logger.info("H = " + H );
132 }
133 if ( H.length() > 0 ) {
134 l++;
135 G.add( H );
136 pairlist.put( H );
137 }
138 }
139 logger.debug("#sequential list = "+G.size());
140 G = leftMinimalGB(G);
141 logger.info("" + pairlist);
142 return G;
143 }
144
145
146 /**
147 * Solvable Extended Groebner base using critical pair class.
148 * @param modv module variable number.
149 * @param F solvable polynomial list.
150 * @return a container for an extended left Groebner base of F.
151 */
152 public SolvableExtendedGB<C>
153 extLeftGB( int modv,
154 List<GenSolvablePolynomial<C>> F ) {
155
156 List<GenSolvablePolynomial<C>> G = new ArrayList<GenSolvablePolynomial<C>>();
157 List<List<GenSolvablePolynomial<C>>> F2G = new ArrayList<List<GenSolvablePolynomial<C>>>();
158 List<List<GenSolvablePolynomial<C>>> G2F = new ArrayList<List<GenSolvablePolynomial<C>>>();
159 PairList<C> pairlist = null;
160 boolean oneInGB = false;
161 int len = F.size();
162
163 List<GenSolvablePolynomial<C>> row = null;
164 List<GenSolvablePolynomial<C>> rows = null;
165 List<GenSolvablePolynomial<C>> rowh = null;
166 GenSolvablePolynomialRing<C> ring = null;
167 GenSolvablePolynomial<C> H;
168 GenSolvablePolynomial<C> p;
169
170 int nzlen = 0;
171 for ( GenSolvablePolynomial<C> f : F ) {
172 if ( f.length() > 0 ) {
173 nzlen++;
174 }
175 if ( ring == null ) {
176 ring = f.ring;
177 }
178 }
179 GenSolvablePolynomial<C> mone = ring.getONE(); //.negate();
180 int k = 0;
181 ListIterator<GenSolvablePolynomial<C>> it = F.listIterator();
182 while ( it.hasNext() ) {
183 p = it.next();
184 if ( p.length() > 0 ) {
185 row = new ArrayList<GenSolvablePolynomial<C>>( nzlen );
186 for ( int j = 0; j < nzlen; j++ ) {
187 row.add(null);
188 }
189 //C c = p.leadingBaseCoefficient();
190 //c = c.inverse();
191 //p = p.multiply( c );
192 row.set( k, mone ); //.multiply(c) );
193 k++;
194 if ( p.isUnit() ) {
195 G.clear(); G.add( p );
196 G2F.clear(); G2F.add( row );
197 oneInGB = true;
198 break;
199 }
200 G.add( p );
201 G2F.add( row );
202 if ( pairlist == null ) {
203 //pairlist = new CriticalPairList<C>( modv, p.ring );
204 pairlist = strategy.create( modv, p.ring );
205 }
206 // putOne not required
207 pairlist.put( p );
208 } else {
209 len--;
210 }
211 }
212 SolvableExtendedGB<C> exgb;
213 if ( len <= 1 || oneInGB ) {
214 // adjust F2G
215 for ( GenSolvablePolynomial<C> f : F ) {
216 row = new ArrayList<GenSolvablePolynomial<C>>( G.size() );
217 for ( int j = 0; j < G.size(); j++ ) {
218 row.add(null);
219 }
220 H = sred.leftNormalform( row, G, f );
221 if ( ! H.isZERO() ) {
222 logger.error("nonzero H = " + H );
223 }
224 F2G.add( row );
225 }
226 exgb = new SolvableExtendedGB<C>(F,G,F2G,G2F);
227 //System.out.println("exgb 1 = " + exgb);
228 return exgb;
229 }
230
231 Pair<C> pair;
232 int i, j;
233 GenSolvablePolynomial<C> pi;
234 GenSolvablePolynomial<C> pj;
235 GenSolvablePolynomial<C> S;
236 GenSolvablePolynomial<C> x;
237 GenSolvablePolynomial<C> y;
238 //GenPolynomial<C> z;
239 while ( pairlist.hasNext() && ! oneInGB ) {
240 pair = pairlist.removeNext();
241 if ( pair == null ) {
242 //pairlist.update(); // ?
243 continue;
244 }
245 i = pair.i;
246 j = pair.j;
247 pi = (GenSolvablePolynomial<C>)pair.pi;
248 pj = (GenSolvablePolynomial<C>)pair.pj;
249 if ( debug ) {
250 logger.info("i, pi = " + i + ", " + pi );
251 logger.info("j, pj = " + j + ", " + pj );
252 }
253
254 rows = new ArrayList<GenSolvablePolynomial<C>>( G.size() );
255 for ( int m = 0; m < G.size(); m++ ) {
256 rows.add(null);
257 }
258 S = sred.leftSPolynomial( rows, i, pi, j, pj );
259 if ( debug ) {
260 logger.debug("is reduction S = "
261 + sred.isLeftReductionNF( rows, G, ring.getZERO(), S ) );
262 }
263 if ( S.isZERO() ) {
264 pair.setZero();
265 //pairlist.update( pair, S );
266 // do not add to G2F
267 continue;
268 }
269 if ( debug ) {
270 logger.debug("ht(S) = " + S.leadingExpVector() );
271 }
272
273 rowh = new ArrayList<GenSolvablePolynomial<C>>( G.size() );
274 for ( int m = 0; m < G.size(); m++ ) {
275 rowh.add(null);
276 }
277 H = sred.leftNormalform( rowh, G, S );
278 if ( debug ) {
279 //System.out.println("H = " + H);
280 logger.debug("is reduction H = "
281 + sred.isLeftReductionNF( rowh, G, S, H ) );
282 }
283 if ( H.isZERO() ) {
284 pair.setZero();
285 //pairlist.update( pair, H );
286 // do not add to G2F
287 continue;
288 }
289 if ( debug ) {
290 logger.debug("ht(H) = " + H.leadingExpVector() );
291 }
292
293 row = new ArrayList<GenSolvablePolynomial<C>>( G.size()+1 );
294 for ( int m = 0; m < G.size(); m++ ) {
295 x = rows.get(m);
296 if ( x != null ) {
297 //System.out.println("ms = " + m + " " + x);
298 x = (GenSolvablePolynomial<C>)x.negate();
299 }
300 y = rowh.get(m);
301 if ( y != null ) {
302 y = (GenSolvablePolynomial<C>)y.negate();
303 //System.out.println("mh = " + m + " " + y);
304 }
305 if ( x == null ) {
306 x = y;
307 } else {
308 x = (GenSolvablePolynomial<C>)x.sum( y );
309 }
310 //System.out.println("mx = " + m + " " + x);
311 row.add( x );
312 }
313 if ( debug ) {
314 logger.debug("is reduction 0+sum(row,G) == H : "
315 + sred.isLeftReductionNF( row, G, H, ring.getZERO() ) );
316 }
317 row.add( null );
318
319
320 // H = H.monic();
321 C c = H.leadingBaseCoefficient();
322 c = c.inverse();
323 H = H.multiply( c );
324 // 1*c*row, leads to wrong method dispatch:
325 row = PolynomialList.<C>castToSolvableList(blas.scalarProduct(mone.multiply(c),PolynomialList.<C>castToList(row)));
326 row.set( G.size(), mone );
327 if ( H.isONE() ) {
328 // pairlist.record( pair, H );
329 // G.clear();
330 G.add( H );
331 G2F.add( row );
332 oneInGB = true;
333 break;
334 }
335 if ( debug ) {
336 logger.debug("H = " + H );
337 }
338 G.add( H );
339 //pairlist.update( pair, H );
340 pairlist.put(H);
341 G2F.add( row );
342 }
343 if ( debug ) {
344 exgb = new SolvableExtendedGB<C>(F,G,F2G,G2F);
345 logger.info("exgb unnorm = " + exgb);
346 }
347 G2F = normalizeMatrix( F.size(), G2F );
348 if ( debug ) {
349 exgb = new SolvableExtendedGB<C>(F,G,F2G,G2F);
350 logger.info("exgb nonmin = " + exgb);
351 boolean t2 = isLeftReductionMatrix( exgb );
352 logger.debug("exgb t2 = " + t2);
353 }
354 exgb = minimalSolvableExtendedGB(F.size(),G,G2F);
355 G = exgb.G;
356 G2F = exgb.G2F;
357 logger.debug("#sequential list = " + G.size());
358 logger.info("" + pairlist);
359 // setup matrices F and F2G
360 for ( GenSolvablePolynomial<C> f : F ) {
361 row = new ArrayList<GenSolvablePolynomial<C>>( G.size() );
362 for ( int m = 0; m < G.size(); m++ ) {
363 row.add(null);
364 }
365 H = sred.leftNormalform( row, G, f );
366 if ( ! H.isZERO() ) {
367 logger.error("nonzero H = " + H );
368 }
369 F2G.add( row );
370 }
371 return new SolvableExtendedGB<C>(F,G,F2G,G2F);
372 }
373
374
375 /**
376 * Twosided Groebner base using pairlist class.
377 * @param modv number of module variables.
378 * @param Fp solvable polynomial list.
379 * @return tsGB(Fp) a twosided Groebner base of Fp.
380 */
381 public List<GenSolvablePolynomial<C>>
382 twosidedGB(int modv,
383 List<GenSolvablePolynomial<C>> Fp) {
384 if ( Fp == null || Fp.size() == 0 ) { // 0 not 1
385 return new ArrayList<GenSolvablePolynomial<C>>( );
386 }
387 GenSolvablePolynomialRing<C> fac = Fp.get(0).ring; // assert != null
388 //List<GenSolvablePolynomial<C>> X = generateUnivar( modv, Fp );
389 List<GenSolvablePolynomial<C>> X = fac.univariateList( modv );
390 //System.out.println("X univ = " + X);
391 List<GenSolvablePolynomial<C>> F
392 = new ArrayList<GenSolvablePolynomial<C>>( Fp.size() * (1+X.size()) );
393 F.addAll( Fp );
394 GenSolvablePolynomial<C> p, x, q;
395 for ( int i = 0; i < Fp.size(); i++ ) {
396 p = Fp.get(i);
397 for ( int j = 0; j < X.size(); j++ ) {
398 x = X.get(j);
399 q = p.multiply( x );
400 q = sred.leftNormalform( F, q );
401 if ( !q.isZERO() ) {
402 F.add( q );
403 }
404 }
405 }
406 //System.out.println("F generated = " + F);
407 List<GenSolvablePolynomial<C>> G
408 = new ArrayList<GenSolvablePolynomial<C>>();
409 PairList<C> pairlist = null;
410 int l = F.size();
411 ListIterator<GenSolvablePolynomial<C>> it = F.listIterator();
412 while ( it.hasNext() ) {
413 p = it.next();
414 if ( p.length() > 0 ) {
415 p = (GenSolvablePolynomial<C>)p.monic();
416 if ( p.isONE() ) {
417 G.clear(); G.add( p );
418 return G; // since no threads are activated
419 }
420 G.add( p );
421 if ( pairlist == null ) {
422 // pairlist = new OrderedPairlist<C>( modv, p.ring );
423 pairlist = strategy.create( modv, p.ring );
424 }
425 // putOne not required
426 pairlist.put( p );
427 } else {
428 l--;
429 }
430 }
431 //System.out.println("G to check = " + G);
432 if ( l <= 1 ) { // 1 ok
433 return G; // since no threads are activated
434 }
435
436 Pair<C> pair;
437 GenSolvablePolynomial<C> pi, pj, S, H;
438 while ( pairlist.hasNext() ) {
439 pair = pairlist.removeNext();
440 if ( pair == null ) {
441 continue;
442 }
443
444 pi = (GenSolvablePolynomial<C>)pair.pi;
445 pj = (GenSolvablePolynomial<C>)pair.pj;
446 if ( false && debug ) {
447 logger.debug("pi = " + pi );
448 logger.debug("pj = " + pj );
449 }
450
451 S = sred.leftSPolynomial( pi, pj );
452 if ( S.isZERO() ) {
453 pair.setZero();
454 continue;
455 }
456 if ( debug ) {
457 logger.debug("ht(S) = " + S.leadingExpVector() );
458 }
459
460 H = sred.leftNormalform( G, S );
461 if ( H.isZERO() ) {
462 pair.setZero();
463 continue;
464 }
465 if ( debug ) {
466 logger.debug("ht(H) = " + H.leadingExpVector() );
467 }
468
469 H = (GenSolvablePolynomial<C>)H.monic();
470 if ( H.isONE() ) {
471 G.clear(); G.add( H );
472 return G; // since no threads are activated
473 }
474 if ( debug ) {
475 logger.debug("H = " + H );
476 }
477 if ( H.length() > 0 ) {
478 l++;
479 G.add( H );
480 pairlist.put( H );
481 for ( int j = 0; j < X.size(); j++ ) {
482 l++;
483 x = X.get(j);
484 p = H.multiply( x );
485 p = sred.leftNormalform( G, p );
486 if ( !p.isZERO() ) {
487 p = (GenSolvablePolynomial<C>)p.monic();
488 if ( p.isONE() ) {
489 G.clear(); G.add( p );
490 return G; // since no threads are activated
491 }
492 G.add( p );
493 pairlist.put( p );
494 }
495 }
496 }
497 }
498 logger.debug("#sequential list = "+G.size());
499 G = leftMinimalGB(G);
500 logger.info("" + pairlist);
501 return G;
502 }
503
504
505 /**
506 * Normalize M.
507 * Make all rows the same size and make certain column elements zero.
508 * @param M a reduction matrix.
509 * @return normalized M.
510 */
511 public List<List<GenSolvablePolynomial<C>>>
512 normalizeMatrix(int flen, List<List<GenSolvablePolynomial<C>>> M) {
513 if ( M == null ) {
514 return M;
515 }
516 if ( M.size() == 0 ) {
517 return M;
518 }
519 List<List<GenSolvablePolynomial<C>>> N = new ArrayList<List<GenSolvablePolynomial<C>>>();
520 List<List<GenSolvablePolynomial<C>>> K = new ArrayList<List<GenSolvablePolynomial<C>>>();
521 int len = M.get( M.size()-1 ).size(); // longest row
522 // pad / extend rows
523 for ( List<GenSolvablePolynomial<C>> row : M ) {
524 List<GenSolvablePolynomial<C>> nrow = new ArrayList<GenSolvablePolynomial<C>>( row );
525 for ( int i = row.size(); i < len; i++ ) {
526 nrow.add( null );
527 }
528 N.add( nrow );
529 }
530 // System.out.println("norm N fill = " + N);
531 // make zero columns
532 int k = flen;
533 for ( int i = 0; i < N.size(); i++ ) { // 0
534 List<GenSolvablePolynomial<C>> row = N.get( i );
535 if ( debug ) {
536 logger.info("row = " + row);
537 }
538 K.add( row );
539 if ( i < flen ) { // skip identity part
540 continue;
541 }
542 List<GenSolvablePolynomial<C>> xrow;
543 GenSolvablePolynomial<C> a;
544 //System.out.println("norm i = " + i);
545 for ( int j = i+1; j < N.size(); j++ ) {
546 List<GenSolvablePolynomial<C>> nrow = N.get( j );
547 //System.out.println("nrow j = " +j + ", " + nrow);
548 if ( k < nrow.size() ) { // always true
549 a = nrow.get( k );
550 //System.out.println("k, a = " + k + ", " + a);
551 if ( a != null && !a.isZERO() ) { // a*row + nrow, leads to wrong method dispatch
552 List<GenPolynomial<C>> yrow = blas.scalarProduct(a,PolynomialList.<C>castToList(row));
553 yrow = blas.vectorAdd(yrow,PolynomialList.<C>castToList(nrow));
554 xrow = PolynomialList.<C>castToSolvableList(yrow);
555 N.set( j, xrow );
556 }
557 }
558 }
559 k++;
560 }
561 //System.out.println("norm K reduc = " + K);
562 // truncate
563 N.clear();
564 for ( List<GenSolvablePolynomial<C>> row: K ) {
565 List<GenSolvablePolynomial<C>> tr = new ArrayList<GenSolvablePolynomial<C>>();
566 for ( int i = 0; i < flen; i++ ) {
567 tr.add( row.get(i) );
568 }
569 N.add( tr );
570 }
571 K = N;
572 //System.out.println("norm K trunc = " + K);
573 return K;
574 }
575
576
577 /**
578 * Test if M is a left reduction matrix.
579 * @param exgb an SolvableExtendedGB container.
580 * @return true, if exgb contains a left reduction matrix, else false.
581 */
582 @Override
583 public boolean
584 isLeftReductionMatrix(SolvableExtendedGB<C> exgb) {
585 if ( exgb == null ) {
586 return true;
587 }
588 return isLeftReductionMatrix(exgb.F,exgb.G,exgb.F2G,exgb.G2F);
589 }
590
591
592 /**
593 * Minimal solvable extended groebner basis.
594 * @param Gp a left Groebner base.
595 * @param M a left reduction matrix, is modified.
596 * @return a (partially) reduced left Groebner base of Gp in a container.
597 */
598 public SolvableExtendedGB<C>
599 minimalSolvableExtendedGB(int flen,
600 List<GenSolvablePolynomial<C>> Gp,
601 List<List<GenSolvablePolynomial<C>>> M) {
602 if ( Gp == null ) {
603 return null; //new SolvableExtendedGB<C>(null,Gp,null,M);
604 }
605 if ( Gp.size() <= 1 ) {
606 return new SolvableExtendedGB<C>(null,Gp,null,M);
607 }
608 List<GenSolvablePolynomial<C>> G;
609 List<GenSolvablePolynomial<C>> F;
610 G = new ArrayList<GenSolvablePolynomial<C>>( Gp );
611 F = new ArrayList<GenSolvablePolynomial<C>>( Gp.size() );
612
613 List<List<GenSolvablePolynomial<C>>> Mg;
614 List<List<GenSolvablePolynomial<C>>> Mf;
615 Mg = new ArrayList<List<GenSolvablePolynomial<C>>>( M.size() );
616 Mf = new ArrayList<List<GenSolvablePolynomial<C>>>( M.size() );
617 List<GenSolvablePolynomial<C>> row;
618 for ( List<GenSolvablePolynomial<C>> r : M ) {
619 // must be copied also
620 row = new ArrayList<GenSolvablePolynomial<C>>( r );
621 Mg.add( row );
622 }
623 row = null;
624
625 GenSolvablePolynomial<C> a;
626 ExpVector e;
627 ExpVector f;
628 GenSolvablePolynomial<C> p;
629 boolean mt;
630 ListIterator<GenSolvablePolynomial<C>> it;
631 ArrayList<Integer> ix = new ArrayList<Integer>();
632 ArrayList<Integer> jx = new ArrayList<Integer>();
633 int k = 0;
634 //System.out.println("flen, Gp, M = " + flen + ", " + Gp.size() + ", " + M.size() );
635 while ( G.size() > 0 ) {
636 a = G.remove(0);
637 e = a.leadingExpVector();
638
639 it = G.listIterator();
640 mt = false;
641 while ( it.hasNext() && ! mt ) {
642 p = it.next();
643 f = p.leadingExpVector();
644 mt = e.multipleOf( f );
645 }
646 it = F.listIterator();
647 while ( it.hasNext() && ! mt ) {
648 p = it.next();
649 f = p.leadingExpVector();
650 mt = e.multipleOf( f );
651 }
652 //System.out.println("k, mt = " + k + ", " + mt);
653 if ( ! mt ) {
654 F.add( a );
655 ix.add( k );
656 } else { // drop polynomial and corresponding row and column
657 // F.add( a.ring.getZERO() );
658 jx.add( k );
659 }
660 k++;
661 }
662 if ( debug ) {
663 logger.debug("ix, #M, jx = " + ix + ", " + Mg.size() + ", " + jx);
664 }
665 int fix = -1; // copied polys
666 // copy Mg to Mf as indicated by ix
667 for ( int i = 0; i < ix.size(); i++ ) {
668 int u = ix.get(i);
669 if ( u >= flen && fix == -1 ) {
670 fix = Mf.size();
671 }
672 //System.out.println("copy u, fix = " + u + ", " + fix);
673 if ( u >= 0 ) {
674 row = Mg.get( u );
675 Mf.add( row );
676 }
677 }
678 if ( F.size() <= 1 || fix == -1 ) {
679 return new SolvableExtendedGB<C>(null,F,null,Mf);
680 }
681 // must return, since extended normalform has not correct order of polys
682 /*
683 G = F;
684 F = new ArrayList<GenSolvablePolynomial<C>>( G.size() );
685 List<GenSolvablePolynomial<C>> temp;
686 k = 0;
687 final int len = G.size();
688 while ( G.size() > 0 ) {
689 a = G.remove(0);
690 if ( k >= fix ) { // dont touch copied polys
691 row = Mf.get( k );
692 //System.out.println("doing k = " + k + ", " + a);
693 // must keep order, but removed polys missing
694 temp = new ArrayList<GenPolynomial<C>>( len );
695 temp.addAll( F );
696 temp.add( a.ring.getZERO() ); // ??
697 temp.addAll( G );
698 //System.out.println("row before = " + row);
699 a = sred.leftNormalform( row, temp, a );
700 //System.out.println("row after = " + row);
701 }
702 F.add( a );
703 k++;
704 }
705 // does Mf need renormalization?
706 */
707 return new SolvableExtendedGB<C>(null,F,null,Mf);
708 }
709
710 }