001 /* 002 * $Id: TermOrderOptimization.java 3446 2010-12-25 21:57:09Z kredel $ 003 */ 004 005 package edu.jas.poly; 006 007 import java.util.List; 008 import java.util.ArrayList; 009 import java.util.Collection; 010 import java.util.Arrays; 011 import java.util.Map; 012 import java.util.SortedMap; 013 import java.util.TreeMap; 014 015 import org.apache.log4j.Logger; 016 017 import edu.jas.structure.RingElem; 018 019 import edu.jas.arith.BigInteger; 020 021 import edu.jas.poly.GenPolynomial; 022 import edu.jas.poly.GenPolynomialRing; 023 024 import edu.jas.vector.BasicLinAlg; 025 026 027 /** 028 * Term order optimization. 029 * See mas10/maspoly/DIPTOO.m{di}. 030 * @author Heinz Kredel 031 */ 032 033 public class TermOrderOptimization { 034 035 036 private static final Logger logger = Logger.getLogger(TermOrderOptimization.class); 037 //private static boolean debug = logger.isDebugEnabled(); 038 039 040 /** 041 * Degree matrix. 042 * @param A polynomial to be considered. 043 * @return degree matrix. 044 */ 045 public static <C extends RingElem<C>> 046 List<GenPolynomial<BigInteger>> degreeMatrix( GenPolynomial<C> A ) { 047 048 List<GenPolynomial<BigInteger>> dem = null; 049 if ( A == null ) { 050 return dem; 051 } 052 053 BigInteger cfac = new BigInteger(); 054 GenPolynomialRing<BigInteger> ufac 055 = new GenPolynomialRing<BigInteger>(cfac,1); 056 057 int nvar = A.numberOfVariables(); 058 dem = new ArrayList<GenPolynomial<BigInteger>>( nvar ); 059 060 for ( int i = 0; i < nvar; i++ ) { 061 dem.add( ufac.getZERO() ); 062 } 063 if ( A.isZERO() ) { 064 return dem; 065 } 066 067 for ( ExpVector e: A.getMap().keySet() ) { 068 dem = expVectorAdd(dem, e ); 069 } 070 return dem; 071 } 072 073 074 /** 075 * Degree matrix exponent vector add. 076 * @param dm degree matrix. 077 * @param e exponent vector. 078 * @return degree matrix + e. 079 */ 080 public static 081 List<GenPolynomial<BigInteger>> expVectorAdd(List<GenPolynomial<BigInteger>> dm, ExpVector e) { 082 for ( int i = 0; i < dm.size() && i < e.length(); i++ ) { 083 GenPolynomial<BigInteger> p = dm.get(i); 084 long u = e.getVal(i); 085 ExpVector f = ExpVector.create(1,0,u); 086 p = p.sum( p.ring.getONECoefficient(), f ); 087 dm.set(i,p); 088 } 089 return dm; 090 } 091 092 093 /** 094 * Degree matrix of coefficient polynomials. 095 * @param A polynomial to be considered. 096 * @return degree matrix for the coeficients. 097 */ 098 public static <C extends RingElem<C>> 099 List<GenPolynomial<BigInteger>> degreeMatrixOfCoefficients( GenPolynomial<GenPolynomial<C>> A ) { 100 if ( A == null ) { 101 throw new IllegalArgumentException("polynomial must not be null"); 102 } 103 return degreeMatrix( A.getMap().values() ); 104 } 105 106 107 /** 108 * Degree matrix. 109 * @param L list of polynomial to be considered. 110 * @return degree matrix. 111 */ 112 public static <C extends RingElem<C>> 113 List<GenPolynomial<BigInteger>> degreeMatrix( Collection<GenPolynomial<C>> L ) { 114 if ( L == null ) { 115 throw new IllegalArgumentException("list must be non null"); 116 } 117 BasicLinAlg<GenPolynomial<BigInteger>> blas = new BasicLinAlg<GenPolynomial<BigInteger>>(); 118 List<GenPolynomial<BigInteger>> dem = null; 119 for ( GenPolynomial<C> p : L ) { 120 List<GenPolynomial<BigInteger>> dm = degreeMatrix( p ); 121 if ( dem == null ) { 122 dem = dm; 123 } else { 124 dem = blas.vectorAdd( dem, dm ); 125 } 126 } 127 return dem; 128 } 129 130 131 /** 132 * Degree matrix of coefficient polynomials. 133 * @param L list of polynomial to be considered. 134 * @return degree matrix for the coeficients. 135 */ 136 public static <C extends RingElem<C>> 137 List<GenPolynomial<BigInteger>> 138 degreeMatrixOfCoefficients( Collection<GenPolynomial<GenPolynomial<C>>> L ) { 139 if ( L == null ) { 140 throw new IllegalArgumentException("list must not be null"); 141 } 142 BasicLinAlg<GenPolynomial<BigInteger>> blas = new BasicLinAlg<GenPolynomial<BigInteger>>(); 143 List<GenPolynomial<BigInteger>> dem = null; 144 for ( GenPolynomial<GenPolynomial<C>> p : L ) { 145 List<GenPolynomial<BigInteger>> dm = degreeMatrixOfCoefficients( p ); 146 if ( dem == null ) { 147 dem = dm; 148 } else { 149 dem = blas.vectorAdd( dem, dm ); 150 } 151 } 152 return dem; 153 } 154 155 156 /** 157 * Optimal permutation for the Degree matrix. 158 * @param D degree matrix. 159 * @return optimal permutation for D. 160 */ 161 public static 162 List<Integer> optimalPermutation( List<GenPolynomial<BigInteger>> D ) { 163 if ( D == null ) { 164 throw new IllegalArgumentException("list must be non null"); 165 } 166 List<Integer> P = new ArrayList<Integer>( D.size() ); 167 if ( D.size() == 0 ) { 168 return P; 169 } 170 if ( D.size() == 1 ) { 171 P.add(0); 172 return P; 173 } 174 SortedMap< GenPolynomial<BigInteger>, List<Integer> > map 175 = new TreeMap<GenPolynomial<BigInteger>,List<Integer>>(); 176 int i = 0; 177 for ( GenPolynomial<BigInteger> p : D ) { 178 List<Integer> il = map.get(p); 179 if ( il == null ) { 180 il = new ArrayList<Integer>(3); 181 } 182 il.add( i ); 183 map.put( p, il ); 184 i++; 185 } 186 List<List<Integer>> V = new ArrayList<List<Integer>>( map.values() ); 187 //System.out.println("V = " + V); 188 //for ( int j = V.size()-1; j >= 0; j-- ) { 189 for ( int j = 0; j < V.size(); j++ ) { 190 List<Integer> v = V.get(j); 191 for ( Integer k : v ) { 192 P.add( k ); 193 } 194 } 195 return P; 196 } 197 198 199 /** 200 * Permutation of a list. 201 * @param L list. 202 * @param P permutation. 203 * @return P(L). 204 */ 205 public static <T> 206 List<T> listPermutation( List<Integer> P, List<T> L ) { 207 if ( L == null || L.size() <= 1 ) { 208 return L; 209 } 210 List<T> pl = new ArrayList<T>( L.size() ); 211 for ( Integer i : P ) { 212 pl.add( L.get( (int)i ) ); 213 } 214 return pl; 215 } 216 217 218 /** 219 * Permutation of an array. 220 * Compiles, but does not work, requires JDK 1.6 to work. 221 * @param a array. 222 * @param P permutation. 223 * @return P(a). 224 */ 225 @SuppressWarnings("unchecked") 226 public static <T> 227 T[] arrayPermutation( List<Integer> P, T[] a ) { 228 if ( a == null || a.length <= 1 ) { 229 return a; 230 } 231 T[] b = (T[]) new Object[a.length]; // jdk 1.5 232 //T[] b = Arrays.<T>copyOf( a, a.length ); // jdk 1.6, works 233 int j = 0; 234 for ( Integer i : P ) { 235 b[j] = a[ (int)i ]; 236 j++; 237 } 238 return b; 239 } 240 241 242 /** 243 * Permutation of an array. 244 * @param a array. 245 * @param P permutation. 246 * @return P(a). 247 */ 248 public static 249 String[] stringArrayPermutation( List<Integer> P, String[] a ) { 250 if ( a == null || a.length <= 1 ) { 251 return a; 252 } 253 String[] b = new String[a.length]; // jdk 1.5 254 //T[] b = Arrays.<T>copyOf( a, a.length ); // jdk 1.6 255 int j = 0; 256 for ( Integer i : P ) { 257 b[j] = a[ (int)i ]; 258 j++; 259 } 260 return b; 261 } 262 263 264 /** 265 * Permutation of a long array. 266 * @param a array of long. 267 * @param P permutation. 268 * @return P(a). 269 */ 270 public static 271 long[] longArrayPermutation( List<Integer> P, long[] a ) { 272 if ( a == null || a.length <= 1 ) { 273 return a; 274 } 275 long[] b = new long[ a.length ]; 276 int j = 0; 277 for ( Integer i : P ) { 278 b[j] = a[ (int)i ]; 279 j++; 280 } 281 return b; 282 } 283 284 285 /** 286 * Permutation of an exponent vector. 287 * @param e exponent vector. 288 * @param P permutation. 289 * @return P(e). 290 */ 291 public static 292 ExpVector permutation( List<Integer> P, ExpVector e ) { 293 if ( e == null ) { 294 return e; 295 } 296 long[] u = longArrayPermutation( P, e.getVal() ); 297 ExpVector f = ExpVector.create( u ); 298 return f; 299 } 300 301 302 /** 303 * Permutation of polynomial exponent vectors. 304 * @param A polynomial. 305 * @param R polynomial ring. 306 * @param P permutation. 307 * @return P(A). 308 */ 309 public static <C extends RingElem<C>> 310 GenPolynomial<C> permutation( List<Integer> P, GenPolynomialRing<C> R, GenPolynomial<C> A ) { 311 if ( A == null ) { 312 return A; 313 } 314 GenPolynomial<C> B = R.getZERO().clone(); 315 Map<ExpVector,C> Bv = B.val; //getMap(); 316 for ( Map.Entry<ExpVector,C> y: A.getMap().entrySet() ) { 317 ExpVector e = y.getKey(); 318 C a = y.getValue(); 319 //System.out.println("e = " + e); 320 ExpVector f = permutation(P,e); 321 //System.out.println("f = " + f); 322 Bv.put( f, a ); // assert f not in Bv 323 } 324 return B; 325 } 326 327 328 /** 329 * Permutation of polynomial exponent vectors. 330 * @param L list of polynomials. 331 * @param R polynomial ring. 332 * @param P permutation. 333 * @return P(L). 334 */ 335 public static <C extends RingElem<C>> 336 List<GenPolynomial<C>> 337 permutation( List<Integer> P, GenPolynomialRing<C> R, List<GenPolynomial<C>> L ) { 338 if ( L == null || L.size() == 0 ) { 339 return L; 340 } 341 List<GenPolynomial<C>> K = new ArrayList<GenPolynomial<C>>( L.size() ); 342 for ( GenPolynomial<C> a: L ) { 343 GenPolynomial<C> b = permutation( P, R, a ); 344 K.add( b ); 345 } 346 return K; 347 } 348 349 350 /** 351 * Permutation of polynomial exponent vectors of coefficient polynomials. 352 * @param A polynomial. 353 * @param R polynomial ring. 354 * @param P permutation. 355 * @return P(A). 356 */ 357 public static <C extends RingElem<C>> 358 GenPolynomial<GenPolynomial<C>> 359 permutationOnCoefficients( List<Integer> P, 360 GenPolynomialRing<GenPolynomial<C>> R, 361 GenPolynomial<GenPolynomial<C>> A ) { 362 if ( A == null ) { 363 return A; 364 } 365 GenPolynomial<GenPolynomial<C>> B = R.getZERO().clone(); 366 GenPolynomialRing<C> cf = (GenPolynomialRing<C>) R.coFac; 367 Map<ExpVector,GenPolynomial<C>> Bv = B.val; //getMap(); 368 for ( Map.Entry<ExpVector,GenPolynomial<C>> y: A.getMap().entrySet() ) { 369 ExpVector e = y.getKey(); 370 GenPolynomial<C> a = y.getValue(); 371 //System.out.println("e = " + e); 372 GenPolynomial<C> b = permutation(P,cf,a); 373 //System.out.println("b = " + b); 374 Bv.put( e, b ); // assert e not in Bv 375 } 376 return B; 377 } 378 379 380 /** 381 * Permutation of polynomial exponent vectors of coefficients. 382 * @param L list of polynomials. 383 * @param R polynomial ring. 384 * @param P permutation. 385 * @return P(L). 386 */ 387 public static <C extends RingElem<C>> 388 List<GenPolynomial<GenPolynomial<C>>> 389 permutationOnCoefficients( List<Integer> P, 390 GenPolynomialRing<GenPolynomial<C>> R, 391 List<GenPolynomial<GenPolynomial<C>>> L ) { 392 if ( L == null || L.size() == 0 ) { 393 return L; 394 } 395 List<GenPolynomial<GenPolynomial<C>>> K 396 = new ArrayList<GenPolynomial<GenPolynomial<C>>>( L.size() ); 397 for ( GenPolynomial<GenPolynomial<C>> a: L ) { 398 GenPolynomial<GenPolynomial<C>> b = permutationOnCoefficients( P, R, a ); 399 K.add( b ); 400 } 401 return K; 402 } 403 404 405 /** 406 * Permutation of polynomial ring variables. 407 * @param R polynomial ring. 408 * @param P permutation. 409 * @return P(R). 410 */ 411 public static <C extends RingElem<C>> 412 GenPolynomialRing<C> 413 permutation( List<Integer> P, GenPolynomialRing<C> R ) { 414 if ( R == null ) { 415 return R; 416 } 417 if ( R.vars == null || R.nvar <= 1 ) { 418 return R; 419 } 420 GenPolynomialRing<C> S; 421 TermOrder tord = R.tord; 422 if ( tord.getEvord2() != 0 ) { 423 //throw new IllegalArgumentException("split term orders not permutable"); 424 logger.warn("split term orders not permutable, resetting to base term order"); 425 tord = new TermOrder( tord.getEvord() ); 426 } 427 long[][] weight = tord.getWeight(); 428 if ( weight != null ) { 429 long[][] w = new long[ weight.length ][]; 430 for ( int i = 0; i < weight.length; i++ ) { 431 w[i] = longArrayPermutation(P,weight[i]); 432 } 433 tord = new TermOrder( w ); 434 } 435 String[] v1 = new String[R.vars.length]; 436 for ( int i = 0; i < v1.length; i++ ) { 437 v1[i] = R.vars[ v1.length-1 - i ]; 438 } 439 String[] vars = stringArrayPermutation( P, v1 ); 440 String[] v2 = new String[R.vars.length]; 441 for ( int i = 0; i < v1.length; i++ ) { 442 v2[i] = vars[ v2.length-1 - i ]; 443 } 444 S = new GenPolynomialRing<C>( R.coFac, R.nvar, tord, v2 ); 445 return S; 446 } 447 448 449 /** 450 * Optimize variable order. 451 * @param R polynomial ring. 452 * @param L list of polynomials. 453 * @return optimized polynomial list. 454 */ 455 public static <C extends RingElem<C>> 456 OptimizedPolynomialList<C> 457 optimizeTermOrder( GenPolynomialRing<C> R, List<GenPolynomial<C>> L ) { 458 List<Integer> perm = optimalPermutation( degreeMatrix(L) ); 459 GenPolynomialRing<C> pring; 460 pring = TermOrderOptimization.<C>permutation( perm, R ); 461 462 List<GenPolynomial<C>> ppolys; 463 ppolys = TermOrderOptimization.<C>permutation( perm, pring, L ); 464 465 OptimizedPolynomialList<C> op 466 = new OptimizedPolynomialList<C>(perm,pring,ppolys); 467 return op; 468 } 469 470 471 /** 472 * Optimize variable order. 473 * @param P polynomial list. 474 * @return optimized polynomial list. 475 */ 476 public static <C extends RingElem<C>> 477 OptimizedPolynomialList<C> optimizeTermOrder( PolynomialList<C> P ) { 478 if ( P == null ) { 479 return null; 480 } 481 List<Integer> perm = optimalPermutation( degreeMatrix( P.list ) ); 482 GenPolynomialRing<C> pring; 483 pring = TermOrderOptimization.<C>permutation( perm, P.ring ); 484 485 List<GenPolynomial<C>> ppolys; 486 ppolys = TermOrderOptimization.<C>permutation( perm, pring, P.list ); 487 488 OptimizedPolynomialList<C> op 489 = new OptimizedPolynomialList<C>(perm,pring,ppolys); 490 return op; 491 } 492 493 494 /** 495 * Optimize variable order on coefficients. 496 * @param P polynomial list. 497 * @return optimized polynomial list. 498 */ 499 public static <C extends RingElem<C>> 500 OptimizedPolynomialList<GenPolynomial<C>> 501 optimizeTermOrderOnCoefficients( PolynomialList<GenPolynomial<C>> P ) { 502 if ( P == null ) { 503 return null; 504 } 505 List<Integer> perm = optimalPermutation( degreeMatrixOfCoefficients( P.list ) ); 506 507 GenPolynomialRing<GenPolynomial<C>> ring = P.ring; 508 GenPolynomialRing<C> coFac = (GenPolynomialRing<C>) ring.coFac; 509 GenPolynomialRing<C> pFac; 510 pFac = TermOrderOptimization.<C>permutation( perm, coFac ); 511 512 GenPolynomialRing<GenPolynomial<C>> pring; 513 pring = new GenPolynomialRing<GenPolynomial<C>>(pFac, ring.nvar, ring.tord, ring.vars); 514 515 List<GenPolynomial<GenPolynomial<C>>> ppolys; 516 ppolys = TermOrderOptimization.<C>permutationOnCoefficients( perm, pring, P.list ); 517 518 OptimizedPolynomialList<GenPolynomial<C>> op 519 = new OptimizedPolynomialList<GenPolynomial<C>>(perm,pring,ppolys); 520 return op; 521 } 522 523 }