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