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 }