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