/// <param name="S"></param> /// <param name="FT"></param> /// <param name="M"></param> /// <param name="d">1 -> generate dual, d = 0 -> generate undual</param> /// <param name="g1"></param> /// <param name="gd"></param> /// <param name="name1"></param> /// <param name="name2"></param> /// <param name="name3"></param> /// <returns>The code to compute a (un)dual at runtime using the geometric product tables.</returns> public static string GetRuntimeDualCode(G25.Specification S, G25.FloatType FT, G25.Metric M, int d, int g1, int gd, string name1, string name2, string name3) { // get pseudoscalar RefGA.Multivector I = RefGA.Multivector.GetPseudoscalar(S.m_dimension); if (d == 1) // if dual: use inverse I { I = RefGA.Multivector.VersorInverse(I, M.m_metric); } // get grade/group of pseudoscalar in GMV int g2 = S.m_GMV.GetGroupIdx(I.BasisBlades[0]); // get sign of pseudo scalar basis blade in GMV: double IbladeSign = S.m_GMV.Group(g2)[0].scale; string tmpArrayCode; if (S.OutputCppOrC()) { tmpArrayCode = "\t" + FT.type + " " + name2 + "[1] = {" + FT.DoubleToString(S, IbladeSign * I.BasisBlades[0].scale) + "};\n"; } else { tmpArrayCode = "\t\t" + FT.type + "[] " + name2 + " = new " + FT.type + "[]{" + FT.DoubleToString(S, IbladeSign * I.BasisBlades[0].scale) + "};\n\t"; } return (tmpArrayCode + "\t" + GPparts.GetGPpartFunctionName(S, FT, M, g1, g2, gd) + "(" + name1 + ", " + name2 + ", " + name3 + ");\n"); }
private static string GetDualCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()"; string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()"; // allocate memory to store result: SB.AppendLine("int idx = 0;"); bool resultIsScalar = false; bool initResultToZero = true; // must init to zero because of compression SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the dual goes from one to the other for (int gi = 0; gi < nbGroups; gi++) { SB.AppendLine("if (" + agu + " & " + (1 << gi) + ") {"); for (int go = 0; go < nbGroups; go++) { string funcName = (dual) ? GetDualPartFunctionName(S, FT, M, gi, go) : GetUndualPartFunctionName(S, FT, M, gi, go); Tuple <string, string, string> key = new Tuple <string, string, string>(FT.type, M.m_name, funcName); if (cgd.m_gmvDualPartFuncNames.ContainsKey(key) && cgd.m_gmvDualPartFuncNames[key]) { SB.AppendLine("\t" + funcName + "(" + ac + " + idx, c + " + gmv.GroupStartIdx(go) + ");"); } } if (gi < (nbGroups - 1)) { SB.AppendLine("\tidx += " + gmv.Group(gi).Length + ";"); } SB.AppendLine("}"); SB.AppendLine(""); } // compress result SB.Append(GPparts.GetCompressCode(S, FT, FAI, resultName, resultIsScalar)); return(SB.ToString()); } // end of GetDualCodeCppOrC()
} // end of GetApplyGomCodeCppOrC private static string GetApplyGomCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; bool groupedByGrade = gmv.IsGroupedByGrade(S.m_dimension); StringBuilder SB = new StringBuilder(); // allocate memory to store result: SB.AppendLine(FT.type + "[][] bc = " + FAI[1].Name + ".to_" + FAI[1].MangledTypeName + "().c();"); bool resultIsScalar = false; bool initResultToZero = !groupedByGrade; SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the OM goes from one to the other for (int srcGroup = 0; srcGroup < nbGroups; srcGroup++) { SB.AppendLine("if (bc[" + srcGroup + "] != null) {"); for (int dstGroup = 0; dstGroup < nbGroups; dstGroup++) { string funcName = GetGomPartFunctionName(S, FT, srcGroup, dstGroup); Tuple <string, string> key = new Tuple <string, string>(FT.type, funcName); if (cgd.m_gmvGomPartFuncNames.ContainsKey(key) && cgd.m_gmvGomPartFuncNames[key]) { string allocCcode = "if (cc[" + dstGroup + "] == null) cc[" + dstGroup + "] = new " + FT.type + "[" + gmv.Group(dstGroup).Length + "];"; SB.AppendLine("\t" + allocCcode); SB.AppendLine("\t" + funcName + "(" + FAI[0].Name + ", bc[" + srcGroup + "], cc[" + dstGroup + "]);"); } } SB.AppendLine("}"); SB.AppendLine(""); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return(SB.ToString()); } // end of GetApplyGomCodeCSharpOrJava()
} // end of GetDualCodeCppOrC() private static string GetDualCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); bool resultIsScalar = false; bool initResultToZero = true; // must init to zero because of compression SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the dual goes from one to the other for (int gi = 0; gi < nbGroups; gi++) { SB.AppendLine("if (ac[" + gi + "] != null) {"); for (int go = 0; go < nbGroups; go++) { string funcName = (dual) ? GetDualPartFunctionName(S, FT, M, gi, go) : GetUndualPartFunctionName(S, FT, M, gi, go); Tuple <string, string, string> key = new Tuple <string, string, string>(FT.type, M.m_name, funcName); if (cgd.m_gmvDualPartFuncNames.ContainsKey(key) && cgd.m_gmvDualPartFuncNames[key]) { SB.AppendLine("\tif (cc[" + go + "] == null) cc[" + go + "] = new " + FT.type + "[" + gmv.Group(go).Length + "];"); SB.AppendLine("\t" + funcName + "(ac[" + gi + "], cc[" + go + "]);"); } } SB.AppendLine("}"); SB.AppendLine(""); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return(SB.ToString()); } // end of GetDualCodeCppOrC()
private static string GetApplyGomCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; bool groupedByGrade = gmv.IsGroupedByGrade(S.m_dimension); StringBuilder SB = new StringBuilder(); // allocate memory to store result: SB.AppendLine("int idxB = 0, gu = 0, idxC = 0;"); bool resultIsScalar = false; bool initResultToZero = !groupedByGrade; SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero)); string bgu = (S.OutputC()) ? FAI[1].Name + "->gu" : FAI[1].Name + ".gu()"; string bc = (S.OutputC()) ? FAI[1].Name + "->c" : FAI[1].Name + ".getC()"; // get number of groups: int nbGroups = gmv.NbGroups; int dstGrade = 0; int srcGradeSizeAccumulator = 0; // for each combination of groups, check if the OM goes from one to the other for (int srcGroup = 0; srcGroup < nbGroups; srcGroup++) { // increment the index into 'C' when we switch grade int srcGrade = gmv.Group(srcGroup)[0].Grade(); if (srcGrade != dstGrade) { if (!groupedByGrade) { SB.AppendLine("idxC += " + srcGradeSizeAccumulator + ";"); SB.AppendLine(""); } dstGrade = srcGrade; srcGradeSizeAccumulator = 0; } srcGradeSizeAccumulator += gmv.Group(srcGroup).Length; SB.AppendLine("if (" + bgu + " & " + (1 << srcGroup) + ") {"); int dstGradeSizeAccumulator = 0; for (int dstGroup = 0; dstGroup < nbGroups; dstGroup++) { string funcName = GetGomPartFunctionName(S, FT, srcGroup, dstGroup); Tuple <string, string> key = new Tuple <string, string>(FT.type, funcName); if (cgd.m_gmvGomPartFuncNames.ContainsKey(key) && cgd.m_gmvGomPartFuncNames[key]) { SB.AppendLine("\t" + funcName + "(" + FAI[0].Name + ", " + bc + " + idxB, c + idxC + " + dstGradeSizeAccumulator + ");"); } if (gmv.Group(dstGroup)[0].Grade() == srcGrade) { dstGradeSizeAccumulator += gmv.Group(dstGroup).Length; } } if (srcGroup < (nbGroups - 1)) { SB.AppendLine("\tidxB += " + gmv.Group(srcGroup).Length + ";"); if (groupedByGrade) { SB.AppendLine("\tidxC += " + gmv.Group(srcGroup).Length + ";"); SB.AppendLine(""); } } SB.AppendLine("}"); SB.AppendLine(""); } // generate code to compress result string cgu = (groupedByGrade) ? bgu : null; // null means: all groups/grades are present SB.Append(GPparts.GetCompressCode(S, FT, FAI, resultName, resultIsScalar, cgu)); // todo: bgu should be 63 when not grouped by grade return(SB.ToString()); } // end of GetApplyGomCodeCppOrC