001/*
002 * $Id: ModSolvableGroebnerBaseAbstract.java 4104 2012-08-18 10:00:59Z kredel $
003 */
004
005package edu.jas.gbmod;
006
007import java.util.ArrayList;
008import java.util.List;
009
010import org.apache.log4j.Logger;
011
012
013import edu.jas.structure.RingElem;
014
015import edu.jas.gb.SolvableGroebnerBase;
016import edu.jas.gb.SolvableGroebnerBaseSeq;
017import edu.jas.poly.GenSolvablePolynomial;
018import edu.jas.poly.GenSolvablePolynomialRing;
019import edu.jas.poly.ModuleList;
020import edu.jas.poly.PolynomialList;
021import edu.jas.poly.TermOrder;
022
023
024
025/**
026 * Module solvable Groebner Bases class.
027 * Implements module solvable Groebner bases and GB test.
028 * @param <C> coefficient type
029 * @author Heinz Kredel
030 */
031
032public class ModSolvableGroebnerBaseAbstract<C extends RingElem<C>> 
033       implements ModSolvableGroebnerBase<C> {
034
035    private static final Logger logger = Logger.getLogger(ModSolvableGroebnerBase.class);
036    private final boolean debug = logger.isDebugEnabled();
037
038
039    /**
040     * Used Solvable Groebner base algorithm.
041     */
042    protected final SolvableGroebnerBase<C> sbb;
043
044
045    /**
046     * Constructor.
047     */
048    public ModSolvableGroebnerBaseAbstract() {
049        sbb = new SolvableGroebnerBaseSeq<C>();
050    }
051
052
053    /**
054     * Module left Groebner base test.
055     * @param modv number of modul variables.
056     * @param F a module basis.
057     * @return true, if F is a left Groebner base, else false.
058     */
059    public boolean 
060           isLeftGB(int modv, List<GenSolvablePolynomial<C>> F) {  
061        return sbb.isLeftGB(modv,F);
062    }
063
064
065    /**
066     * Module left Groebner base test.
067     * @param M a module basis.
068     * @return true, if M is a left Groebner base, else false.
069     */
070    public boolean 
071           isLeftGB(ModuleList<C> M) {  
072        if ( M == null || M.list == null ) {
073            return true;
074        }
075        if ( M.rows == 0 || M.cols == 0 ) {
076            return true;
077        }
078        int modv = M.cols; // > 0  
079        PolynomialList<C> F = M.getPolynomialList();
080        return sbb.isLeftGB(modv,F.castToSolvableList());
081    }
082
083
084    /**
085     * Left Groebner base using pairlist class.
086     * @param modv number of modul variables.
087     * @param F a module basis.
088     * @return leftGB(F) a left Groebner base for F.
089     */
090    public List<GenSolvablePolynomial<C>> 
091           leftGB(int modv, List<GenSolvablePolynomial<C>> F) {  
092        return sbb.leftGB(modv,F);
093    }
094
095    /**
096     * Left Groebner base using pairlist class.
097     * @param M a module basis.
098     * @return leftGB(M) a left Groebner base for M.
099     */
100    @SuppressWarnings("unchecked")
101    public ModuleList<C> 
102           leftGB(ModuleList<C> M) {  
103        ModuleList<C> N = M;
104        if ( M == null || M.list == null ) {
105            return N;
106        }
107        if ( M.rows == 0 || M.cols == 0 ) {
108            return N;
109        }
110        PolynomialList<C> F = M.getPolynomialList();
111        if ( debug ) {
112           logger.info("F left +++++++++++++++++++ \n" + F);
113        }
114        GenSolvablePolynomialRing<C> sring 
115            = (GenSolvablePolynomialRing<C>)F.ring;
116        int modv = M.cols;
117        List<GenSolvablePolynomial<C>> G 
118            = sbb.leftGB(modv,F.castToSolvableList());
119        F = new PolynomialList<C>(sring,G);
120        if ( debug ) {
121           logger.info("G left +++++++++++++++++++ \n" + F);
122        }
123        N = F.getModuleList(modv);
124        return N;
125    }
126
127
128
129    /**
130     * Module twosided Groebner base test.
131     * @param modv number of modul variables.
132     * @param F a module basis.
133     * @return true, if F is a twosided Groebner base, else false.
134     */
135    public boolean 
136           isTwosidedGB(int modv, List<GenSolvablePolynomial<C>> F) {  
137        return sbb.isTwosidedGB(modv,F);
138    }
139
140    /**
141     * Module twosided Groebner base test.
142     * @param M a module basis.
143     * @return true, if M is a twosided Groebner base, else false.
144     */
145    public boolean 
146           isTwosidedGB(ModuleList<C> M) {  
147        if ( M == null || M.list == null ) {
148            return true;
149        }
150        if ( M.rows == 0 || M.cols == 0 ) {
151            return true;
152        }
153        PolynomialList<C> F = M.getPolynomialList();
154        int modv = M.cols; // > 0  
155        return sbb.isTwosidedGB(modv,F.castToSolvableList());
156    }
157
158
159    /**
160     * Twosided Groebner base using pairlist class.
161     * @param modv number of modul variables.
162     * @param F a module basis.
163     * @return tsGB(F) a twosided Groebner base for F.
164     */
165    public List<GenSolvablePolynomial<C>> 
166           twosidedGB(int modv, List<GenSolvablePolynomial<C>> F) {  
167        return sbb.twosidedGB(modv,F);
168    }
169
170    /**
171     * Twosided Groebner base using pairlist class.
172     * @param M a module basis.
173     * @return tsGB(M) a twosided Groebner base for M.
174     */
175    @SuppressWarnings("unchecked")
176    public ModuleList<C> 
177           twosidedGB(ModuleList<C> M) {  
178        ModuleList<C> N = M;
179        if ( M == null || M.list == null ) {
180            return N;
181        }
182        if ( M.rows == 0 || M.cols == 0 ) {
183            return N;
184        }
185        PolynomialList<C> F = M.getPolynomialList();
186        GenSolvablePolynomialRing<C> sring 
187            = (GenSolvablePolynomialRing<C>)F.ring;
188        int modv = M.cols;
189        List<GenSolvablePolynomial<C>> G 
190            = sbb.twosidedGB(modv,F.castToSolvableList());
191        F = new PolynomialList<C>(sring,G);
192        N = F.getModuleList(modv);
193        return N;
194    }
195
196
197    /**
198     * Module right Groebner base test.
199     * @param modv number of modul variables.
200     * @param F a module basis.
201     * @return true, if F is a right Groebner base, else false.
202     */
203    public boolean 
204           isRightGB(int modv, List<GenSolvablePolynomial<C>> F) {  
205        return sbb.isRightGB(modv,F);
206    }
207
208
209    /**
210     * Module right Groebner base test.
211     * @param M a module basis.
212     * @return true, if M is a right Groebner base, else false.
213     */
214    public boolean 
215           isRightGB(ModuleList<C> M) {  
216        if ( M == null || M.list == null ) {
217            return true;
218        }
219        if ( M.rows == 0 || M.cols == 0 ) {
220            return true;
221        }
222        int modv = M.cols; // > 0  
223        PolynomialList<C> F = M.getPolynomialList();
224        //System.out.println("F test = " + F);
225        return sbb.isRightGB( modv, F.castToSolvableList() );
226    }
227
228
229    /**
230     * Right Groebner base using pairlist class.
231     * @param modv number of modul variables.
232     * @param F a module basis.
233     * @return rightGB(F) a right Groebner base for F.
234     */
235    public List<GenSolvablePolynomial<C>> 
236           rightGB(int modv, List<GenSolvablePolynomial<C>> F) {  
237        if ( modv == 0 ) {
238           return sbb.rightGB(modv,F);
239        }
240        throw new UnsupportedOperationException("modv != 0 not jet implemented");
241        // return sbb.rightGB(modv,F);
242    }
243
244
245    /**
246     * Right Groebner base using pairlist class.
247     * @param M a module basis.
248     * @return rightGB(M) a right Groebner base for M.
249     */
250    @SuppressWarnings("unchecked")
251    public ModuleList<C> 
252           rightGB(ModuleList<C> M) {  
253        ModuleList<C> N = M;
254        if ( M == null || M.list == null ) {
255            return N;
256        }
257        if ( M.rows == 0 || M.cols == 0 ) {
258            return N;
259        }
260        if ( debug ) {
261           logger.info("M ====================== \n" + M);
262        }
263        TermOrder to = M.ring.tord;
264        if ( to.getSplit() <= M.ring.nvar ) {
265            throw new IllegalArgumentException("extended TermOrders not supported for rightGBs: " + to);
266        }
267        List<List<GenSolvablePolynomial<C>>> mlist = M.castToSolvableList();
268        GenSolvablePolynomialRing<C> sring 
269            = (GenSolvablePolynomialRing<C>)M.ring;
270        GenSolvablePolynomialRing<C> rring = sring.reverse(true); //true
271        sring = rring.reverse(true); // true
272
273        List<List<GenSolvablePolynomial<C>>> nlist = 
274            new ArrayList<List<GenSolvablePolynomial<C>>>( M.rows );
275        for ( List<GenSolvablePolynomial<C>> row : mlist ) {
276            List<GenSolvablePolynomial<C>> nrow = 
277                new ArrayList<GenSolvablePolynomial<C>>( row.size() );
278            for ( GenSolvablePolynomial<C> elem : row ) {
279                GenSolvablePolynomial<C> nelem 
280                   = (GenSolvablePolynomial<C>)elem.reverse(rring);
281                nrow.add( nelem );
282            }
283            nlist.add( nrow );
284        }
285        ModuleList<C> rM = new ModuleList<C>( rring, nlist );
286        if ( debug ) {
287           logger.info("rM -------------------- \n" + rM);
288        }
289        ModuleList<C> rMg = leftGB( rM );
290        if ( debug ) {
291           logger.info("rMg -------------------- \n" + rMg);
292           logger.info("isLeftGB(rMg) ---------- " + isLeftGB(rMg));
293        }
294        mlist = rMg.castToSolvableList();
295        nlist = new ArrayList<List<GenSolvablePolynomial<C>>>( rMg.rows );
296        for ( List<GenSolvablePolynomial<C>> row : mlist ) {
297            List<GenSolvablePolynomial<C>> nrow = 
298                new ArrayList<GenSolvablePolynomial<C>>( row.size() );
299            for ( GenSolvablePolynomial<C> elem : row ) {
300                GenSolvablePolynomial<C> nelem 
301                   = (GenSolvablePolynomial<C>)elem.reverse(sring);
302                nrow.add( nelem );
303            }
304            nlist.add( nrow );
305        }
306        ModuleList<C> Mg = new ModuleList<C>( sring, nlist );
307        if ( debug ) {
308           logger.info("Mg -------------------- \n" + Mg);
309           logger.info("isRightGB(Mg) --------- " + isRightGB(Mg));
310        }
311        return Mg;
312    }
313
314}