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