001/*
002 * $Id: GenVectorModul.java 5872 2018-07-20 16:01:46Z kredel $
003 */
004
005package edu.jas.vector;
006
007
008// import java.io.IOException;
009import java.io.Reader;
010import java.math.BigInteger;
011import java.util.ArrayList;
012import java.util.List;
013import java.util.Random;
014
015import org.apache.logging.log4j.Logger;
016import org.apache.logging.log4j.LogManager; 
017
018import edu.jas.kern.StringUtil;
019import edu.jas.structure.ModulFactory;
020import edu.jas.structure.RingElem;
021import edu.jas.structure.RingFactory;
022
023
024/**
025 * GenVectorModul implements a generic vector factory with RingElem entries.
026 * Vectors of n columns over C.
027 * @author Heinz Kredel
028 */
029
030public class GenVectorModul<C extends RingElem<C>> implements ModulFactory<GenVector<C>, C> {
031
032
033    private static final Logger logger = LogManager.getLogger(GenVectorModul.class);
034
035
036    public final RingFactory<C> coFac;
037
038
039    public final int cols;
040
041
042    public final GenVector<C> ZERO;
043
044
045    public final List<GenVector<C>> BASIS;
046
047
048    private final static Random random = new Random();
049
050
051    public final static float DEFAULT_DENSITY = 0.5f;
052
053
054    private final float density = DEFAULT_DENSITY;
055
056
057    /**
058     * Constructor for GenVectorModul.
059     */
060    @SuppressWarnings("unchecked")
061    public GenVectorModul(RingFactory<C> b, int s) {
062        coFac = b;
063        cols = s;
064        ArrayList<C> z = new ArrayList<C>(cols);
065        for (int i = 0; i < cols; i++) {
066            z.add(coFac.getZERO());
067        }
068        ZERO = new GenVector<C>(this, z);
069        BASIS = new ArrayList<GenVector<C>>(cols);
070        List<C> cgens = coFac.generators();
071        ArrayList<C> v;
072        for (int i = 0; i < cols; i++) {
073            for (C g : cgens) {
074                v = new ArrayList<C>(z);// z.clone();
075                v.set(i, g);
076                BASIS.add(new GenVector<C>(this, v));
077            }
078        }
079        logger.info(cols + " module over " + coFac + "constructed");
080    }
081
082
083    /**
084     * Get the String representation as RingElem.
085     * @see java.lang.Object#toString()
086     */
087    @Override
088    public String toString() {
089        StringBuffer s = new StringBuffer();
090        s.append(coFac.getClass().getSimpleName());
091        s.append("[" + cols + "]");
092        return s.toString();
093    }
094
095
096    /**
097     * Get a scripting compatible string representation.
098     * @return script compatible representation for this ElemFactory.
099     * @see edu.jas.structure.ElemFactory#toScript()
100     */
101    @Override
102    public String toScript() {
103        // Python case
104        StringBuffer s = new StringBuffer("Vec(");
105        String f = null;
106        try {
107            f = ((RingElem<C>) coFac).toScriptFactory(); // sic
108        } catch (Exception e) {
109            f = coFac.toScript();
110        }
111        s.append(f + "," + cols + " )");
112        return s.toString();
113    }
114
115
116    /**
117     * getZERO.
118     * @return ZERO.
119     */
120    public GenVector<C> getZERO() {
121        return ZERO;
122    }
123
124
125    /**
126     * Get a list of the generating elements.
127     * @return list of generators for the algebraic structure.
128     * @see edu.jas.structure.ElemFactory#generators()
129     */
130    public List<GenVector<C>> generators() {
131        return BASIS;
132    }
133
134
135    /**
136     * Is this structure finite or infinite.
137     * @return true if this structure is finite, else false.
138     * @see edu.jas.structure.ElemFactory#isFinite()
139     */
140    public boolean isFinite() {
141        return coFac.isFinite();
142    }
143
144
145    /**
146     * Comparison with any other object.
147     * @see java.lang.Object#equals(java.lang.Object)
148     */
149    @Override
150    @SuppressWarnings("unchecked")
151    public boolean equals(Object other) {
152        if (!(other instanceof GenVectorModul)) {
153            return false;
154        }
155        GenVectorModul omod = (GenVectorModul) other;
156        if (cols != omod.cols) {
157            return false;
158        }
159        if (!coFac.equals(omod.coFac)) {
160            return false;
161        }
162        return true;
163    }
164
165
166    /**
167     * Hash code for this vector module.
168     * @see java.lang.Object#hashCode()
169     */
170    @Override
171    public int hashCode() {
172        int h;
173        h = cols;
174        h = 37 * h + coFac.hashCode();
175        return h;
176    }
177
178
179    /**
180     * Get the vector for a.
181     * @param a long
182     * @return vector corresponding to a.
183     */
184    public GenVector<C> fromInteger(long a) {
185        C c = coFac.fromInteger(a);
186        return BASIS.get(0).scalarMultiply(c);
187    }
188
189
190    /**
191     * Get the vector for a.
192     * @param a long
193     * @return vector corresponding to a.
194     */
195    public GenVector<C> fromInteger(BigInteger a) {
196        C c = coFac.fromInteger(a);
197        return BASIS.get(0).scalarMultiply(c);
198    }
199
200
201    /**
202     * From List of coefficients.
203     * @param v list of coefficients.
204     * @return vector from v.
205     */
206    public GenVector<C> fromList(List<C> v) {
207        if (v == null) {
208            return ZERO;
209        }
210        if (v.size() > cols) {
211            throw new IllegalArgumentException("size v > cols " + v + " > " + cols);
212        }
213        List<C> r = new ArrayList<C>(cols);
214        r.addAll(v);
215        // pad with zeros if required:
216        for (int i = r.size(); i < cols; i++) {
217            r.add(coFac.getZERO());
218        }
219        return new GenVector<C>(this, r);
220    }
221
222
223    /**
224     * Random vector.
225     * @param k size of random coefficients.
226     * @return random vector.
227     */
228    public GenVector<C> random(int k) {
229        return random(k, density, random);
230    }
231
232
233    /**
234     * Random vector.
235     * @param k size of random coefficients.
236     * @param q density of nonzero coefficients.
237     * @return random vector.
238     */
239    public GenVector<C> random(int k, float q) {
240        return random(k, q, random);
241    }
242
243
244    /**
245     * Random vector.
246     * @param k size of random coefficients.
247     * @param random is a source for random bits.
248     * @return a random element.
249     */
250    public GenVector<C> random(int k, Random random) {
251        return random(k, density, random);
252    }
253
254
255    /**
256     * Random vector.
257     * @param k size of random coefficients.
258     * @param q density of nonzero coefficients.
259     * @param random is a source for random bits.
260     * @return a random element.
261     */
262    public GenVector<C> random(int k, float q, Random random) {
263        List<C> r = new ArrayList<C>(cols);
264        for (int i = 0; i < cols; i++) {
265            if (random.nextFloat() < q) {
266                r.add(coFac.random(k));
267            } else {
268                r.add(coFac.getZERO());
269            }
270        }
271        return new GenVector<C>(this, r);
272    }
273
274
275    /**
276     * copy vector.
277     * @param c vector.
278     * @return copy of vector c.
279     */
280    public GenVector<C> copy(GenVector<C> c) {
281        if (c == null) {
282            return c;
283        }
284        return c.copy();
285    }
286
287
288    /**
289     * Parse a vector from a String. Syntax: [ c, ..., c ]
290     * @param s String with vector.
291     * @return parsed vector.
292     */
293    public GenVector<C> parse(String s) {
294        int i = s.indexOf("[");
295        if (i >= 0) {
296            s = s.substring(i + 1);
297        }
298        i = s.indexOf("]");
299        if (i >= 0) {
300            s = s.substring(0, i);
301        }
302        List<C> vec = new ArrayList<C>(cols);
303        String e;
304        C c;
305        do {
306            i = s.indexOf(",");
307            if (i >= 0) {
308                e = s.substring(0, i);
309                s = s.substring(i + 1);
310                c = coFac.parse(e);
311                vec.add(c);
312            }
313        } while (i >= 0);
314        if (s.trim().length() > 0) {
315            c = coFac.parse(s);
316            vec.add(c);
317        }
318        return new GenVector<C>(this, vec);
319    }
320
321
322    /**
323     * Parse a vector from a Reader.
324     * @param r Reader containing a vector.
325     * @return parsed vector.
326     */
327    public GenVector<C> parse(Reader r) {
328        String s = StringUtil.nextPairedString(r, '[', ']');
329        return parse(s);
330    }
331
332}