/// <summary> /// Evaluate a cast to multivector value operation /// </summary> /// <param name="expr"></param> /// <returns></returns> private ILanguageValue EvaluateBasicUnaryCastToMultivector(BasicUnary expr) { var value1 = expr.Operand.AcceptVisitor(this); var mvType = (GMacFrameMultivector)expr.Operator; if (value1.ExpressionType.IsNumber()) { var scalarValue = ((ValuePrimitive <MathematicaScalar>)value1).Value; return(GMacValueMultivector.Create( mvType, GaMultivector.CreateScalar( mvType.ParentFrame.GaSpaceDimension, scalarValue ) )); } if (value1.ExpressionType.IsFrameMultivector() && value1.ExpressionType.GetFrame().VSpaceDimension == mvType.ParentFrame.VSpaceDimension) { var mvValue = (GMacValueMultivector)value1; return(GMacValueMultivector.Create( mvType, GaMultivector.CreateCopy(mvValue.MultivectorCoefficients) )); } throw new InvalidOperationException("Invalid cast operation"); }
public static GaOuterMorphismFull Create(ISymbolicMatrix vectorTransformMatrix) { var domainGaSpaceDim = FrameUtils.GaSpaceDimension(vectorTransformMatrix.Columns); var codomainGaSpaceDim = FrameUtils.GaSpaceDimension(vectorTransformMatrix.Rows); var transformedBasisBlades = new GaMultivector[domainGaSpaceDim]; transformedBasisBlades[0] = GaMultivector.CreateScalar(codomainGaSpaceDim, MathematicaScalar.Create(vectorTransformMatrix.CasInterface, 1)); for (var id = 1; id <= domainGaSpaceDim - 1; id++) { if (id.IsValidBasisVectorId()) { transformedBasisBlades[id] = CreateFromMatrixColumn(vectorTransformMatrix, id.BasisBladeIndex()); } else { int id1, id2; id.SplitBySmallestBasicPattern(out id1, out id2); transformedBasisBlades[id] = transformedBasisBlades[id1].OuterProduct(transformedBasisBlades[id2]); } } return(new GaOuterMorphismFull(transformedBasisBlades)); }
public static GaMultivector OuterProduct(this GaMultivector mv1, GaMultivector mv2) { if (mv1.GaSpaceDim != mv2.GaSpaceDim) { throw new GMacSymbolicException("Multivector size mismatch"); } var terms1 = mv1.ToStringsDictionary(); var terms2 = mv2.ToStringsDictionary(); var accumExprDict = new Dictionary <int, ListComposer>(); foreach (var term1 in terms1) { var id1 = term1.Key; var coef1 = term1.Value; foreach (var term2 in terms2.FilterTermsForOp(id1)) { var id2 = term2.Key; var coef2 = term2.Value; var resultId = id1 ^ id2; var resultCoefDelta = Times(coef1, coef2, FrameUtils.IsNegativeEGp(id1, id2)); accumExprDict.AddTerm(resultId, resultCoefDelta); } } return(accumExprDict.ToMultivector(mv1.GaSpaceDim)); }
public override GaMultivector BasisBladeSignature(int id) { var basisBlade = GaMultivector.CreateBasisBlade(GaSpaceDimension, id); var sig = Gp(basisBlade, basisBlade); return(id.BasisBladeIdHasNegativeReverse() ? -sig : sig); }
public MathematicaScalar Magnitude2(GaMultivector mv) { return (mv .ToKVectors() .Select(pair => Sp(pair.Value, pair.Value.Reverse())) .Aggregate(CasConstants.Zero, (current, mv1) => current + mv1[0].Abs())); }
public override GaMultivector BasisBladeSignature(int id) { if (id >= 0 && id < GaSpaceDimension) { return(GaMultivector.CreateScalar(GaSpaceDimension, CasConstants.One)); } throw new IndexOutOfRangeException(); }
private GaMultivector BilinearProduct(GaMultivector mv1, GaMultivector mv2, Func <GaMultivector, GaMultivector, GaMultivector> bofProduct) { var omv1 = Dfs.DerivedToBaseOm.Transform(mv1); var omv2 = Dfs.DerivedToBaseOm.Transform(mv2); var mv = bofProduct(omv1, omv2); return(Dfs.BaseToDerivedOm.Transform(mv)); }
/// <summary> /// Convert this basis blade into a multivector value with unity coefficient of its single term /// </summary> /// <returns></returns> public AstValueMultivector ToMultivectorValue() { return(new AstValueMultivector( GMacValueMultivector.Create( AssociatedFrame.MultivectorType, GaMultivector.CreateBasisBlade( AssociatedFrame.GaSpaceDimension, BasisBladeId ) ) )); }
public override GaMultivector BasisBladeSignature(int id) { if (id < 0 || id >= GaSpaceDimension) { throw new IndexOutOfRangeException(); } var s = _basisBladesSignatures[id] == 1 ? CasConstants.One : CasConstants.MinusOne; GaMultivector.CreateScalar(GaSpaceDimension, s); throw new IndexOutOfRangeException(); }
private static GaMultivector CreateFromMatrixColumn(ISymbolicMatrix matrix, int col) { var gaSpaceDim = FrameUtils.GaSpaceDimension(matrix.Rows); var mv = GaMultivector.CreateZero(gaSpaceDim); for (var index = 0; index < matrix.Rows; index++) { mv[1, index] = matrix[index, col]; } return(mv); }
/// <summary> /// Convert this binding pattern into a multivector value /// </summary> /// <param name="varNameTemplate"></param> /// <returns></returns> public AstValueMultivector ToValue(StringSequenceTemplate varNameTemplate) { var mv = GaMultivector.CreateZero(BaseFrameMultivector.AssociatedFrameMultivector.ParentFrame.GaSpaceDimension); foreach (var pair in _patternDictionary) { mv[pair.Key] = pair.Value.ToMathematicaScalar(varNameTemplate); } return(new AstValueMultivector( GMacValueMultivector.Create( BaseFrameMultivector.AssociatedFrameMultivector, mv ) )); }
internal static GaMultivector ToMultivector(this Dictionary <int, ListComposer> accumExprDict, int gaSpaceDim) { var resultMv = GaMultivector.CreateZero(gaSpaceDim); foreach (var pair in accumExprDict) { var resultCoef = SymbolicUtils.Cas[pair.Value.ToString()]; if (!(resultCoef.Args.Length == 0 && resultCoef.ToString() == "0")) { resultMv.Add(pair.Key, MathematicaScalar.Create(SymbolicUtils.Cas, resultCoef)); } } return(resultMv); }
/// <summary> /// Create a derived frame system where the derived frame is the reciprocal of the base frame /// </summary> /// <param name="baseFrame"></param> /// <returns></returns> public static DerivedFrameSystem CreateReciprocalCbmFrameSystem(GaFrame baseFrame) { if (baseFrame.IsOrthogonal) { var cbmat = baseFrame.Ipm.Inverse(); var b2DOm = GaOuterMorphismFull.Create(baseFrame.Ipm); var d2BOm = GaOuterMorphismFull.Create(cbmat); var derivedFrame = CreateOrthogonal(cbmat.GetDiagonal()); return(new DerivedFrameSystem(baseFrame, derivedFrame, d2BOm, b2DOm)); } var cbmArray = new MathematicaScalar[baseFrame.VSpaceDimension, baseFrame.VSpaceDimension]; var mv2 = baseFrame.CreateInverseUnitPseudoScalar(); for (var i = 0; i < baseFrame.VSpaceDimension; i++) { var id = (1 << i) ^ baseFrame.MaxBasisBladeId; var mv1 = GaMultivector.CreateTerm(baseFrame.GaSpaceDimension, id, SymbolicUtils.Constants.One); var mv = baseFrame.Lcp(mv1, mv2); foreach (var term in mv) { var j = term.Key.BasisBladeIndex(); if ((i & 1) == 1) { cbmArray[i, j] = term.Value; } else { cbmArray[i, j] = -term.Value; } } } var cbm = MathematicaMatrix.CreateFullMatrix(SymbolicUtils.Cas, cbmArray); return(CreateDerivedCbmFrameSystem(baseFrame, cbm)); }
//TODO: This requires more acceleration (try to build the expressions then evaluate once per basis blade id for result_mv) //private GAMultivectorCoefficients BilinearProduct(GAMultivectorCoefficients mv1, GAMultivectorCoefficients mv2, Func<int, int, bool> term_discard_function) //{ // if (mv1.GASpaceDim != mv2.GASpaceDim || mv1.GASpaceDim != GASpaceDim) // throw new GMacSymbolicException("Multivector size mismatch"); // GAMultivectorCoefficients mv = GAMultivectorCoefficients.CreateZero(mv1.GASpaceDim); // foreach (var term1 in mv1) // { // int id1 = term1.Key; // MathematicaScalar coef1 = term1.Value; // foreach (var term2 in mv2.FilterTermsUsing(id1, term_discard_function)) // { // int id2 = term2.Key; // MathematicaScalar coef2 = term2.Value; // int id = id1 ^ id2; // if (GAUtils.IDs_To_EGP_Sign(id1, id2)) // mv[id] -= coef1 * coef2 * _BasisBladesSignatures[id]; // else // mv[id] += coef1 * coef2 * _BasisBladesSignatures[id]; // } // } // return mv; //} private GaMultivector BilinearProduct(GaMultivector mv1, GaMultivector mv2, Func <int, int, bool> termDiscardFunction) { if (mv1.GaSpaceDim != mv2.GaSpaceDim || mv1.GaSpaceDim != GaSpaceDimension) { throw new GMacSymbolicException("Multivector size mismatch"); } var terms1 = mv1.ToStringsDictionary(); var terms2 = mv2.ToStringsDictionary(); var accumExprDict = new Dictionary <int, ListComposer>(); foreach (var term1 in terms1) { var id1 = term1.Key; var coef1 = term1.Value; foreach (var term2 in terms2.FilterTermsUsing(id1, termDiscardFunction)) { var id2 = term2.Key; var coef2 = term2.Value; var resultId = id1 ^ id2; var sigId = id1 & id2; var resultCoefDelta = EuclideanUtils.Times( coef1, coef2, _basisBladesSignatures[sigId].MathExpr.ToString(), FrameUtils.IsNegativeEGp(id1, id2) ); accumExprDict.AddTerm(resultId, resultCoefDelta); } } return(accumExprDict.ToMultivector(mv1.GaSpaceDim)); }
//TODO: This requires more acceleration (try to build the expressions then evaluate once per basis blade id for result_mv) //public override GAMultivectorCoefficients Transform(GAMultivectorCoefficients mv1) //{ // if (mv1.GASpaceDim != this.DomainGASpaceDim) // throw new GMacSymbolicException("Multivector GA space dimension does not agree with domain GA space dimension"); // GAMultivectorCoefficients result_mv = GAMultivectorCoefficients.CreateZero(CodomainGASpaceDim); // foreach (var term1 in mv1) // { // var coef1 = term1.Value; // var mv2 = _TransformedBasisBlades[term1.Key]; // foreach (var term2 in mv2) // { // var coef2 = term2.Value; // var result_id = term2.Key; // result_mv[result_id] += coef1 * coef2; // } // } // return result_mv; //} public override GaMultivector Transform(GaMultivector mv1) { if (mv1.GaSpaceDim != DomainGaSpaceDim) { throw new GMacSymbolicException("Multivector GA space dimension does not agree with domain GA space dimension"); } var accumExprDict = new Dictionary <int, ListComposer>(); var terms1 = mv1.ToStringsDictionary(); foreach (var term1 in terms1) { var terms2 = _transformedBasisBlades[term1.Key].ToStringsDictionary(); foreach (var term2 in terms2) { accumExprDict.AddTerm(term2.Key, EuclideanUtils.Times(term1.Value, term2.Value)); } } return(accumExprDict.ToMultivector(CodomainGaSpaceDim)); }
/// <summary> /// Convert this binding pattern into a multivector value /// </summary> /// <param name="basisBladeToVarName"></param> /// <returns></returns> public AstValueMultivector ToValue(Func <AstFrameBasisBlade, string> basisBladeToVarName) { var frameInfo = new AstFrame(BaseFrameMultivector.AssociatedFrameMultivector.ParentFrame); var mv = GaMultivector.CreateZero(BaseFrameMultivector.AssociatedFrameMultivector.ParentFrame.GaSpaceDimension); foreach (var pair in _patternDictionary) { mv[pair.Key] = pair.Value.IsConstant ? pair.Value.ConstantSymbolicScalar : MathematicaScalar.Create( SymbolicUtils.Cas, basisBladeToVarName(frameInfo.BasisBlade(pair.Key)) ); } return (new AstValueMultivector( GMacValueMultivector.Create( BaseFrameMultivector.AssociatedFrameMultivector, mv ) )); }
public override GaMultivector Transform(GaMultivector mv) { //TODO: Complete this throw new NotImplementedException(); }
public abstract GaMultivector Transform(GaMultivector mv);
public override GaMultivector Transform(GaMultivector mv) { return(mv); }
public GaMultivector CreateUnitPseudoScalar() { return(GaMultivector.CreateBasisBlade(GaSpaceDimension, MaxBasisBladeId)); }
public static MathematicaScalar EuclideanMagnitude2(this GaMultivector mv) { return(EuclideanSp(mv, mv.Reverse())[0]); }
public static GaMultivector EuclideanAcp(this GaMultivector mv1, GaMultivector mv2) { return(EuclideanBilinearProduct(mv1, mv2, IsZeroEuclideanAcp)); }
public override GaMultivector Rcp(GaMultivector mv1, GaMultivector mv2) { return(BilinearProduct(mv1, mv2, BaseOrthogonalFrame.Rcp)); }
public abstract GaMultivector Cp(GaMultivector mv1, GaMultivector mv2);
public GaMultivector CreateInverseUnitPseudoScalar() { //TODO: Review this computation return(GaMultivector.CreateTerm(GaSpaceDimension, MaxBasisBladeId, UnitPseudoScalarCoef)); }
public override GaMultivector Acp(GaMultivector mv1, GaMultivector mv2) { return(mv1.EuclideanBilinearProduct(mv2, EuclideanUtils.IsZeroEuclideanAcp)); }
public GaMultivector Op(GaMultivector mv1, GaMultivector mv2) { return(mv1.OuterProduct(mv2)); }
public MathematicaScalar Norm2(GaMultivector mv) { return(Sp(mv, mv.Reverse())[0]); }
public override GaMultivector Cp(GaMultivector mv1, GaMultivector mv2) { return(BilinearProduct(mv1, mv2, EuclideanUtils.IsZeroEuclideanCp)); }
public override GaMultivector BasisBladeSignature(int id) { return(GaMultivector.CreateScalar(GaSpaceDimension, _basisBladesSignatures[id])); }