/// <summary> /// Create a derived frame system using a change of basis matrix for the basis vectors /// </summary> /// <param name="baseFrame">The base frame. It may be any kind of frame</param> /// <param name="cbm">The 'Change Of Basis Vectors' matrix. It must be invertable</param> /// <returns></returns> public static GaNumMetricNonOrthogonal CreateDerivedCbmFrameSystem(GaNumFrame baseFrame, Matrix cbm) { var baseIpm = baseFrame.Ipm; var cbmTrans = (Matrix)cbm.Transpose(); var cbmInverseTrans = (Matrix)cbmTrans.Inverse(); var ipm = cbm * baseIpm * cbmTrans; var baseToDerivedCba = cbmInverseTrans.ToOutermorphismTree(); var derivedToBaseCba = cbmTrans.ToOutermorphismTree(); if ((ipm as Matrix).IsDiagonal()) { var derivedFrame = CreateOrthogonal(ipm.Diagonal()); return(new GaNumMetricNonOrthogonal(baseFrame, derivedFrame, derivedToBaseCba, baseToDerivedCba)); } if (baseFrame.IsOrthogonal) { var derivedFrame = new GaNumFrameNonOrthogonal(baseFrame, ipm as Matrix, derivedToBaseCba, baseToDerivedCba); return(derivedFrame.NonOrthogonalMetric); } var gaFrame = //new GaFrameNonOrthogonal(baseFrame, ipm, derivedToBaseOm, baseToDerivedOm); CreateNonOrthogonalFromIpm(ipm as Matrix); return(gaFrame.NonOrthogonalMetric); //return new DerivedFrameSystem(baseFrame, gaFrame, derivedToBaseOm, baseToDerivedOm); }
/// <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 GaNumMetricNonOrthogonal CreateReciprocalCbmFrameSystem(GaNumFrame baseFrame) { if (baseFrame.IsOrthogonal) { var cbmat = baseFrame.Ipm.Inverse(); var b2DOm = baseFrame.Ipm.ToOutermorphismTree(); var d2BOm = (cbmat as Matrix).ToOutermorphismTree(); var derivedFrame = CreateOrthogonal(cbmat.Diagonal()); return(new GaNumMetricNonOrthogonal(baseFrame, derivedFrame, d2BOm, b2DOm)); } var cbmArray = new double[baseFrame.VSpaceDimension, baseFrame.VSpaceDimension]; var mv2 = baseFrame.CreateInverseUnitPseudoScalar(); for (var i = 0; i < baseFrame.VSpaceDimension; i++) { var id = (1 << i) ^ baseFrame.MaxBasisBladeId; var mv1 = GaNumMultivector.CreateTerm(baseFrame.GaSpaceDimension, id, 1.0d); var mv = baseFrame.Lcp[mv1, mv2]; foreach (var term in mv.NonZeroTerms) { var j = term.Key.BasisBladeIndex(); if ((i & 1) == 1) { cbmArray[i, j] = term.Value; } else { cbmArray[i, j] = -term.Value; } } } var cbm = DenseMatrix.OfArray(cbmArray); return(CreateDerivedCbmFrameSystem(baseFrame, cbm)); }
internal GaNumFrameNonOrthogonal(GaNumFrame baseOrthoFrame, Matrix ipm, GaNumOutermorphism derivedToBaseOm, GaNumOutermorphism baseToDerivedOm) { if (baseOrthoFrame.IsOrthogonal == false) { throw new GMacNumericException("Base frame must be orthogonal"); } if (ipm.IsDiagonal()) { throw new GMacNumericException("Inner product matrix must be non-diagonal"); } InnerProductMatrix = ipm; NonOrthogonalMetric = new GaNumMetricNonOrthogonal( baseOrthoFrame, this, derivedToBaseOm, baseToDerivedOm ); Op = ComputedOp = new GaNumOp(VSpaceDimension); Gp = ComputedGp = GaNumBilinearProductCba.CreateGp(NonOrthogonalMetric); Sp = ComputedSp = GaNumBilinearProductCba.CreateSp(NonOrthogonalMetric); Lcp = ComputedLcp = GaNumBilinearProductCba.CreateLcp(NonOrthogonalMetric); Rcp = ComputedRcp = GaNumBilinearProductCba.CreateRcp(NonOrthogonalMetric); Fdp = ComputedFdp = GaNumBilinearProductCba.CreateFdp(NonOrthogonalMetric); Hip = ComputedHip = GaNumBilinearProductCba.CreateHip(NonOrthogonalMetric); Acp = ComputedAcp = GaNumBilinearProductCba.CreateAcp(NonOrthogonalMetric); Cp = ComputedCp = GaNumBilinearProductCba.CreateCp(NonOrthogonalMetric); UnitPseudoScalarCoef = (MaxBasisBladeId.BasisBladeIdHasNegativeReverse() ? -1.0d : 1.0d) / BasisBladeSignature(MaxBasisBladeId)[0]; }