/// <summary> /// Utility function Takes a bunch of basis blades in a double list and sorts them based on grade (keeping the /// original order, for each grade). /// </summary> /// <returns>Double lists of basis blades. The first index is for grade in range [0 ... m_dimension].</returns> public List <List <G25.rsbbp.BasisBlade> > SortBasisBladeListByGrade(List <List <G25.rsbbp.BasisBlade> > B) { // alloc mem for all grades: List <List <G25.rsbbp.BasisBlade> > L = new List <List <G25.rsbbp.BasisBlade> >(); for (int i = 0; i < m_spec.m_dimension + 1; i++) { L.Add(new List <G25.rsbbp.BasisBlade>()); } for (int i = 0; i < B.Count; i++) { for (int j = 0; j < B[i].Count; j++) { G25.rsbbp.BasisBlade b = B[i][j]; L[b.GetBasisBlade.Grade()].Add(b); } } return(L); }
/// <summary> /// Converts a tree of G25.rsep.FunctionApplication to a G25.rsbbp.BasisBlade. /// The allowed functions are assign(), op(), negate() and nop() /// </summary> /// <param name="O">Tree of G25.rsep.FunctionApplication, or a String (name of basisvector, or "scalar")</param> /// <param name="originalStr">The full string (used only for error messages)</param> /// <returns>the tree converted to a basis blade (with a possible constant value assigned to it).</returns> private G25.rsbbp.BasisBlade ConvertParsedXMLtoBasisBlade(Object O, String originalStr) { // O is either a string or assign(...), op(...), negate(...) or nop(...) { // is 'O' a string? String Ostr = O as String; if (Ostr != null) { // either a basis blade name, or "scalar" if (Ostr == "scalar") { return(new G25.rsbbp.BasisBlade(RefGA.BasisBlade.ONE)); } else { return(new G25.rsbbp.BasisBlade(new RefGA.BasisBlade((uint)(1 << m_spec.BasisVectorNameToIndex(Ostr))))); } } } G25.rsep.FunctionApplication FA = O as G25.rsep.FunctionApplication; if ((FA.FunctionName == "assign") && (FA.NbArguments == 2)) { // assign(e1^e2^e3, scalarValue) G25.rsbbp.BasisBlade basisBlade = ConvertParsedXMLtoBasisBlade(FA.Arguments[0], originalStr); if (basisBlade.IsConstant) { throw new Exception("Invalid assignment '=' in blade specification: " + originalStr); } double value = ConvertParsedXMLtoScalar(FA.Arguments[1], originalStr); // arg0 = basis blade (not const assignment // arg1 = scalar value return(new G25.rsbbp.BasisBlade(basisBlade.GetBasisBlade, value)); } else if ((FA.FunctionName == "op") && (FA.NbArguments == 2)) { G25.rsbbp.BasisBlade arg1 = ConvertParsedXMLtoBasisBlade(FA.Arguments[0], originalStr); G25.rsbbp.BasisBlade arg2 = ConvertParsedXMLtoBasisBlade(FA.Arguments[1], originalStr); if (arg1.IsConstant || arg2.IsConstant) { throw new Exception("Invalid assignment '=' in blade specification: " + originalStr); } return(new G25.rsbbp.BasisBlade(RefGA.BasisBlade.op(arg1.GetBasisBlade, arg2.GetBasisBlade))); } else if ((FA.FunctionName == "negate") && (FA.NbArguments == 1)) { G25.rsbbp.BasisBlade arg1 = ConvertParsedXMLtoBasisBlade(FA.Arguments[0], originalStr); if (arg1.IsConstant) { throw new Exception("Invalid assignment '=' in blade specification: " + originalStr); } return(new G25.rsbbp.BasisBlade(RefGA.BasisBlade.op(RefGA.BasisBlade.MINUS_ONE, arg1.GetBasisBlade))); } else if ((FA.FunctionName == "nop") && (FA.NbArguments == 1)) { return(ConvertParsedXMLtoBasisBlade(FA.Arguments[0], originalStr)); } else { throw new Exception("Error in basis blade list " + originalStr); } }