001/* 002 * $Id: BigQuaternionRing.java 5784 2017-12-09 18:52:37Z kredel $ 003 */ 004 005package edu.jas.arith; 006 007 008import java.io.Reader; 009// import java.math.BigInteger; 010import java.util.ArrayList; 011import java.util.List; 012import java.util.Random; 013 014import org.apache.log4j.Logger; 015 016import edu.jas.kern.StringUtil; 017import edu.jas.kern.Scripting; 018import edu.jas.structure.RingFactory; 019 020 021/** 022 * BigQuaternion ring class based on BigRational implementing the RingElem 023 * interface. 024 * @author Heinz Kredel 025 */ 026 027public final class BigQuaternionRing implements RingFactory<BigQuaternion> { 028 029 030 /** 031 * List of all 24 integral units. 032 */ 033 static List<BigQuaternion> entierUnits = null; //later: unitsOfHurwitzian(); 034 035 036 /** 037 * Flag to signal if this ring is integral. 038 */ 039 protected boolean integral = false; 040 041 042 protected final static Random random = new Random(); 043 044 045 private static final Logger logger = Logger.getLogger(BigQuaternionRing.class); 046 047 048 //private static final boolean debug = logger.isDebugEnabled(); 049 050 051 /** 052 * Constructor for a BigQuaternion ring. 053 */ 054 public BigQuaternionRing() { 055 this(false); 056 } 057 058 059 /** 060 * Constructor for a BigQuaternion ring. 061 */ 062 public BigQuaternionRing(boolean i) { 063 integral = i; 064 logger.info("integral = " + integral); 065 } 066 067 068 /** 069 * Get a list of the generating elements. 070 * @return list of generators for the algebraic structure. 071 * @see edu.jas.structure.ElemFactory#generators() 072 */ 073 public List<BigQuaternion> generators() { 074 List<BigQuaternion> g = new ArrayList<BigQuaternion>(4); 075 g.add(getONE()); 076 g.add(I); 077 g.add(J); 078 g.add(K); 079 return g; 080 } 081 082 083 /** 084 * Is this structure finite or infinite. 085 * @return true if this structure is finite, else false. 086 * @see edu.jas.structure.ElemFactory#isFinite() 087 */ 088 public boolean isFinite() { 089 return false; 090 } 091 092 093 /** 094 * Copy BigQuaternion element c. 095 * @param c BigQuaternion. 096 * @return a copy of c. 097 */ 098 public BigQuaternion copy(BigQuaternion c) { 099 return new BigQuaternion(this, c.re, c.im, c.jm, c.km); 100 } 101 102 103 /** 104 * Get the zero element. 105 * @return 0 as BigQuaternion. 106 */ 107 public BigQuaternion getZERO() { 108 return ZERO; 109 } 110 111 112 /** 113 * Get the one element. 114 * @return q as BigQuaternion. 115 */ 116 public BigQuaternion getONE() { 117 return ONE; 118 } 119 120 121 /** 122 * Query if this ring is commutative. 123 * @return false. 124 */ 125 public boolean isCommutative() { 126 return false; 127 } 128 129 130 /** 131 * Query if this ring is associative. 132 * @return true. 133 */ 134 public boolean isAssociative() { 135 return true; 136 } 137 138 139 /** 140 * Query if this ring is a field. 141 * @return true. 142 */ 143 public boolean isField() { 144 return !integral; 145 } 146 147 148 /** 149 * Characteristic of this ring. 150 * @return characteristic of this ring. 151 */ 152 public java.math.BigInteger characteristic() { 153 return java.math.BigInteger.ZERO; 154 } 155 156 157 /** 158 * Get a BigQuaternion element from a BigInteger. 159 * @param a BigInteger. 160 * @return a BigQuaternion. 161 */ 162 public BigQuaternion fromInteger(java.math.BigInteger a) { 163 return new BigQuaternion(this, new BigRational(a)); 164 } 165 166 167 /** 168 * Get a BigQuaternion element from a long. 169 * @param a long. 170 * @return a BigQuaternion. 171 */ 172 public BigQuaternion fromInteger(long a) { 173 return new BigQuaternion(this, new BigRational(a)); 174 } 175 176 177 /** 178 * Get a BigQuaternion element from a long vector. 179 * @param a long vector. 180 * @return a BigQuaternion. 181 */ 182 public BigQuaternion fromInteger(long[] a) { 183 return new BigQuaternion(this, new BigRational(a[0]), new BigRational(a[1]), new BigRational(a[2]), 184 new BigRational(a[3])); 185 } 186 187 188 /** 189 * The constant 0. 190 */ 191 public final BigQuaternion ZERO = new BigQuaternion(this); 192 193 194 /** 195 * The constant 1. 196 */ 197 public final BigQuaternion ONE = new BigQuaternion(this, BigRational.ONE); 198 199 200 /** 201 * The constant i. 202 */ 203 public final BigQuaternion I = new BigQuaternion(this, BigRational.ZERO, BigRational.ONE); 204 205 206 /** 207 * The constant j. 208 */ 209 public final BigQuaternion J = new BigQuaternion(this, BigRational.ZERO, BigRational.ZERO, 210 BigRational.ONE); 211 212 213 /** 214 * The constant k. 215 */ 216 public final BigQuaternion K = new BigQuaternion(this, BigRational.ZERO, BigRational.ZERO, 217 BigRational.ZERO, BigRational.ONE); 218 219 220 /** 221 * Get the string representation. Is compatible with the string constructor. 222 * @see java.lang.Object#toString() 223 */ 224 @Override 225 public String toString() { 226 String s = "BigQuaternionRing(" + integral + ")"; 227 return s; 228 } 229 230 231 /** 232 * Get a scripting compatible string representation. 233 * @return script compatible representation for this Element. 234 * @see edu.jas.structure.Element#toScript() 235 */ 236 @Override 237 public String toScript() { 238 StringBuffer s = new StringBuffer("BigQuaternionRing("); 239 switch (Scripting.getLang()) { 240 case Ruby: 241 s.append((integral ? ",true" : ",false")); 242 break; 243 case Python: 244 default: 245 s.append((integral ? ",True" : ",False")); 246 } 247 s.append(")"); 248 return s.toString(); 249 } 250 251 252 /** 253 * Comparison with any other object. 254 * @see java.lang.Object#equals(java.lang.Object) 255 */ 256 @Override 257 public boolean equals(Object b) { 258 if (!(b instanceof BigQuaternionRing)) { 259 return false; 260 } 261 BigQuaternionRing B = (BigQuaternionRing) b; 262 return this.integral == B.integral; 263 } 264 265 266 /** 267 * Hash code for this BigQuaternionRing. 268 * @see java.lang.Object#hashCode() 269 */ 270 @Override 271 public int hashCode() { 272 int h = 4711; 273 return h; 274 } 275 276 277 /** 278 * BigQuaternion units of the Hurwitzian integers. BigQuaternion units with 279 * all integer or all 1/2 times integer components. 280 * @return list of all 24 units. 281 */ 282 public List<BigQuaternion> unitsOfHurwitzian() { 283 if (entierUnits != null) { 284 return entierUnits; 285 } 286 BigRational half = BigRational.HALF; 287 // Lipschitz integer units 288 List<BigQuaternion> units = generators(); 289 List<BigQuaternion> u = new ArrayList<BigQuaternion>(units); 290 for (BigQuaternion ue : u) { 291 units.add(ue.negate()); 292 } 293 // Hurwitz integer units 294 long[][] comb = new long[][] { { 1, 1, 1, 1 }, { -1, 1, 1, 1 }, { 1, -1, 1, 1 }, { -1, -1, 1, 1 }, 295 { 1, 1, -1, 1 }, { -1, 1, -1, 1 }, { 1, -1, -1, 1 }, { -1, -1, -1, 1 }, { 1, 1, 1, -1 }, 296 { -1, 1, 1, -1 }, { 1, -1, 1, -1 }, { -1, -1, 1, -1 }, { 1, 1, -1, -1 }, { -1, 1, -1, -1 }, 297 { 1, -1, -1, -1 }, { -1, -1, -1, -1 } }; 298 for (long[] row : comb) { 299 BigQuaternion ue = fromInteger(row); 300 ue = ue.multiply(half); 301 units.add(ue); 302 } 303 //System.out.println("units = " + units); 304 //for (BigQuaternion ue : units) { 305 //System.out.println("unit = " + ue + ", norm = " + ue.norm()); 306 //} 307 entierUnits = units; 308 return units; 309 } 310 311 312 /** 313 * BigQuaternion random. Random rational numbers A, B, C and D are generated 314 * using random(n). Then R is the quaternion number with real part A and 315 * imaginary parts B, C and D. 316 * @param n such that 0 ≤ A, B, C, D ≤ (2<sup>n</sup>-1). 317 * @return R, a random BigQuaternion. 318 */ 319 public BigQuaternion random(int n) { 320 return random(n, random); 321 } 322 323 324 /** 325 * BigQuaternion random. Random rational numbers A, B, C and D are generated 326 * using RNRAND(n). Then R is the quaternion number with real part A and 327 * imaginary parts B, C and D. 328 * @param n such that 0 ≤ A, B, C, D ≤ (2<sup>n</sup>-1). 329 * @param rnd is a source for random bits. 330 * @return R, a random BigQuaternion. 331 */ 332 public BigQuaternion random(int n, Random rnd) { 333 BigRational r = BigRational.ONE.random(n, rnd); 334 BigRational i = BigRational.ONE.random(n, rnd); 335 BigRational j = BigRational.ONE.random(n, rnd); 336 BigRational k = BigRational.ONE.random(n, rnd); 337 BigQuaternion q = new BigQuaternion(this, r, i, j, k); 338 if (integral) { 339 q = q.roundToHurwitzian(); 340 } 341 return q; 342 } 343 344 345 /* 346 * Quaternion number, random. Random rational numbers A, B, C and D are 347 * generated using RNRAND(n). Then R is the quaternion number with real part 348 * A and imaginary parts B, C and D. 349 * @param n such that 0 ≤ A, B, C, D ≤ (2<sup>n</sup>-1). 350 * @return R, a random BigQuaternion. 351 public static BigQuaternion QRAND(int n) { 352 return ONE.random(n, random); 353 } 354 */ 355 356 357 /** 358 * Parse quaternion number from String. 359 * @param s String. 360 * @return BigQuaternion from s. 361 */ 362 public BigQuaternion parse(String s) { 363 return new BigQuaternion(this, s); 364 } 365 366 367 /** 368 * Parse quaternion number from Reader. 369 * @param r Reader. 370 * @return next BigQuaternion from r. 371 */ 372 public BigQuaternion parse(Reader r) { 373 return parse(StringUtil.nextString(r)); 374 } 375 376}