001/* 002 * $Id: GenVectorModul.java 5872 2018-07-20 16:01:46Z kredel $ 003 */ 004 005package edu.jas.vector; 006 007 008// import java.io.IOException; 009import java.io.Reader; 010import java.math.BigInteger; 011import java.util.ArrayList; 012import java.util.List; 013import java.util.Random; 014 015import org.apache.logging.log4j.Logger; 016import org.apache.logging.log4j.LogManager; 017 018import edu.jas.kern.StringUtil; 019import edu.jas.structure.ModulFactory; 020import edu.jas.structure.RingElem; 021import edu.jas.structure.RingFactory; 022 023 024/** 025 * GenVectorModul implements a generic vector factory with RingElem entries. 026 * Vectors of n columns over C. 027 * @author Heinz Kredel 028 */ 029 030public class GenVectorModul<C extends RingElem<C>> implements ModulFactory<GenVector<C>, C> { 031 032 033 private static final Logger logger = LogManager.getLogger(GenVectorModul.class); 034 035 036 public final RingFactory<C> coFac; 037 038 039 public final int cols; 040 041 042 public final GenVector<C> ZERO; 043 044 045 public final List<GenVector<C>> BASIS; 046 047 048 private final static Random random = new Random(); 049 050 051 public final static float DEFAULT_DENSITY = 0.5f; 052 053 054 private final float density = DEFAULT_DENSITY; 055 056 057 /** 058 * Constructor for GenVectorModul. 059 */ 060 @SuppressWarnings("unchecked") 061 public GenVectorModul(RingFactory<C> b, int s) { 062 coFac = b; 063 cols = s; 064 ArrayList<C> z = new ArrayList<C>(cols); 065 for (int i = 0; i < cols; i++) { 066 z.add(coFac.getZERO()); 067 } 068 ZERO = new GenVector<C>(this, z); 069 BASIS = new ArrayList<GenVector<C>>(cols); 070 List<C> cgens = coFac.generators(); 071 ArrayList<C> v; 072 for (int i = 0; i < cols; i++) { 073 for (C g : cgens) { 074 v = new ArrayList<C>(z);// z.clone(); 075 v.set(i, g); 076 BASIS.add(new GenVector<C>(this, v)); 077 } 078 } 079 logger.info(cols + " module over " + coFac + "constructed"); 080 } 081 082 083 /** 084 * Get the String representation as RingElem. 085 * @see java.lang.Object#toString() 086 */ 087 @Override 088 public String toString() { 089 StringBuffer s = new StringBuffer(); 090 s.append(coFac.getClass().getSimpleName()); 091 s.append("[" + cols + "]"); 092 return s.toString(); 093 } 094 095 096 /** 097 * Get a scripting compatible string representation. 098 * @return script compatible representation for this ElemFactory. 099 * @see edu.jas.structure.ElemFactory#toScript() 100 */ 101 @Override 102 public String toScript() { 103 // Python case 104 StringBuffer s = new StringBuffer("Vec("); 105 String f = null; 106 try { 107 f = ((RingElem<C>) coFac).toScriptFactory(); // sic 108 } catch (Exception e) { 109 f = coFac.toScript(); 110 } 111 s.append(f + "," + cols + " )"); 112 return s.toString(); 113 } 114 115 116 /** 117 * getZERO. 118 * @return ZERO. 119 */ 120 public GenVector<C> getZERO() { 121 return ZERO; 122 } 123 124 125 /** 126 * Get a list of the generating elements. 127 * @return list of generators for the algebraic structure. 128 * @see edu.jas.structure.ElemFactory#generators() 129 */ 130 public List<GenVector<C>> generators() { 131 return BASIS; 132 } 133 134 135 /** 136 * Is this structure finite or infinite. 137 * @return true if this structure is finite, else false. 138 * @see edu.jas.structure.ElemFactory#isFinite() 139 */ 140 public boolean isFinite() { 141 return coFac.isFinite(); 142 } 143 144 145 /** 146 * Comparison with any other object. 147 * @see java.lang.Object#equals(java.lang.Object) 148 */ 149 @Override 150 @SuppressWarnings("unchecked") 151 public boolean equals(Object other) { 152 if (!(other instanceof GenVectorModul)) { 153 return false; 154 } 155 GenVectorModul omod = (GenVectorModul) other; 156 if (cols != omod.cols) { 157 return false; 158 } 159 if (!coFac.equals(omod.coFac)) { 160 return false; 161 } 162 return true; 163 } 164 165 166 /** 167 * Hash code for this vector module. 168 * @see java.lang.Object#hashCode() 169 */ 170 @Override 171 public int hashCode() { 172 int h; 173 h = cols; 174 h = 37 * h + coFac.hashCode(); 175 return h; 176 } 177 178 179 /** 180 * Get the vector for a. 181 * @param a long 182 * @return vector corresponding to a. 183 */ 184 public GenVector<C> fromInteger(long a) { 185 C c = coFac.fromInteger(a); 186 return BASIS.get(0).scalarMultiply(c); 187 } 188 189 190 /** 191 * Get the vector for a. 192 * @param a long 193 * @return vector corresponding to a. 194 */ 195 public GenVector<C> fromInteger(BigInteger a) { 196 C c = coFac.fromInteger(a); 197 return BASIS.get(0).scalarMultiply(c); 198 } 199 200 201 /** 202 * From List of coefficients. 203 * @param v list of coefficients. 204 * @return vector from v. 205 */ 206 public GenVector<C> fromList(List<C> v) { 207 if (v == null) { 208 return ZERO; 209 } 210 if (v.size() > cols) { 211 throw new IllegalArgumentException("size v > cols " + v + " > " + cols); 212 } 213 List<C> r = new ArrayList<C>(cols); 214 r.addAll(v); 215 // pad with zeros if required: 216 for (int i = r.size(); i < cols; i++) { 217 r.add(coFac.getZERO()); 218 } 219 return new GenVector<C>(this, r); 220 } 221 222 223 /** 224 * Random vector. 225 * @param k size of random coefficients. 226 * @return random vector. 227 */ 228 public GenVector<C> random(int k) { 229 return random(k, density, random); 230 } 231 232 233 /** 234 * Random vector. 235 * @param k size of random coefficients. 236 * @param q density of nonzero coefficients. 237 * @return random vector. 238 */ 239 public GenVector<C> random(int k, float q) { 240 return random(k, q, random); 241 } 242 243 244 /** 245 * Random vector. 246 * @param k size of random coefficients. 247 * @param random is a source for random bits. 248 * @return a random element. 249 */ 250 public GenVector<C> random(int k, Random random) { 251 return random(k, density, random); 252 } 253 254 255 /** 256 * Random vector. 257 * @param k size of random coefficients. 258 * @param q density of nonzero coefficients. 259 * @param random is a source for random bits. 260 * @return a random element. 261 */ 262 public GenVector<C> random(int k, float q, Random random) { 263 List<C> r = new ArrayList<C>(cols); 264 for (int i = 0; i < cols; i++) { 265 if (random.nextFloat() < q) { 266 r.add(coFac.random(k)); 267 } else { 268 r.add(coFac.getZERO()); 269 } 270 } 271 return new GenVector<C>(this, r); 272 } 273 274 275 /** 276 * copy vector. 277 * @param c vector. 278 * @return copy of vector c. 279 */ 280 public GenVector<C> copy(GenVector<C> c) { 281 if (c == null) { 282 return c; 283 } 284 return c.copy(); 285 } 286 287 288 /** 289 * Parse a vector from a String. Syntax: [ c, ..., c ] 290 * @param s String with vector. 291 * @return parsed vector. 292 */ 293 public GenVector<C> parse(String s) { 294 int i = s.indexOf("["); 295 if (i >= 0) { 296 s = s.substring(i + 1); 297 } 298 i = s.indexOf("]"); 299 if (i >= 0) { 300 s = s.substring(0, i); 301 } 302 List<C> vec = new ArrayList<C>(cols); 303 String e; 304 C c; 305 do { 306 i = s.indexOf(","); 307 if (i >= 0) { 308 e = s.substring(0, i); 309 s = s.substring(i + 1); 310 c = coFac.parse(e); 311 vec.add(c); 312 } 313 } while (i >= 0); 314 if (s.trim().length() > 0) { 315 c = coFac.parse(s); 316 vec.add(c); 317 } 318 return new GenVector<C>(this, vec); 319 } 320 321 322 /** 323 * Parse a vector from a Reader. 324 * @param r Reader containing a vector. 325 * @return parsed vector. 326 */ 327 public GenVector<C> parse(Reader r) { 328 String s = StringUtil.nextPairedString(r, '[', ']'); 329 return parse(s); 330 } 331 332}