/// <summary> /// Writes a increment or decrement function. /// (not based on CASN parts code, but put here anyway). /// </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="increment"></param> public static string WriteIncrementFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, bool increment) { // 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.GetIncrementCode(S, cgd, FT, FAI, fgs.RETURN_ARG_NAME, increment); // 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 } // 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); }
/// <summary> /// Writes a function to copy the value of one SMV struct to another, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteCopy(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; String typeName = FT.GetMangledName(S, smv.Name); String funcName = typeName + "_copy"; bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { smv.Name }, null, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); declSB.AppendLine("/** Copies " + typeName + ": " + FAI[0].Name + " = " + returnArgument.Name + " */"); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, value); } } }
} // end of WriteFunctions() /// <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); } } // end of WriteSpecializedFunction()
/// <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; }
/// <summary> /// Writes a function to set an SMV struct to zero, 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> public static void WriteSetZero(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) { continue; } string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setZero"; 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 = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to zero */"); string returnVarName = null; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", returnVarName, funcName, returnArgument, null, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, new RefGA.Multivector(0.0)); } } } // end of WriteSetZero()
/// <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 WriteSet() /// <summary> /// Writes a function to set an SMV struct to an array of specified coordinates, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) { continue; } string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setArray"; bool mustCast = false; string[] argTypename = new string[1] { FT.type }; string[] argName = new string[1] { "A" }; System.Collections.ArrayList L = new System.Collections.ArrayList(); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); //argTypename[i] = FT.type; String coordStr = argName[0] + "[" + i + "]"; //argName[i] = coordStr; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); F.SetArgumentPtr(0, true); // first argument is a pointer to array bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); int nbArgs = 1; // one array of coordinates G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to specified coordinates */"); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue); } } } // end of WriteSetArray()
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 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); } // end of WriteGradeFunction()
/// <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); } // end of WriteGMVgpFunction
/// <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); }
} // end of WriteGMVigpFunction /// <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); } // end of WriteGMVnormFunction
} // end of WriteSetZero() /// <summary> /// Writes a function to set an SMV struct to a scalar coordinate, for all floating point types which have a non-constant scalar coordinate. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteSetScalar(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { // if (smv.NbNonConstBasisBlade == 0) continue; if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) { continue; // if no scalar coordinate, continue } string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setScalar"; bool mustCast = false; System.Collections.ArrayList L = new System.Collections.ArrayList(); const int NB_COORDS = 1; string[] argTypename = new string[NB_COORDS]; string[] argName = new string[NB_COORDS]; { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; argTypename[0] = FT.type; argName[0] = "scalarVal"; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, argName[0])); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_COORDS, FT, null, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to a scalar value */"); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue); } } }
} // end of WriteCopy() /// <summary> /// Writes a function to copy the value of one SMV struct to another with a different floating point type, for all combinations of floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteCopyCrossFloat(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType srcFT in S.m_floatTypes) { foreach (G25.FloatType dstFT in S.m_floatTypes) { if (srcFT.type == dstFT.type) { continue; } foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) { continue; } String srcTypeName = srcFT.GetMangledName(S, smv.Name); String dstTypeName = dstFT.GetMangledName(S, smv.Name); G25.fgs tmpFgs = null; String funcName = G25.CG.Shared.Converter.GetConverterName(S, tmpFgs, srcTypeName, dstTypeName); bool mustCast = dstFT.MustCastIfAssigned(S, srcFT); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { smv.Name }, null, new String[] { srcFT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, dstFT, smv.Name, computeMultivectorValue); int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, srcFT, null, computeMultivectorValue); declSB.AppendLine("/** Copies " + srcTypeName + " to " + dstTypeName + ": " + returnArgument.Name + " = " + FAI[0].Name + " */"); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, dstFT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, value); } } } } // end of WriteCopyCrossFloat()
} // end of WriteExFunction /// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { //G25.SMV smv = m_specification.GetSMV(m_SMVname); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); m_fgs.m_argumentTypeNames[0] = FT.type; bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, FT.type, computeMultivectorValue); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, m_fgs, FAI); WriteExFunction(FT, CF.OutputName + "_ex"); System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " " + MINIMUM_NORM + " = " + FT.DoubleToString(m_specification, 0.0001) + ";")); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " " + LARGEST_COORDINATE + " = " + FT.DoubleToString(m_specification, 4.0) + ";")); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, ((m_specification.OutputC()) ? "" : "return ") + CF.OutputName + "_ex(" + ((m_specification.OutputC()) ? (G25.fgs.RETURN_ARG_NAME + ", ") : "") + FAI[0].Name + ", minimumNorm, " + FAI[0].Name + " * largestCoordinate);")); // generate comment Comment comment = new Comment(m_fgs.AddUserComment("Returns random " + m_SMVname + " with a scale in the interval [0, scale)")); G25.CG.Shared.FuncArgInfo returnArgument = null; if (m_specification.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(m_specification, m_fgs, -1, FT, m_SMVname, false); // false = compute value } string returnTypeName = FT.GetMangledName(m_specification, m_SMVname); bool staticFunc = Functions.OutputStaticFunctions(m_specification); G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, CF, m_specification.m_inlineFunctions, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); } } // end of WriteFunction
} // end of WriteDeclaration() /// <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); } // end of WriteFunction()
} // end of WriteFunction /// <summary> /// Writes an zero test function for specialized multivectors. /// </summary> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> protected void WriteZeroFunction(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>(); string BOOL = CodeUtil.GetBoolType(m_specification); string TRUE = CodeUtil.GetTrueValue(m_specification); string FALSE = CodeUtil.GetFalseValue(m_specification); // write the function: { int nbTabs = 1; // add one instruction (verbatim code) //I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // get largest constant coordinate: double largestConstCoord = 0.0; if (m_smv != null) { // first find largest const coord: if any const coord above eps, always return 0 for (int c = 0; c < m_smv.NbConstBasisBlade; c++) { if (Math.Abs(m_smv.ConstBasisBlade(c).scale) > largestConstCoord) { largestConstCoord = Math.Abs(m_smv.ConstBasisBlade(c).scale); } } } if (largestConstCoord > 0.0) // generate code to check if largest coord > 'eps' { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "if (" + FT.DoubleToString(m_specification, largestConstCoord) + " > " + FAI[1].Name + ") return " + FALSE + ";")); } // generate code to check all coordiantes string[] accessStr = G25.CG.Shared.CodeUtil.GetAccessStr(m_specification, m_smv, FAI[0].Name, FAI[0].Pointer); for (int i = 0; i < accessStr.Length; i++) { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "if ((" + accessStr[i] + " < -" + FAI[1].Name + ") || (" + accessStr[i] + " > " + FAI[1].Name + ")) return " + FALSE + ";")); } // finally, return 1 if all check were OK I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "return " + TRUE + ";")); } // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, F, FAI); m_funcName[FT.type] = CF.OutputName; // setup return type and argument: string returnTypeName = BOOL; G25.CG.Shared.FuncArgInfo returnArgument = null; // write function bool staticFunc = Functions.OutputStaticFunctions(m_specification); G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, F, m_specification.m_inlineFunctions, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); } // end of WriteZeroFunction()
/// <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 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; }
/// <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 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); }
} // end of WriteFunction /// <summary> /// Writes an zero test function for specialized multivectors. /// </summary> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> protected void WriteGradeBitmapFunction(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>(); // write the function: { int nbTabs = 1; I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "int bitmap = 0;")); // get largest constant coordinate for each grade: Dictionary <int, double> largestConstCoord = new Dictionary <int, double>(); if (m_smv != null) { // first find largest const coord: if any const coord above eps, always return 0 for (int c = 0; c < m_smv.NbConstBasisBlade; c++) { int g = m_smv.ConstBasisBlade(c).Grade(); double absVal = Math.Abs(m_smv.ConstBasisBlade(c).scale); if (!largestConstCoord.ContainsKey(g)) { largestConstCoord[g] = absVal; } else if (absVal > largestConstCoord[g]) { largestConstCoord[g] = absVal; } } } // generate code to check if largest coord of grade > 'eps' foreach (KeyValuePair <int, double> kvp in largestConstCoord) { if (kvp.Value > 0.0) { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "if (" + FT.DoubleToString(m_specification, kvp.Value) + " > " + FAI[1].Name + ") bitmap |= " + (1 << kvp.Key) + ";")); } } // generate code to check all coordiantes String[] accessStr = G25.CG.Shared.CodeUtil.GetAccessStr(m_specification, m_smv, FAI[0].Name, FAI[0].Pointer); for (int i = 0; i < accessStr.Length; i++) { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "if ((" + accessStr[i] + " < -" + FAI[1].Name + ") || (" + accessStr[i] + " > " + FAI[1].Name + ")) bitmap |= " + (1 << m_smv.NonConstBasisBlade(i).Grade()) + ";")); } // finally, return 1 if all check were OK I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "return bitmap;")); } // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, F, FAI); m_funcName[FT.type] = CF.OutputName; // setup return type and argument: string returnTypeName = G25.IntegerType.INTEGER; G25.CG.Shared.FuncArgInfo returnArgument = null; // write function bool staticFunc = Functions.OutputStaticFunctions(m_specification); G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, F, m_specification.m_inlineFunctions, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); } // end of WriteGradeBitmapFunction()
/// <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 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); }
/// <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 an SMV struct to an array of specified coordinates, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setArray"; bool mustCast = false; string[] argTypename = new string[1] { FT.type }; string[] argName = new string[1] { "A" }; System.Collections.ArrayList L = new System.Collections.ArrayList(); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); //argTypename[i] = FT.type; String coordStr = argName[0] + "[" + i + "]"; //argName[i] = coordStr; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); F.SetArgumentPtr(0, true); // first argument is a pointer to array bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); int nbArgs = 1; // one array of coordinates G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to specified coordinates */"); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue); } } }
/// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { //G25.SMV smv = m_specification.GetSMV(m_SMVname); foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); m_fgs.m_argumentTypeNames[0] = FT.type; bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, FT.type, computeMultivectorValue); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, m_fgs, FAI); WriteExFunction(FT, CF.OutputName + "_ex"); System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); int nbTabs = 1; I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " " + MINIMUM_NORM + " = " + FT.DoubleToString(m_specification, 0.0001) + ";")); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " " + LARGEST_COORDINATE + " = " + FT.DoubleToString(m_specification, 4.0) + ";")); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, ((m_specification.OutputC()) ? "" : "return ") + CF.OutputName + "_ex(" + ((m_specification.OutputC()) ? (G25.fgs.RETURN_ARG_NAME + ", ") : "") + FAI[0].Name + ", minimumNorm, " + FAI[0].Name + " * largestCoordinate);")); // generate comment Comment comment = new Comment(m_fgs.AddUserComment("Returns random " + m_SMVname + " with a scale in the interval [0, scale)")); G25.CG.Shared.FuncArgInfo returnArgument = null; if (m_specification.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(m_specification, m_fgs, -1, FT, m_SMVname, false); // false = compute value string returnTypeName = FT.GetMangledName(m_specification, m_SMVname); bool staticFunc = Functions.OutputStaticFunctions(m_specification); G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, CF, m_specification.m_inlineFunctions, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); } }
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 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); }
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); }
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 code for all converters (as specified in Function Generation Specification). /// </summary> public void WriteConverter() { try { string rawSrcTypeName = m_fgs.GetArgumentTypeName(0, null); // null = no default name string rawDstTypeName = m_fgs.Name.Substring(1); // dest = function name minus the underscore. bool srcIsGMV = m_specification.m_GMV.GetName().Equals(rawSrcTypeName); const int nbArgs = 1; foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string srcTypeName = FT.GetMangledName(m_specification, rawSrcTypeName); string dstTypeName = FT.GetMangledName(m_specification, rawDstTypeName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, nbArgs, FT, m_specification.m_GMV.Name, computeMultivectorValue); // comment: Comment comment = GetComment(m_specification, srcTypeName, dstTypeName, FAI[0].Name, m_fgs.Comment); comment.Write((m_specification.OutputCSharpOrJava()) ? m_defSB : m_declSB, m_specification, 1); string funcName = G25.CG.Shared.Converter.GetConverterName(m_specification, m_fgs, srcTypeName, dstTypeName); if (srcIsGMV) { // convert GMV to SMV writeGmvToSmvConverter(FT, srcTypeName, dstTypeName, comment, funcName, FAI); } else if (srcTypeName == dstTypeName) { // convert to the same type writeSmvPassThroughConverter(FT, srcTypeName, comment, funcName, FAI); } else { // convert SMV/scalar to SMV // if scalar or specialized: generate specialized function: first get symbolic result RefGA.Multivector value = FAI[0].MultivectorValue[0]; G25.CG.Shared.CGdata localCGD = new G25.CG.Shared.CGdata(m_cgd, m_declSB, m_defSB, m_inlineDefSB); G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(m_specification, m_fgs, -1, FT, rawDstTypeName, false); // false = compute value bool staticFunc = Functions.OutputStaticFunctions(m_specification); bool mustCast = false; if (m_specification.OutputC()) { Functions.WriteAssignmentFunction(m_specification, localCGD, m_specification.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, returnArgument.Type as G25.SMV, returnArgument.Name, returnArgument.Pointer, value); } else { Functions.WriteReturnFunction( m_specification, localCGD, m_specification.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnArgument.Type as G25.SMV, value); } } } } catch (G25.UserException E) { if (E.m_XMLerrorSource.Length == 0) { string XMLstring = XML.FunctionToXmlString(m_specification, m_fgs); m_cgd.AddError(new G25.UserException(E.m_message, XMLstring, E.m_filename, E.m_line, E.m_column)); } else { m_cgd.AddError(E); } } } // end of function WriteConverter()
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); }
/// <summary> /// Writes a function to set an SMV struct to zero, 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> public static void WriteSetZero(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setZero"; 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 = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to zero */"); string returnVarName = null; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", returnVarName, funcName, returnArgument, null, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, new RefGA.Multivector(0.0)); } } }
} // end of WriteFunction /// <summary> /// Writes an equality test function for specialized multivectors /// </summary> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> protected void WriteEqualsFunction(FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment) { // setup instructions List <G25.CG.Shared.Instruction> I = new List <G25.CG.Shared.Instruction>(); // get a basis blade list which contains all basis blades (this is used in conjunction with GetAssignmentStrings()) RefGA.BasisBlade[] BL = new RefGA.BasisBlade[1 << m_specification.m_dimension]; for (uint bitmap = 0; bitmap < (uint)BL.Length; bitmap++) { BL[bitmap] = new RefGA.BasisBlade(bitmap); } // get string to access the coordinates of each basis blade wrt to the basis bool mustCast = false; bool writeZeros = false; string[] assStr1 = G25.CG.Shared.CodeUtil.GetAssignmentStrings(m_specification, FT, mustCast, BL, FAI[0].MultivectorValue[0], writeZeros); string[] assStr2 = G25.CG.Shared.CodeUtil.GetAssignmentStrings(m_specification, FT, mustCast, BL, FAI[1].MultivectorValue[0], writeZeros); string BOOL = CodeUtil.GetBoolType(m_specification); string TRUE = CodeUtil.GetTrueValue(m_specification); string FALSE = CodeUtil.GetFalseValue(m_specification); { // setup instructions // get tmp storage for 'difference' int nbTabs = 1; bool dDeclared = false; // for each assStr, subtract the other, see if difference is within limits for (int i = 0; i < BL.Length; i++) { if ((assStr1[i] == null) && (assStr2[i] == null)) { continue; } else if (assStr1[i] == null) { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "if ((" + assStr2[i] + " < -" + FAI[2].Name + ") || (" + assStr2[i] + " > " + FAI[2].Name + ")) return " + FALSE + "; /* " + BL[i].ToString(m_specification.m_basisVectorNames) + " */")); } else if (assStr2[i] == null) { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "if ((" + assStr1[i] + " < -" + FAI[2].Name + ") || (" + assStr1[i] + " > " + FAI[2].Name + ")) return " + FALSE + "; /* " + BL[i].ToString(m_specification.m_basisVectorNames) + " */")); } else { if (!dDeclared) { // declare a variable 'd', but only if required I.Insert(0, new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " d;")); dDeclared = true; } I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "d = " + assStr1[i] + " - " + assStr2[i] + "; " + "if ((d < -" + FAI[2].Name + ") || (d > " + FAI[2].Name + ")) return " + FALSE + "; /* " + BL[i].ToString(m_specification.m_basisVectorNames) + " */")); } } // finally, return 1 if all check were OK I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "return " + TRUE + ";")); } // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, F, FAI); m_funcName[FT.type] = CF.OutputName; // setup return type and argument: string returnTypeName = BOOL; G25.CG.Shared.FuncArgInfo returnArgument = null; // write function bool staticFunc = Functions.OutputStaticFunctions(m_specification); G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, F, m_specification.m_inlineFunctions, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); }
/// <summary> /// Writes a function to set an SMV struct to a scalar coordinate, for all floating point types which have a non-constant scalar coordinate. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteSetScalar(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { // if (smv.NbNonConstBasisBlade == 0) continue; if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) continue; // if no scalar coordinate, continue string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setScalar"; bool mustCast = false; System.Collections.ArrayList L = new System.Collections.ArrayList(); const int NB_COORDS = 1; string[] argTypename = new string[NB_COORDS]; string[] argName = new string[NB_COORDS]; { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; argTypename[0] = FT.type; argName[0] = "scalarVal"; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, argName[0])); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_COORDS, FT, null, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to a scalar value */"); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue); } } }
/// <summary> /// Writes code for all converters (as specified in Function Generation Specification). /// </summary> public void WriteConverter() { try { string rawSrcTypeName = m_fgs.GetArgumentTypeName(0, null); // null = no default name string rawDstTypeName = m_fgs.Name.Substring(1); // dest = function name minus the underscore. bool srcIsGMV = m_specification.m_GMV.GetName().Equals(rawSrcTypeName); const int nbArgs = 1; foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); string srcTypeName = FT.GetMangledName(m_specification, rawSrcTypeName); string dstTypeName = FT.GetMangledName(m_specification, rawDstTypeName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, nbArgs, FT, m_specification.m_GMV.Name, computeMultivectorValue); // comment: Comment comment = GetComment(m_specification, srcTypeName, dstTypeName, FAI[0].Name, m_fgs.Comment); comment.Write((m_specification.OutputCSharpOrJava()) ? m_defSB : m_declSB, m_specification, 1); string funcName = G25.CG.Shared.Converter.GetConverterName(m_specification, m_fgs, srcTypeName, dstTypeName); if (srcIsGMV) { // convert GMV to SMV writeGmvToSmvConverter(FT, srcTypeName, dstTypeName, comment, funcName, FAI); } else if (srcTypeName == dstTypeName) { // convert to the same type writeSmvPassThroughConverter(FT, srcTypeName, comment, funcName, FAI); } else { // convert SMV/scalar to SMV // if scalar or specialized: generate specialized function: first get symbolic result RefGA.Multivector value = FAI[0].MultivectorValue[0]; G25.CG.Shared.CGdata localCGD = new G25.CG.Shared.CGdata(m_cgd, m_declSB, m_defSB, m_inlineDefSB); G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(m_specification, m_fgs, -1, FT, rawDstTypeName, false); // false = compute value bool staticFunc = Functions.OutputStaticFunctions(m_specification); bool mustCast = false; if (m_specification.OutputC()) { Functions.WriteAssignmentFunction(m_specification, localCGD, m_specification.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, returnArgument.Type as G25.SMV, returnArgument.Name, returnArgument.Pointer, value); } else { Functions.WriteReturnFunction( m_specification, localCGD, m_specification.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnArgument.Type as G25.SMV, value); } } } } catch (G25.UserException E) { if (E.m_XMLerrorSource.Length == 0) { string XMLstring = XML.FunctionToXmlString(m_specification, m_fgs); m_cgd.AddError(new G25.UserException(E.m_message, XMLstring, E.m_filename, E.m_line, E.m_column)); } else m_cgd.AddError(E); } }
/// <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); } }