Exemple #1
0
        public static string GetCompressCode(Specification S, G25.FloatType FT,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool resultIsScalar, string GUstr)
        {
            if ((GUstr == null) || (GUstr.Length == 0))
            {
                GUstr = ((1 << S.m_GMV.NbGroups) - 1).ToString();
            }

            StringBuilder SB = new StringBuilder();
            if (resultIsScalar)
            {
                SB.AppendLine("return c[0];");
            }
            else
            {
                string funcName = (S.OutputC())
                    ? FT.GetMangledName(S, "compress")
                    : FT.GetMangledName(S, S.m_GMV.Name) + "_compress";

                if (S.m_outputLanguage != OUTPUT_LANGUAGE.C)
                    SB.Append("return ");

                SB.Append(funcName + "(c, ");
                if (S.OutputC())
                    SB.Append(resultName + "->c, &(" + resultName + "->gu), ");
                SB.AppendLine(FT.DoubleToString(S, 0.0) + ", " + GUstr + ");");
            }
            return SB.ToString();
        }
Exemple #2
0
        private static string GetAnyMetricNormCode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            G25.Metric M, bool squared,
            G25.CG.Shared.FuncArgInfo[] FAI, G25.SMV returnType, string returnName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            SB.AppendLine(FT.type + " n2 = " + FT.DoubleToString(S, 0.0) + ";");

            if (S.OutputCSharpOrJava())
            {
                SB.AppendLine(FT.type + "[] c = new " + FT.type + "[1];");
                SB.AppendLine(FT.type + "[][] ac = " + FAI[0].Name + ".to_" + FAI[0].MangledTypeName + "().c();");
            }
            else {
                bool resultIsScalar = true;
                bool initResultToZero = true;
                SB.Append(GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));
            }

            string exaName = "_" + FAI[0].Name;

            for (int g1 = 0; g1 < gmv.NbGroups; g1++)
            {
                bool funcFound = false;

                for (int g2 = 0; g2 < gmv.NbGroups; g2++) {
                    // get function name
                    string funcName = GetGPpartFunctionName(S, FT, M, g1, g2, 0); // grade 0 part of gp(g, g)

                    // check if funcName (gp part) exists)
                    Tuple<string, string, string> key = new Tuple<string, string, string>(FT.type, M.m_name, funcName);
                    if (cgd.m_gmvGPpartFuncNames.ContainsKey(key) && cgd.m_gmvGPpartFuncNames[key])
                    {
                        if (!funcFound)
                        {
                            if (S.OutputCSharpOrJava())
                                SB.Append("if (ac[" + g1 + "] != null) {");
                            else SB.Append("if (" + exaName + "[" + g1 + "] != NULL) { ");
                            SB.AppendLine(" /* group " + g1 + " (grade " + gmv.Group(g1)[0].Grade() + ") */");
                            SB.AppendLine("\tc[0] = " + FT.DoubleToString(S, 0.0) + ";");
                            funcFound = true;
                        }

                        if (g1 != g2)
                        {
                            if (S.OutputCSharpOrJava())
                                SB.Append("\tif (ac[" + g2 + "] != null) {");
                            else SB.Append("\tif (" + exaName + "[" + g2 + "] != NULL) {");
                            SB.AppendLine(" /* group " + g2 + " (grade " + gmv.Group(g2)[0].Grade() + ") */");
                        }

                        if (S.OutputCSharpOrJava())
                            SB.AppendLine("\t\t" + funcName + "(ac[" + g1 + "], ac[" + g2 + "], c);");
                        else SB.AppendLine("\t\t" + funcName + "(" + exaName + "[" + g1 + "], " + exaName + "[" + g2 + "], c);");

                        if (g1 != g2)
                            SB.AppendLine("\t}");
                    }
                }

                if (funcFound) // only do this if any matching gp function for this group was found
                {
                    // get multiplier
                    double m = gmv.Group(g1)[0].Reverse().scale / gmv.Group(g1)[0].scale; // must always have the same grade
                    if (m == 1.0) SB.AppendLine("\tn2 += c[0];");
                    else if (m == -1.0) SB.AppendLine("\tn2 -= c[0];");
                    else SB.AppendLine("\tn2 += " + FT.DoubleToString(S, m) + " * c[0];");
                    SB.AppendLine("}");
                }

            }

            string returnVal;
            { // get return value
                if (squared) returnVal = "n2";
                else
                {
                    string sqrtFuncName = G25.CG.Shared.CodeUtil.OpNameToLangString(S, FT, RefGA.Symbolic.UnaryScalarOp.SQRT);
                    if (M.m_metric.IsPositiveDefinite()) // if PD, then negative values are impossible
                        returnVal = sqrtFuncName + "(n2)";
                    else returnVal = "((n2 < " + FT.DoubleToString(S, 0.0) + ") ? " + sqrtFuncName + "(-n2) : " + sqrtFuncName + "(n2))";
                }
            }

            // can be shared with other GetNormCode
            if ((returnType == null) || (returnName == null))
            {
                SB.AppendLine("return " + returnVal + ";");
            }
            else
            {
                if (S.OutputC())
                {
                    // get assign code, assign it
                    bool mustCast = false;
                    bool dstPtr = true;
                    int nbTabs = 0;
                    bool writeZeros = true;
                    SB.Append(CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast,
                        returnType, returnName, dstPtr, new RefGA.Multivector(returnVal), nbTabs, writeZeros));
                }
                else
                {
                    bool mustCast = false;
                    int nbTabs = 0;
                    new ReturnInstruction(nbTabs, returnType, FT, mustCast, new RefGA.Multivector(returnVal)).Write(SB, S, cgd);
                }
            }

            return SB.ToString();
        }
Exemple #3
0
        private static string GetDiagonalMetricNormCode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            G25.Metric M, bool squared,
            G25.CG.Shared.FuncArgInfo[] FAI, G25.SMV returnType, string returnName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            if (S.OutputCSharpOrJava())
            {
                SB.AppendLine(FT.type + "[] c = new " + FT.type + "[1];");
                SB.AppendLine(FT.type + "[][] ac = " + FAI[0].Name + ".to_" + FAI[0].MangledTypeName + "().c();");
            }
            else SB.AppendLine(FT.type + " c[1];");

            SB.AppendLine(FT.type + " n2 = " + FT.DoubleToString(S, 0.0) + ";");
            if (S.OutputCppOrC())
                SB.AppendLine("int idx = 0;");

            string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()";
            string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()";

            for (int g = 0; g < gmv.NbGroups; g++)
            {
                // get function name
                string funcName = GetGPpartFunctionName(S, FT, M, g, g, 0); // grade 0 part of gp(g, g)

                // get multiplier
                double m = gmv.Group(g)[0].Reverse().scale / gmv.Group(g)[0].scale;

                SB.AppendLine("");
                if (S.OutputCSharpOrJava())
                    SB.Append("if (ac[" + g + "] != null) {");
                else SB.Append("if (" + agu + " & " + (1 << g) + ") {");
                SB.AppendLine(" /* group " + g + " (grade " + gmv.Group(g)[0].Grade() + ") */");

                // check if funcName (gp part) exists)
                Tuple<string, string, string> key = new Tuple<string, string, string>(FT.type, M.m_name, funcName);
                if (cgd.m_gmvGPpartFuncNames.ContainsKey(key) && cgd.m_gmvGPpartFuncNames[key])
                {
                    SB.AppendLine("\tc[0] = " + FT.DoubleToString(S, 0.0) + ";");

                    if (S.OutputCSharpOrJava())
                        SB.AppendLine("\t" + funcName + "(ac[" + g + "], ac[ " + g + "], c);");
                    else SB.AppendLine("\t" + funcName + "(" + ac + " + idx, " + ac + " + idx, c);");

                    if (m == 1.0) SB.AppendLine("\tn2 += c[0];");
                    else if (m == -1.0) SB.AppendLine("\tn2 -= c[0];");
                    else SB.AppendLine("\tn2 += " + FT.DoubleToString(S, m) + " * c[0];");
                }
                if ((g < (gmv.NbGroups - 1)) && S.OutputCppOrC())
                    SB.AppendLine("\tidx += " + gmv.Group(g).Length + ";");
                SB.AppendLine("}");
            }

            string returnVal;
            { // get return value
                if (squared) returnVal = "n2";
                else
                {
                    string sqrtFuncName = G25.CG.Shared.CodeUtil.OpNameToLangString(S, FT, RefGA.Symbolic.UnaryScalarOp.SQRT);
                    if (M.m_metric.IsPositiveDefinite()) // if PD, then negative values are impossible
                        returnVal = sqrtFuncName + "(n2)";
                    else returnVal = "((n2 < " + FT.DoubleToString(S, 0.0) + ") ? " + sqrtFuncName + "(-n2) : " + sqrtFuncName + "(n2))";
                }
            }

            if ((returnType == null) || (returnName == null))
            {
                SB.AppendLine("return " + returnVal + ";");
            }
            else
            {
                if (S.OutputC())
                {
                    // get assign code, assign it
                    bool mustCast = false;
                    bool dstPtr = true;
                    int nbTabs = 0;
                    bool writeZeros = true;
                    SB.Append(CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast,
                        returnType, returnName, dstPtr, new RefGA.Multivector(returnVal), nbTabs, writeZeros));
                }
                else
                {
                    bool mustCast = false;
                    int nbTabs = 0;
                    new ReturnInstruction(nbTabs, returnType, FT, mustCast, new RefGA.Multivector(returnVal)).Write(SB, S, cgd);
                }
            }

            return SB.ToString();
        }
Exemple #4
0
        public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;
            string srcTypeName = FT.GetMangledName(S, srcOm.Name);
            string dstTypeName = FT.GetMangledName(S, dstOm.Name);
            bool writeDecl = S.OutputC();

            string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName);

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");
            string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : "";
            string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : "");
            string CONST = (S.OutputCppOrC()) ? "const " : "";

            string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)";

            // write comment, function declaration
            Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" +
                "Warning 1: coordinates which cannot be represented are silenty lost.\n" +
                "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n");
            if (writeDecl)
            {
                comment.Write(declSB, S, 0);
                declSB.Append(funcDecl);
                declSB.AppendLine(";");
            }

            if (S.OutputCSharpOrJava())
                comment.Write(defSB, S, 0);

            defSB.Append(funcDecl);
            {
                defSB.AppendLine(" {");

                Dictionary<Tuple<int, int, int>, Tuple<int, int, double>> D = dstOm.getMapping(srcOm);

                StringBuilder copySB = new StringBuilder();
                List<string> setToZero = new List<string>();

                string matrixStr = (S.OutputC()) ? "m" : "m_m";
                string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr;
                string ptrStr = (S.OutputC()) ? "->" : ".";

                // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null
                // Do not use foreach() on D because we want to fill in coordinates in their proper order.
                for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++)
                {
                    for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++)
                    {
                        for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++)
                        {
                            Tuple<int, int, int> key = new Tuple<int, int, int>(gradeIdx, somDomainIdx, somRangeIdx);

                            int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx);
                            string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = ";
                            if (D.ContainsKey(key))
                            {
                                Tuple<int, int, double> value = D[key];
                                int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2);
                                double multiplier = value.Value3;
                                string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * ");

                                copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];");
                            }
                            else
                            {
                                setToZero.Add(dstString);
                            }
                        }
                    }
                }

                // append copy statements
                defSB.Append(copySB);

                // append statements to set coordinates to zero
                if (setToZero.Count > 0)
                {
                    int cnt = 0;
                    defSB.Append("\t");
                    foreach (string str in setToZero)
                    {
                        defSB.Append(str);
                        cnt++;
                        if (cnt > 8)
                        {
                            cnt = 0;
                            defSB.AppendLine("");
                            defSB.Append("\t\t");
                        }
                    }
                    defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";");
                }

                defSB.AppendLine("}");
            }
        }
Exemple #5
0
        private static void WriteCoordExtractFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            String bladeName = B.ToLangString(S.m_basisVectorNames);

            string varName = "A";

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");

            string funcName = gmvTypeName + "_" + bladeName;

            string funcDecl = inlineStr + FT.type + " " + funcName + "(const " + gmvTypeName + " *" + varName + ")";

            string comment = "/** Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate of '" + varName + "' */";
            //                    declSB.AppendLine("/* group : " + groupIdx + " element: " + elementIdx + "*/");
            declSB.AppendLine(comment);
            declSB.Append(funcDecl);
            declSB.AppendLine(";");

            defSB.AppendLine("");
            defSB.Append(funcDecl);
            defSB.AppendLine(" {");
            defSB.AppendLine("\treturn (" + varName + "->gu & " + (1 << groupIdx) + ") ? " +
                varName + "->c[" + S.m_namespace + "_mvSize[" + varName + "->gu & " + ((1 << groupIdx) - 1) + "] + " + elementIdx + "] : " +
                FT.DoubleToString(S, 0.0) + ";");
            defSB.AppendLine("}");

            // add extract coord extract function for scalar
            if (B.Grade() == 0)
            {
                string floatFuncName = gmvTypeName + "_" + FT.type;
                string floatFuncDecl = inlineStr + FT.type + " " + floatFuncName + "(const " + gmvTypeName + " *" + varName + ")";

                declSB.AppendLine(comment);
                declSB.Append(floatFuncDecl);
                declSB.AppendLine(";");

                defSB.Append(floatFuncDecl);
                defSB.AppendLine(" {");
                defSB.AppendLine("\treturn " + funcName + "(" + varName + ");");
                defSB.AppendLine("}");
            }
        }
Exemple #6
0
        private static void WriteGetCoordFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, StringBuilder SB,
            string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

            // do we inline this func?
            string inlineStr = "inline ";

            string funcName = MainGenerator.GETTER_PREFIX + bladeName;

            string funcDecl = "\t" + inlineStr + FT.type + " " + funcName + "() const";

            SB.AppendLine("\t/// Returns the " + bladeName + " coordinate of this " + gmvTypeName + ".");
            SB.Append(funcDecl);
            SB.AppendLine(" {");
            SB.AppendLine("\t\treturn (m_gu & " + (1 << groupIdx) + ") ? " +
                "m_c[" + S.m_namespace + "_mvSize[m_gu & " + ((1 << groupIdx) - 1) + "] + " + elementIdx + "] : " +
                FT.DoubleToString(S, 0.0) + ";");
            SB.AppendLine("\t}");
        }
Exemple #7
0
        private static void WriteGetCoordFunction(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

            string funcName = G25.CG.Shared.Main.GETTER_PREFIX + bladeName;

            string funcDecl = "\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + funcName + "() ";

            int nbTabs = 1;
            new G25.CG.Shared.Comment("Returns the " + bladeName + " coordinate of this " + gmvTypeName).Write(SB, S, nbTabs);

            SB.Append(funcDecl);
            SB.AppendLine(" {");
            SB.AppendLine("\t\treturn (m_c[" + groupIdx + "] == null) ? " +
                FT.DoubleToString(S, 0.0) + ": " +
                "m_c[" + groupIdx + "][" + elementIdx + "];");
            SB.AppendLine("\t}");
        }
Exemple #8
0
        /// <summary>
        /// Writes functions to copy GMVs to SMVs
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteGMVtoSMVcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv)
        {
            StringBuilder defSB = cgd.m_defSB;

            G25.GMV gmv = S.m_GMV;
            string srcClassName = FT.GetMangledName(S, gmv.Name);

            //string dstClassName = FT.GetMangledName(S, smv.Name);

            bool dstPtr = false;
            string[] smvAccessStr = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr);

            string funcName = GMV.GetSetFuncName(S);

            string FINAL = (S.OutputJava()) ? "final " : "";
            string funcDecl = "\tpublic " + FINAL + "void " + funcName + "(" + FINAL + srcClassName + " src)";

            defSB.Append(funcDecl);
            {
                defSB.AppendLine(" {");

                // get a dictionary which tells you for each basis blade of 'smv' where it is in 'gmv'
                // A dictionary from <smv group, smv element> to <gmv group, gmv element>
                Dictionary<Tuple<int, int>, Tuple<int, int>> D = G25.MV.GetCoordMap(smv, gmv);

                // what is the highest group of the 'gmv' that must be (partially) copied to the 'smv'
                int highestGroup = -1;
                foreach (KeyValuePair<Tuple<int, int>, Tuple<int, int>> KVP in D)
                    if (KVP.Value.Value1 > highestGroup) highestGroup = KVP.Value.Value1;

                // generate code for each group
                for (int g = 0; g <= highestGroup; g++)
                {
                    // determine if group 'g' is to be copied to smv:
                    bool groupIsUsedBySMV = false;
                    foreach (KeyValuePair<Tuple<int, int>, Tuple<int, int>> KVP in D)
                    {
                        // KVP.Key = SMV<group, element>
                        // KVP.Value = GMV<group, element>
                        if (KVP.Value.Value1 == g)
                        {
                            if (!smv.IsCoordinateConstant(KVP.Key.Value2))
                            {
                                groupIsUsedBySMV = true;
                                break;
                            }
                        }
                    }

                    // if group is present in GMV:
                    if (groupIsUsedBySMV)
                    {
                        defSB.AppendLine("\t\tif (src.c()[" + g + "] != null) {");
                        defSB.AppendLine("\t\t\t" + FT.type + "[] ptr = src.c()[" + g + "];");
                        bool mustCast = false;
                        bool srcPtr = true;
                        int nbTabs = 3;
                        RefGA.Multivector[] value = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, "ptr", srcPtr, g);
                        bool writeZeros = false;
                        string str = G25.CG.Shared.CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr, value[g], nbTabs, writeZeros);
                        defSB.Append(str);
                        defSB.AppendLine("\t\t}");

                        defSB.AppendLine("\t\telse {");
                        foreach (KeyValuePair<Tuple<int, int>, Tuple<int, int>> KVP in D)
                        {
                            if ((KVP.Value.Value1 == g) && (!smv.IsCoordinateConstant(KVP.Key.Value2)))
                            {
                                // translate KVP.Key.Value2 to non-const idx, because the accessStrs are only about non-const blades blades!
                                int bladeIdx = smv.BladeIdxToNonConstBladeIdx(KVP.Key.Value2);
                                defSB.AppendLine("\t\t\t" + smvAccessStr[bladeIdx] + " = " + FT.DoubleToString(S, 0.0) + ";");
                            }
                        }
                        defSB.AppendLine("\t\t}");
                    }
                }
                defSB.AppendLine("\t}");
            }
        }
Exemple #9
0
        /// <summary>
        /// Writes code for abs largest coordinate
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteLargestCoordinateFunctions(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv)
        {
            StringBuilder defSB = cgd.m_defSB;
            defSB.AppendLine("");

            const string smvName = G25.CG.Shared.SmvUtil.THIS;
            const bool ptr = false;

            string fabsFunc = G25.CG.Shared.CodeUtil.OpNameToLangString(S, FT, RefGA.Symbolic.UnaryScalarOp.ABS);

            string[] AS = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, smvName, ptr);

            RefGA.BasisBlade maxBasisBlade = smv.AbsoluteLargestConstantBasisBlade();

            //string className = FT.GetMangledName(S, smv.Name);

            for (int _returnBitmap = 0; _returnBitmap <= 1; _returnBitmap++)
            {
                bool returnBitmap = (_returnBitmap != 0);

                // write comment
                int nbTabs = 1;
                if (returnBitmap)
                    new G25.CG.Shared.Comment("Returns the absolute largest coordinate,\nand the corresponding basis blade bitmap.").Write(defSB, S, nbTabs);
                else new G25.CG.Shared.Comment("Returns the absolute largest coordinate.").Write(defSB, S, nbTabs);

                string funcName = Util.GetFunctionName(S, ((returnBitmap) ? "largestBasisBlade" : "largestCoordinate"));

                string funcDecl;
                if ((S.OutputCSharp()) && returnBitmap)
                {
                    funcDecl = FT.type + " " + funcName + "(int bm) ";
                }
                else if ((S.OutputJava()) && returnBitmap)
                {
                    funcDecl = FT.type + "[] " + funcName + "() ";
                }
                else
                {
                    funcDecl = FT.type + " " + funcName + "()";
                }

                string FINAL = (S.OutputJava()) ? "final " : "";
                defSB.Append("\tpublic " + FINAL + funcDecl);
                {
                    defSB.AppendLine(" {");

                    if ((S.OutputJava()) && returnBitmap)
                        defSB.AppendLine("\t\tint bm;");

                    int startIdx = 0;
                    if (maxBasisBlade != null)
                    {
                        defSB.AppendLine("\t\t" + FT.type + " maxValue = " + FT.DoubleToString(S, Math.Abs(maxBasisBlade.scale)) + ";");
                        if (returnBitmap)
                            defSB.AppendLine("\t\tbm = " + maxBasisBlade.bitmap + ";");
                    }
                    else
                    {
                        defSB.AppendLine("\t\t" + FT.type + " maxValue = " + fabsFunc + "(" + AS[0] + ");");
                        if (returnBitmap)
                            defSB.AppendLine("\t\tbm = 0;");
                        startIdx = 1;
                    }

                    for (int c = startIdx; c < smv.NbNonConstBasisBlade; c++)
                    {
                        defSB.Append("\t\tif (" + fabsFunc + "(" + AS[c] + ") > maxValue) { maxValue = " + fabsFunc + "(" + AS[c] + "); ");
                        if (returnBitmap) defSB.Append("bm = " + smv.NonConstBasisBlade(c).bitmap + "; ");
                        defSB.AppendLine("}");
                    }

                    if ((S.OutputJava()) && returnBitmap)
                    {
                        defSB.AppendLine("\t\treturn new " + FT.type + "[]{maxValue, (" + FT.type + ")bm};");
                    }
                    else
                    {
                        defSB.AppendLine("\t\treturn maxValue;");
                    }
                    defSB.AppendLine("\t}");
                }
            }
        }
        /// <summary>
        /// Returns the code for <c>gmv + scalar</c>
        /// 
        /// The code is NOT composed of calls to functions generated by <c>WriteCANSparts()</c>.
        /// 
        /// The returned code is only the body. The function declaration is not included.
        /// </summary>
        /// <param name="S">Specification of algebra (used for output language).</param>
        /// <param name="cgd">Currently not used.</param>
        /// <param name="FT">Floating point type.</param>
        /// <param name="FAI">Info about function arguments</param>
        /// <param name="resultName">Name of variable where the result goes (in the generated code).</param>
        /// <param name="increment">Whether write increment or decrement function.</param>
        /// <returns>code for the requested function.</returns>
        public static string GetIncrementCode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool increment)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            if (S.OutputC())
            {
                SB.AppendLine(FT.type + " val" + " = " +
                    FAI[0].MangledTypeName + "_" + gmv.Group(0)[0].ToLangString(S.m_basisVectorNames) + "(" + FAI[0].Name + ")" +
                    ((increment) ? " + " : " - ") + FT.DoubleToString(S, 1.0) + ";");

                SB.AppendLine(FAI[0].MangledTypeName + "_copy(" + resultName + ", " + FAI[0].Name + ");");
                SB.AppendLine(FAI[0].MangledTypeName + "_set_" + gmv.Group(0)[0].ToLangString(S.m_basisVectorNames) + "(" + resultName + ", val);");
            }
            else
            {
                string convertMvIfCode = (S.OutputCSharpOrJava()) ? (".to_" + FAI[0].MangledTypeName + "()") : "";

                if (S.OutputCpp())
                    SB.AppendLine(FAI[0].MangledTypeName + " " + resultName + "(" + FAI[0].Name + ");");
                else SB.AppendLine(FAI[0].MangledTypeName + " " + resultName + " = new " + FAI[0].MangledTypeName + "(" + FAI[0].Name + convertMvIfCode + ");");
                SB.AppendLine(FT.type + " val" + " = " + resultName + ".get_" + gmv.Group(0)[0].ToLangString(S.m_basisVectorNames) + "()" +
                    ((increment) ? " + " : " - ") + FT.DoubleToString(S, 1.0) + ";");
                SB.AppendLine(resultName + ".set_" + gmv.Group(0)[0].ToLangString(S.m_basisVectorNames) + "(val);");
                SB.AppendLine("return " + resultName + ";");
            }

            return SB.ToString();
        }
Exemple #11
0
        /// <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";
        }
Exemple #12
0
        /// <summary>
        /// Used internally by ScalarToLangString().
        /// 
        /// Emits on term (+ ....) of a blade value. Contains some optimizations
        /// to avoid stuff like <c>+-1.0</c>.
        /// </summary>
        protected static int EmitTerm(G25.Specification S, G25.FloatType FT, Object[] T, int tCnt, StringBuilder symResult)
        {
            // make stuff below a function
            bool plusEmitted = false;
            int pCnt = 0; // number of non-null terms in 'T'
            for (int p = 0; p < T.Length; p++) // for each product ...*
            {
                if (T[p] != null)
                {
                    if ((!plusEmitted) && (tCnt > 0))
                    {
                        symResult.Append("+");
                        plusEmitted = true;
                    }
                    if ((pCnt > 0) && (symResult.Length > 0) && (!((symResult[symResult.Length - 1] == '-') || (symResult[symResult.Length - 1] == '+'))))
                        symResult.Append("*");

                    System.Object O = T[p];
                    if ((O is System.Double) ||
                        (O is System.Single) ||
                        (O is System.Int16) ||
                        (O is System.Int32) ||
                        (O is System.Int64)) // etc . . . (all number types)
                    {
                        double val = (double)O;
                        if ((val == -1.0) && (p == 0) && (T.Length > 1))
                        { // when multiplying with -1.0, output only a '-', IF the term is the first (p==0) and more terms follow (T.Length > 1)
                            if (symResult.Length > 0)
                            {// when val = -1, output code which is better for humans, instead of -1.0 * ...
                                if (symResult[symResult.Length - 1] == '+') // change '+' to '-'
                                    symResult[symResult.Length - 1] = '-';
                                else symResult.Append("-");
                            }
                            else symResult.Append("-");
                        }
                        else if ((val == 1.0) && (p == 0) && (T.Length > 1))
                        { // when multiplying with 1.0, output nothing IF the term is the first (p==0) and more terms follow (T.Length > 1)
                            // do nothing
                        }
                        else symResult.Append(FT.DoubleToString(S, (double)O));

                    }
                    else if (O is UnaryScalarOp)
                    {
                        UnaryScalarOp USO = (UnaryScalarOp)O;
                        symResult.Append(UnaryScalarOpToLangString(S, FT, USO));
                    }
                    else if (O is BinaryScalarOp)
                    {
                        BinaryScalarOp BSO = (BinaryScalarOp)O;
                        symResult.Append(BinaryScalarOpToLangString(S, FT, BSO));
                    }
                    else if (O is RefGA.BasisBlade)
                    {
                        symResult.Append(ScalarToLangString(S, FT, (RefGA.BasisBlade)O));
                    }
                    else if (O is RefGA.Multivector)
                    {
                        RefGA.Multivector mv = (RefGA.Multivector)O;
                        StringBuilder mvSB = new StringBuilder();
                        mvSB.Append("(");
                        bool first = true;
                        foreach (RefGA.BasisBlade B in mv.BasisBlades)
                        {
                            if (!first) mvSB.Append(" + ");
                            first = false;
                            mvSB.Append(ScalarToLangString(S, FT, B));
                        }

                        mvSB.Append(")");

                        symResult.Append(mvSB);
                    }
                    else
                    {
                        symResult.Append(O.ToString());
                    }

                    pCnt++;
                }
            }
            return pCnt;
        }
Exemple #13
0
        /// <summary>
        /// Converts a scalar basis blade (with optional symbolic part) to a string in the output language of <c>S</c>.
        /// 
        /// Some effort is made to output code which is close to that a human would write.
        /// </summary>
        /// <param name="S">Specification of algebra, used for output language, basis vector names, etc.</param>
        /// <param name="FT">Floating point type of output.</param>
        /// <param name="B">The basis blade.</param>
        /// <returns>String code representation of 'B'.</returns>
        public static string ScalarToLangString(G25.Specification S, G25.FloatType FT, RefGA.BasisBlade B)
        {
            string symScaleStr = "";
            { // convert symbolic part
                if (B.symScale != null)
                {
                    // symbolic scalar string goes in  symResult
                    System.Text.StringBuilder symResult = new System.Text.StringBuilder();
                    int tCnt = 0;
                    for (int t = 0; t < B.symScale.Length; t++) // for each term ...*...*...+
                    {
                        Object[] T = (Object[])B.symScale[t].Clone(); // clone 'T' because IsolateInverses() might alter it!
                        if (T != null) // if term is not null
                        {
                            // first find all scalarop inverses
                            // turn those into a new term, but without inverses?
                            Object[] TI = IsolateInverses(T);

                            // emit 'T'
                            int pCnt = EmitTerm(S, FT, T, tCnt, symResult);

                            if (TI != null)  // do we have to divide by a number of terms?
                            {
                                // emit '/(TI)'
                                symResult.Append("/(");
                                EmitTerm(S, FT, TI, 0, symResult);
                                symResult.Append(")");
                            }

                            if (pCnt > 0) tCnt++; // only increment number of terms when T was not empty
                        }
                    }

                    if (tCnt > 0)
                        symScaleStr = ((tCnt > 1) ? "(" : "") + symResult + ((tCnt > 1) ? ")" : "");
                }
            } // end of symbolic part

            // special cases when numerical scale is exactly +- 1
            if (B.scale == 1.0)
            {
                if (symScaleStr.Length > 0) return symScaleStr;
                else return FT.DoubleToString(S, 1.0);
            }
            else if (B.scale == -1.0)
            {
                if (symScaleStr.Length > 0) return "-" + symScaleStr;
                else return FT.DoubleToString(S, -1.0);
            }
            else
            {
                // get numerical part
                string numScaleStr = FT.DoubleToString(S, B.scale);

                // merge symbolic and numerical
                if (symScaleStr.Length > 0)
                    numScaleStr = numScaleStr + "*" + symScaleStr;

                // done
                return numScaleStr;
            }
        }
Exemple #14
0
        /// <summary>
        /// Writes a function to set an GOM struct to identity, for all floating point types.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <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 point type of 'GOM'.</param>
        public static void WriteSetIdentity(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT)
        {
            SB.AppendLine("");

            string omName = "a";
            string matrixName = "m_m"; // todo: centralize this name

            Dictionary<double, List<string>> nonZero = G25.CG.Shared.OMinit.GetGomIdentityInitCode(S, S.m_GOM, omName, matrixName);

            //string className = FT.GetMangledName(S, S.m_GOM.Name);
            string funcName = Util.GetFunctionName(S, "setIdentity");
            SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " void " + funcName + "() {");
            for (int g = 1; g < S.m_GOM.Domain.Length; g++)
            {
                int s = S.m_GOM.Domain[g].Length * S.m_GOM.Range[g].Length;
                SB.AppendLine("\t\t" + G25.CG.Shared.Util.GetSetToZeroCode(S, FT, matrixName + g, s));
            } // end of loop over all grades of the OM

            // do the nonZero assignments:
            foreach (KeyValuePair<double, List<string>> kvp in nonZero)
            {
                SB.Append("\t\t");
                int cnt = 0;
                foreach (string coordStr in kvp.Value)
                {
                    SB.Append(coordStr + " = ");
                    cnt++;
                    if ((cnt % 8) == 0)
                        SB.Append("\n\t\t\t");
                }
                SB.AppendLine(FT.DoubleToString(S, kvp.Key) + ";");
            }

            SB.AppendLine("\t}");
        }