public double this[Basis basis] { get { if (blades.ContainsKey(basis)) { return(blades[basis].Value); } else { return(0.0); } } set { // HACK if (Math.Abs(value) < 1E-3) { if (blades.ContainsKey(basis)) { blades.Remove(basis); } } else { if (blades.ContainsKey(basis)) { blades[basis] = new Blade(basis, value); } else { blades.Add(basis, new Blade(basis, value)); } } } }
public static int Order(Basis e1, Basis e2) { int a = e1.bitMask; int b = e2.bitMask; int n = 0; do { a >>= 1; n += (new Basis(a & b, false)).Grade; } while (a != 0); if (n % 2 == 0) return 1; else return -1; }
public static bool IsCompatible(Basis e1, Basis e2) { return !(e1.IsNullMetric && e2.IsMinkowskiMetric || e1.IsMinkowskiMetric && e2.IsNullMetric); }
public static int GetHashPair(Basis e1, Basis e2) { return (e1.GetHashCode() << 16) | e2.GetHashCode(); }
public static MultiVector GeometricProduct(Basis e1, Basis e2) { int hashPair = Basis.GetHashPair(e1, e2); if (geometricProductCache.ContainsKey(hashPair)) return geometricProductCache[hashPair]; MultiVector result; if (e1.IsNullMetric || e2.IsNullMetric) { MultiVector m1 = e1.ToMinkowskiMetric(); MultiVector m2 = e2.ToMinkowskiMetric(); result = (m1 * m2).ToNullMetric(); } else { int rBitMask = e1.bitMask ^ e2.bitMask; double rValue = Basis.Order(e1, e2); int common = e1.bitMask & e2.bitMask; int i = 0; while (common != 0) { if ((common & 0x1) != 0) rValue *= Basis.minkowskiSignature[i]; common >>= 1; i++; } result = new Blade(new Basis(rBitMask, false), rValue); } geometricProductCache.Add(hashPair, result); return result; }
public static int DisplayOrder(Basis e1, Basis e2) { if (e1.Grade != e2.Grade) { return e1.Grade - e2.Grade; } else { return (int)(e1.bitMask - e2.bitMask); } }
public static MultiVector GeometricProduct(Blade b1, Blade b2) { return((b1.Value * b2.Value) * Basis.GeometricProduct(b1.Basis, b2.Basis)); }
public MultiVector ToMinkowskiMetric() { if (!this.IsNullMetric) return this; if (this.Contains(Basis.EPLANE)) return this; int b = this.bitMask & ~Basis.EPLANE.bitMask; Basis bp = new Basis(b | Basis.EPLUS.bitMask, false); Basis bm = new Basis(b | Basis.EMINUS.bitMask, false); if (this.Contains(Basis.E0)) return 0.5 * (bm + bp); if (this.Contains(Basis.E8)) return bm - bp; // not possible return this; }
public static bool IsCompatible(Basis e1, Basis e2) { return(!(e1.IsNullMetric && e2.IsMinkowskiMetric || e1.IsMinkowskiMetric && e2.IsNullMetric)); }
public static int GetHashPair(Basis e1, Basis e2) { return((e1.GetHashCode() << 16) | e2.GetHashCode()); }
public static Blade operator ^(Basis e1, Basis e2) { return(Basis.OuterProduct(e1, e2)); }
public static MultiVector operator *(Basis e1, Basis e2) { return(Basis.GeometricProduct(e1, e2)); }
public Blade(Basis basis, double value) { this.basis = basis; this.value = value; }
public override string ToString() { string basis = this.Basis.ToString(); return((basis != "") ? "(" + Value.ToString() + "*" + Basis.ToString() + ")" : "(" + Value.ToString() + ")"); }
public static Blade InnerProduct(Blade b1, Blade b2) { return((b1.Value * b2.Value) * Basis.InnerProduct(b1.Basis, b2.Basis)); }
public static Blade OuterProduct(Basis e1, Basis e2) { int hashPair = Basis.GetHashPair(e1, e2); if (outerProductCache.ContainsKey(hashPair)) return outerProductCache[hashPair]; Blade result; if (e1.IsNullMetric || e2.IsNullMetric) { MultiVector m1 = e1.ToMinkowskiMetric(); MultiVector m2 = e2.ToMinkowskiMetric(); result = (Blade)(m1 ^ m2).ToNullMetric(); } else { if ((e1.bitMask & e2.bitMask) == 0) result = (Blade)(e1 * e2); else result = Blade.Zero; } outerProductCache.Add(hashPair, result); return result; }
public bool Contains(Basis basis) { if (!Basis.IsCompatible(this, basis)) return false; return (this.bitMask & basis.bitMask) == basis.bitMask; }
public double this[Basis basis] { get { if (blades.ContainsKey(basis)) return blades[basis].Value; else return 0.0; } set { // HACK if (Math.Abs(value) < 1E-3) { if (blades.ContainsKey(basis)) blades.Remove(basis); } else { if (blades.ContainsKey(basis)) blades[basis] = new Blade(basis, value); else blades.Add(basis, new Blade(basis, value)); } } }
public MultiVector ToNullMetric() { if (!this.IsMinkowskiMetric) return this; if (this.Contains(Basis.EPLANE)) return this; int b = this.bitMask & ~Basis.EPLANE.bitMask; Basis b0 = new Basis(b | Basis.E0.bitMask, true); Basis b8 = new Basis(b | Basis.E8.bitMask, true); if (this.Contains(Basis.EPLUS)) return b0 - 0.5 * b8; if (this.Contains(Basis.EMINUS)) return b0 + 0.5 * b8; return this; }