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