Ejemplo n.º 1
0
        }                     // end of function WriteDualParts()

        /// <summary>
        /// Returns the code for dualization wrt to whole space using metric <c>M</c>.
        /// The code is composed of calls to functions generated by <c>WriteGmvDualParts()</c>.
        ///
        /// This function uses <c>cdg.m_gmvDualPartFuncNames</c>, but only to check whether a
        /// geometric product of some group with the pseudoscalar will get non-zero results in some
        /// other group.
        ///
        /// The returned code is only the body. The function declaration is not included.
        /// </summary>
        /// <param name="S">Specification of algebra (used for general multivector type, output language).</param>
        /// <param name="cgd">Used for <c>m_gmvDualPartFuncNames</c>.</param>
        /// <param name="FT">Floating point type.</param>
        /// <param name="M">The metric of the dual.</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="dual">When true, 'dual' is generated, otherwise, 'undual' is generated.</param>
        /// <returns>code for the requested product type.</returns>
        public static string GetDualCode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
                                         G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual)
        {
            if (S.OutputCppOrC())
            {
                return(GetDualCodeCppOrC(S, cgd, FT, M, FAI, resultName, dual));
            }
            else
            {
                return(GetDualCodeCSharpOrJava(S, cgd, FT, M, FAI, resultName, dual));
            }
        }
Ejemplo n.º 2
0
        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()
Ejemplo n.º 3
0
        } // 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()
Ejemplo n.º 4
0
        /// <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
Ejemplo n.º 5
0
        } // end of WriteGMVnormFunction

        /// <summary>
        /// Writes any versor application function for general multivectors,
        /// based on norm2 and geometric product.
        /// </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 WriteGMVapplyVersorFunction(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.ApplyVersorTypes AVtype)
        {
            // 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.GetVersorApplicationCode(S, cgd, FT, M, AVtype, 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);
            //       Console.WriteLine("Ft = " + FT.type + " funname = " + CF.OutputName);

            string funcName = CF.OutputName;

            // 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(funcName);
        }
Ejemplo n.º 6
0
        } // 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
Ejemplo n.º 7
0
 /// <summary>
 /// Must be called before CompleteFGS(), CheckDepencies() or WriteFunction() is called.
 /// Subclass can override, but if so, must always call superclass version of Init()
 /// </summary>
 /// <param name="S"></param>
 /// <param name="F"></param>
 /// <param name="cgd">Where the generate code goes.</param>
 public virtual void Init(Specification S, G25.fgs F, G25.CG.Shared.CGdata cgd)
 {
     m_specification = S;
     m_fgs = F;
     m_cgd = cgd;
     m_gmv = m_specification.m_GMV;
     m_G25M = m_specification.GetMetric(m_fgs.MetricName);
     m_M = m_G25M.m_metric;
     m_sane = true;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'.
        /// </summary>
        public override void WriteFunction()
        {
            // get metric
            G25.Metric G25M = m_specification.GetMetric(m_fgs.MetricName);
            //RefGA.Metric M = G25M.m_metric;

            bool isUnit = IsApplyUnitVersor(m_fgs) || IsApplyVersorWI(m_fgs);

            foreach (string floatName in m_fgs.FloatNames)
            {
                FloatType FT = m_specification.GetFloatType(floatName);

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

                // generate comment
                string  warningComment = (isUnit) ? " Only gives the correct result when the versor has a positive squared norm.\n" : "";
                Comment comment        = new Comment(
                    m_fgs.AddUserComment("Returns " + FAI[0].Name + " * " + FAI[1].Name + " * " + ((isUnit) ? "reverse" : "inverse") + "(" + FAI[0].Name + ") using " + m_G25M.m_name + " metric." + warningComment));

                if (m_gmvFunc)
                { // generate function over GMVs
                    // determine what type of function is requested:
                    G25.CG.Shared.GPparts.ApplyVersorTypes AVtype;
                    if (IsApplyVersor(m_fgs))
                    {
                        AVtype = G25.CG.Shared.GPparts.ApplyVersorTypes.INVERSE;
                    }
                    else if (IsApplyUnitVersor(m_fgs))
                    {
                        AVtype = G25.CG.Shared.GPparts.ApplyVersorTypes.REVERSE;
                    }
                    else
                    {
                        AVtype = G25.CG.Shared.GPparts.ApplyVersorTypes.EXPLICIT_INVERSE;
                    }

                    // generate code:
                    m_funcName[FT.type] = G25.CG.Shared.GmvGpParts.WriteGMVapplyVersorFunction(m_specification, m_cgd, FT, G25M, FAI, m_fgs, comment, AVtype);
                }
                else
                { // write  specialized function:
                    // setup instructions
                    System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>();
                    {
                        int  nbTabs    = 1;
                        bool mustCast  = false;
                        bool n2Ptr     = false;
                        bool declareN2 = true;

                        if (!isUnit)
                        {
                            // n2 = reverse(versor) * versor
                            I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, FT, FT, mustCast, m_n2Value, m_normSquaredName, n2Ptr, declareN2));
                        }

                        //bool transformedPtr = !(FAI[1].Type is G25.FloatType);
                        //bool declareTransformed = false;


                        if (isUnit)
                        {
                            // result = versor * X * reverse(versor)
                            I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, m_returnType, FT, mustCast, m_transformedValue));
                        }
                        else
                        {
                            // result = versor * X * reverse(versor) / (reverse(versor).versor)
                            I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, m_returnType, FT, mustCast, m_transformedValue, "/", new RefGA.Multivector(m_normSquaredName)));
                        }
                    }

                    // 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);
                    m_funcName[FT.type] = CF.OutputName;

                    bool staticFunc = Functions.OutputStaticFunctions(m_specification);
                    G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, CF, m_specification.m_inlineFunctions, staticFunc, CF.OutputName, FAI, I, comment);
                }
            }
        } // end of WriteFunction
Ejemplo n.º 9
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");
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Returns the name of a partial undual function.
 /// </summary>
 /// <param name="FT">Float type (used for mangled name).</param>
 /// <param name="M">Metric of dual.</param>
 /// <param name="gi">Grade/group of input.</param>
 /// <param name="go">Grade/group of output.</param>
 /// <returns>name of a partial geometric product function.</returns>
 public static string GetUndualPartFunctionName(Specification S, G25.FloatType FT, G25.Metric M, int gi, int go)
 {
     return(FT.GetMangledName(S, "undual") + "_" + M.m_name + "_" + gi + "_" + go);
 }