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 }