/// <summary> /// Writes getters and setters for the SMV coordinates.. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteGetSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { // write variable coordinates for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { string name = smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames); string accessName = GetCoordAccessString(S, smv, i); SB.AppendLine("\t/// Returns the " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate."); SB.AppendLine("\tinline " + FT.type + " " + MainGenerator.GETTER_PREFIX + name + "() const { return " + accessName + ";}"); SB.AppendLine("\t/// Sets the " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate."); SB.AppendLine("\tinline void " + MainGenerator.SETTER_PREFIX + name + "(" + FT.type + " " + name + ") { " + accessName + " = " + name + ";}"); } // write constant coordinates for (int i = 0; i < smv.NbConstBasisBlade; i++) { RefGA.BasisBlade B = smv.ConstBasisBlade(i); SB.AppendLine("\t/// Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."); SB.AppendLine("\tinline " + FT.type + " " + MainGenerator.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() const { return " + FT.DoubleToString(S, smv.ConstBasisBladeValue(i)) + ";}"); } // write a getter for the scalar which returns 0 if no scalar coordinate is present if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; SB.AppendLine("\t/// Returns the scalar coordinate (which is always 0)."); SB.AppendLine("\tinline " + FT.type + " " + MainGenerator.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() const { return " + FT.DoubleToString(S, 0.0) + ";}"); } // getter for the coordinates (stored in array) if ((S.m_coordStorage == COORD_STORAGE.ARRAY) && (smv.NbNonConstBasisBlade > 0)) { SB.AppendLine("\t/// Returns array of coordinates."); SB.AppendLine("\tinline const " + FT.type + " *getC(" + G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM + ") const { return m_c;}"); } }
/// <summary> /// Writes the SMV class comment 'SB'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> /// <param name="emitCoordIndices">Whether to emit constants for array indices to coordinates.</param> public static void WriteComment(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv, bool emitCoordIndices) { SB.AppendLine("/**"); SB.AppendLine(" * This class can hold a specialized multivector of type " + FT.GetMangledName(S, smv.Name) + "."); SB.AppendLine(" * "); SB.AppendLine(" * The coordinates are stored in type " + FT.type + "."); SB.AppendLine(" * "); if (smv.NbNonConstBasisBlade > 0) { SB.AppendLine(" * The variable non-zero coordinates are:"); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine(" * - coordinate " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " (array index: " + GetCoordIndexDefine(S, FT, smv, i) + " = " + i + ")"); } } else SB.AppendLine(" * The type is constant."); SB.AppendLine(" * "); if (smv.NbConstBasisBlade > 0) { SB.AppendLine(" * The constant non-zero coordinates are:"); for (int i = 0; i < smv.NbConstBasisBlade; i++) SB.AppendLine(" * - " + smv.ConstBasisBlade(i).ToString(S.m_basisVectorNames) + " = " + smv.ConstBasisBladeValue(i).ToString()); } else SB.AppendLine(" * The type has no constant coordinates."); SB.AppendLine(" * "); if ((smv.Comment != null) && (smv.Comment.Length > 0)) { SB.AppendLine(" * "); SB.AppendLine(" * " + smv.Comment); } SB.AppendLine(" */"); }
/// <summary> /// Writes getters and setters for the SMV coordinates.. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteGetSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { int nbTabs = 1; string className = FT.GetMangledName(S, smv.Name); // for variable coordinates: for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); string name = smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames); string accessName = G25.CG.Shared.SmvUtil.GetCoordAccessString(S, smv, i); // get string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + name + "() { return " + accessName + ";}"); // set string setComment = "Sets the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(setComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " void " + G25.CG.Shared.Main.SETTER_PREFIX + name + "(" + FT.type + " " + name + ") { " + accessName + " = " + name + ";}"); } // for constant coordinates: for (int i = 0; i < smv.NbConstBasisBlade; i++) { RefGA.BasisBlade B = smv.ConstBasisBlade(i); // get string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, smv.ConstBasisBladeValue(i)) + ";}"); } // write a getter for the scalar which returns 0 if no scalar coordinate is present if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; string getComment = "Returns the scalar coordinate (which is always 0)."; new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, 0.0) + ";}"); } // getter for the coordinates (stored in array) if ((S.m_coordStorage == COORD_STORAGE.ARRAY) && (smv.NbNonConstBasisBlade > 0)) { string constantName = G25.CG.Shared.SmvUtil.GetCoordinateOrderConstant(S, smv); string COORD_ORDER = "coordOrder"; new G25.CG.Shared.Comment("Returns array of coordinates."). SetParamComment(COORD_ORDER, "pass the value '" + className + "." + constantName + "'"). Write(SB, S, nbTabs); SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + "[] c(" + G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM + " " + COORD_ORDER + ") { return m_c;}"); } }
/// <summary> /// Takes a specialized multivector specification (G25.SMV) and converts it into a symbolic multivector. /// The symbolic weights of the multivector are the coordinates of the SMV, labelled according to 'smvName'. /// /// An example is <c>A.c[0]*e1 + A.c[1]*e2 + A.c[2]*e3</c>. /// </summary> /// <param name="S">Specification of the algebra. Used for the access convention (. or ->) and for how to name the coordinates ([0] or e1, e2, e3).</param> /// <param name="smv">The specification of the specialized multivector.</param> /// <param name="smvName">Name the variable should have.</param> /// <param name="ptr">Is 'smvName' a pointer? This changes the way the variable is accessed.</param> /// <returns></returns> public static RefGA.Multivector SMVtoSymbolicMultivector(Specification S, G25.SMV smv, string smvName, bool ptr) { int idx = 0; // index into 'L' RefGA.BasisBlade[] L = new RefGA.BasisBlade[smv.NbConstBasisBlade + smv.NbNonConstBasisBlade]; string[] AL = CodeUtil.GetAccessStr(S, smv, smvName, ptr); // get non-const coords for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { // get basis blade of coordinate RefGA.BasisBlade B = smv.NonConstBasisBlade(i); // merge L[idx++] = new RefGA.BasisBlade(B.bitmap, B.scale, AL[i]); } // get const coords for (int i = 0; i < smv.NbConstBasisBlade; i++) { // get value of coordinate double value = smv.ConstBasisBladeValue(i); // get basis blade of coordinate RefGA.BasisBlade B = smv.ConstBasisBlade(i); // merge L[idx++] = new RefGA.BasisBlade(B.bitmap, B.scale * value); } return new RefGA.Multivector(L); }
/// <summary> /// Writes the definition of an SMV struct to 'SB' (including comments). /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> public static void WriteSMVstruct(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv) { SB.AppendLine(""); { // comments for type: SB.AppendLine("/**"); SB.AppendLine(" * This struct can hold a specialized multivector of type " + FT.GetMangledName(S, smv.Name) + "."); SB.AppendLine(" * "); SB.AppendLine(" * The coordinates are stored in type " + FT.type + "."); SB.AppendLine(" * "); if (smv.NbNonConstBasisBlade > 0) { SB.AppendLine(" * The variable non-zero coordinates are:"); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine(" * - coordinate " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " (array index: " + GetCoordIndexDefine(S, smv, i) + " = " + i + ")"); } } else SB.AppendLine(" * The type is constant."); SB.AppendLine(" * "); if (smv.NbConstBasisBlade > 0) { SB.AppendLine(" * The constant non-zero coordinates are:"); for (int i = 0; i < smv.NbConstBasisBlade; i++) SB.AppendLine(" * - " + smv.ConstBasisBlade(i).ToString(S.m_basisVectorNames) + " = " + smv.ConstBasisBladeValue(i).ToString()); } else SB.AppendLine(" * The type has no constant coordinates."); SB.AppendLine(" * "); if ((smv.Comment != null) && (smv.Comment.Length > 0)) { SB.AppendLine(" * "); SB.AppendLine(" * " + smv.Comment); } SB.AppendLine(" */"); } // typedef SB.AppendLine("typedef struct "); SB.AppendLine("{"); // individual coordinates or one array? if (smv.NbNonConstBasisBlade > 0) { if (S.m_coordStorage == COORD_STORAGE.VARIABLES) { // emit float e1; float e2; float e3; for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine("\t/** The " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate. */"); SB.AppendLine("\t" + FT.type + " " + smv.GetCoordLangID(i, S) + ";"); //G25.CG.Shared.Util.BasisBladeToLangString(smv.NonConstBasisBlade(i), S.m_basisVectorNames) + ";"); } } else { // emit: float c[3]; // e1, e2, e3 SB.AppendLine("\t/** The coordinates (stored in an array). */"); SB.Append("\t" + FT.type + " c[" + smv.NbNonConstBasisBlade + "]; /* "); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { if (i > 0) SB.Append(", "); SB.Append(smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames)); } SB.AppendLine("*/"); } } else { SB.AppendLine("\t/** Filler, because C does not allow empty structs. */"); SB.AppendLine("\tint filler;"); } // emit: // no=1 for (int i = 0; i < smv.NbConstBasisBlade; i++) { SB.AppendLine("\t/* " + smv.ConstBasisBlade(i).ToString(S.m_basisVectorNames) + " = " + smv.ConstBasisBladeValue(i).ToString() + "*/"); } SB.AppendLine("} " + FT.GetMangledName(S, smv.Name) + ";"); }
/// <summary> /// Returns the comment for a SMV class. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="smv">The specialized multivector for which the struct should be written.</param> /// <param name="emitCoordIndices">Whether to emit constants for array indices to coordinates.</param> public static Comment GetSmvComment(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv, bool emitCoordIndices) { StringBuilder SB = new StringBuilder(); SB.AppendLine("This class can hold a specialized multivector of type " + FT.GetMangledName(S, smv.Name) + "."); SB.AppendLine(""); SB.AppendLine("The coordinates are stored in type " + FT.type + "."); SB.AppendLine(""); if (smv.NbNonConstBasisBlade > 0) { SB.AppendLine("The variable non-zero coordinates are:"); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { SB.AppendLine(" - coordinate " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " (array index: " + smv.GetCoordLangID(i, S, COORD_STORAGE.VARIABLES).ToUpper() + " = " + i + ")"); } } else SB.AppendLine("The type is constant."); SB.AppendLine(""); if (smv.NbConstBasisBlade > 0) { SB.AppendLine("The constant non-zero coordinates are:"); for (int i = 0; i < smv.NbConstBasisBlade; i++) SB.AppendLine(" - " + smv.ConstBasisBlade(i).ToString(S.m_basisVectorNames) + " = " + smv.ConstBasisBladeValue(i).ToString()); } else SB.AppendLine("The type has no constant coordinates."); SB.AppendLine(""); if ((smv.Comment != null) && (smv.Comment.Length > 0)) { SB.AppendLine(""); SB.AppendLine("" + smv.Comment); } return new Comment(SB.ToString()); }