001/*
002 * $Id$
003  */
004
005package edu.jas.gb;
006
007import java.io.StringReader;
008import java.util.ArrayList;
009import java.util.List;
010
011import edu.jas.arith.BigInteger;
012import edu.jas.poly.GenPolynomial;
013import edu.jas.poly.GenPolynomialRing;
014
015
016/**
017 * Class to produce a system of equations defined as Cyclic.
018 * 
019 * @author Heinz Kredel
020 */
021public class Cyclic {
022
023   /**
024    * main.
025    */
026    public static void main(String[] args) {
027        if ( args.length == 0 ) {
028           System.out.println("usage: Cyclic N <order> <var>");
029           return;
030        }
031        int n = Integer.parseInt(args[0]);
032        Cyclic k = null;
033        if ( args.length == 1 ) {               
034           k = new Cyclic(n);
035        }
036        if ( args.length == 2 ) {               
037           k = new Cyclic("x",n, args[1]);
038        }
039        if ( args.length == 3 ) {               
040           k = new Cyclic(args[2],n, args[1]);
041        }
042        System.out.println("#Cyclic equations for N = " + n + ":");
043        System.out.println("" + k);
044    }
045
046    final int N;
047    final String var;
048    final String order;
049    public final GenPolynomialRing<BigInteger> ring;
050
051    /**
052     * Cyclic constructor.
053     * @param n problem size.
054     */
055    public Cyclic(int n) {
056           this("x", n);
057    }
058
059
060    /**
061     * Cyclic constructor.
062     * @param v name of variables.
063     * @param n problem size.
064     */
065    public Cyclic(String v, int n) {
066           this(v, n, "G");
067    }
068
069
070    /**
071     * Cyclic constructor.
072     * @param var name of variables.
073     * @param n problem size.
074     * @param order term order letter for output.
075     */
076    public Cyclic(String var, int n, String order) {
077           this.var = var;
078           this.N = n;
079           this.order = order;
080           BigInteger fac = new BigInteger();
081           ring = new GenPolynomialRing<BigInteger>(fac, N); //,var);
082           //System.out.println("ring = " + ring);
083    }
084
085
086
087    /**
088     * toString.
089     * @return Cyclic problem as string.
090     */
091    @Override
092    public String toString() {
093           StringBuffer s = new StringBuffer();
094           s.append(ring.toString().replace("BigInteger","Z"));
095           s.append(System.getProperty("line.separator"));
096           s.append( cyclicPolys(ring).toString() );
097           return s.toString();
098    }
099
100
101    /**
102     * Compute list of polynomials.
103     * @return Cyclic problem as string of list of polynomials.
104     */
105    public String polyList() {
106        return cyclicPolys(ring).toString().replace("[","(").replace("]",")");
107    }
108
109
110    /**
111     * Compute list of polynomials.
112     * @return Cyclic problem as list of polynomials.
113     */
114    public List<GenPolynomial<BigInteger>> cyclicPolys() {
115        return cyclicPolys(ring);
116    }
117
118
119    /**
120     * Compute list of polynomials.
121     * @param ring polynomial ring.
122     * @return Cyclic problem as list of polynomials.
123     */
124   List<GenPolynomial<BigInteger>> cyclicPolys(GenPolynomialRing<BigInteger> ring) {
125        int n = ring.nvar;
126        List<GenPolynomial<BigInteger>> cp = new ArrayList<GenPolynomial<BigInteger>>(n);
127        for (int i = 1; i <= n; i++) {
128            GenPolynomial<BigInteger> p = cyclicPoly(ring, n, i);
129            cp.add(p);
130            //System.out.println("p[" + i + "] = " + p);
131        }
132        return cp;
133    }
134
135
136    GenPolynomial<BigInteger> cyclicPoly(GenPolynomialRing<BigInteger> ring, int n, int i) {
137        List<? extends GenPolynomial<BigInteger>> X = ring.univariateList();
138        GenPolynomial<BigInteger> p = ring.getZERO();
139        for (int j = 1; j <= n; j++) {
140            GenPolynomial<BigInteger> pi = ring.getONE();
141            for (int k = j; k < j + i; k++) {
142                pi = pi.multiply(X.get(k % n));
143            }
144            p = p.sum(pi);
145            if (i == n) {
146                p = p.subtract(ring.getONE());
147                break;
148            }
149        }
150        return p;
151    }
152
153}