001/*
002 * $Id: SyzygyAbstract.java 5267 2015-07-27 17:57:50Z kredel $
003 */
004
005package edu.jas.gbufd;
006
007
008import java.io.Serializable;
009import java.util.ArrayList;
010import java.util.List;
011import java.util.Map;
012
013import org.apache.log4j.Logger;
014
015import edu.jas.gb.Reduction;
016import edu.jas.gb.ReductionSeq;
017import edu.jas.poly.ExpVector;
018import edu.jas.poly.GenPolynomial;
019import edu.jas.poly.ModuleList;
020import edu.jas.poly.PolynomialList;
021import edu.jas.structure.GcdRingElem;
022import edu.jas.structure.RingElem;
023import edu.jas.vector.BasicLinAlg;
024import edu.jas.vector.GenVector;
025import edu.jas.vector.GenVectorModul;
026
027
028/**
029 * SyzygyAbstract class. Implements Syzygy computations and tests.
030 * @param <C> coefficient type
031 * @author Heinz Kredel
032 */
033
034public abstract class SyzygyAbstract<C extends GcdRingElem<C>> implements Syzygy<C> {
035
036
037    private static final Logger logger = Logger.getLogger(SyzygyAbstract.class);
038
039
040    private final boolean debug = logger.isDebugEnabled();
041
042
043    /**
044     * Reduction engine.
045     */
046    protected Reduction<C> red;
047
048
049    /**
050     * Linear algebra engine.
051     */
052    protected BasicLinAlg<GenPolynomial<C>> blas;
053
054
055    /**
056     * Constructor.
057     */
058    public SyzygyAbstract() {
059        red = new ReductionSeq<C>();
060        blas = new BasicLinAlg<GenPolynomial<C>>();
061    }
062
063
064    /**
065     * Syzygy module from Groebner base. F must be a Groebner base.
066     * @param F a Groebner base.
067     * @return syz(F), a basis for the module of syzygies for F.
068     */
069    public List<List<GenPolynomial<C>>> zeroRelations(List<GenPolynomial<C>> F) {
070        return zeroRelations(0, F);
071    }
072
073
074    /**
075     * Syzygy module from Groebner base. F must be a Groebner base.
076     * @param modv number of module variables.
077     * @param F a Groebner base.
078     * @return syz(F), a basis for the module of syzygies for F.
079     */
080    public List<List<GenPolynomial<C>>> zeroRelations(int modv, List<GenPolynomial<C>> F) {
081        List<List<GenPolynomial<C>>> Z = new ArrayList<List<GenPolynomial<C>>>();
082        if (F == null) {
083            return Z;
084        }
085        GenVectorModul<GenPolynomial<C>> mfac = null;
086        int i = 0;
087        while (mfac == null && i < F.size()) {
088            GenPolynomial<C> p = F.get(i);
089            if (p != null) {
090                mfac = new GenVectorModul<GenPolynomial<C>>(p.ring, F.size());
091            }
092        }
093        if (mfac == null) {
094            return Z;
095        }
096        GenVector<GenPolynomial<C>> v = mfac.fromList(F);
097        //System.out.println("F = " + F + " v = " + v);
098        return zeroRelations(modv, v);
099    }
100
101
102    /**
103     * Syzygy module from Groebner base. v must be a Groebner base.
104     * @param modv number of module variables.
105     * @param v a Groebner base.
106     * @return syz(v), a basis for the module of syzygies for v.
107     */
108    public List<List<GenPolynomial<C>>> zeroRelations(int modv, GenVector<GenPolynomial<C>> v) {
109        List<List<GenPolynomial<C>>> Z = new ArrayList<List<GenPolynomial<C>>>();
110        GenVectorModul<GenPolynomial<C>> mfac = v.modul;
111        List<GenPolynomial<C>> F = v.val;
112        GenVector<GenPolynomial<C>> S = mfac.getZERO();
113        GenPolynomial<C> pi, pj, s, h;
114        //zero = mfac.coFac.getZERO();
115        for (int i = 0; i < F.size(); i++) {
116            pi = F.get(i);
117            for (int j = i + 1; j < F.size(); j++) {
118                pj = F.get(j);
119                //logger.info("p"+i+", p"+j+" = " + pi + ", " +pj);
120
121                if (!red.moduleCriterion(modv, pi, pj)) {
122                    continue;
123                }
124                // if ( ! red.criterion4( pi, pj ) ) { continue; }
125                List<GenPolynomial<C>> row = S.copy().val;
126
127                s = red.SPolynomial(row, i, pi, j, pj);
128                if (s.isZERO()) {
129                    Z.add(row);
130                    continue;
131                }
132
133                h = red.normalform(row, F, s);
134                if (!h.isZERO()) {
135                    throw new RuntimeException("Syzygy no GB");
136                }
137                if (debug) {
138                    logger.info("row = " + row.size());
139                }
140                Z.add(row);
141            }
142        }
143        return Z;
144    }
145
146
147    /**
148     * Syzygy module from module Groebner base. M must be a module Groebner
149     * base.
150     * @param M a module Groebner base.
151     * @return syz(M), a basis for the module of syzygies for M.
152     */
153    public ModuleList<C> zeroRelations(ModuleList<C> M) {
154        ModuleList<C> N = M;
155        if (M == null || M.list == null) {
156            return N;
157        }
158        if (M.rows == 0 || M.cols == 0) {
159            return N;
160        }
161        GenPolynomial<C> zero = M.ring.getZERO();
162        //System.out.println("zero = " + zero);
163
164        //ModuleList<C> Np = null;
165        PolynomialList<C> F = M.getPolynomialList();
166        int modv = M.cols; // > 0  
167        //System.out.println("modv = " + modv);
168        List<List<GenPolynomial<C>>> G = zeroRelations(modv, F.list);
169        List<List<GenPolynomial<C>>> Z = new ArrayList<List<GenPolynomial<C>>>();
170        for (int i = 0; i < G.size(); i++) {
171            //F = new PolynomialList(F.ring,(List)G.get(i));
172            List<GenPolynomial<C>> Gi = G.get(i);
173            List<GenPolynomial<C>> Zi = new ArrayList<GenPolynomial<C>>();
174            // System.out.println("\nG("+i+") = " + G.get(i));
175            for (int j = 0; j < Gi.size(); j++) {
176                //System.out.println("\nG("+i+","+j+") = " + Gi.get(j));
177                GenPolynomial<C> p = Gi.get(j);
178                if (p != null) {
179                    Map<ExpVector, GenPolynomial<C>> r = p.contract(M.ring);
180                    int s = 0;
181                    for (GenPolynomial<C> vi : r.values()) {
182                        Zi.add(vi);
183                        s++;
184                    }
185                    if (s == 0) {
186                        Zi.add(zero);
187                    } else if (s > 1) { // will not happen
188                        System.out.println("p = " + p);
189                        System.out.println("map(" + i + "," + j + ") = " + r + ", size = " + r.size());
190                        throw new RuntimeException("Map.size() > 1 = " + r.size());
191                    }
192                }
193            }
194            //System.out.println("\nZ("+i+") = " + Zi);
195            Z.add(Zi);
196        }
197        N = new ModuleList<C>(M.ring, Z);
198        //System.out.println("\n\nN = " + N);
199        return N;
200    }
201
202
203    /**
204     * Test if sysygy.
205     * @param Z list of sysygies.
206     * @param F a polynomial list.
207     * @return true, if Z is a list of syzygies for F, else false.
208     */
209
210    public boolean isZeroRelation(List<List<GenPolynomial<C>>> Z, List<GenPolynomial<C>> F) {
211        for (List<GenPolynomial<C>> row : Z) {
212            GenPolynomial<C> p = blas.scalarProduct(row, F);
213            if (p == null) {
214                continue;
215            }
216            if (!p.isZERO()) {
217                logger.info("is not ZeroRelation = " + p.toString(p.ring.getVars()));
218                logger.info("row = " + row);
219                //logger.info("F = " + F);
220                return false;
221            }
222        }
223        return true;
224    }
225
226
227    /**
228     * Test if sysygy of modules.
229     * @param Z list of sysygies.
230     * @param F a module list.
231     * @return true, if Z is a list of syzygies for F, else false.
232     */
233
234    public boolean isZeroRelation(ModuleList<C> Z, ModuleList<C> F) {
235        if (Z == null || Z.list == null) {
236            return true;
237        }
238        for (List<GenPolynomial<C>> row : Z.list) {
239            List<GenPolynomial<C>> zr = blas.leftScalarProduct(row, F.list);
240            if (!blas.isZero(zr)) {
241                logger.info("is not ZeroRelation (" + zr.size() + ") = " + zr);
242                return false;
243            }
244        }
245        return true;
246    }
247
248
249    /**
250     * Syzygy module from arbitrary base.
251     * @param F a polynomial list.
252     * @return syz(F), a basis for the module of syzygies for F.
253     */
254    public List<List<GenPolynomial<C>>> zeroRelationsArbitrary(List<GenPolynomial<C>> F) {
255        return zeroRelationsArbitrary(0, F);
256    }
257
258
259    /**
260     * Syzygy module from arbitrary module base.
261     * @param M an arbitrary module base.
262     * @return syz(M), a basis for the module of syzygies for M.
263     */
264    public ModuleList<C> zeroRelationsArbitrary(ModuleList<C> M) {
265        ModuleList<C> N = M;
266        if (M == null || M.list == null) {
267            return N;
268        }
269        if (M.rows == 0 || M.cols == 0) {
270            return N;
271        }
272        GenPolynomial<C> zero = M.ring.getZERO();
273        //System.out.println("zero = " + zero);
274
275        //ModuleList<C> Np = null;
276        PolynomialList<C> F = M.getPolynomialList();
277        int modv = M.cols; // > 0  
278        //System.out.println("modv = " + modv);
279        List<List<GenPolynomial<C>>> G = zeroRelationsArbitrary(modv, F.list);
280        List<List<GenPolynomial<C>>> Z = new ArrayList<List<GenPolynomial<C>>>();
281        for (int i = 0; i < G.size(); i++) {
282            //F = new PolynomialList(F.ring,(List)G.get(i));
283            List<GenPolynomial<C>> Gi = G.get(i);
284            List<GenPolynomial<C>> Zi = new ArrayList<GenPolynomial<C>>();
285            // System.out.println("\nG("+i+") = " + G.get(i));
286            for (int j = 0; j < Gi.size(); j++) {
287                //System.out.println("\nG("+i+","+j+") = " + Gi.get(j));
288                GenPolynomial<C> p = Gi.get(j);
289                if (p != null) {
290                    Map<ExpVector, GenPolynomial<C>> r = p.contract(M.ring);
291                    int s = 0;
292                    for (GenPolynomial<C> vi : r.values()) {
293                        Zi.add(vi);
294                        s++;
295                    }
296                    if (s == 0) {
297                        Zi.add(zero);
298                    } else if (s > 1) { // will not happen
299                        System.out.println("p = " + p);
300                        System.out.println("map(" + i + "," + j + ") = " + r + ", size = " + r.size());
301                        throw new RuntimeException("Map.size() > 1 = " + r.size());
302                    }
303                }
304            }
305            //System.out.println("\nZ("+i+") = " + Zi);
306            Z.add(Zi);
307        }
308        N = new ModuleList<C>(M.ring, Z);
309        //System.out.println("\n\nN = " + N);
310        return N;
311    }
312
313}
314
315
316/**
317 * Container for module resolution components.
318 * @param <C> coefficient type
319 */
320class ResPart<C extends RingElem<C>> implements Serializable {
321
322
323    public final ModuleList<C> module;
324
325
326    public final ModuleList<C> GB;
327
328
329    public final ModuleList<C> syzygy;
330
331
332    /**
333     * ResPart.
334     * @param m a module list.
335     * @param g a module list GB.
336     * @param z a syzygy module list.
337     */
338    public ResPart(ModuleList<C> m, ModuleList<C> g, ModuleList<C> z) {
339        module = m;
340        GB = g;
341        syzygy = z;
342    }
343
344
345    /**
346     * toString.
347     */
348    @Override
349    public String toString() {
350        StringBuffer s = new StringBuffer("ResPart(\n");
351        s.append("module = " + module);
352        s.append("\n GB = " + GB);
353        s.append("\n syzygy = " + syzygy);
354        s.append(")");
355        return s.toString();
356    }
357}
358
359
360/**
361 * Container for polynomial resolution components.
362 */
363class ResPolPart<C extends RingElem<C>> implements Serializable {
364
365
366    public final PolynomialList<C> ideal;
367
368
369    public final PolynomialList<C> GB;
370
371
372    public final ModuleList<C> syzygy;
373
374
375    /**
376     * ResPolPart.
377     * @param m a polynomial list.
378     * @param g a polynomial list GB.
379     * @param z a syzygy module list.
380     */
381    public ResPolPart(PolynomialList<C> m, PolynomialList<C> g, ModuleList<C> z) {
382        ideal = m;
383        GB = g;
384        syzygy = z;
385    }
386
387
388    /**
389     * toString.
390     */
391    @Override
392    public String toString() {
393        StringBuffer s = new StringBuffer("ResPolPart(\n");
394        s.append("ideal = " + ideal);
395        s.append("\n GB = " + GB);
396        s.append("\n syzygy = " + syzygy);
397        s.append(")");
398        return s.toString();
399    }
400
401}