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