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