コード例 #1
0
        public static void WriteOpenNamespace(StringBuilder SB, G25.Specification S, string namespaceName)
        {
            switch (S.m_outputLanguage)
            {
            case OUTPUT_LANGUAGE.CPP:
            case OUTPUT_LANGUAGE.CSHARP:
                if (S.m_namespace.Length > 0)
                {
                    SB.Append("namespace ");
                    SB.Append(namespaceName);
                    SB.AppendLine(" {");
                }
                break;

            case OUTPUT_LANGUAGE.JAVA:
                if (S.m_namespace.Length > 0)
                {
                    SB.Append("package ");
                    SB.Append(namespaceName);
                    SB.AppendLine(";");
                }
                break;

            default:
                throw new Exception("G25.CG.Shared.Util.WriteOpenNamespace(): output language not supported");
            }
        }
コード例 #2
0
 /// <summary>
 /// Writes the license (as specified in 'S') to 'SB'. Uses opening and closing
 /// comments.
 /// </summary>
 /// <param name="S">Specification (used for license).</param>
 /// <param name="SB">Where the code goes.</param>
 public static void WriteLicense(StringBuilder SB, G25.Specification S)
 {
     WriteOpenMultilineComment(SB, S);
     SB.Append(S.GetLicense());
     SB.AppendLine("");
     WriteCloseMultilineComment(SB, S);
 }
コード例 #3
0
        } // end of WriteParserTest()

        public static List <string> WriteMetricTests(G25.Specification S, G25.CG.Shared.CGdata cgd,
                                                     Dictionary <String, String> gpGmvFuncName) // , string gpFuncName
        {
            List <string> testFunctionNames = new List <string>();

            foreach (FloatType FT in S.m_floatTypes)
            {
                //string testStr = FT.DoubleToString(S, FT.PrecisionEpsilon());

                foreach (Metric M in S.m_metric)
                {
                    string gmvName      = FT.GetMangledName(S, S.m_GMV.Name);
                    string testFuncName = "test_metric_" + M.m_name + "_" + gmvName;

                    cgd.m_cog.EmitTemplate(cgd.m_defSB, "testMetric",
                                           "S=", S,
                                           "FT=", FT,
                                           "M=", M,
                                           "gmv=", S.m_GMV,
                                           "gmvName=", gmvName,
                                           "testFuncName=", testFuncName,
                                           "gpGmvFuncName=", gpGmvFuncName[FT.type + "_" + M.m_name]
                                           );
                    testFunctionNames.Add(testFuncName);
                }
            }

            return(testFunctionNames);
        } // WriteMetricTests()
コード例 #4
0
        /// <summary>
        /// Converts a <c>RefGA.Symbolic.UnaryScalarOp</c> to code.
        ///
        /// Handles special cases (such as inversion) and understands floating point
        /// types (e.g., <c>fabsf()</c> is used for floats and <c>fabs()</c> is used for doubles in C.
        /// </summary>
        /// <param name="S">Used for output language.</param>
        /// <param name="FT">Floating point type used.</param>
        /// <param name="Op">The operation to convert to code.</param>
        /// <returns>Code for implementing <c>Op</c>c>.</returns>
        public static string UnaryScalarOpToLangString(G25.Specification S, G25.FloatType FT, RefGA.Symbolic.UnaryScalarOp Op)
        {
            string valueStr = ScalarOpValueToLangString(S, FT, Op.value);

            /*{
             *  if (!Op.value.IsScalar()) throw new Exception("G25.CG.Shared.BasisBlade.ScalarOpToLangString(): value should be scalar, found: " + Op.value.ToString(S.m_basisVectorNames));
             *  if (Op.value.IsZero()) valueStr = ScalarToLangString(S, FT, RefGA.BasisBlade.ZERO);
             *  else valueStr = ScalarToLangString(S, FT, Op.value.BasisBlades[0]);
             * }*/

            if (Op.opName == UnaryScalarOp.INVERSE)
            {
                if (FT.type == "float")
                {
                    return("1.0f / (" + valueStr + ")");
                }
                else if (FT.type == "double")
                {
                    return("1.0 / (" + valueStr + ")");
                }
                else
                {
                    return(FT.castStr + "1.0 / (" + valueStr + ")");
                }
            }
            else
            {
                return(OpNameToLangString(S, FT, Op.opName) + "(" + valueStr + ")");
            }
        } // end of function ScalarOpToLangString()
コード例 #5
0
        public static void LoadAndSave(string srcFilename, string dstFilename)
        {
            try
            {
                Console.WriteLine("Loading algebra specification: " + srcFilename);
                G25.Specification S = new G25.Specification(srcFilename);

                Console.WriteLine("Saving algebra specification: " + dstFilename);
                string str = XML.ToXmlString(S);
                G25.CG.Shared.Util.WriteFile(dstFilename, str);

                // write list of generated files
                if (OptionSaveFileListFile != null)
                {
                    List <string> L = new List <string>();
                    L.Add(dstFilename);
                    SaveGenerateFileList(OptionSaveFileListFile, L);
                }
            }
            catch (G25.UserException E)
            {
                System.Console.WriteLine("Error:");
                System.Console.Write(E.GetErrorReport());
            }
            catch (System.Exception E)
            {
                System.Console.WriteLine("Exception:");
                System.Console.WriteLine(E.ToString());
                System.Console.WriteLine(E.Message);
            }
        }
コード例 #6
0
        } // WriteMetricTests()

        public static List <string> WriteGetterSetterTests(G25.Specification S, G25.CG.Shared.CGdata cgd,
                                                           List <string> randomNumberGeneratorFuncName,
                                                           Dictionary <string, string> randomVersorFuncName) // , string gpFuncName
        {
            List <string> testFunctionNames = new List <string>();
            int           FTidx             = 0;

            //G25.GMV gmv = S.m_GMV;

            foreach (FloatType FT in S.m_floatTypes)
            {
                //string testStr = FT.DoubleToString(S, FT.PrecisionEpsilon());

                string gmvName      = FT.GetMangledName(S, S.m_GMV.Name);
                string testFuncName = "test_getter_setter_" + gmvName;

                cgd.m_cog.EmitTemplate(cgd.m_defSB, "testGetterSetter",
                                       "S=", S,
                                       "FT=", FT,
                                       "gmv=", S.m_GMV,
                                       "gmvName=", gmvName,
                                       "testFuncName=", testFuncName,
                                       "randomScalarFuncName=", randomNumberGeneratorFuncName[FTidx],
                                       "randomVersorFuncName=", randomVersorFuncName[FT.type]
                                       );
                testFunctionNames.Add(testFuncName);


                FTidx++;
            }

            return(testFunctionNames);
        } // WriteGetterSetterTests()
コード例 #7
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");
        }
コード例 #8
0
        } // end of function ScalarOpToLangString()

        /// <summary>
        /// Converts a <c>RefGA.Symbolic.BinaryScalarOpToLangString</c> to code.
        ///
        /// Handles special cases (such as inversion) and understands floating point
        /// types (e.g., <c>fabsf()</c> is used for floats and <c>fabs()</c> is used for doubles in C.
        /// </summary>
        /// <param name="S">Used for output language.</param>
        /// <param name="FT">Floating point type used.</param>
        /// <param name="Op">The operation to convert to code.</param>
        /// <returns>Code for implementing <c>Op</c>c>.</returns>
        public static string BinaryScalarOpToLangString(G25.Specification S, G25.FloatType FT, RefGA.Symbolic.BinaryScalarOp Op)
        {
            string value1Str = ScalarOpValueToLangString(S, FT, Op.value1);
            string value2Str = ScalarOpValueToLangString(S, FT, Op.value2);

            return(OpNameToLangString(S, FT, Op.opName) + "(" + value1Str + ", " + value2Str + ")");
        } // end of function BinaryScalarOpToLangString()
コード例 #9
0
ファイル: Program.cs プロジェクト: Sciumo/gaigen
        public static void Generate(string filename)
        {
            try
            {
                G25.Specification S = new G25.Specification(filename);

                // get the code generator and plugins ready
                CodeGeneratorLoader L = new CodeGeneratorLoader(S.GetOutputLanguageString());
                LoadDefaultCodeGenerators(L);
                // todo: load custom plugins (their location will be in the specification XML?)
                if (L.GetMainCodeGenerator() == null)
                    throw new G25.UserException("No code generator for language " + S.GetOutputLanguageString());

                // generate the code
                List<string> generatedFiles = L.GetMainCodeGenerator().GenerateCode(S, L.GetCodeGeneratorPlugins());

                // insert verbatim code:
                S.InsertVerbatimCode(generatedFiles);

                // write list of generated files
                if (OptionSaveFileListFile != null)
                    SaveGenerateFileList(OptionSaveFileListFile, generatedFiles);
            }
            catch (G25.UserException E)
            {
                System.Console.WriteLine("Error:");
                System.Console.Write(E.GetErrorReport());
            }
            catch (System.Exception E)
            {
                System.Console.WriteLine("Exception:");
                System.Console.WriteLine(E.ToString());
                System.Console.WriteLine(E.Message);
            }
        }
コード例 #10
0
 /// <summary>
 /// Writes the copyright notice (as specified in 'S') to 'SB'.
 /// Uses opening and closing comments.
 /// </summary>
 /// <param name="S">Specification (used for license).</param>
 /// <param name="SB">Where the code goes.</param>
 public static void WriteCopyright(StringBuilder SB, G25.Specification S)
 {
     if (S.m_copyright.Length > 0)
     {
         WriteOpenMultilineComment(SB, S);
         SB.AppendLine(S.m_copyright);
         WriteCloseMultilineComment(SB, S);
     }
 }
コード例 #11
0
 /// <summary>
 /// Constructs an array of func arg info for all arguments of an G25.fgs.
 /// </summary>
 /// <param name="S">Used for retrieving the G25.VariableType of 'm_typeName'.</param>
 /// <param name="F">Function for which you want an array of FuncArgInfo.</param>
 /// <param name="nbArgs">Default number of arguments. (the user may not specified arguments and then a default is used).</param>
 /// <param name="FT">Floating point type of arguments.</param>
 /// <param name="defaultTypeName">When the user does not specify arguments, this is the default type used.</param>
 /// <param name="computeMultivectorValue">Set to true to expand all multivector values to symbolic RefGA.Multivectors.</param>
 /// <returns>Array of FuncArgInfo describing the arguments of 'F'.</returns>
 public static FuncArgInfo[] GetAllFuncArgInfo(G25.Specification S, G25.fgs F, int nbArgs, G25.FloatType FT, string defaultTypeName, bool computeMultivectorValue)
 {
     FuncArgInfo[] FAI = new FuncArgInfo[nbArgs];
     for (int i = 0; i < nbArgs; i++)
     {
         FAI[i] = new FuncArgInfo(S, F, i, FT, defaultTypeName, computeMultivectorValue);
     }
     return(FAI);
 }
コード例 #12
0
 /// <summary>
 /// Returns the code to copy an array of 'nb' floats from 'srcPtrName' to 'dstPtrName'.
 /// </summary>
 public static string GetCopyCode(G25.Specification S, G25.FloatType FT, string srcPtrName, string dstPtrName, int nb)
 {
     if (nb <= Main.MAX_EXPLICIT_ZERO)
     {
         return(GetZeroCodePrefix(S, FT) + GetCopyFuncName(S) + "_" + nb + "(" + dstPtrName + ", " + srcPtrName + ");\n");
     }
     else
     {
         return(GetCopyCode(S, FT, srcPtrName, dstPtrName, nb.ToString()));
     }
 }
コード例 #13
0
 /// <summary>
 /// Returns the code to set ptrName[0] to ptrName[nb-1] to 0.
 /// </summary>
 public static string GetSetToZeroCode(G25.Specification S, G25.FloatType FT, string ptrName, int nb)
 {
     if (nb <= Main.MAX_EXPLICIT_ZERO)
     {
         return(GetZeroCodePrefix(S, FT) + GetZeroFuncName(S) + "_" + nb + "(" + ptrName + ");\n");
     }
     else
     {
         return(GetSetToZeroCode(S, FT, ptrName, nb.ToString()));
     }
 }
コード例 #14
0
 public static string GetNamespaceName(G25.Specification S)
 {
     if (S.OutputJava())
     {
         return(S.m_namespace + "_pkg");
     }
     else if (S.OutputCSharp())
     {
         return(S.m_namespace + "_ns");
     }
     else
     {
         return(S.m_namespace);
     }
 }
コード例 #15
0
        } // end of function ScalarToLangString

        /// <summary>
        /// Converts scalar part of 'value' to ouput language dependent string.
        /// </summary>
        private static string ScalarOpValueToLangString(G25.Specification S, G25.FloatType FT, RefGA.Multivector value)
        {
            if (!value.IsScalar())
            {
                throw new Exception("G25.CG.Shared.BasisBlade.ScalarOpValueToLangString(): value should be scalar, found: " + value.ToString(S.m_basisVectorNames));
            }
            if (value.IsZero())
            {
                return(ScalarToLangString(S, FT, RefGA.BasisBlade.ZERO));
            }
            else
            {
                return(ScalarToLangString(S, FT, value.BasisBlades[0]));
            }
        }
コード例 #16
0
        } // end of function BinaryScalarOpToLangString()

        public static string OpNameToLangString(G25.Specification S, G25.FloatType FT, string opName)
        {
            switch (S.m_outputLanguage)
            {
            case OUTPUT_LANGUAGE.C:
                if (FT.type == "float")
                {
                    return(m_floatOpsC[opName]);
                }
                else
                {
                    return(m_doubleOpsC[opName]);
                }

            case OUTPUT_LANGUAGE.CPP:
                if (FT.type == "float")
                {
                    return(m_floatOpsCpp[opName]);
                }
                else
                {
                    return(m_doubleOpsCpp[opName]);
                }

            case OUTPUT_LANGUAGE.CSHARP:
                if (FT.type == "float")
                {
                    return(m_floatOpsCSharp[opName]);
                }
                else
                {
                    return(m_doubleOpsCSharp[opName]);
                }

            case OUTPUT_LANGUAGE.JAVA:
                if (FT.type == "float")
                {
                    return(m_floatOpsJava[opName]);
                }
                else
                {
                    return(m_doubleOpsJava[opName]);
                }

            default:
                throw new Exception("G25.CG.Shared.BasisBlade.ScalarOpToLangString(): todo: language " + S.GetOutputLanguageString());
            }
        }
コード例 #17
0
        /// <summary>
        /// Converts a symbolic multivector value to a textual description of the specialized multivector 
        /// type that would be required to store that value. This is used for presenting error messages 
        /// to users when a suitable specialized type cannot be found for a specific multivector value.
        /// </summary>
        /// <param name="S">Specification, used for basis vector names.</param>
        /// <param name="value">The value to describe.</param>
        /// <returns>Textual description of the type that can store 'value'.</returns>
        public static String MultivectorToTypeDescription(G25.Specification S, RefGA.Multivector value)
        {
            StringBuilder SB = new StringBuilder();

            bool appendSpace = false;
            foreach (RefGA.BasisBlade B in value.BasisBlades)
            {
                if (appendSpace) SB.Append(" ");

                SB.Append(new RefGA.BasisBlade(B.bitmap).ToString(S.m_basisVectorNames));
                if (B.symScale == null)
                    SB.Append("=" + B.scale);

                appendSpace = true;
            }
            return SB.ToString();
        }
コード例 #18
0
        private static string GetZeroCodePrefix(G25.Specification S, G25.FloatType FT)
        {
            switch (S.m_outputLanguage)
            {
            case OUTPUT_LANGUAGE.C:
                return(S.m_namespace + "_" + FT.type + "_");

            case OUTPUT_LANGUAGE.CPP:
                return(S.m_namespace + "::");

            case OUTPUT_LANGUAGE.CSHARP:
            case OUTPUT_LANGUAGE.JAVA:
                return(S.m_namespace + ".");

            default:
                return("GetZeroCodePrefix(): not implemented yet");
            }
        }
コード例 #19
0
        } // end of GenerateCode()

        /// <summary>
        /// Writes test code for multivector parser and toString() to <c>cgd.m_defSB</c>.
        /// </summary>
        /// <param name="S">Specification of algebra.</param>
        /// <param name="cgd">Code generation data (used for <c>m_cog</c> and <c>m_defSB</c>.</param>
        /// <param name="randomNumberGeneratorFuncName">Function for random number generator (main float type).</param>
        /// <param name="randomVersorFuncName">Function for random versor (main float type).</param>
        /// <param name="subtractGmvFuncName">Function for subtracting general multivectors (main float type).</param>
        /// <returns></returns>
        public static string WriteParserTest(G25.Specification S, G25.CG.Shared.CGdata cgd,
                                             string randomNumberGeneratorFuncName,
                                             string randomVersorFuncName,
                                             string subtractGmvFuncName)
        {
            string testFuncName = "test_parse_" + S.m_GMV.Name;

            cgd.m_cog.EmitTemplate(cgd.m_defSB, "testParse",
                                   "S=", S,
                                   "FT=", S.m_floatTypes[0],
                                   "gmvName=", S.m_floatTypes[0].GetMangledName(S, S.m_GMV.Name),
                                   "testFuncName=", testFuncName,
                                   "targetFuncName=", "Parse",
                                   "randomScalarFuncName=", randomNumberGeneratorFuncName,
                                   "randomVersorFuncName=", randomVersorFuncName,
                                   "subtractGmvFuncName=", subtractGmvFuncName
                                   );
            return(testFuncName);
        } // end of WriteParserTest()
コード例 #20
0
        /// <summary>
        /// Returns the name of a converter function. For example, <c>"dualSphere_to_vectorE3GA"</c>.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="F">Used for OutputName. Can be null for default name.</param>
        /// <param name="mangledSrcTypename">Source type (e.g. <c>"dualSphere"</c>).</param>
        /// <param name="mangledDstTypename">Destination type (e.g. <c>"vectorE3GA"</c>).</param>
        /// <returns>the name of a converter function.</returns>
        public static string GetConverterName(G25.Specification S, G25.fgs F, string mangledSrcTypename, string mangledDstTypename)
        {
            if ((F != null) && (F.OutputName != F.Name))
            {
                return(F.OutputName);
            }

            switch (S.m_outputLanguage)
            {
            case OUTPUT_LANGUAGE.C:
                return(mangledSrcTypename + "_to_" + mangledDstTypename);

            case OUTPUT_LANGUAGE.CPP:
            case OUTPUT_LANGUAGE.CSHARP:
            case OUTPUT_LANGUAGE.JAVA:
                return("_" + mangledDstTypename);

            default:
                throw new Exception("Not implemented yet");
            }
        }
コード例 #21
0
        public static void Generate(string filename)
        {
            try
            {
                G25.Specification S = new G25.Specification(filename);

                // get the code generator and plugins ready
                CodeGeneratorLoader L = new CodeGeneratorLoader(S.GetOutputLanguageString());
                LoadDefaultCodeGenerators(L);
                // todo: load custom plugins (their location will be in the specification XML?)
                if (L.GetMainCodeGenerator() == null)
                {
                    throw new G25.UserException("No code generator for language " + S.GetOutputLanguageString());
                }

                // generate the code
                List <string> generatedFiles = L.GetMainCodeGenerator().GenerateCode(S, L.GetCodeGeneratorPlugins());

                // insert verbatim code:
                S.InsertVerbatimCode(generatedFiles);

                // write list of generated files
                if (OptionSaveFileListFile != null)
                {
                    SaveGenerateFileList(OptionSaveFileListFile, generatedFiles);
                }
            }
            catch (G25.UserException E)
            {
                System.Console.WriteLine("Error:");
                System.Console.Write(E.GetErrorReport());
            }
            catch (System.Exception E)
            {
                System.Console.WriteLine("Exception:");
                System.Console.WriteLine(E.ToString());
                System.Console.WriteLine(E.Message);
            }
        }
コード例 #22
0
        /// <summary>
        /// Writes the appropriate 'close multiline comment' string to <c>SB</c>.
        /// For example, if <c>S.m_outputLanguage</c> is a C-like language, "*/\n" is written.
        /// For Python, "\"\"\"\\n" is written.
        /// </summary>
        /// <param name="SB">Where the result goes.</param>
        /// <param name="S">Used for <c>S.m_outputLanguage</c>.</param>
        public static void WriteCloseMultilineComment(StringBuilder SB, G25.Specification S)
        {
            switch (S.m_outputLanguage)
            {
            case OUTPUT_LANGUAGE.C:
            case OUTPUT_LANGUAGE.CPP:
            case OUTPUT_LANGUAGE.JAVA:
            case OUTPUT_LANGUAGE.CSHARP:
                SB.AppendLine("*/");
                break;

            case OUTPUT_LANGUAGE.PYTHON:
                SB.AppendLine("\"\"\"");
                break;

            case OUTPUT_LANGUAGE.MATLAB:
                SB.AppendLine("%}");
                break;

            default:
                throw new Exception("G25.CG.Shared.Util.WriteOpenMultilineComment(): output language not supported");
            }
        }
コード例 #23
0
 public static void WriteCloseNamespace(StringBuilder SB, G25.Specification S)
 {
     WriteCloseNamespace(SB, S, GetNamespaceName(S));
 }
コード例 #24
0
ファイル: Program.cs プロジェクト: Sciumo/gaigen
        public static void LoadAndSave(string srcFilename, string dstFilename)
        {
            try
            {
                Console.WriteLine("Loading algebra specification: " + srcFilename);
                G25.Specification S = new G25.Specification(srcFilename);

                Console.WriteLine("Saving algebra specification: " + dstFilename);
                string str = XML.ToXmlString(S);
                G25.CG.Shared.Util.WriteFile(dstFilename, str);

                // write list of generated files
                if (OptionSaveFileListFile != null) {
                    List<string> L = new List<string>();
                    L.Add(dstFilename);
                    SaveGenerateFileList(OptionSaveFileListFile, L);
                }

            }
            catch (G25.UserException E)
            {
                System.Console.WriteLine("Error:");
                System.Console.Write(E.GetErrorReport());
            }
            catch (System.Exception E)
            {
                System.Console.WriteLine("Exception:");
                System.Console.WriteLine(E.ToString());
                System.Console.WriteLine(E.Message);
            }
        }
コード例 #25
0
        /// <summary>
        /// This function contains a function to find a tightly matching specialized multivector.
        /// Given a Multivector 'M', it find the best match which can contain it.
        ///
        /// The function tries each SMV in the specification. It rates them as follows:
        /// -missing variable basis blade: disqualified
        /// -constant coordinate mismatch: disqualified
        /// -constant coordinate match: +1
        /// -excess variable coordinate : -1
        ///
        /// If the symbolic multivector 'M' has a scalar return type, the function will insist on returning
        /// a scalar type! It will not (for example) return a rotor.
        /// </summary>
        /// <param name="S">Specification of algebra, used for the m_SMV</param>
        /// <param name="M">The multivector for which a matching SMV is sought.</param>
        /// <param name="FT">The preferred floating point type (only used when scalar is returned).</param>
        /// <returns>null when no match found; the selected G25.SMV or G25.FloatType otherwise.</returns>
        public static G25.VariableType FindTightestMatch(G25.Specification S, RefGA.Multivector M, FloatType FT)
        {
            G25.SMV   bestSMV       = null;
            const int LOWEST_RATING = -10000000; // rating of good-enough blades _can_ be negative, if they have excess variable coordinates
            int       bestRating    = LOWEST_RATING;

            const double EPSILON = 1e-6; // make this user controllable??

            foreach (G25.SMV smv in S.m_SMV)
            {
                int rating         = 0;
                int nbConstMatched = 0; // number of elements from M.BasisBlades matched with const coordinates
                for (int i = 0; i < M.BasisBlades.Length; i++)
                {
                    // get blade, see if it is constant
                    RefGA.BasisBlade B        = M.BasisBlades[i];
                    bool             constant = (B.symScale == null);

                    // if constant, then try constant blades first
                    bool found = false; // set to true when matching basis blade is found
                    if (constant)
                    {
                        // loop over all constant basis blades
                        for (int j = 0; j < smv.NbConstBasisBlade; j++)
                        {
                            // get basis blade, compare bitmaps
                            RefGA.BasisBlade C = smv.ConstBasisBlade(j);
                            if (C.bitmap == B.bitmap)
                            {
                                if (Math.Abs(C.scale - B.scale) / Math.Abs(C.scale) > EPSILON)
                                {
                                    rating = LOWEST_RATING;
                                    break; // this break the outer loop (over 'i') too
                                }
                                else
                                {
                                    rating++;
                                    nbConstMatched++;
                                    found = true;
                                    break;
                                }
                            }
                        }
                    }
                    if (rating == LOWEST_RATING)
                    {
                        break;
                    }

                    // if no constant basis blade was found, loop over all variable basis blades
                    if (!found)
                    {
                        for (int j = 0; j < smv.NbNonConstBasisBlade; j++)
                        {
                            // get basis blade, compare bitmaps
                            RefGA.BasisBlade C = smv.NonConstBasisBlade(j);
                            if (C.bitmap == B.bitmap)
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    if (!found)
                    {// if neither constant nor variable basis blade found: no match
                        rating = LOWEST_RATING;
                        break;
                    }
                }

                // disqualify 'smv' when it has const coords not present in 'M'
                if (nbConstMatched < smv.NbConstBasisBlade)
                {
                    rating = LOWEST_RATING;
                }

                if (rating != LOWEST_RATING)
                {
                    // adjust rating for excess variable coordinates:
                    int nbNonConstCoords = M.BasisBlades.Length - nbConstMatched;
                    int nbExcess         = smv.NbNonConstBasisBlade - nbNonConstCoords;
                    if (nbExcess > 0)
                    {
                        rating -= nbExcess;               // subtract 1 for each non-const coordinate that is in 'smv' without actually being useful
                    }
                }

                // keep best SMV so far
                if (rating > bestRating)
                {
                    bestRating = rating;
                    bestSMV    = smv;
                }
            }

            if ((M.IsZero() || M.IsScalar()) && (bestRating < 0))
            {
                return(FT);                                                  // insist on retuning a scalar type
            }
            else
            {
                return(bestSMV);
            }
        } // end of function FindTightestMatch()
コード例 #26
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);
            }
        } // end of function ScalarToLangString
コード例 #27
0
        } // end of GetAssignmentStrings()

        /// <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);
        }
コード例 #28
0
 /// <summary>
 /// Returns the code to copy an array of 'nb' floats from 'srcPtrName' to 'dstPtrName'.
 /// </summary>
 public static string GetCopyCode(G25.Specification S, G25.FloatType FT, string srcPtrName, string dstPtrName, string nb)
 {
     return(GetZeroCodePrefix(S, FT) + GetCopyFuncName(S) + "_N(" + dstPtrName + ", " + srcPtrName + ", " + nb + ");\n");
 }
コード例 #29
0
        /// <summary>
        /// Write code for conversion to string.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Specification.</param>
        /// <param name="cgd">Code generation data.</param>
        /// <param name="def">Whether to generate code for definition or declaration.</param>
        public static void WriteToString(StringBuilder SB, G25.Specification S, G25.CG.Shared.CGdata cgd, bool def)
        {
            string TEMPLATE_NAME = (def) ? "toStringSource"  : "toStringHeader";

            cgd.m_cog.EmitTemplate(SB, TEMPLATE_NAME, "S=", S, "STRING_PARAMETERS=", STRING_PARAMETERS);
        }
コード例 #30
0
 /// <summary>
 /// Returns the code to set ptrName[0] to ptrName[nb-1] to 0.
 /// </summary>
 public static string GetSetToZeroCode(G25.Specification S, G25.FloatType FT, string ptrName, string nb)
 {
     return(GetZeroCodePrefix(S, FT) + GetZeroFuncName(S) + "_N(" + ptrName + ", " + nb + ");\n");
 }
コード例 #31
0
        /// <summary>
        /// Constructs a new FuncArgInfo class for a specific argument 'argIdx' of function 'F'.
        /// </summary>
        /// <param name="S">Used for retrieving the G25.VariableType of 'm_typeName'.</param>
        /// <param name="F">Function for which this FuncArgInfo describes an argument.</param>
        /// <param name="argIdx">Index of argument. Use -1 for artificial 'return argument' used for the C language.</param>
        /// <param name="FT">Floating point type of the type of the argument.</param>
        /// <param name="defaultTypeName">Name of the type of the argument.</param>
        /// <param name="computeMultivectorValue">Set to true to convert the type into symbolic code. Uses 'F' to obtain the actual name of the variable to use inside the symbolic multivector.</param>
        public FuncArgInfo(G25.Specification S, G25.fgs F, int argIdx, G25.FloatType FT, string defaultTypeName, bool computeMultivectorValue)
        {
            m_mvInterface = true;
            m_name        = F.GetArgumentName(argIdx);
            m_typeName    = F.GetArgumentTypeName(argIdx, defaultTypeName);
            m_type        = S.GetType(m_typeName);
            m_varType     = m_type.GetVariableType();
            if (m_varType != VARIABLE_TYPE.FLOAT)
            {
                m_floatType = FT;
            }
            else
            {
                m_floatType = S.GetFloatType(m_typeName);
            }

            // set mangled type name (depends on whether type is scalar or not)
            if ((m_varType == VARIABLE_TYPE.FLOAT) || (m_varType == VARIABLE_TYPE.ENUM))
            {
                m_mangledTypeName = m_typeName;
            }
            else
            {
                m_mangledTypeName = FT.GetMangledName(S, m_typeName);

                // temp (currently disabled) test for C# and Java
                // if (S.OutputCSharpOrJava() && (m_varType == VARIABLE_TYPE.GMV))
                // m_mangledTypeName = m_mangledTypeName + G25.CG.Shared.Main.IF_SUFFIX;
            }

            // set pointer / non pointer flag
            m_pointer = F.GetArgumentPtr(S, argIdx);

            // set array  flag
            m_array = F.GetArgumentArr(S, argIdx);

            m_constant = (argIdx >= 0);


            if (computeMultivectorValue)
            {
                if (m_varType == VARIABLE_TYPE.SMV)
                {
                    m_multivectorValue = new RefGA.Multivector[1] {
                        Symbolic.SMVtoSymbolicMultivector(S, (G25.SMV)m_type, m_name, m_pointer)
                    };
                }
                else if (m_varType == VARIABLE_TYPE.GMV)
                {
                    m_multivectorValue = Symbolic.GMVtoSymbolicMultivector(S, (G25.GMV)m_type, m_name, m_pointer, -1); // -1 = sym mv for all groups
                }
                else if (m_varType == VARIABLE_TYPE.FLOAT)
                {
                    m_multivectorValue = new RefGA.Multivector[1] {
                        Symbolic.ScalarToSymbolicMultivector(S, (G25.FloatType)m_type, m_name)
                    }
                }
                ;
                else
                {
                    // OM: do nothing?
                    m_multivectorValue = null;
                }
            }
        }