/// <summary>Computes unit version of this multivector given its norm <paramref name="N"/>.</summary> /// <param name="N">The norm of the multivector.</param> /// <returns>Normalized Multivector</returns> /// <remarks>Throws exception when norm is 0.</remarks> protected Multivector Unit(Multivector N) { // zero -> throw exception if (N.IsZero()) throw new ArgumentException("Multivector.Unit_e(): zero norm"); // scalar: the unit scalar is 1 if (this.IsScalar()) return new Multivector(1.0); // if no symbolic scalars, then we can actually compute: if (!N.HasSymbolicScalars()) return Multivector.gp(this, 1.0 / N.BasisBlades[0].scale); // otherwise: symbolically invert else return Multivector.gp(this, RefGA.Symbolic.UnaryScalarOp.Inverse(N)); }
/// <summary> /// Internal function. Computes the versor inverse given the reverse R and the scale of (R reverse(R)) /// Throws exception when non-invertible. Can handle symbolic scalars. /// </summary> /// <param name="R">Reverse of multivector</param> /// <param name="s">scale of (R reverse(R))</param> /// <returns>Inverse of Multivector reverse(R)</returns> private static Multivector VersorInverseInternal(Multivector R, Multivector s) { if (s.IsZero()) throw new Exception("non-invertible multivector"); if (!s.HasSymbolicScalars()) { // noni symbolic scalars: do true inverse double ss = s.BasisBlades[0].scale; return gp(R, 1.0 / ss); } else { // do symbolic inverse: return gp(R, RefGA.Symbolic.UnaryScalarOp.Inverse(s)); } }
/// <summary>Computes the norm given the squared norm of this multivector.</summary> /// <returns>Norm of 'this', given norm squared 'N2'</returns> protected Multivector Norm(Multivector N2, bool positiveDefinite) { if (N2.IsZero()) return Multivector.ZERO; if (!N2.HasSymbolicScalars()) { double s = N2.BasisBlades[0].scale; return new Multivector(Math.Sign(s) * Math.Sqrt(Math.Abs(s))); } else { // if metric is note positive definite, add a fabs inside the sqrt because otherwise we could do sqrt(negative value) // TODO: maybe just also have a ABS because floating point noise can make a (small) positive or zero value negative . . . if (!positiveDefinite) N2 = RefGA.Symbolic.UnaryScalarOp.Abs(N2); return RefGA.Symbolic.UnaryScalarOp.Sqrt(N2); // NOTE: this is not the same result as the numerical version above!!! } }