001    /*
002     * $Id: BasicLinAlg.java 3584 2011-03-26 11:39:39Z kredel $
003     */
004    
005    package edu.jas.vector;
006    
007    
008    import java.util.ArrayList;
009    import java.util.Iterator;
010    import java.util.List;
011    
012    import org.apache.log4j.Logger;
013    
014    import edu.jas.structure.RingElem;
015    
016    
017    /**
018     * Basic linear algebra methods. Implements Basic linear algebra computations
019     * and tests. <b>Note:</b> will use wrong method dispatch in JRE when used with
020     * GenSolvablePolynomial.
021     * @param <C> coefficient type
022     * @author Heinz Kredel
023     */
024    
025    public class BasicLinAlg<C extends RingElem<C>> {
026    
027    
028        private static final Logger logger = Logger.getLogger(BasicLinAlg.class);
029    
030    
031        //private final boolean debug = logger.isDebugEnabled();
032    
033    
034        /**
035         * Constructor.
036         */
037        public BasicLinAlg() {
038        }
039    
040    
041        /**
042         * Scalar product of vectors of ring elements.
043         * @param G a ring element list.
044         * @param F a ring element list.
045         * @return the scalar product of G and F.
046         */
047        public C scalarProduct(List<C> G, List<C> F) {
048            C sp = null;
049            Iterator<C> it = G.iterator();
050            Iterator<C> jt = F.iterator();
051            while (it.hasNext() && jt.hasNext()) {
052                C pi = it.next();
053                C pj = jt.next();
054                if (pi == null || pj == null) {
055                    continue;
056                }
057                if (sp == null) {
058                    sp = pi.multiply(pj);
059                } else {
060                    sp = sp.sum(pi.multiply(pj));
061                }
062            }
063            if (it.hasNext() || jt.hasNext()) {
064                logger.error("scalarProduct wrong sizes");
065            }
066            return sp;
067        }
068    
069    
070        /**
071         * Scalar product of vectors and a matrix of ring elements.
072         * @param G a ring element list.
073         * @param F a list of ring element lists.
074         * @return the scalar product of G and F.
075         */
076        public List<C> leftScalarProduct(List<C> G, List<List<C>> F) {
077            List<C> sp = null; //new ArrayList<C>(G.size());
078            Iterator<C> it = G.iterator();
079            Iterator<List<C>> jt = F.iterator();
080            while (it.hasNext() && jt.hasNext()) {
081                C pi = it.next();
082                List<C> pj = jt.next();
083                if (pi == null || pj == null) {
084                    continue;
085                }
086                List<C> s = scalarProduct(pi, pj);
087                if (sp == null) {
088                    sp = s;
089                } else {
090                    sp = vectorAdd(sp, s);
091                }
092            }
093            if (it.hasNext() || jt.hasNext()) {
094                logger.error("scalarProduct wrong sizes");
095            }
096            return sp;
097        }
098    
099    
100        /**
101         * Scalar product of vectors and a matrix of ring elements.
102         * @param G a ring element list.
103         * @param F a list of ring element lists.
104         * @return the right scalar product of G and F.
105         */
106        public List<C> rightScalarProduct(List<C> G, List<List<C>> F) {
107            List<C> sp = null; //new ArrayList<C>(G.size());
108            Iterator<C> it = G.iterator();
109            Iterator<List<C>> jt = F.iterator();
110            while (it.hasNext() && jt.hasNext()) {
111                C pi = it.next();
112                List<C> pj = jt.next();
113                if (pi == null || pj == null) {
114                    continue;
115                }
116                List<C> s = scalarProduct(pj, pi);
117                if (sp == null) {
118                    sp = s;
119                } else {
120                    sp = vectorAdd(sp, s);
121                }
122            }
123            if (it.hasNext() || jt.hasNext()) {
124                logger.error("scalarProduct wrong sizes");
125            }
126            return sp;
127        }
128    
129    
130        /**
131         * Addition of vectors of ring elements.
132         * @param a a ring element list.
133         * @param b a ring element list.
134         * @return a+b, the vector sum of a and b.
135         */
136    
137        public List<C> vectorAdd(List<C> a, List<C> b) {
138            if (a == null) {
139                return b;
140            }
141            if (b == null) {
142                return a;
143            }
144            List<C> V = new ArrayList<C>(a.size());
145            Iterator<C> it = a.iterator();
146            Iterator<C> jt = b.iterator();
147            while (it.hasNext() && jt.hasNext()) {
148                C pi = it.next();
149                C pj = jt.next();
150                C p = pi.sum(pj);
151                V.add(p);
152            }
153            //System.out.println("vectorAdd" + V);
154            if (it.hasNext() || jt.hasNext()) {
155                logger.error("vectorAdd wrong sizes");
156            }
157            return V;
158        }
159    
160    
161        /**
162         * Test vector of zero ring elements.
163         * @param a a ring element list.
164         * @return true, if all polynomial in a are zero, else false.
165         */
166        public boolean isZero(List<C> a) {
167            if (a == null) {
168                return true;
169            }
170            for (C pi : a) {
171                if (pi == null) {
172                    continue;
173                }
174                if (!pi.isZERO()) {
175                    return false;
176                }
177            }
178            return true;
179        }
180    
181    
182        /**
183         * Scalar product of ring element with vector of ring elements.
184         * @param p a ring element.
185         * @param F a ring element list.
186         * @return the scalar product of p and F.
187         */
188        public List<C> scalarProduct(C p, List<C> F) {
189            List<C> V = new ArrayList<C>(F.size());
190            for (C pi : F) {
191                if (p != null) {
192                    pi = p.multiply(pi);
193                } else {
194                    pi = null;
195                }
196                V.add(pi);
197            }
198            return V;
199        }
200    
201    
202        /**
203         * Scalar product of vector of ring element with ring element.
204         * @param F a ring element list.
205         * @param p a ring element.
206         * @return the scalar product of F and p.
207         */
208        public List<C> scalarProduct(List<C> F, C p) {
209            List<C> V = new ArrayList<C>(F.size());
210            for (C pi : F) {
211                if (pi != null) {
212                    pi = pi.multiply(p);
213                }
214                V.add(pi);
215            }
216            return V;
217        }
218    
219    }