/// <summary> /// Writes any addition or subtraction function for general multivectors, /// based on CASN parts code. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="funcType">ADD, SUB or HP</param> /// <returns>Full name of generated function.</returns> public static string WriteAddSubHpFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.CANSparts.ADD_SUB_HP_TYPE funcType) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.CANSparts.GetAddSubtractHpCode(S, cgd, FT, funcType, FAI, fgs.RETURN_ARG_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value string funcName = CF.OutputName; //if (S.OutputC()) // funcName = FT.GetMangledName(S, funcName); // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return funcName; }
public static Comment GetComment(Specification S, string srcTypeName, string dstTypeName, string argName, string extraComment) { Comment comment = new Comment("Converts " + srcTypeName + " to " + dstTypeName + ": " + "dst" + " = " + argName + "."); if ((extraComment != null) && (extraComment.Length > 0)) { comment = comment.AddSummaryComment(extraComment); } return comment; }
public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; string srcTypeName = FT.GetMangledName(S, srcOm.Name); string dstTypeName = FT.GetMangledName(S, dstOm.Name); bool writeDecl = S.OutputC(); string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : ""; string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : ""); string CONST = (S.OutputCppOrC()) ? "const " : ""; string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)"; // write comment, function declaration Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" + "Warning 1: coordinates which cannot be represented are silenty lost.\n" + "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n"); if (writeDecl) { comment.Write(declSB, S, 0); declSB.Append(funcDecl); declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) comment.Write(defSB, S, 0); defSB.Append(funcDecl); { defSB.AppendLine(" {"); Dictionary<Tuple<int, int, int>, Tuple<int, int, double>> D = dstOm.getMapping(srcOm); StringBuilder copySB = new StringBuilder(); List<string> setToZero = new List<string>(); string matrixStr = (S.OutputC()) ? "m" : "m_m"; string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr; string ptrStr = (S.OutputC()) ? "->" : "."; // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null // Do not use foreach() on D because we want to fill in coordinates in their proper order. for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++) { for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++) { for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++) { Tuple<int, int, int> key = new Tuple<int, int, int>(gradeIdx, somDomainIdx, somRangeIdx); int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx); string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = "; if (D.ContainsKey(key)) { Tuple<int, int, double> value = D[key]; int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2); double multiplier = value.Value3; string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * "); copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];"); } else { setToZero.Add(dstString); } } } } // append copy statements defSB.Append(copySB); // append statements to set coordinates to zero if (setToZero.Count > 0) { int cnt = 0; defSB.Append("\t"); foreach (string str in setToZero) { defSB.Append(str); cnt++; if (cnt > 8) { cnt = 0; defSB.AppendLine(""); defSB.Append("\t\t"); } } defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";"); } defSB.AppendLine("}"); } }
/// <summary> /// Writes a function to apply general outermorphisms to general multivectors, /// based on gom_parts code. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <returns>Name of generated function.</returns> public static String WriteApplyOmFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.GomParts.GetApplyGomCode(S, cgd, FT, FAI, fgs.RETURN_ARG_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: String returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } // string funcName = FT.GetMangledName(S, CF.OutputName); string funcName = CF.OutputName; // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return(funcName); }
public static void WriteSetMatrix(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som, bool transpose) { int NB_ARGS = 1; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; argTypes[0] = FT.type; argNames[0] = "M"; // construct image values RefGA.Multivector[] imageValue = new RefGA.Multivector[som.DomainVectors.Length]; for (int d = 0; d < som.DomainVectors.Length; d++) { //imageValue[d] = RefGA.Multivector.ZERO; RefGA.BasisBlade[] IV = new RefGA.BasisBlade[som.RangeVectors.Length]; for (int r = 0; r < som.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * som.RangeVectors.Length + r) : (r * som.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(som.RangeVectors[r].bitmap, 1.0, entryName); } imageValue[d] = new RefGA.Multivector(IV); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setMatrix"); if (transpose) { funcName = funcName + "Transpose"; } //argNames[0] = "*" + argNames[0]; // quick hack: add pointer to name instead of type! G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (S.OutputCppOrC()) { F.m_argumentPtr[0] = true; } else { F.m_argumentArr[0] = true; } bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); } // setup instructions List <G25.CG.Shared.Instruction> I = new List <G25.CG.Shared.Instruction>(); { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c]; RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade for (uint v = 0; v < som.DomainVectors.Length; v++) { if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0) { value = RefGA.Multivector.op(value, imageValue[v]); } } I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix."); bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
private static void WriteConvertingConstructor(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.fgs fgs, SMV srcSmv, SMV dstSmv) { string srcTypeName = FT.GetMangledName(S, srcSmv.GetName()); string dstTypeName = FT.GetMangledName(S, dstSmv.GetName()); string argName = "x"; Comment comment = new Comment("Converting constructor, from " + srcTypeName + " to " + dstTypeName); comment.Write(SB, S, 1); SB.AppendLine("\tpublic " + dstTypeName + "(" + srcTypeName + " " + argName + ") {"); int nbTabs = 2; bool declareVariable = false; bool cast = false; bool srcPtr = false; bool dstPtr = false; RefGA.Multivector value = Symbolic.SMVtoSymbolicMultivector(S, srcSmv, argName, srcPtr); AssignInstruction AI = new AssignInstruction(nbTabs, dstSmv, FT, cast, value, SmvUtil.THIS, dstPtr, declareVariable); AI.Write(SB, S, cgd); SB.AppendLine("\t}"); }
/// <summary> /// Writes any code to extract a grade part. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="gradeIdx">Grade to be selected (use -1 for user-specified).</param> public static string WriteGradeFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, int gradeIdx) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: const string GROUP_BITMAP_NAME = "groupBitmap"; string code = G25.CG.Shared.CANSparts.GetGradeCode(S, cgd, FT, gradeIdx, FAI, fgs.RETURN_ARG_NAME, GROUP_BITMAP_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); string funcName = CF.OutputName; //if (S.OutputC()) // funcName = FT.GetMangledName(S, funcName); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value //StringBuilder tmpSB = new StringBuilder(); // G25.CG.Shared.Functions.WriteFunction() writes to this SB first so we can add the grade index if required // write function G25.CG.Shared.CGdata tmpCgd = new G25.CG.Shared.CGdata(cgd); bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, tmpCgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); if (gradeIdx < 0) // hack: if grade is func arg, then add it: { // add extra argument (int) to select the grade //if (S.OutputCppOrC()) // tmpCgd.m_declSB = AddGradeArg(S, tmpCgd.m_declSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); //tmpCgd.m_defSB = AddGradeArg(S, tmpCgd.m_defSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); //tmpCgd.m_inlineDefSB = AddGradeArg(S, tmpCgd.m_inlineDefSB.ToString(), gradeIdx, GROUP_BITMAP_NAME); } cgd.m_declSB.Append(tmpCgd.m_declSB); cgd.m_defSB.Append(tmpCgd.m_defSB); cgd.m_inlineDefSB.Append(tmpCgd.m_inlineDefSB); return funcName; }
public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SOM som) { G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, som); // loop over som.DomainVectors // setup array of arguments, function specification, etc int NB_ARGS = som.DomainVectors.Length; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; RefGA.Multivector[] argValue = new RefGA.Multivector[NB_ARGS]; for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + som.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = (S.OutputC()); argValue[d] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setVectorImages"); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c]; RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade for (uint v = 0; v < som.DomainVectors.Length; v++) { if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0) { value = RefGA.Multivector.op(value, argValue[v]); } } I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Sets " + typeName + " from images of the domain vectors."); bool writeDecl = false; bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
public static void WriteSetMatrix(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som, bool transpose) { int NB_ARGS = 1; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; argTypes[0] = FT.type; argNames[0] = "M"; // construct image values RefGA.Multivector[] imageValue = new RefGA.Multivector[som.DomainVectors.Length]; for (int d = 0; d < som.DomainVectors.Length; d++) { //imageValue[d] = RefGA.Multivector.ZERO; RefGA.BasisBlade[] IV = new RefGA.BasisBlade[som.RangeVectors.Length]; for (int r = 0; r < som.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * som.RangeVectors.Length + r) : (r * som.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(som.RangeVectors[r].bitmap, 1.0, entryName); } imageValue[d] = new RefGA.Multivector(IV); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setMatrix"); if (transpose) funcName = funcName + "Transpose"; //argNames[0] = "*" + argNames[0]; // quick hack: add pointer to name instead of type! G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (S.OutputCppOrC()) F.m_argumentPtr[0] = true; else F.m_argumentArr[0] = true; bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c]; RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade for (uint v = 0; v < som.DomainVectors.Length; v++) { if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0) { value = RefGA.Multivector.op(value, imageValue[v]); } } I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix."); bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes any geometric product based product for general multivectors, /// based on gp parts code. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="declOnly"></param> /// <param name="productType"></param> /// <returns>name of generated function</returns> public static string WriteGMVgpFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.GPparts.ProductTypes productType) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.GPparts.GetGPcode(S, cgd, FT, M, productType, FAI, fgs.RETURN_ARG_NAME); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = null; G25.CG.Shared.FuncArgInfo returnArgument = null; if (productType == G25.CG.Shared.GPparts.ProductTypes.SCALAR_PRODUCT) { // return scalar returnTypeName = FT.type; } else { // return GMV (in C, via 'return argument') returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } string funcName = CF.OutputName; // FAI[0].MangledTypeName; //CF.ArgumentTypeNames[0] = CF.ArgumentTypeNames[0] + G25.CG.Shared.Main.IF_SUFFIX; // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return funcName; }
/// <summary> /// Writes a simple function which assigns some value based on specialized multivectors or scalars to some variable. /// /// Used by a lot of simple C functions, like gp, op, lc. /// /// Somewhat obsolete (preferably, use the more generic, instruction based WriteFunction()). /// /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">The function generation specification.</param> /// <param name="FT">Default float pointer type.</param> /// <param name="FAI">Info on the arguments of the function.</param> /// <param name="value">The value to assign.</param> /// <param name="comment">Optional comment for function (can be null).</param> public static void WriteSpecializedFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, RefGA.Multivector value, Comment comment) { // get return type (may be a G25.SMV or a G25.FloatType) G25.VariableType returnType = G25.CG.Shared.SpecializedReturnType.GetReturnType(S, cgd, F, FT, value); if (returnType == null) throw new G25.UserException("Missing return type: " + G25.CG.Shared.BasisBlade.MultivectorToTypeDescription(S, value), XML.FunctionToXmlString(S, F)); bool ptr = true; string dstName = G25.fgs.RETURN_ARG_NAME; //string dstTypeName = (returnType is G25.SMV) ? FT.GetMangledName((returnType as G25.SMV).Name) : (returnType as G25.FloatType).type; string funcName = F.OutputName; // write comment to declaration if (comment != null) { if (S.OutputCppOrC()) comment.Write(cgd.m_declSB, S, 0); else comment.Write(cgd.m_defSB, S, 0); } if ((returnType is G25.SMV) && (S.OutputC())) { bool mustCast = false; G25.SMV dstSmv = returnType as G25.SMV; G25.CG.Shared.FuncArgInfo returnArgument = null; returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, dstSmv.Name, false); // false = compute value bool staticFunc = S.OutputCSharpOrJava(); G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineFunctions, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, dstSmv, dstName, ptr, value); } else { G25.FloatType returnFT = ((returnType as G25.FloatType) == null) ? FT : (returnType as G25.FloatType); bool mustCast = false; for (int i = 0; i < FAI.Length; i++) mustCast |= returnFT.MustCastIfAssigned(S, FAI[i].FloatType); bool staticFunc = S.OutputCSharpOrJava(); G25.CG.Shared.Functions.WriteReturnFunction(S, cgd, S.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnType, value); } }
/// <summary> /// Writes generic function based on Instructions. /// /// The other WriteFunction() can figure out the return type automatically, so /// it is preferred over this more verbose version. /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">Function specification.</param> /// <param name="inline">When true, the code is inlined.</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">The type to return (String, can also be e.g. <c>"code"</c>.</param> /// <param name="functionName">Name of generated function.</param> /// <param name="returnArgument">For use with the 'C' language, an extra argument can be used to return results.</param> /// <param name="arguments">Arguments of function (any `return argument' used for the C language is automatically generated).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated code (used for decl only).</param> /// <param name="writeDecl">When false, no declaration is written</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List<Instruction> instructions, Comment comment, bool writeDecl) { // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // declaration: if (writeDecl) { if (comment != null) comment.Write(cgd.m_declSB, S, 0); bool inlineDecl = false; // never put inline keywords in declaration WriteDeclaration(cgd.m_declSB, S, cgd, inlineDecl, staticFunc, returnType, functionName, returnArgument, arguments); cgd.m_declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) comment.Write(defSB, S, 0); WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); // open function defSB.AppendLine(""); defSB.AppendLine("{"); // add extra instruction for reporting usage of SMVs if (S.m_reportUsage) instructions.Insert(0, ReportUsage.GetReportInstruction(S, F, arguments)); if (returnArgument != null) { int nbTabs = 1; instructions.Add(new VerbatimCodeInstruction(nbTabs, "return " + returnArgument.Name + ";")); } // write all instructions foreach (Instruction I in instructions) { I.Write(defSB, S, cgd); } // close function defSB.AppendLine("}"); }
public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List<Instruction> instructions, Comment comment) { bool writeDecl = S.OutputCppOrC(); WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment, writeDecl); }
/// <summary> /// Writes generic function based on Instructions. /// /// This version automatically figures out the return type (so it is recommended over the other WriteFunction()). /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">Function specification.</param> /// <param name="inline">When true, the code is inlined.</param> /// <param name="staticFunc">static function?</param> /// <param name="functionName">Name of generated function.</param> /// <param name="arguments">Arguments of function (any 'return argument' used for the C language is automatically setup correctly).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated declration code.</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string functionName, FuncArgInfo[] arguments, List<Instruction> instructions, Comment comment) { List<G25.VariableType> returnTypes = new List<G25.VariableType>(); List<G25.FloatType> returnTypeFT = new List<G25.FloatType>(); // floating point types of return types Instruction.GetReturnType(instructions, returnTypes, returnTypeFT); // for now, assume only one return type is used? string returnType = "void"; G25.CG.Shared.FuncArgInfo returnArgument = null; if (returnTypes.Count > 0) { G25.VariableType returnVT = returnTypes[0]; G25.FloatType returnFT = returnTypeFT[0]; if (returnVT is G25.FloatType) returnVT = returnFT; string returnTypeName = (returnVT is G25.MV) ? (returnVT as G25.MV).Name : (returnVT as FloatType).type; returnType = returnFT.GetMangledName(S, returnTypeName); if (S.OutputC()) { if (!(returnVT is G25.FloatType)) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, returnFT, returnTypeName, false); // false = compute value } } } WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment); }
public static void WriteSetCopy(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) declSB.AppendLine(); defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_set"); bool mustCast = false; const int NB_ARGS = 1; string srcName = "src"; bool srcPtr = S.OutputC(); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { som.Name }, new String[] { srcName }, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { int nbTabs = 1; mustCast = false; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = (S.OutputCppOrC()); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.Multivector srcValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, srcName, srcPtr); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, srcValue, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Copies " + typeName + "."); ; bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes a function to set an SOM struct/class to identity /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> /// <param name="som"></param> public static void WriteSetIdentity(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) declSB.AppendLine(); defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "setIdentity", "_setIdentity"); bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", null, null, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { int nbTabs = 1; mustCast = false; string valueName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool valuePtr = S.OutputCppOrC(); bool declareValue = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, new RefGA.Multivector(som.DomainForGrade(g)[c]), valueName, valuePtr, declareValue)); } } } Comment comment = new Comment("Sets " + typeName + " to identity."); bool writeDecl = S.OutputC(); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, new G25.CG.Shared.FuncArgInfo[0], I, comment, writeDecl); }
/// <summary> /// Writes any norm function for general multivectors, based on gp parts code. /// </summary> /// <param name="SB"></param> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="declOnly"></param> /// <param name="squared"></param> /// <returns>name of generated function.</returns> public static string WriteGMVnormFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, bool squared) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); string funcName = CF.OutputName; // get return info G25.SMV returnType = null; string returnTypeName = null; G25.CG.Shared.FuncArgInfo returnArgument = null; { // try to get scalar type returnType = S.GetScalarSMV(); if (returnType == null) { returnTypeName = FT.type; } else { if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, returnType.Name, false); // false = compute value returnTypeName = FT.GetMangledName(S, returnType.GetName()); } } // write this function: string code = G25.CG.Shared.GPparts.GetNormCode(S, cgd, FT, M, squared, FAI, returnType, G25.fgs.RETURN_ARG_NAME); // add the verbatim code I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, funcName, returnArgument, FAI, I, comment); return funcName; }
/// <summary> /// Writes a function to set a GOM struct according to vector images, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float type.</param> /// <param name="matrixMode">When true, generates code for setting from matrix instead of vector images.</param> /// <param name="transpose">When this parameter is true and <c>matrixMode</c> is true, generates code for setting from transpose matrix.</param> public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, bool matrixMode, bool transpose) { G25.GOM gom = S.m_GOM; // get the 'plan' on how to initialize all domain basis blades efficiently: uint[][][] plan = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsPlan(S, gom); double[][] signs = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsSigns(S, gom, plan); // get range vector type G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, gom); // setup array of arguments, function specification, etc int NB_ARGS = (matrixMode) ? 1 : gom.DomainVectors.Length; string[] argTypes = new string[NB_ARGS], argNames = new string[NB_ARGS]; RefGA.Multivector[] symbolicBBvalues = new RefGA.Multivector[1 << S.m_dimension]; // symbolic basis blade values go here if (matrixMode) { argTypes[0] = FT.type; argNames[0] = "M"; // convert matrix columns to symbolic Multivector values for (int d = 0; d < gom.DomainVectors.Length; d++) { RefGA.BasisBlade[] IV = new RefGA.BasisBlade[gom.RangeVectors.Length]; for (int r = 0; r < gom.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * gom.RangeVectors.Length + r) : (r * gom.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(gom.RangeVectors[r].bitmap, 1.0, entryName); } symbolicBBvalues[gom.DomainVectors[d].bitmap] = new RefGA.Multivector(IV); } } else { for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + gom.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = S.OutputC(); symbolicBBvalues[gom.DomainVectors[d].bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } } // generate function names for all grades (basis blade names not included) string typeName = FT.GetMangledName(S, gom.Name); string[] funcNames = GetSetFromLowerGradeFunctionNames(S, FT, matrixMode); // setup instructions (for main function, and subfunctions for grades) List<G25.CG.Shared.Instruction> mainI = new List<G25.CG.Shared.Instruction>(); List<G25.CG.Shared.Instruction>[] bladeI = new List<G25.CG.Shared.Instruction>[1 << S.m_dimension]; { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { G25.SMVOM smvOM = gom.DomainSmvForGrade(g)[d]; RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; if (g > 1) { bladeI[domainBlade.bitmap] = new List<G25.CG.Shared.Instruction>(); string funcCallCode = funcNames[g] + "_" + d + "("; if (S.OutputC()) funcCallCode += G25.fgs.RETURN_ARG_NAME; funcCallCode += ");"; mainI.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, funcCallCode)); } // follow the plan RefGA.Multivector value = new RefGA.Multivector(signs[g][d]); uint[] P = plan[g][d]; for (int p = 0; p < P.Length; p++) value = RefGA.Multivector.op(value, symbolicBBvalues[P[p]]); // add instructions List<G25.CG.Shared.Instruction> I = (g == 1) ? mainI : bladeI[domainBlade.bitmap]; I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); // store symbolic value symbolicBBvalues[domainBlade.bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, dstName, dstPtr); } } } // output grade > 1 functions if (cgd.generateOmInitCode(FT.type)) { for (int g = 2; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; string funcName = funcNames[g] + "_" + d; G25.fgs F = new G25.fgs(funcName, funcName, "", new string[0], new string[0], new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options //F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); int nbArgs = 0; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; comment = new Comment("Sets grade " + g + " part of outermorphism matrix based on lower grade parts."); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcName, returnArgument, FAI, bladeI[domainBlade.bitmap], comment, writeDecl); } } } { // output grade 1 function G25.fgs F = new G25.fgs(funcNames[1], funcNames[1], "", argTypes, argNames, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (matrixMode) { F.m_argumentPtr[0] = S.OutputCppOrC(); F.m_argumentArr[0] = S.OutputCSharpOrJava(); } bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; if (!matrixMode) comment = new Comment("Sets " + typeName + " from images of the domain vectors."); else comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix"); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcNames[1], returnArgument, FAI, mainI, comment, writeDecl); } }
/// <summary> /// Writes a function to set a GOM struct according to vector images, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float type.</param> /// <param name="matrixMode">When true, generates code for setting from matrix instead of vector images.</param> /// <param name="transpose">When this parameter is true and <c>matrixMode</c> is true, generates code for setting from transpose matrix.</param> public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, bool matrixMode, bool transpose) { G25.GOM gom = S.m_GOM; // get the 'plan' on how to initialize all domain basis blades efficiently: uint[][][] plan = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsPlan(S, gom); double[][] signs = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsSigns(S, gom, plan); // get range vector type G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, gom); // setup array of arguments, function specification, etc int NB_ARGS = (matrixMode) ? 1 : gom.DomainVectors.Length; string[] argTypes = new string[NB_ARGS], argNames = new string[NB_ARGS]; RefGA.Multivector[] symbolicBBvalues = new RefGA.Multivector[1 << S.m_dimension]; // symbolic basis blade values go here if (matrixMode) { argTypes[0] = FT.type; argNames[0] = "M"; // convert matrix columns to symbolic Multivector values for (int d = 0; d < gom.DomainVectors.Length; d++) { RefGA.BasisBlade[] IV = new RefGA.BasisBlade[gom.RangeVectors.Length]; for (int r = 0; r < gom.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * gom.RangeVectors.Length + r) : (r * gom.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(gom.RangeVectors[r].bitmap, 1.0, entryName); } symbolicBBvalues[gom.DomainVectors[d].bitmap] = new RefGA.Multivector(IV); } } else { for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + gom.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = S.OutputC(); symbolicBBvalues[gom.DomainVectors[d].bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } } // generate function names for all grades (basis blade names not included) string typeName = FT.GetMangledName(S, gom.Name); string[] funcNames = GetSetFromLowerGradeFunctionNames(S, FT, matrixMode); // setup instructions (for main function, and subfunctions for grades) List <G25.CG.Shared.Instruction> mainI = new List <G25.CG.Shared.Instruction>(); List <G25.CG.Shared.Instruction>[] bladeI = new List <G25.CG.Shared.Instruction> [1 << S.m_dimension]; { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { G25.SMVOM smvOM = gom.DomainSmvForGrade(g)[d]; RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; if (g > 1) { bladeI[domainBlade.bitmap] = new List <G25.CG.Shared.Instruction>(); string funcCallCode = funcNames[g] + "_" + d + "("; if (S.OutputC()) { funcCallCode += G25.fgs.RETURN_ARG_NAME; } funcCallCode += ");"; mainI.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, funcCallCode)); } // follow the plan RefGA.Multivector value = new RefGA.Multivector(signs[g][d]); uint[] P = plan[g][d]; for (int p = 0; p < P.Length; p++) { value = RefGA.Multivector.op(value, symbolicBBvalues[P[p]]); } // add instructions List <G25.CG.Shared.Instruction> I = (g == 1) ? mainI : bladeI[domainBlade.bitmap]; I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); // store symbolic value symbolicBBvalues[domainBlade.bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, dstName, dstPtr); } } } // output grade > 1 functions if (cgd.generateOmInitCode(FT.type)) { for (int g = 2; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; string funcName = funcNames[g] + "_" + d; G25.fgs F = new G25.fgs(funcName, funcName, "", new string[0], new string[0], new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options //F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); } int nbArgs = 0; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; comment = new Comment("Sets grade " + g + " part of outermorphism matrix based on lower grade parts."); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcName, returnArgument, FAI, bladeI[domainBlade.bitmap], comment, writeDecl); } } } { // output grade 1 function G25.fgs F = new G25.fgs(funcNames[1], funcNames[1], "", argTypes, argNames, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (matrixMode) { F.m_argumentPtr[0] = S.OutputCppOrC(); F.m_argumentArr[0] = S.OutputCSharpOrJava(); } bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); } G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; if (!matrixMode) { comment = new Comment("Sets " + typeName + " from images of the domain vectors."); } else { comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix"); } bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcNames[1], returnArgument, FAI, mainI, comment, writeDecl); } } // end of WriteSetVectorImages()
/// <summary> /// Writes a zero or equality test function for general multivectors, /// based on CASN parts code. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="writeZero">When true, a function to test for zero is written.</param> /// <returns>full (mangled) name of generated function</returns> public static string WriteEqualsOrZeroOrGradeBitmapFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE funcType) { // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = ""; if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.EQUALS) code = G25.CG.Shared.CANSparts.GetEqualsCode(S, cgd, FT, FAI); else if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.ZERO) code = G25.CG.Shared.CANSparts.GetZeroCode(S, cgd, FT, FAI); else if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.GRADE_BITMAP) code = G25.CG.Shared.CANSparts.GetGradeBitmapCode(S, cgd, FT, FAI); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = null; if (S.OutputC()) { returnTypeName = G25.IntegerType.INTEGER; } else { if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.GRADE_BITMAP) returnTypeName = G25.IntegerType.INTEGER; else returnTypeName = CodeUtil.GetBoolType(S); } G25.CG.Shared.FuncArgInfo returnArgument = null; // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); return CF.OutputName; }
} // end of WriteSetVectorImages() public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; string srcTypeName = FT.GetMangledName(S, srcOm.Name); string dstTypeName = FT.GetMangledName(S, dstOm.Name); bool writeDecl = S.OutputC(); string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : ""; string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : ""); string CONST = (S.OutputCppOrC()) ? "const " : ""; string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)"; // write comment, function declaration Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" + "Warning 1: coordinates which cannot be represented are silenty lost.\n" + "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n"); if (writeDecl) { comment.Write(declSB, S, 0); declSB.Append(funcDecl); declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) { comment.Write(defSB, S, 0); } defSB.Append(funcDecl); { defSB.AppendLine(" {"); Dictionary <Tuple <int, int, int>, Tuple <int, int, double> > D = dstOm.getMapping(srcOm); StringBuilder copySB = new StringBuilder(); List <string> setToZero = new List <string>(); string matrixStr = (S.OutputC()) ? "m" : "m_m"; string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr; string ptrStr = (S.OutputC()) ? "->" : "."; // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null // Do not use foreach() on D because we want to fill in coordinates in their proper order. for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++) { for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++) { for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++) { Tuple <int, int, int> key = new Tuple <int, int, int>(gradeIdx, somDomainIdx, somRangeIdx); int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx); string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = "; if (D.ContainsKey(key)) { Tuple <int, int, double> value = D[key]; int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2); double multiplier = value.Value3; string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * "); copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];"); } else { setToZero.Add(dstString); } } } } // append copy statements defSB.Append(copySB); // append statements to set coordinates to zero if (setToZero.Count > 0) { int cnt = 0; defSB.Append("\t"); foreach (string str in setToZero) { defSB.Append(str); cnt++; if (cnt > 8) { cnt = 0; defSB.AppendLine(""); defSB.Append("\t\t"); } } defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";"); } defSB.AppendLine("}"); } }
public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SOM som) { G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, som); // loop over som.DomainVectors // setup array of arguments, function specification, etc int NB_ARGS = som.DomainVectors.Length; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; RefGA.Multivector[] argValue = new RefGA.Multivector[NB_ARGS]; for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + som.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = (S.OutputC()); argValue[d] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setVectorImages"); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); } // setup instructions List <G25.CG.Shared.Instruction> I = new List <G25.CG.Shared.Instruction>(); { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c]; RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade for (uint v = 0; v < som.DomainVectors.Length; v++) { if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0) { value = RefGA.Multivector.op(value, argValue[v]); } } I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Sets " + typeName + " from images of the domain vectors."); bool writeDecl = false; bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
protected void writeSmvPassThroughConverter(FloatType FT, string smvTypeName, Comment comment, string funcName, G25.CG.Shared.FuncArgInfo[] FAI) { // verbatim code List<Instruction> instructions = new List<Instruction>(); int nbTabs = 1; instructions.Add(new VerbatimCodeInstruction(nbTabs, "return " + FAI[0].Name + ";")); G25.CG.Shared.CGdata localCGD = new G25.CG.Shared.CGdata(m_cgd, m_declSB, m_defSB, m_inlineDefSB); string returnType = smvTypeName; bool staticFunc = Functions.OutputStaticFunctions(m_specification); FuncArgInfo returnArgument = null; Functions.WriteFunction(m_specification, localCGD, this.m_fgs, m_specification.m_inlineSet, staticFunc, returnType, funcName, returnArgument, FAI, instructions, comment); }