} // end of ComputeOmInitFromVectorsSigns() /// <summary> /// Returns info about <c>bitmap</c>. /// /// If bitmap is not in the domain of <c>om</c>, the basis blade in the returned value will be null, /// and the domainIdx will be -1. /// /// If the grade of the bitmap is 1, the domainIdx will be -1 because it is /// assumed to be an input vector. /// </summary> /// <param name="S"></param> /// <param name="om"></param> /// <param name="bitmap"></param> /// <returns><c>BasisBlade, grade, domainIdx</c> for <c>bitmap</c></returns> public static G25.Tuple <RefGA.BasisBlade, int, int> GetDomainBladeInfo(Specification S, OM om, uint bitmap) { int grade = (int)RefGA.Bits.BitCount(bitmap); if (grade == 1) // basis vector { return(new G25.Tuple <RefGA.BasisBlade, int, int>(new RefGA.BasisBlade(bitmap), grade, -1)); } // find the bitmap in the domain RefGA.BasisBlade B = null; int domainIdx = -1; for (int i = 0; i < om.DomainForGrade(grade).Length; i++) { if (bitmap == om.DomainForGrade(grade)[i].bitmap) { domainIdx = i; B = om.DomainForGrade(grade)[i]; break; } } return(new G25.Tuple <RefGA.BasisBlade, int, int>(B, grade, domainIdx)); } // end of GetDomainBladeInfo()
} // end of ComputeOmInitFromVectorsPlan() /// <summary> /// Computes the signs for the plan as computed by GetOmInitFromVectorsPlan(). /// /// Because the basis blades in the domain of 'om' do not have to be in canonical order, /// there may be some signs required to correctly executed the plan /// </summary> /// <param name="S"></param> /// <param name="om"></param> /// <param name="plan"></param> /// <returns>signs for the plan</returns> public static double[][] ComputeOmInitFromVectorsSigns(Specification S, OM om, uint[][][] plan) { double[][] result = new double[S.m_dimension + 1][]; for (int g = 1; g <= S.m_dimension; g++) { result[g] = new double[om.DomainForGrade(g).Length]; for (int d = 0; d < om.DomainForGrade(g).Length; d++) { // get domain blade we have to construct RefGA.BasisBlade D = om.DomainForGrade(g)[d]; // follow the plan to construct the blade RefGA.BasisBlade P = RefGA.BasisBlade.ONE; for (int p = 0; p < plan[g][d].Length; p++) { G25.Tuple <RefGA.BasisBlade, int, int> info = GetDomainBladeInfo(S, om, plan[g][d][p]); P = RefGA.BasisBlade.op(P, info.Value1); } // compute sign difference & store double s = D.scale / P.scale; result[g][d] = s; } } return(result); } // end of ComputeOmInitFromVectorsSigns()
/// <summary> /// 'Plans' how to initialize an outermorphism from vector images. /// /// The plan is returned in the form of nested array <c>uint[grade][domain][plan steps]</c>. /// The <c>plan steps</c> are the bitmaps of the basis blades that should be wedged together /// to form the basis blade for <c>grade,domain</c>. /// </summary> /// <param name="S"></param> /// <param name="om"></param> /// <returns>plan for initialization of <c>om</c> from vector images.</returns> public static uint[][][] ComputeOmInitFromVectorsPlan(Specification S, OM om) { // keep track of which basis blades are available (domain vectors are the input, so they are always available) bool[] availableBasisBlades = new bool[1 << S.m_dimension]; for (int i = 0; i < om.DomainVectors.Length; i++) { availableBasisBlades[om.DomainVectors[i].bitmap] = true; } // for each grade, figure out how to construct the basis blades of that grade from basis blades which are already available uint[][][] result = new uint[S.m_dimension + 1][][]; for (int g = 1; g <= S.m_dimension; g++) { result[g] = new uint[om.DomainForGrade(g).Length][]; for (int d = 0; d < om.DomainForGrade(g).Length; d++) { RefGA.BasisBlade D = om.DomainForGrade(g)[d]; // find the largest part of D which is already known List <uint> plan = new List <uint>(); uint bitmap = D.bitmap; while (bitmap != 0) { // find first bit, plan it, see if the rest is available uint lowestBitIdx = (uint)RefGA.Bits.LowestOneBit(bitmap); uint lowestBitmap = (uint)(1 << (int)lowestBitIdx); plan.Add(lowestBitmap); bitmap ^= lowestBitmap; if (availableBasisBlades[bitmap]) // if remaining bitmap has already been computed, use that { plan.Add(bitmap); bitmap ^= bitmap; } } // plan for this basis blade is done: result[g][d] = plan.ToArray(); availableBasisBlades[D.bitmap] = true; } } return(result); } // end of ComputeOmInitFromVectorsPlan()
/// <summary> /// 'Plans' how to initialize an outermorphism from vector images. /// /// The plan is returned in the form of nested array <c>uint[grade][domain][plan steps]</c>. /// The <c>plan steps</c> are the bitmaps of the basis blades that should be wedged together /// to form the basis blade for <c>grade,domain</c>. /// </summary> /// <param name="S"></param> /// <param name="om"></param> /// <returns>plan for initialization of <c>om</c> from vector images.</returns> public static uint[][][] ComputeOmInitFromVectorsPlan(Specification S, OM om) { // keep track of which basis blades are available (domain vectors are the input, so they are always available) bool[] availableBasisBlades = new bool[1 << S.m_dimension]; for (int i = 0; i < om.DomainVectors.Length; i++) availableBasisBlades[om.DomainVectors[i].bitmap] = true; // for each grade, figure out how to construct the basis blades of that grade from basis blades which are already available uint[][][] result = new uint[S.m_dimension + 1][][]; for (int g = 1; g <= S.m_dimension; g++) { result[g] = new uint[om.DomainForGrade(g).Length][]; for (int d = 0; d < om.DomainForGrade(g).Length; d++) { RefGA.BasisBlade D = om.DomainForGrade(g)[d]; // find the largest part of D which is already known List<uint> plan = new List<uint>(); uint bitmap = D.bitmap; while (bitmap != 0) { // find first bit, plan it, see if the rest is available uint lowestBitIdx = (uint)RefGA.Bits.LowestOneBit(bitmap); uint lowestBitmap = (uint)(1 << (int)lowestBitIdx); plan.Add(lowestBitmap); bitmap ^= lowestBitmap; if (availableBasisBlades[bitmap]) // if remaining bitmap has already been computed, use that { plan.Add(bitmap); bitmap ^= bitmap; } } // plan for this basis blade is done: result[g][d] = plan.ToArray(); availableBasisBlades[D.bitmap] = true; } } return result; }
/// <summary> /// Computes the signs for the plan as computed by GetOmInitFromVectorsPlan(). /// /// Because the basis blades in the domain of 'om' do not have to be in canonical order, /// there may be some signs required to correctly executed the plan /// </summary> /// <param name="S"></param> /// <param name="om"></param> /// <param name="plan"></param> /// <returns>signs for the plan</returns> public static double[][] ComputeOmInitFromVectorsSigns(Specification S, OM om, uint[][][] plan) { double[][] result = new double[S.m_dimension + 1][]; for (int g = 1; g <= S.m_dimension; g++) { result[g] = new double[om.DomainForGrade(g).Length]; for (int d = 0; d < om.DomainForGrade(g).Length; d++) { // get domain blade we have to construct RefGA.BasisBlade D = om.DomainForGrade(g)[d]; // follow the plan to construct the blade RefGA.BasisBlade P = RefGA.BasisBlade.ONE; for (int p = 0; p < plan[g][d].Length; p++) { G25.Tuple<RefGA.BasisBlade, int, int> info = GetDomainBladeInfo(S, om, plan[g][d][p]); P = RefGA.BasisBlade.op(P, info.Value1); } // compute sign difference & store double s = D.scale / P.scale; result[g][d] = s; } } return result; }
/// <summary> /// Returns info about <c>bitmap</c>. /// /// If bitmap is not in the domain of <c>om</c>, the basis blade in the returned value will be null, /// and the domainIdx will be -1. /// /// If the grade of the bitmap is 1, the domainIdx will be -1 because it is /// assumed to be an input vector. /// </summary> /// <param name="S"></param> /// <param name="om"></param> /// <param name="bitmap"></param> /// <returns><c>BasisBlade, grade, domainIdx</c> for <c>bitmap</c></returns> public static G25.Tuple<RefGA.BasisBlade, int, int> GetDomainBladeInfo(Specification S, OM om, uint bitmap) { int grade = (int)RefGA.Bits.BitCount(bitmap); if (grade == 1) // basis vector return new G25.Tuple<RefGA.BasisBlade, int, int>(new RefGA.BasisBlade(bitmap), grade, -1); // find the bitmap in the domain RefGA.BasisBlade B = null; int domainIdx = -1; for (int i = 0; i < om.DomainForGrade(grade).Length; i++) { if (bitmap == om.DomainForGrade(grade)[i].bitmap) { domainIdx = i; B = om.DomainForGrade(grade)[i]; break; } } return new G25.Tuple<RefGA.BasisBlade, int, int>(B, grade, domainIdx); }