/geogebra/edu/jas/poly/TermOrderOptimization.java

https://github.com/ancsing/ggw · Java · 535 lines · 342 code · 64 blank · 129 comment · 82 complexity · 7a4e17efe974cb42f5526acfda511d5a MD5 · raw file

  1. /*
  2. * $Id: TermOrderOptimization.java 3210 2010-07-05 12:25:27Z kredel $
  3. */
  4. package edu.jas.poly;
  5. import java.util.List;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.Arrays;
  9. import java.util.Map;
  10. import java.util.SortedMap;
  11. import java.util.TreeMap;
  12. import org.apache.log4j.Logger;
  13. import edu.jas.structure.RingElem;
  14. import edu.jas.arith.BigInteger;
  15. import edu.jas.poly.GenPolynomial;
  16. import edu.jas.poly.GenPolynomialRing;
  17. import edu.jas.vector.BasicLinAlg;
  18. /**
  19. * Term order optimization.
  20. * See mas10/maspoly/DIPTOO.m{di}.
  21. * @author Heinz Kredel
  22. */
  23. public class TermOrderOptimization {
  24. private static final Logger logger = Logger.getLogger(TermOrderOptimization.class);
  25. //private static boolean debug = logger.isDebugEnabled();
  26. /**
  27. * Degree matrix.
  28. * @param A polynomial to be considered.
  29. * @return degree matrix.
  30. */
  31. public static <C extends RingElem<C>>
  32. List<GenPolynomial<BigInteger>>
  33. degreeMatrix( GenPolynomial<C> A ) {
  34. List<GenPolynomial<BigInteger>> dem = null;
  35. if ( A == null ) {
  36. return dem;
  37. }
  38. BigInteger cfac = new BigInteger();
  39. GenPolynomialRing<BigInteger> ufac
  40. = new GenPolynomialRing<BigInteger>(cfac,1);
  41. int nvar = A.numberOfVariables();
  42. dem = new ArrayList<GenPolynomial<BigInteger>>( nvar );
  43. for ( int i = 0; i < nvar; i++ ) {
  44. dem.add( ufac.getZERO() );
  45. }
  46. if ( A.isZERO() ) {
  47. return dem;
  48. }
  49. for ( ExpVector e: A.getMap().keySet() ) {
  50. dem = expVectorAdd(dem, e );
  51. }
  52. return dem;
  53. }
  54. /**
  55. * Degree matrix exponent vector add.
  56. * @param dm degree matrix.
  57. * @param e exponent vector.
  58. * @return degree matrix + e.
  59. */
  60. public static
  61. List<GenPolynomial<BigInteger>>
  62. expVectorAdd(List<GenPolynomial<BigInteger>> dm, ExpVector e) {
  63. for ( int i = 0; i < dm.size() && i < e.length(); i++ ) {
  64. GenPolynomial<BigInteger> p = dm.get(i);
  65. long u = e.getVal(i);
  66. ExpVector f = ExpVector.create(1,0,u);
  67. p = p.sum( p.ring.getONECoefficient(), f );
  68. dm.set(i,p);
  69. }
  70. return dm;
  71. }
  72. /**
  73. * Degree matrix of coefficient polynomials.
  74. * @param A polynomial to be considered.
  75. * @return degree matrix for the coeficients.
  76. */
  77. public static <C extends RingElem<C>>
  78. List<GenPolynomial<BigInteger>>
  79. degreeMatrixOfCoefficients( GenPolynomial<GenPolynomial<C>> A ) {
  80. if ( A == null ) {
  81. throw new IllegalArgumentException("polynomial must not be null");
  82. }
  83. return degreeMatrix( A.getMap().values() );
  84. }
  85. /**
  86. * Degree matrix.
  87. * @param L list of polynomial to be considered.
  88. * @return degree matrix.
  89. */
  90. public static <C extends RingElem<C>>
  91. List<GenPolynomial<BigInteger>>
  92. degreeMatrix( Collection<GenPolynomial<C>> L ) {
  93. if ( L == null ) {
  94. throw new IllegalArgumentException("list must be non null");
  95. }
  96. BasicLinAlg<BigInteger> bla
  97. = new BasicLinAlg<BigInteger>();
  98. List<GenPolynomial<BigInteger>> dem = null;
  99. for ( GenPolynomial<C> p : L ) {
  100. List<GenPolynomial<BigInteger>> dm = degreeMatrix( p );
  101. if ( dem == null ) {
  102. dem = dm;
  103. } else {
  104. dem = bla.vectorAdd( dem, dm );
  105. }
  106. }
  107. return dem;
  108. }
  109. /**
  110. * Degree matrix of coefficient polynomials.
  111. * @param L list of polynomial to be considered.
  112. * @return degree matrix for the coeficients.
  113. */
  114. public static <C extends RingElem<C>>
  115. List<GenPolynomial<BigInteger>>
  116. degreeMatrixOfCoefficients( Collection<GenPolynomial<GenPolynomial<C>>> L ) {
  117. if ( L == null ) {
  118. throw new IllegalArgumentException("list must not be null");
  119. }
  120. BasicLinAlg<BigInteger> bla
  121. = new BasicLinAlg<BigInteger>();
  122. List<GenPolynomial<BigInteger>> dem = null;
  123. for ( GenPolynomial<GenPolynomial<C>> p : L ) {
  124. List<GenPolynomial<BigInteger>> dm = degreeMatrixOfCoefficients( p );
  125. if ( dem == null ) {
  126. dem = dm;
  127. } else {
  128. dem = bla.vectorAdd( dem, dm );
  129. }
  130. }
  131. return dem;
  132. }
  133. /**
  134. * Optimal permutation for the Degree matrix.
  135. * @param D degree matrix.
  136. * @return optimal permutation for D.
  137. */
  138. public static
  139. List<Integer>
  140. optimalPermutation( List<GenPolynomial<BigInteger>> D ) {
  141. if ( D == null ) {
  142. throw new IllegalArgumentException("list must be non null");
  143. }
  144. List<Integer> P = new ArrayList<Integer>( D.size() );
  145. if ( D.size() == 0 ) {
  146. return P;
  147. }
  148. if ( D.size() == 1 ) {
  149. P.add(0);
  150. return P;
  151. }
  152. SortedMap< GenPolynomial<BigInteger>, List<Integer> > map
  153. = new TreeMap<GenPolynomial<BigInteger>,List<Integer>>();
  154. int i = 0;
  155. for ( GenPolynomial<BigInteger> p : D ) {
  156. List<Integer> il = map.get(p);
  157. if ( il == null ) {
  158. il = new ArrayList<Integer>(3);
  159. }
  160. il.add( i );
  161. map.put( p, il );
  162. i++;
  163. }
  164. List<List<Integer>> V = new ArrayList<List<Integer>>( map.values() );
  165. //System.out.println("V = " + V);
  166. //for ( int j = V.size()-1; j >= 0; j-- ) {
  167. for ( int j = 0; j < V.size(); j++ ) {
  168. List<Integer> v = V.get(j);
  169. for ( Integer k : v ) {
  170. P.add( k );
  171. }
  172. }
  173. return P;
  174. }
  175. /**
  176. * Permutation of a list.
  177. * @param L list.
  178. * @param P permutation.
  179. * @return P(L).
  180. */
  181. public static <T>
  182. List<T>
  183. listPermutation( List<Integer> P, List<T> L ) {
  184. if ( L == null || L.size() <= 1 ) {
  185. return L;
  186. }
  187. List<T> pl = new ArrayList<T>( L.size() );
  188. for ( Integer i : P ) {
  189. pl.add( L.get( (int)i ) );
  190. }
  191. return pl;
  192. }
  193. /**
  194. * Permutation of an array.
  195. * Compiles, but does not work, requires JDK 1.6 to work.
  196. * @param a array.
  197. * @param P permutation.
  198. * @return P(a).
  199. */
  200. @SuppressWarnings("unchecked")
  201. public static <T>
  202. T[]
  203. arrayPermutation( List<Integer> P, T[] a ) {
  204. if ( a == null || a.length <= 1 ) {
  205. return a;
  206. }
  207. T[] b = (T[]) new Object[a.length]; // jdk 1.5
  208. //T[] b = Arrays.<T>copyOf( a, a.length ); // jdk 1.6, works
  209. int j = 0;
  210. for ( Integer i : P ) {
  211. b[j] = a[ (int)i ];
  212. j++;
  213. }
  214. return b;
  215. }
  216. /**
  217. * Permutation of an array.
  218. * @param a array.
  219. * @param P permutation.
  220. * @return P(a).
  221. */
  222. public static
  223. String[]
  224. stringArrayPermutation( List<Integer> P, String[] a ) {
  225. if ( a == null || a.length <= 1 ) {
  226. return a;
  227. }
  228. String[] b = new String[a.length]; // jdk 1.5
  229. //T[] b = Arrays.<T>copyOf( a, a.length ); // jdk 1.6
  230. int j = 0;
  231. for ( Integer i : P ) {
  232. b[j] = a[ (int)i ];
  233. j++;
  234. }
  235. return b;
  236. }
  237. /**
  238. * Permutation of a long array.
  239. * @param a array of long.
  240. * @param P permutation.
  241. * @return P(a).
  242. */
  243. public static
  244. long[]
  245. longArrayPermutation( List<Integer> P, long[] a ) {
  246. if ( a == null || a.length <= 1 ) {
  247. return a;
  248. }
  249. long[] b = new long[ a.length ];
  250. int j = 0;
  251. for ( Integer i : P ) {
  252. b[j] = a[ (int)i ];
  253. j++;
  254. }
  255. return b;
  256. }
  257. /**
  258. * Permutation of an exponent vector.
  259. * @param e exponent vector.
  260. * @param P permutation.
  261. * @return P(e).
  262. */
  263. public static
  264. ExpVector
  265. permutation( List<Integer> P, ExpVector e ) {
  266. if ( e == null ) {
  267. return e;
  268. }
  269. long[] u = longArrayPermutation( P, e.getVal() );
  270. ExpVector f = ExpVector.create( u );
  271. return f;
  272. }
  273. /**
  274. * Permutation of polynomial exponent vectors.
  275. * @param A polynomial.
  276. * @param R polynomial ring.
  277. * @param P permutation.
  278. * @return P(A).
  279. */
  280. public static <C extends RingElem<C>>
  281. GenPolynomial<C>
  282. permutation( List<Integer> P, GenPolynomialRing<C> R, GenPolynomial<C> A ) {
  283. if ( A == null ) {
  284. return A;
  285. }
  286. GenPolynomial<C> B = R.getZERO().clone();
  287. Map<ExpVector,C> Bv = B.val; //getMap();
  288. for ( Map.Entry<ExpVector,C> y: A.getMap().entrySet() ) {
  289. ExpVector e = y.getKey();
  290. C a = y.getValue();
  291. //System.out.println("e = " + e);
  292. ExpVector f = permutation(P,e);
  293. //System.out.println("f = " + f);
  294. Bv.put( f, a ); // assert f not in Bv
  295. }
  296. return B;
  297. }
  298. /**
  299. * Permutation of polynomial exponent vectors.
  300. * @param L list of polynomials.
  301. * @param R polynomial ring.
  302. * @param P permutation.
  303. * @return P(L).
  304. */
  305. public static <C extends RingElem<C>>
  306. List<GenPolynomial<C>>
  307. permutation( List<Integer> P, GenPolynomialRing<C> R, List<GenPolynomial<C>> L ) {
  308. if ( L == null || L.size() == 0 ) {
  309. return L;
  310. }
  311. List<GenPolynomial<C>> K = new ArrayList<GenPolynomial<C>>( L.size() );
  312. for ( GenPolynomial<C> a: L ) {
  313. GenPolynomial<C> b = permutation( P, R, a );
  314. K.add( b );
  315. }
  316. return K;
  317. }
  318. /**
  319. * Permutation of polynomial exponent vectors of coefficient polynomials.
  320. * @param A polynomial.
  321. * @param R polynomial ring.
  322. * @param P permutation.
  323. * @return P(A).
  324. */
  325. public static <C extends RingElem<C>>
  326. GenPolynomial<GenPolynomial<C>>
  327. permutationOnCoefficients( List<Integer> P,
  328. GenPolynomialRing<GenPolynomial<C>> R,
  329. GenPolynomial<GenPolynomial<C>> A ) {
  330. if ( A == null ) {
  331. return A;
  332. }
  333. GenPolynomial<GenPolynomial<C>> B = R.getZERO().clone();
  334. GenPolynomialRing<C> cf = (GenPolynomialRing<C>) R.coFac;
  335. Map<ExpVector,GenPolynomial<C>> Bv = B.val; //getMap();
  336. for ( Map.Entry<ExpVector,GenPolynomial<C>> y: A.getMap().entrySet() ) {
  337. ExpVector e = y.getKey();
  338. GenPolynomial<C> a = y.getValue();
  339. //System.out.println("e = " + e);
  340. GenPolynomial<C> b = permutation(P,cf,a);
  341. //System.out.println("b = " + b);
  342. Bv.put( e, b ); // assert e not in Bv
  343. }
  344. return B;
  345. }
  346. /**
  347. * Permutation of polynomial exponent vectors of coefficients.
  348. * @param L list of polynomials.
  349. * @param R polynomial ring.
  350. * @param P permutation.
  351. * @return P(L).
  352. */
  353. public static <C extends RingElem<C>>
  354. List<GenPolynomial<GenPolynomial<C>>>
  355. permutationOnCoefficients( List<Integer> P,
  356. GenPolynomialRing<GenPolynomial<C>> R,
  357. List<GenPolynomial<GenPolynomial<C>>> L ) {
  358. if ( L == null || L.size() == 0 ) {
  359. return L;
  360. }
  361. List<GenPolynomial<GenPolynomial<C>>> K
  362. = new ArrayList<GenPolynomial<GenPolynomial<C>>>( L.size() );
  363. for ( GenPolynomial<GenPolynomial<C>> a: L ) {
  364. GenPolynomial<GenPolynomial<C>> b = permutationOnCoefficients( P, R, a );
  365. K.add( b );
  366. }
  367. return K;
  368. }
  369. /**
  370. * Permutation of polynomial ring variables.
  371. * @param R polynomial ring.
  372. * @param P permutation.
  373. * @return P(R).
  374. */
  375. public static <C extends RingElem<C>>
  376. GenPolynomialRing<C>
  377. permutation( List<Integer> P, GenPolynomialRing<C> R ) {
  378. if ( R == null ) {
  379. return R;
  380. }
  381. if ( R.vars == null || R.nvar <= 1 ) {
  382. return R;
  383. }
  384. GenPolynomialRing<C> S;
  385. TermOrder tord = R.tord;
  386. if ( tord.getEvord2() != 0 ) {
  387. throw new IllegalArgumentException("split term orders not permutable");
  388. }
  389. long[][] weight = tord.getWeight();
  390. if ( weight != null ) {
  391. long[][] w = new long[ weight.length ][];
  392. for ( int i = 0; i < weight.length; i++ ) {
  393. w[i] = longArrayPermutation(P,weight[i]);
  394. }
  395. tord = new TermOrder( w );
  396. }
  397. String[] v1 = new String[R.vars.length];
  398. for ( int i = 0; i < v1.length; i++ ) {
  399. v1[i] = R.vars[ v1.length-1 - i ];
  400. }
  401. String[] vars = stringArrayPermutation( P, v1 );
  402. String[] v2 = new String[R.vars.length];
  403. for ( int i = 0; i < v1.length; i++ ) {
  404. v2[i] = vars[ v2.length-1 - i ];
  405. }
  406. S = new GenPolynomialRing<C>( R.coFac, R.nvar, tord, v2 );
  407. return S;
  408. }
  409. /**
  410. * Optimize variable order.
  411. * @param R polynomial ring.
  412. * @param L list of polynomials.
  413. * @return optimized polynomial list.
  414. */
  415. public static <C extends RingElem<C>>
  416. OptimizedPolynomialList<C>
  417. optimizeTermOrder( GenPolynomialRing<C> R, List<GenPolynomial<C>> L ) {
  418. List<Integer> perm = optimalPermutation( degreeMatrix(L) );
  419. GenPolynomialRing<C> pring;
  420. pring = TermOrderOptimization.<C>permutation( perm, R );
  421. List<GenPolynomial<C>> ppolys;
  422. ppolys = TermOrderOptimization.<C>permutation( perm, pring, L );
  423. OptimizedPolynomialList<C> op
  424. = new OptimizedPolynomialList<C>(perm,pring,ppolys);
  425. return op;
  426. }
  427. /**
  428. * Optimize variable order.
  429. * @param P polynomial list.
  430. * @return optimized polynomial list.
  431. */
  432. public static <C extends RingElem<C>>
  433. OptimizedPolynomialList<C>
  434. optimizeTermOrder( PolynomialList<C> P ) {
  435. if ( P == null ) {
  436. return null;
  437. }
  438. List<Integer> perm = optimalPermutation( degreeMatrix( P.list ) );
  439. GenPolynomialRing<C> pring;
  440. pring = TermOrderOptimization.<C>permutation( perm, P.ring );
  441. List<GenPolynomial<C>> ppolys;
  442. ppolys = TermOrderOptimization.<C>permutation( perm, pring, P.list );
  443. OptimizedPolynomialList<C> op
  444. = new OptimizedPolynomialList<C>(perm,pring,ppolys);
  445. return op;
  446. }
  447. /**
  448. * Optimize variable order on coefficients.
  449. * @param P polynomial list.
  450. * @return optimized polynomial list.
  451. */
  452. public static <C extends RingElem<C>>
  453. OptimizedPolynomialList<GenPolynomial<C>>
  454. optimizeTermOrderOnCoefficients( PolynomialList<GenPolynomial<C>> P ) {
  455. if ( P == null ) {
  456. return null;
  457. }
  458. List<Integer> perm = optimalPermutation( degreeMatrixOfCoefficients( P.list ) );
  459. GenPolynomialRing<GenPolynomial<C>> ring = P.ring;
  460. GenPolynomialRing<C> coFac = (GenPolynomialRing<C>) ring.coFac;
  461. GenPolynomialRing<C> pFac;
  462. pFac = TermOrderOptimization.<C>permutation( perm, coFac );
  463. GenPolynomialRing<GenPolynomial<C>> pring;
  464. pring = new GenPolynomialRing<GenPolynomial<C>>(pFac, ring.nvar, ring.tord, ring.vars);
  465. List<GenPolynomial<GenPolynomial<C>>> ppolys;
  466. ppolys = TermOrderOptimization.<C>permutationOnCoefficients( perm, pring, P.list );
  467. OptimizedPolynomialList<GenPolynomial<C>> op
  468. = new OptimizedPolynomialList<GenPolynomial<C>>(perm,pring,ppolys);
  469. return op;
  470. }
  471. }