001/* 002 * $Id: GBSigBased.java 5809 2018-04-23 19:54:18Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import javax.script.ScriptEngine; 012import javax.script.ScriptEngineManager; 013import javax.script.ScriptException; 014 015import org.apache.log4j.Logger; 016 017import edu.jas.poly.GenPolynomial; 018import edu.jas.structure.GcdRingElem; 019 020 021/** 022 * Groebner bases via signatur based GBs using jython script. TODO: Computing 023 * via the ScriptEngine is way slower than the direct execution in the jython 024 * interpreter. Check if a different engine is in the path or if it must be 025 * configured in some special way. 026 * @author Heinz Kredel 027 */ 028 029public class GBSigBased<C extends GcdRingElem<C>> extends GroebnerBaseAbstract<C> { 030 031 032 private static final Logger logger = Logger.getLogger(GBSigBased.class); 033 034 035 private static final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled(); 036 037 038 /** 039 * GB algorithm indicators: 040 * sbgb = sigbased_gb(), arri = arris_algorithm(), 041 * ggv = ggv(), ggv1 = ggv_first_implementation(), f5 = f5(), ff5 = f5z(). 042 */ 043 public static enum GBAlgo { 044 sbgb, arri, ggv, ggv1, f5, ff5 045 } 046 047 048 /** 049 * Scripting engine. 050 */ 051 public final ScriptEngine engine; 052 053 054 /** 055 * Selected GB algorithm. 056 */ 057 public final GBAlgo algo; 058 059 060 /** 061 * GBSigBased constructor. 062 */ 063 public GBSigBased() { 064 this(GBAlgo.ggv1); 065 } 066 067 068 /** 069 * GBSigBased constructor. 070 * @param a GB algorithm indicator. 071 */ 072 public GBSigBased(GBAlgo a) { 073 algo = a; 074 ScriptEngineManager manager = new ScriptEngineManager(); 075 //System.out.println("manager = " + manager); 076 //System.out.println("factories = " + manager.getEngineFactories()); 077 engine = manager.getEngineByExtension("py"); 078 if (engine == null) { 079 logger.error("no script engine found"); 080 throw new RuntimeException("no script engine found"); 081 } 082 StringBuffer sb = new StringBuffer(); 083 sb.append("from jas import PolyRing, ZZ, QQ, arraylist2pylist, pylist2arraylist;\n"); 084 sb.append("from basic_sigbased_gb import sigbased_gb, arris_algorithm, ggv, ggv_first_implementation, f5, f5z;\n"); 085 sb.append("sbgb = sigbased_gb();\n"); 086 sb.append("arri = arris_algorithm();\n"); 087 sb.append("ggv = ggv();\n"); 088 sb.append("ggv1 = ggv_first_implementation();\n"); 089 sb.append("f5 = f5();\n"); 090 sb.append("ff5 = f5z();\n"); 091 String ex = sb.toString(); 092 if (debug) { 093 logger.info("input for evaluation:\n" + ex); 094 } 095 try { 096 Object ans = engine.eval(ex); 097 if (ans != null) { 098 logger.info("constructor answer: " + ans); 099 } 100 } catch (ScriptException e) { 101 e.printStackTrace(); 102 throw new RuntimeException(e); 103 } 104 logger.info(toString()); 105 } 106 107 108 /** 109 * Get the String representation with GB engine. 110 * @see java.lang.Object#toString() 111 */ 112 @Override 113 public String toString() { 114 return "GBSigBased[ " + engine.getClass().getName() + ", GBAlgo = " + algo + " ]"; 115 } 116 117 118 /** 119 * Cleanup and terminate ThreadPool. 120 */ 121 @Override 122 public void terminate() { 123 } 124 125 126 /** 127 * Cancel ThreadPool. 128 */ 129 @Override 130 public int cancel() { 131 return 0; 132 } 133 134 135 /** 136 * Groebner base. 137 * @param modv module variable number. 138 * @param F polynomial list. 139 * @return GB(F) a Groebner base of F. 140 */ 141 @Override 142 @SuppressWarnings("unchecked") 143 public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) { 144 if (F == null || F.isEmpty()) { 145 return F; 146 } 147 if (modv != 0) { 148 throw new UnsupportedOperationException("implemented only for modv = 0, not " + modv); 149 } 150 //GenPolynomialRing<C> pfac = F.get(0).ring; 151 List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>(); 152 long millis = System.currentTimeMillis(); 153 try { 154 engine.put("F", F); 155 StringBuffer sb = new StringBuffer(); 156 //sb.append("r = " + pfac.toScript() + ";\n"); 157 //sb.append("print str(r);\n"); 158 //sb.append("print \"F = \" + str(F);\n"); 159 sb.append("Fp = arraylist2pylist(F);\n"); 160 161 //sb.append("Gp = sbgb.basis_sig(Fp);\n"); 162 //sb.append("Gp = ff5.basis_sig(Fp);\n"); 163 //sb.append("Gp = arri.basis_sig(Fp);\n"); 164 //sb.append("Gp = ggv1.basis_sig(Fp);\n"); 165 sb.append("Gp = " + algo + ".basis_sig(Fp);\n"); 166 sb.append("G = pylist2arraylist(Gp);\n"); 167 168 String ex = sb.toString(); 169 if (debug) { 170 logger.info("input for evaluation:\n" + ex); 171 } 172 Object ans = engine.eval(ex); 173 if (ans != null) { 174 logger.info("answer: " + ans); 175 } 176 G = (List<GenPolynomial<C>>) engine.get("G"); 177 } catch (ScriptException e) { 178 e.printStackTrace(); 179 } catch (Exception e) { 180 e.printStackTrace(); 181 } 182 millis = System.currentTimeMillis() - millis; 183 System.out.println("evaluation took " + millis); 184 if (debug) { 185 logger.info("polynomials G: " + G); 186 } 187 return G; 188 } 189 190}