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