Beispiel #1
0
        }         // end of WriteGMVtoSMVcopy()

        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("}");
            }
        }
Beispiel #2
0
        /// <returns>a list of basis blades in canonical order, sorted by grade.
        /// Each entry in the outer list contains the basis blades for that grade.</returns>
        public List <List <G25.rsbbp.BasisBlade> > GetDefaultBasisBlades()
        {
            // allocate list for each grade
            List <List <G25.rsbbp.BasisBlade> > L = new List <List <G25.rsbbp.BasisBlade> >();

            for (int i = 0; i < m_spec.m_dimension + 1; i++)
            {
                L.Add(new List <G25.rsbbp.BasisBlade>());
            }

            // enumerate over all basis blades, add them to respective lists
            for (uint b = 0; b < (1 << m_spec.m_dimension); b++)
            {
                RefGA.BasisBlade B = new RefGA.BasisBlade(b);
                L[B.Grade()].Add(new G25.rsbbp.BasisBlade(B));
            }

            return(L);
        }
Beispiel #3
0
        /// <summary>
        /// If this FunctionGenerator can implement 'F', then this function should complete the (possible)
        /// blanks in 'F'. This means:
        ///  - Fill in F.m_returnTypeName if it is empty
        ///  - Fill in F.m_argumentTypeNames (and m_argumentVariableNames) if it is empty.
        /// </summary>
        public override void CompleteFGS()
        {
            // fill in ArgumentTypeNames
            if (m_fgs.ArgumentTypeNames.Length == 0)
            {
                if (m_specification.m_GOM == null)
                {
                    throw new G25.UserException("No general outermorphism type defined, while it is required because the type of the first argument was unspecified.");
                }
                m_fgs.m_argumentTypeNames = new String[] { m_specification.m_GOM.Name, m_gmv.Name };
            }

            // init argument pointers from the completed typenames (language sensitive);
            m_fgs.InitArgumentPtrFromTypeNames(m_specification);

            // get all function info
            FloatType FT = m_specification.GetFloatType(m_fgs.FloatNames[0]);
            bool      computeMultivectorValue = true;

            G25.CG.Shared.FuncArgInfo[] tmpFAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue);

            m_om      = (G25.OM)tmpFAI[0].Type;
            m_mv      = (G25.MV)tmpFAI[1].Type;
            m_gmvFunc = !tmpFAI[1].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;           // gmv + gmv = gmv
            }
            else
            {
                RefGA.Multivector inputValue = tmpFAI[1].MultivectorValue[0];

                // Compute m_returnValue:
                // Replace each basis blade in 'inputValue' with its value under the outermorphism.
                m_returnValue = RefGA.Multivector.ZERO;
                for (int i = 0; i < inputValue.BasisBlades.Length; i++)
                {
                    // get input blade and domain for that grade
                    RefGA.BasisBlade   inputBlade   = inputValue.BasisBlades[i];
                    RefGA.BasisBlade[] domainBlades = m_om.DomainForGrade(inputBlade.Grade());
                    for (int c = 0; c < domainBlades.Length; c++)
                    {
                        // if a match is found in the domain, add range vector to m_returnValue
                        if (domainBlades[c].bitmap == inputBlade.bitmap)
                        {
                            bool ptr = m_specification.OutputC();
                            RefGA.Multivector omColumnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, m_om.DomainSmvForGrade(inputBlade.Grade())[c], tmpFAI[0].Name, ptr);
                            RefGA.Multivector inputBladeScalarMultiplier  = new RefGA.Multivector(new RefGA.BasisBlade(inputBlade, 0));
                            RefGA.Multivector domainBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(domainBlades[c], 0));
                            m_returnValue = RefGA.Multivector.Add(m_returnValue,
                                                                  RefGA.Multivector.gp(
                                                                      RefGA.Multivector.gp(omColumnValue, inputBladeScalarMultiplier),
                                                                      domainBladeScalarMultiplier));
                            break; // no need to search the other domainBlades too
                        }
                    }
                }

                // get name of return type
                if (m_fgs.m_returnTypeName.Length == 0)
                {
                    m_fgs.m_returnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName();
                }
            }
        }
Beispiel #4
0
        public static void GenerateBasisElementArrays(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            string accessModifierArr = Keywords.ConstArrayAccessModifier(S);

            G25.GMV gmv = S.m_GMV;

            double[] s             = new double[1 << S.m_dimension];
            int[]    IndexByBitmap = new int[1 << S.m_dimension];
            int[]    BitmapByIndex = new int[1 << S.m_dimension];
            int[]    GradeByBitmap = new int[1 << S.m_dimension];
            int[]    GroupByBitmap = new int[1 << S.m_dimension];
            new G25.CG.Shared.Comment("This array of integers contains the 'sign' (even/odd permutation of canonical order) of basis elements in the general multivector.\n" +
                                      "Use it to answer 'what is the permutation of the coordinate at index [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " double[] BasisElementSignByIndex = new double[]");
            SB.Append("\t\t{");
            {
                bool comma = false;
                int  idx   = 0;
                for (int i = 0; i < gmv.NbGroups; i++)
                {
                    for (int j = 0; j < gmv.Group(i).Length; j++)
                    {
                        if (comma)
                        {
                            SB.Append(", ");
                        }
                        RefGA.BasisBlade B = gmv.Group(i)[j];
                        s[gmv.Group(i)[j].bitmap] = B.scale;
                        IndexByBitmap[B.bitmap]   = idx;
                        BitmapByIndex[idx]        = (int)B.bitmap;
                        GradeByBitmap[B.bitmap]   = B.Grade();
                        GroupByBitmap[B.bitmap]   = i;
                        SB.Append(B.scale);
                        comma = true;
                        idx++;
                    }
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of integers contains the 'sign' (even/odd permutation of canonical order) of basis elements in the general multivector.\n" +
                                      "Use it to answer 'what is the permutation of the coordinate of bitmap [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " double[] BasisElementSignByBitmap = new double[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(s[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of integers contains the order of basis elements in the general multivector.\n" +
                                      "Use it to answer: 'at what index do I find basis element [x] (x = basis vector bitmap)?'").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementIndexByBitmap = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(IndexByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of integers contains the indices of basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what basis element do I find at index [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementBitmapByIndex = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(BitmapByIndex[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of grade of each basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what is the grade of basis element bitmap [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementGradeByBitmap = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GradeByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of group of each basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what is the group of basis element bitmap [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementGroupByBitmap = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GroupByBitmap[i]);
                }
            }
            SB.AppendLine("};");
        } // end of GenerateBasisElementArrays()
Beispiel #5
0
        public static void GenerateBasisElementArrays(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB)
        {
            G25.GMV gmv = S.m_GMV;

            double[] s             = new double[1 << S.m_dimension];
            int[]    IndexByBitmap = new int[1 << S.m_dimension];
            int[]    BitmapByIndex = new int[1 << S.m_dimension];
            int[]    GradeByBitmap = new int[1 << S.m_dimension];
            int[]    GroupByBitmap = new int[1 << S.m_dimension];
            SB.AppendLine("const double " + S.m_namespace + "_basisElementSignByIndex[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                bool comma = false;
                int  idx   = 0;
                for (int i = 0; i < gmv.NbGroups; i++)
                {
                    for (int j = 0; j < gmv.Group(i).Length; j++)
                    {
                        if (comma)
                        {
                            SB.Append(", ");
                        }
                        RefGA.BasisBlade B = gmv.Group(i)[j];
                        s[gmv.Group(i)[j].bitmap] = B.scale;
                        IndexByBitmap[B.bitmap]   = idx;
                        BitmapByIndex[idx]        = (int)B.bitmap;
                        GradeByBitmap[B.bitmap]   = B.Grade();
                        GroupByBitmap[B.bitmap]   = i;
                        SB.Append(B.scale);
                        comma = true;
                        idx++;
                    }
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const double " + S.m_namespace + "_basisElementSignByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(s[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementIndexByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(IndexByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementBitmapByIndex[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(BitmapByIndex[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementGradeByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GradeByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementGroupByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GroupByBitmap[i]);
                }
            }
            SB.AppendLine("};");
        } // end of GenerateBasisElementArrays()
Beispiel #6
0
        /// <returns>a list of basis blades in canonical order, sorted by grade.
        /// Each entry in the outer list contains the basis blades for that grade.</returns>
        public List<List<G25.rsbbp.BasisBlade>> GetDefaultBasisBlades()
        {
            // allocate list for each grade
            List<List<G25.rsbbp.BasisBlade>> L = new List<List<G25.rsbbp.BasisBlade>>();
            for (int i = 0; i < m_spec.m_dimension + 1; i++)
                L.Add(new List<G25.rsbbp.BasisBlade>());

            // enumerate over all basis blades, add them to respective lists
            for (uint b = 0; b < (1 << m_spec.m_dimension); b++)
            {
                RefGA.BasisBlade B = new RefGA.BasisBlade(b);
                L[B.Grade()].Add(new G25.rsbbp.BasisBlade(B));
            }

            return L;
        }
Beispiel #7
0
        /// <summary>
        /// Generates functions which compute parts of the application of a general outermorphism to a general multivector.
        ///
        /// This function should be called early on in the code generation process, at least
        /// before any of the <c>???()</c> functions is called.
        /// </summary>
        /// <param name="S">Specification (used for output language, GMV).</param>
        /// <param name="cgd">Where the result goes.</param>
        public static void WriteGomParts(Specification S, CGdata cgd)
        {
            if (S.m_GOM == null)
            {
                return;                  // nothing to do if GOM not defiend
            }
            int nbBaseTabs = (S.OutputCSharpOrJava()) ? 1 : 0;
            int nbCodeTabs = nbBaseTabs + 1;

            G25.GMV gmv = S.m_GMV;
            G25.GOM gom = S.m_GOM;

            string nameGOM    = "O";
            string nameSrcGMV = "A";
            string nameDstGMV = "C";

            // get symbolic multivector value
            RefGA.Multivector[] M1 = null;
            {
                bool ptr       = (S.OutputC());
                int  allGroups = -1;
                M1 = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, nameSrcGMV, ptr, allGroups);
            }

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                // map from code fragment to name of function
                Dictionary <string, string> generatedCode = new Dictionary <string, string>();

                // loop over all groups of the GMV, multiply with GOM, and assign the result
                for (int srcGroup = 0; srcGroup < gmv.NbGroups; srcGroup++)
                {
                    RefGA.Multivector inputValue = M1[srcGroup];
                    if (inputValue.IsScalar())
                    {
                        continue;
                    }

                    // Replace each basis blade in 'inputValue' with its value under the outermorphism.
                    RefGA.Multivector returnValue = RefGA.Multivector.ZERO; // returnValue = gom * gmv[srcGroup]
                    for (int i = 0; i < inputValue.BasisBlades.Length; i++)
                    {
                        // get input blade and domain for that grade
                        RefGA.BasisBlade   inputBlade   = inputValue.BasisBlades[i];
                        RefGA.BasisBlade[] domainBlades = gom.DomainForGrade(inputBlade.Grade());
                        for (int c = 0; c < domainBlades.Length; c++)
                        {
                            // if a match is found in the domain, add range vector to m_returnValue
                            if (domainBlades[c].bitmap == inputBlade.bitmap)
                            {
                                bool ptr = (S.OutputC());
                                RefGA.Multivector omColumnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, gom.DomainSmvForGrade(inputBlade.Grade())[c], nameGOM, ptr);
                                RefGA.Multivector inputBladeScalarMultiplier  = new RefGA.Multivector(new RefGA.BasisBlade(inputBlade, 0));
                                RefGA.Multivector domainBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(domainBlades[c], 0));
                                returnValue = RefGA.Multivector.Add(returnValue,
                                                                    RefGA.Multivector.gp(
                                                                        RefGA.Multivector.gp(omColumnValue, inputBladeScalarMultiplier),
                                                                        domainBladeScalarMultiplier));
                                break; // no need to search the other domainBlades too
                            }
                        }
                    } // end of 'compute return value'

                    // assign returnValue to various groups of the gmv
                    for (int dstGroup = 0; dstGroup < gmv.NbGroups; dstGroup++)
                    {
                        bool   mustCast   = false;
                        bool   writeZeros = false; // no need to generate "+= 0.0;"
                        int    dstBaseIdx = 0;
                        string code       = G25.CG.Shared.CodeUtil.GenerateGMVassignmentCode(S, FT, mustCast, gmv, nameDstGMV, dstGroup, dstBaseIdx, returnValue, nbCodeTabs, writeZeros);

                        string funcName = GetGomPartFunctionName(S, FT, srcGroup, dstGroup);
                        cgd.m_gmvGomPartFuncNames[new Tuple <string, string>(FT.type, funcName)] = (code.Length > 0);

                        if (code.Length == 0)
                        {
                            continue;
                        }

                        if (!S.m_GMV.IsGroupedByGrade(S.m_dimension))
                        {
                            code = code.Replace("=", "+=");
                        }

                        // check if code was already generated, and, if so, reuse it
                        if (generatedCode.ContainsKey(code))
                        {
                            // ready generated: call that function
                            code = "\t" + generatedCode[code] + "(" + nameGOM + ", " + nameSrcGMV + ", " + nameDstGMV + ");\n";
                        }
                        else
                        {
                            // not generated yet: remember code -> function
                            generatedCode[code] = funcName;
                        }

                        // write comment
                        string comment = "Computes the partial application of a general outermorphism to a general multivector";

                        string OM_PTR = "";
                        if (S.OutputC())
                        {
                            OM_PTR = "*";
                        }
                        else if (S.OutputCpp())
                        {
                            OM_PTR = "&";
                        }

                        string ACCESS = "";
                        if (S.OutputJava())
                        {
                            ACCESS = "protected static ";
                        }
                        else if (S.OutputCSharp())
                        {
                            ACCESS = "protected internal static ";
                        }

                        string ARR   = (S.OutputCSharpOrJava()) ? "[] " : " *";
                        string CONST = (S.OutputCSharpOrJava()) ? "" : "const ";

                        string funcDecl = ACCESS + "void " + funcName + "(" + CONST + FT.GetMangledName(S, gom.Name) + " " + OM_PTR + nameGOM + ", " + CONST + FT.type + ARR + nameSrcGMV + ", " + FT.type + ARR + nameDstGMV + ")";

                        if (S.OutputCppOrC())
                        {
                            new Comment(comment).Write(cgd.m_declSB, S, nbBaseTabs);
                            cgd.m_declSB.Append(funcDecl); cgd.m_declSB.AppendLine(";");
                        }
                        else
                        {
                            new Comment(comment).Write(cgd.m_defSB, S, nbBaseTabs);
                        }

                        // emit def
                        cgd.m_defSB.Append('\t', nbBaseTabs);
                        cgd.m_defSB.Append(funcDecl);
                        cgd.m_defSB.AppendLine(" {");
                        cgd.m_defSB.Append(code);
                        cgd.m_defSB.Append('\t', nbBaseTabs);
                        cgd.m_defSB.AppendLine("}");
                    } // end of loop over all dest GMV groups
                }     // end of loop over all source GMV groups
            }         // end of loop over all float types
        }             // end of function WriteGomParts()