001/* 002 * $Id: RecSolvableWordPolynomialRing.java 5835 2018-05-18 19:12:07Z kredel $ 003 */ 004 005package edu.jas.poly; 006 007 008import java.io.IOException; 009import java.io.Reader; 010import java.io.StringReader; 011import java.math.BigInteger; 012import java.util.ArrayList; 013import java.util.List; 014import java.util.Random; 015 016import org.apache.log4j.Logger; 017 018import edu.jas.kern.PrettyPrint; 019import edu.jas.kern.Scripting; 020import edu.jas.structure.RingElem; 021import edu.jas.structure.RingFactory; 022 023 024/** 025 * RecSolvableWordPolynomialRing generic recursive solvable polynomial factory 026 * implementing RingFactory and extending GenSolvablePolynomialRing factory. 027 * Factory for n-variate ordered solvable polynomials over non-commutative word 028 * polynomial coefficients. The non-commutative multiplication relations are 029 * maintained in a relation table and the non-commutative multiplication 030 * relations between the coefficients and the main variables are maintained in a 031 * coefficient relation table. Almost immutable object, except variable names 032 * and relation table contents. 033 * @param <C> base coefficient type. 034 * @author Heinz Kredel 035 */ 036 037public class RecSolvableWordPolynomialRing<C extends RingElem<C>> extends 038 GenSolvablePolynomialRing<GenWordPolynomial<C>> { 039 040 041 /** 042 * The solvable multiplication relations between variables and coefficients. 043 */ 044 public final RelationTable<GenWordPolynomial<C>> coeffTable; 045 046 047 /** 048 * The constant polynomial 0 for this ring. Hides super ZERO. 049 */ 050 public final RecSolvableWordPolynomial<C> ZERO; 051 052 053 /** 054 * The constant polynomial 1 for this ring. Hides super ONE. 055 */ 056 public final RecSolvableWordPolynomial<C> ONE; 057 058 059 private static final Logger logger = Logger.getLogger(RecSolvableWordPolynomialRing.class); 060 061 062 private static final boolean debug = logger.isDebugEnabled(); 063 064 065 /** 066 * The constructor creates a solvable polynomial factory object with the 067 * default term order and commutative relations. 068 * @param cf factory for coefficients of type C. 069 * @param n number of variables. 070 */ 071 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n) { 072 this(cf, n, new TermOrder(), null, null); 073 } 074 075 076 /** 077 * The constructor creates a solvable polynomial factory object with the 078 * default term order. 079 * @param cf factory for coefficients of type C. 080 * @param n number of variables. 081 * @param rt solvable multiplication relations. 082 */ 083 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, 084 RelationTable<GenWordPolynomial<C>> rt) { 085 this(cf, n, new TermOrder(), null, rt); 086 } 087 088 089 /** 090 * The constructor creates a solvable polynomial factory object with the 091 * given term order and commutative relations. 092 * @param cf factory for coefficients of type C. 093 * @param n number of variables. 094 * @param t a term order. 095 */ 096 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t) { 097 this(cf, n, t, null, null); 098 } 099 100 101 /** 102 * The constructor creates a solvable polynomial factory object with the 103 * given term order. 104 * @param cf factory for coefficients of type C. 105 * @param n number of variables. 106 * @param t a term order. 107 * @param rt solvable multiplication relations. 108 */ 109 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t, 110 RelationTable<GenWordPolynomial<C>> rt) { 111 this(cf, n, t, null, rt); 112 } 113 114 115 /** 116 * The constructor creates a solvable polynomial factory object with the 117 * given term order and commutative relations. 118 * @param cf factory for coefficients of type C. 119 * @param n number of variables. 120 * @param t a term order. 121 * @param v names for the variables. 122 */ 123 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t, String[] v) { 124 this(cf, n, t, v, null); 125 } 126 127 128 /** 129 * The constructor creates a solvable polynomial factory object with the 130 * given term order and commutative relations. 131 * @param cf factory for coefficients of type C. 132 * @param t a term order. 133 * @param v names for the variables. 134 */ 135 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, TermOrder t, String[] v) { 136 this(cf, v.length, t, v, null); 137 } 138 139 140 /** 141 * The constructor creates a solvable polynomial factory object with the 142 * default term order. 143 * @param cf factory for coefficients of type C. 144 * @param v names for the variables. 145 */ 146 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, String[] v) { 147 this(cf, v.length, new TermOrder(), v, null); 148 } 149 150 151 /** 152 * The constructor creates a solvable polynomial factory object with the 153 * given term order. 154 * @param cf factory for coefficients of type C. 155 * @param n number of variables. 156 * @param t a term order. 157 * @param v names for the variables. 158 * @param rt solvable multiplication relations. 159 */ 160 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, int n, TermOrder t, 161 String[] v, RelationTable<GenWordPolynomial<C>> rt) { 162 super(cf, n, t, v, rt); 163 //if (rt == null) { // handled in super } 164 coeffTable = new RelationTable<GenWordPolynomial<C>>(this, true); 165 ZERO = new RecSolvableWordPolynomial<C>(this); 166 GenWordPolynomial<C> coeff = coFac.getONE(); 167 //evzero = ExpVector.create(nvar); // from super 168 ONE = new RecSolvableWordPolynomial<C>(this, coeff, evzero); 169 } 170 171 172 /** 173 * The constructor creates a solvable polynomial factory object with the the 174 * same term order, number of variables and variable names as the given 175 * polynomial factory, only the coefficient factories differ and the 176 * solvable multiplication relations are <b>empty</b>. 177 * @param cf factory for coefficients of type C. 178 * @param o other solvable polynomial ring. 179 */ 180 public RecSolvableWordPolynomialRing(RingFactory<GenWordPolynomial<C>> cf, RecSolvableWordPolynomialRing o) { 181 this(cf, o.nvar, o.tord, o.getVars(), null); 182 } 183 184 185 /** 186 * Get the String representation. 187 * @see java.lang.Object#toString() 188 */ 189 @Override 190 public String toString() { 191 String res = super.toString(); 192 if (PrettyPrint.isTrue()) { 193 //res += "\n" + table.toString(vars); 194 res += "\n" + coeffTable.toString(vars); 195 } else { 196 res += ", #rel = " + table.size() + " + " + coeffTable.size(); 197 } 198 return res; 199 } 200 201 202 /** 203 * Get a scripting compatible string representation. 204 * @return script compatible representation for this Element. 205 * @see edu.jas.structure.Element#toScript() 206 */ 207 @Override 208 public String toScript() { 209 StringBuffer s = new StringBuffer(); 210 switch (Scripting.getLang()) { 211 case Ruby: 212 s.append("SolvPolyRing.new("); 213 break; 214 case Python: 215 default: 216 s.append("SolvPolyRing("); 217 } 218 if (coFac instanceof RingElem) { 219 s.append(((RingElem<GenWordPolynomial<C>>) coFac).toScriptFactory()); 220 } else { 221 s.append(coFac.toScript().trim()); 222 } 223 s.append(",\"" + varsToString() + "\","); 224 String to = tord.toScript(); 225 s.append(to); 226 if (table.size() > 0) { 227 String rel = table.toScript(); 228 s.append(",rel="); 229 s.append(rel); 230 } 231 if (coeffTable.size() > 0) { 232 String rel = coeffTable.toScript(); 233 s.append(",coeffrel="); 234 s.append(rel); 235 } 236 s.append(")"); 237 return s.toString(); 238 } 239 240 241 /** 242 * Comparison with any other object. 243 * @see java.lang.Object#equals(java.lang.Object) 244 */ 245 @Override 246 @SuppressWarnings("unchecked") 247 public boolean equals(Object other) { 248 if (other == null) { 249 return false; 250 } 251 if (!(other instanceof RecSolvableWordPolynomialRing)) { 252 return false; 253 } 254 // do a super.equals( ) 255 if (!super.equals(other)) { 256 return false; 257 } 258 RecSolvableWordPolynomialRing<C> oring = (RecSolvableWordPolynomialRing<C>) other; 259 // check same base relations 260 //if ( ! table.equals(oring.table) ) { // done in super 261 // return false; 262 //} 263 if (!coeffTable.equals(oring.coeffTable)) { 264 return false; 265 } 266 return true; 267 } 268 269 270 /** 271 * Hash code for this polynomial ring. 272 * @see java.lang.Object#hashCode() 273 */ 274 @Override 275 public int hashCode() { 276 int h; 277 h = super.hashCode(); 278 h = 37 * h + table.hashCode(); // may be different after some computations 279 h = 37 * h + coeffTable.hashCode(); // may be different 280 return h; 281 } 282 283 284 /** 285 * Get the zero element. 286 * @return 0 as RecSolvableWordPolynomial<C>. 287 */ 288 @Override 289 public RecSolvableWordPolynomial<C> getZERO() { 290 return ZERO; 291 } 292 293 294 /** 295 * Get the one element. 296 * @return 1 as RecSolvableWordPolynomial<C>. 297 */ 298 @Override 299 public RecSolvableWordPolynomial<C> getONE() { 300 return ONE; 301 } 302 303 304 /** 305 * Query if this ring is commutative. 306 * @return true if this ring is commutative, else false. 307 */ 308 @Override 309 public boolean isCommutative() { 310 if (coeffTable.isEmpty()) { 311 return super.isCommutative(); 312 } 313 return false; 314 } 315 316 317 /** 318 * Query if this ring is associative. Test if the relations between the mian 319 * variables and the coefficient generators define an associative solvable 320 * ring. 321 * @return true, if this ring is associative, else false. 322 */ 323 @SuppressWarnings("unused") 324 @Override 325 public boolean isAssociative() { 326 if (!coFac.isAssociative()) { 327 return false; 328 } 329 RecSolvableWordPolynomial<C> Xi, Xj, Xk, p, q; 330 List<GenPolynomial<GenWordPolynomial<C>>> gens = generators(); 331 //System.out.println("Rec word gens = " + gens); 332 int ngen = gens.size(); 333 for (int i = 0; i < ngen; i++) { 334 Xi = (RecSolvableWordPolynomial<C>) gens.get(i); 335 if (Xi.isONE()) { 336 continue; 337 } 338 for (int j = i + 1; j < ngen; j++) { 339 Xj = (RecSolvableWordPolynomial<C>) gens.get(j); 340 for (int k = j + 1; k < ngen; k++) { 341 Xk = (RecSolvableWordPolynomial<C>) gens.get(k); 342 try { 343 p = Xk.multiply(Xj).multiply(Xi); 344 q = Xk.multiply(Xj.multiply(Xi)); 345 if (!p.equals(q)) { 346 if (true || debug) { 347 logger.info("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi); 348 logger.info("p = ( Xk * Xj ) * Xi = " + p); 349 logger.info("q = Xk * ( Xj * Xi ) = " + q); 350 } 351 return false; 352 } 353 } catch (RuntimeException e) { 354 e.printStackTrace(); 355 System.out.println("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi); 356 } 357 } 358 } 359 } 360 return true; 361 } 362 363 364 /** 365 * Get a (constant) RecSolvableWordPolynomial<C> element from a 366 * coefficient value. 367 * @param a coefficient. 368 * @return a RecSolvableWordPolynomial<C>. 369 */ 370 @Override 371 public RecSolvableWordPolynomial<C> valueOf(GenWordPolynomial<C> a) { 372 return new RecSolvableWordPolynomial<C>(this, a); 373 } 374 375 376 /** 377 * Get a RecSolvableWordPolynomial<C> element from an ExpVector. 378 * @param e exponent vector. 379 * @return a RecSolvableWordPolynomial<C>. 380 */ 381 @Override 382 public RecSolvableWordPolynomial<C> valueOf(ExpVector e) { 383 return valueOf(coFac.getONE(), e); 384 } 385 386 387 /** 388 * Get a RecSolvableWordPolynomial<C> element from a coeffcient and an 389 * ExpVector. 390 * @param a coefficient. 391 * @param e exponent vector. 392 * @return a RecSolvableWordPolynomial<C>. 393 */ 394 @Override 395 public RecSolvableWordPolynomial<C> valueOf(GenWordPolynomial<C> a, ExpVector e) { 396 return new RecSolvableWordPolynomial<C>(this, a, e); 397 } 398 399 400 /** 401 * Get a (constant) RecSolvableWordPolynomial<C> element from a long 402 * value. 403 * @param a long. 404 * @return a RecSolvableWordPolynomial<C>. 405 */ 406 @Override 407 public RecSolvableWordPolynomial<C> fromInteger(long a) { 408 return new RecSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero); 409 } 410 411 412 /** 413 * Get a (constant) RecSolvableWordPolynomial<C> element from a 414 * BigInteger value. 415 * @param a BigInteger. 416 * @return a RecSolvableWordPolynomial<C>. 417 */ 418 @Override 419 public RecSolvableWordPolynomial<C> fromInteger(BigInteger a) { 420 return new RecSolvableWordPolynomial<C>(this, coFac.fromInteger(a), evzero); 421 } 422 423 424 /** 425 * Random solvable polynomial. Generates a random solvable polynomial with k 426 * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3. 427 * @param n number of terms. 428 * @return a random solvable polynomial. 429 */ 430 @Override 431 public RecSolvableWordPolynomial<C> random(int n) { 432 return random(n, random); 433 } 434 435 436 /** 437 * Random solvable polynomial. Generates a random solvable polynomial with k 438 * = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3. 439 * @param n number of terms. 440 * @param rnd is a source for random bits. 441 * @return a random solvable polynomial. 442 */ 443 @Override 444 public RecSolvableWordPolynomial<C> random(int n, Random rnd) { 445 if (nvar == 1) { 446 return random(5, n, n, 0.7f, rnd); 447 } 448 return random(5, n, 3, 0.3f, rnd); 449 } 450 451 452 /** 453 * Generate a random solvable polynomial. 454 * @param k bitsize of random coefficients. 455 * @param l number of terms. 456 * @param d maximal degree in each variable. 457 * @param q density of nozero exponents. 458 * @return a random solvable polynomial. 459 */ 460 @Override 461 public RecSolvableWordPolynomial<C> random(int k, int l, int d, float q) { 462 return random(k, l, d, q, random); 463 } 464 465 466 /** 467 * Random solvable polynomial. 468 * @param k size of random coefficients. 469 * @param l number of terms. 470 * @param d maximal degree in each variable. 471 * @param q density of nozero exponents. 472 * @param rnd is a source for random bits. 473 * @return a random solvable polynomial. 474 */ 475 @Override 476 public RecSolvableWordPolynomial<C> random(int k, int l, int d, float q, Random rnd) { 477 RecSolvableWordPolynomial<C> r = getZERO(); // copy( ZERO ); 478 ExpVector e; 479 GenWordPolynomial<C> a; 480 // add random coeffs and exponents 481 for (int i = 0; i < l; i++) { 482 e = ExpVector.EVRAND(nvar, d, q, rnd); 483 a = coFac.random(k, rnd); 484 r = (RecSolvableWordPolynomial<C>) r.sum(a, e); 485 // somewhat inefficient but clean 486 } 487 return r; 488 } 489 490 491 /** 492 * Copy polynomial c. 493 * @param c 494 * @return a copy of c. 495 */ 496 public RecSolvableWordPolynomial<C> copy(RecSolvableWordPolynomial<C> c) { 497 return new RecSolvableWordPolynomial<C>(this, c.val); 498 } 499 500 501 /** 502 * Parse a solvable polynomial with the use of GenPolynomialTokenizer 503 * @param s String. 504 * @return RecSolvableWordPolynomial from s. 505 */ 506 @Override 507 public RecSolvableWordPolynomial<C> parse(String s) { 508 return parse(new StringReader(s)); 509 } 510 511 512 /** 513 * Parse a solvable polynomial with the use of GenPolynomialTokenizer 514 * @param r Reader. 515 * @return next RecSolvableWordPolynomial from r. 516 */ 517 @Override 518 @SuppressWarnings("unchecked") 519 public RecSolvableWordPolynomial<C> parse(Reader r) { 520 GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r); 521 RecSolvableWordPolynomial<C> p = null; 522 try { 523 GenSolvablePolynomial<GenWordPolynomial<C>> s = pt.nextSolvablePolynomial(); 524 p = new RecSolvableWordPolynomial<C>(this, s); 525 } catch (IOException e) { 526 logger.error(e.toString() + " parse " + this); 527 p = ZERO; 528 } 529 return p; 530 } 531 532 533 /** 534 * Generate univariate solvable polynomial in a given variable. 535 * @param i the index of the variable. 536 * @return X_i as solvable univariate polynomial. 537 */ 538 @Override 539 public RecSolvableWordPolynomial<C> univariate(int i) { 540 return (RecSolvableWordPolynomial<C>) super.univariate(i); 541 } 542 543 544 /** 545 * Generate univariate solvable polynomial in a given variable with given 546 * exponent. 547 * @param i the index of the variable. 548 * @param e the exponent of the variable. 549 * @return X_i^e as solvable univariate polynomial. 550 */ 551 @Override 552 public RecSolvableWordPolynomial<C> univariate(int i, long e) { 553 return (RecSolvableWordPolynomial<C>) super.univariate(i, e); 554 } 555 556 557 /** 558 * Generate univariate solvable polynomial in a given variable with given 559 * exponent. 560 * @param modv number of module variables. 561 * @param i the index of the variable. 562 * @param e the exponent of the variable. 563 * @return X_i^e as solvable univariate polynomial. 564 */ 565 @Override 566 public RecSolvableWordPolynomial<C> univariate(int modv, int i, long e) { 567 return (RecSolvableWordPolynomial<C>) super.univariate(modv, i, e); 568 } 569 570 571 /** 572 * Generate list of univariate polynomials in all variables. 573 * @return List(X_1,...,X_n) a list of univariate polynomials. 574 */ 575 @Override 576 public List<RecSolvableWordPolynomial<C>> univariateList() { 577 //return castToSolvableList( super.univariateList() ); 578 return univariateList(0, 1L); 579 } 580 581 582 /** 583 * Generate list of univariate polynomials in all variables. 584 * @param modv number of module variables. 585 * @return List(X_1,...,X_n) a list of univariate polynomials. 586 */ 587 @Override 588 public List<RecSolvableWordPolynomial<C>> univariateList(int modv) { 589 return univariateList(modv, 1L); 590 } 591 592 593 /** 594 * Generate list of univariate polynomials in all variables with given 595 * exponent. 596 * @param modv number of module variables. 597 * @param e the exponent of the variables. 598 * @return List(X_1^e,...,X_n^e) a list of univariate polynomials. 599 */ 600 @Override 601 public List<RecSolvableWordPolynomial<C>> univariateList(int modv, long e) { 602 List<RecSolvableWordPolynomial<C>> pols = new ArrayList<RecSolvableWordPolynomial<C>>(nvar); 603 int nm = nvar - modv; 604 for (int i = 0; i < nm; i++) { 605 RecSolvableWordPolynomial<C> p = univariate(modv, nm - 1 - i, e); 606 pols.add(p); 607 } 608 return pols; 609 } 610 611 612 /** 613 * Extend variables. Used e.g. in module embedding. Extend number of 614 * variables by i. 615 * @param i number of variables to extend. 616 * @return extended solvable polynomial ring factory. 617 */ 618 @Override 619 public RecSolvableWordPolynomialRing<C> extend(int i) { 620 GenSolvablePolynomialRing<GenWordPolynomial<C>> pfac = super.extend(i); 621 RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar, 622 pfac.tord, pfac.vars, pfac.table); 623 //spfac.table.extend(this.table); // pfac.table 624 spfac.coeffTable.extend(this.coeffTable); 625 return spfac; 626 } 627 628 629 /** 630 * Extend variables. Used e.g. in module embedding. Extend number of 631 * variables by length(vn). New variables commute with the exiting 632 * variables. 633 * @param vs names for extended variables. 634 * @return extended polynomial ring factory. 635 */ 636 @Override 637 public RecSolvableWordPolynomialRing<C> extend(String[] vs) { 638 GenSolvablePolynomialRing<GenWordPolynomial<C>> pfac = super.extend(vs); 639 RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar, 640 pfac.tord, pfac.vars, pfac.table); 641 //spfac.table.extend(this.table); // pfac.table?? 642 spfac.coeffTable.extend(this.coeffTable); 643 return spfac; 644 } 645 646 647 /** 648 * Contract variables. Used e.g. in module embedding. Contract number of 649 * variables by i. 650 * @param i number of variables to remove. 651 * @return contracted solvable polynomial ring factory. 652 */ 653 @Override 654 public RecSolvableWordPolynomialRing<C> contract(int i) { 655 GenPolynomialRing<GenWordPolynomial<C>> pfac = super.contract(i); 656 RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar, 657 pfac.tord, pfac.vars); 658 spfac.table.contract(this.table); 659 spfac.coeffTable.contract(this.coeffTable); 660 return spfac; 661 } 662 663 664 /** 665 * Reverse variables. Used e.g. in opposite rings. 666 * @return solvable polynomial ring factory with reversed variables. 667 */ 668 @Override 669 public RecSolvableWordPolynomialRing<C> reverse() { 670 return reverse(false); 671 } 672 673 674 /** 675 * Reverse variables. Used e.g. in opposite rings. 676 * @param partial true for partialy reversed term orders. 677 * @return solvable polynomial ring factory with reversed variables. 678 */ 679 @Override 680 public RecSolvableWordPolynomialRing<C> reverse(boolean partial) { 681 GenPolynomialRing<GenWordPolynomial<C>> pfac = super.reverse(partial); 682 RecSolvableWordPolynomialRing<C> spfac = new RecSolvableWordPolynomialRing<C>(pfac.coFac, pfac.nvar, 683 pfac.tord, pfac.vars); 684 spfac.partial = partial; 685 spfac.table.reverse(this.table); 686 spfac.coeffTable.reverse(this.coeffTable); 687 return spfac; 688 } 689 690 691 /* not possible: 692 * Distributive representation as polynomial with all main variables. 693 * @return distributive polynomial ring factory. 694 @SuppressWarnings({"cast","unchecked"}) 695 public static <C extends RingElem<C>> // must be static because of types 696 GenSolvablePolynomialRing<C> distribute(RecSolvableWordPolynomialRing<C> rf) { 697 } 698 */ 699 700 701 /** 702 * Permutation of polynomial ring variables. 703 * @param P permutation. 704 * @return P(this). 705 */ 706 @Override 707 public GenSolvablePolynomialRing<GenWordPolynomial<C>> permutation(List<Integer> P) { 708 if (!coeffTable.isEmpty()) { 709 throw new UnsupportedOperationException("permutation with coeff relations: " + this); 710 } 711 GenSolvablePolynomialRing<GenWordPolynomial<C>> pfac = (GenSolvablePolynomialRing<GenWordPolynomial<C>>) super 712 .permutation(P); 713 return pfac; 714 } 715 716}