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

        /// <summary>
        /// Writes a simple function which assigns some value based on specialized multivectors or scalars to some variable.
        ///
        /// Used by a lot of simple C functions, like gp, op, lc.
        ///
        /// Somewhat obsolete (preferably, use the more generic, instruction based WriteFunction()).
        ///
        /// </summary>
        /// <param name="S">Specification of algebra.</param>
        /// <param name="cgd">Results go into cgd.m_defSB, and so on</param>
        /// <param name="F">The function generation specification.</param>
        /// <param name="FT">Default float pointer type.</param>
        /// <param name="FAI">Info on the arguments of the function.</param>
        /// <param name="value">The value to assign.</param>
        /// <param name="comment">Optional comment for function (can be null).</param>
        public static void WriteSpecializedFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F,
                                                    FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, RefGA.Multivector value, Comment comment)
        {
            // get return type (may be a G25.SMV or a G25.FloatType)
            G25.VariableType returnType = G25.CG.Shared.SpecializedReturnType.GetReturnType(S, cgd, F, FT, value);

            if (returnType == null)
            {
                throw new G25.UserException("Missing return type: " + G25.CG.Shared.BasisBlade.MultivectorToTypeDescription(S, value),
                                            XML.FunctionToXmlString(S, F));
            }

            bool ptr = true;

            string dstName = G25.fgs.RETURN_ARG_NAME;
            //string dstTypeName = (returnType is G25.SMV) ? FT.GetMangledName((returnType as G25.SMV).Name) : (returnType as G25.FloatType).type;

            string funcName = F.OutputName;

            // write comment to declaration
            if (comment != null)
            {
                if (S.OutputCppOrC())
                {
                    comment.Write(cgd.m_declSB, S, 0);
                }
                else
                {
                    comment.Write(cgd.m_defSB, S, 0);
                }
            }

            if ((returnType is G25.SMV) && (S.OutputC()))
            {
                bool    mustCast = false;
                G25.SMV dstSmv   = returnType as G25.SMV;

                G25.CG.Shared.FuncArgInfo returnArgument = null;
                returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, dstSmv.Name, false); // false = compute value

                bool staticFunc = S.OutputCSharpOrJava();
                G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd,
                                                                S.m_inlineFunctions, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, dstSmv, dstName, ptr,
                                                                value);
            }
            else
            {
                G25.FloatType returnFT = ((returnType as G25.FloatType) == null) ? FT : (returnType as G25.FloatType);

                bool mustCast = false;
                for (int i = 0; i < FAI.Length; i++)
                {
                    mustCast |= returnFT.MustCastIfAssigned(S, FAI[i].FloatType);
                }

                bool staticFunc = S.OutputCSharpOrJava();
                G25.CG.Shared.Functions.WriteReturnFunction(S, cgd,
                                                            S.m_inlineSet, staticFunc, funcName, FAI, FT, mustCast, returnType, value);
            }
        } // end of WriteSpecializedFunction()
Ejemplo n.º 2
0
 /// <summary>
 /// Instruction for generating code for an assignment to or a return of a variable.
 /// </summary>
 /// <param name="nbTabs">How many tabs to put in front of code.</param>
 /// <param name="T">Type of assigned variable.</param>
 /// <param name="FT">Floating point type of coordinates of assigned variable.</param>
 /// <param name="mustCast">When assigning to variable, should the coordinates be cast to FT?</param>
 /// <param name="value">The assigned value.</param>
 public AssignOrReturnInstruction(int nbTabs, G25.VariableType T, G25.FloatType FT, bool mustCast, RefGA.Multivector value)
     : base(nbTabs)
 {
     m_type      = T;
     m_floatType = FT;
     m_mustCast  = mustCast;
     m_value     = value;
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Instruction for generating code for an assignment to a variable, with an optional declration of that same variable.
 /// </summary>
 /// <param name="nbTabs">How many tabs to put in front of code.</param>
 /// <param name="T">Type of assigned variable.</param>
 /// <param name="FT">Floating point type of coordinates of assigned variable. If T is a floating point type, then is equal to T.</param>
 /// <param name="mustCast">When assigning to variable, should the coordinates be cast to FT?</param>
 /// <param name="value">The assigned value.</param>
 /// <param name="name">Name of assigned variable.</param>
 /// <param name="ptr">Is the assigned variable a pointer?</param>
 /// <param name="declareVariable">If true, code for declaring the variable is also generated.</param>
 public AssignInstruction(int nbTabs, G25.VariableType T, G25.FloatType FT, bool mustCast, RefGA.Multivector value, string name, bool ptr, bool declareVariable)
     :
     base(nbTabs, T, FT, mustCast, value)
 {
     m_name            = name;
     m_ptr             = ptr;
     m_declareVariable = declareVariable;
 }
Ejemplo n.º 4
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)
            {
                m_fgs.m_argumentTypeNames = new String[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;            // dual(gmv) = gmv
            }
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                // get symbolic result
                m_reverseValue = RefGA.Multivector.Reverse(tmpFAI[0].MultivectorValue[0]);
                m_n2Value      = RefGA.Multivector.gp(m_reverseValue, tmpFAI[0].MultivectorValue[0], m_M);
                if (m_G25M.m_round)
                {
                    m_n2Value = m_n2Value.Round(1e-14);
                }

                if (m_n2Value.HasSymbolicScalars() || (!m_n2Value.IsScalar()) || m_n2Value.IsZero())
                {
                    m_inverseValue = RefGA.Multivector.gp(m_reverseValue,
                                                          RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(new RefGA.BasisBlade(0, 1.0, m_normSquaredName))));
                }
                else
                {
                    m_inverseValue = RefGA.Multivector.gp(m_reverseValue, new RefGA.Multivector(1.0 / m_n2Value.RealScalarPart()));
                    m_n2Value      = null;
                }

                // 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_inverseValue).GetName();
                }
            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 5
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)
            {
                m_fgs.m_argumentTypeNames = new string[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;            // unit(gmv) = gmv
            }
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                // get symbolic result
                m_grade0Value = tmpFAI[0].MultivectorValue[0].ExtractGrade(0);
                m_grade2Value = tmpFAI[0].MultivectorValue[0].ExtractGrade(2);
                RefGA.Multivector reverseGrade2Value = RefGA.Multivector.Reverse(m_grade2Value);
                m_grade2norm2Value = RefGA.Multivector.gp(reverseGrade2Value, m_grade2Value, m_M);

                m_returnValue = RefGA.Multivector.gp(m_grade2Value, new RefGA.Multivector(mulName)); // where mulName = atan2(sqrt(grade2norm2), grade0) / sqrt(grade2norm2)

                // 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();
                }
            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 6
0
        } // end of WriteAssignmentFunction()

        /// <summary>
        ///
        /// </summary>
        /// <param name="S">Used for all kinds of stuff.</param>
        /// <param name="cgd">Results go into cgd.m_defSB, and so on</param>
        /// <param name="inline">Should the function we inline?</param>
        /// <param name="staticFunc">Static function?</param>
        /// <param name="functionName">The name of the function which is to be generated.</param>
        /// <param name="arguments">Array of FuncArg which describes the arguments of the function.</param>
        /// <param name="returnFT">Floating point type of return variable.</param>
        /// <param name="mustCastDst">set to true if coordinates of 'value' must be cast to 'dstFT'.</param>
        /// <param name="returnType">The type to be returned.</param>
        /// <param name="value">Value to be written to the returned.</param>
        public static void WriteReturnFunction(
            Specification S, G25.CG.Shared.CGdata cgd,
            bool inline, bool staticFunc, string functionName,
            FuncArgInfo[] arguments,
            FloatType returnFT, bool mustCastDst, G25.VariableType returnType, RefGA.Multivector value)
        {
            string returnTypeName;
            bool   returnSMV = returnType is G25.SMV;

            if (returnSMV)
            {
                returnTypeName = returnFT.GetMangledName(S, (returnType as G25.SMV).Name);
            }
            else
            {
                returnTypeName = (returnType as G25.FloatType).type;
            }

            // where the definition goes:
            StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB;

            // declaration:
            if (S.OutputCppOrC())
            {
                WriteDeclaration(cgd.m_declSB, S, cgd, false, staticFunc, returnTypeName, functionName, null, arguments);
                cgd.m_declSB.AppendLine(";");
            }

            WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnTypeName, functionName, null, arguments);


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

            int nbTabs           = 1;
            ReturnInstruction RI = new ReturnInstruction(nbTabs, returnType, returnFT, mustCastDst, value);

            RI.Write(defSB, S, cgd);

            defSB.Append("\n");

            defSB.AppendLine("}");
        } // end of WriteReturnFunction()
Ejemplo n.º 7
0
        } // end of function FindTightestMatch()

        /// <summary>
        /// The user may have requested a return type (F.ReturnTypeName).
        /// In that case, the type with the same name is found, or an exception
        /// is thrown if it does not exists.
        ///
        /// Otherwise, finds the (tightest, best) return type for a function 'F' which
        /// returning the (symbolic) value 'value'.
        /// This  may or may not result in an SMV being found. If no
        /// type is found and the return type is a scalar, then a floating
        /// point type may be returned.
        ///
        /// If no SMV type is found, then a new type is created, and an exception
        /// is thrown which described the missing type.
        /// </summary>
        /// <param name="S">The specification (used to find SMVs)</param>
        /// <param name="cgd">Not used currently.</param>
        /// <param name="F">Function description (used for user-specified return type).</param>
        /// <param name="FT">Floating point type used in function.</param>
        /// <param name="value">The symbolic return value.</param>
        /// <returns>The SMV, FloatType or null if none found.</returns>
        public static G25.VariableType GetReturnType(Specification S, CGdata cgd, G25.fgs F, FloatType FT, RefGA.Multivector value)
        {
            if ((F.ReturnTypeName != null) && (F.ReturnTypeName.Length > 0))
            {
                // The user specified a return type
                G25.SMV returnSmv = S.GetSMV(F.ReturnTypeName); // is it a SMV?
                if (returnSmv != null)
                {
                    return(returnSmv);
                }
                G25.FloatType returnFT = S.GetFloatType(F.ReturnTypeName); // is it a specific float?
                if (returnFT != null)
                {
                    return(FT);                                  //returnFT;
                }
                else if (F.ReturnTypeName == G25.XML.XML_SCALAR) // is it a unspecified float?
                {
                    return(FT);
                }

                // type does not exist: abort (TODO: error message)
                else
                {
                    throw new G25.UserException("Non-existant user-specified return type: " + F.ReturnTypeName,
                                                XML.FunctionToXmlString(S, F)); // non-existant return type
                }
            }
            else
            {
                G25.VariableType RT = FindTightestMatch(S, value, FT);
                if (RT != null)
                {
                    return(RT);
                }
                else
                {
                    return(CreateSyntheticSMVtype(S, cgd, FT, value));
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Should write the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'.
        /// </summary>
        public override void WriteFunction()
        {
            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_gmv.Name, computeMultivectorValue);

                // comment
                Comment comment = new Comment(
                    m_fgs.AddUserComment("Returns " + FAI[1].TypeName + " " + FAI[1].Name + " * " +
                                         FAI[0].TypeName + " " + FAI[0].Name + " + " +
                                         FAI[2].TypeName + " " + FAI[2].Name + "."));


                // if scalar or specialized: generate specialized function
                if (m_gmvFunc)
                {
                    G25.CG.Shared.GmvCASNparts.WriteSASfunction(m_specification, m_cgd, FT, FAI, m_fgs, comment);
                }
                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;
                        G25.VariableType returnType = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue);
                        I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, returnType, FT, mustCast, m_returnValue));
                    }

                    // 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);

                    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
        } // end of WriteDeclaration()

        /// <summary>
        /// Writes generic function based on Instructions.
        ///
        /// This version automatically figures out the return type (so it is recommended over the other WriteFunction()).
        /// </summary>
        /// <param name="S">Specification of algebra.</param>
        /// <param name="cgd">Results go into cgd.m_defSB, and so on</param>
        /// <param name="F">Function specification.</param>
        /// <param name="inline">When true, the code is inlined.</param>
        /// <param name="staticFunc">static function?</param>
        /// <param name="functionName">Name of generated function.</param>
        /// <param name="arguments">Arguments of function (any 'return argument' used for the C language is automatically setup correctly).</param>
        /// <param name="instructions">List of GA-instructions which make up the function.</param>
        /// <param name="comment">Comment to go into generated declration code.</param>
        public static void WriteFunction(
            Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F,
            bool inline, bool staticFunc, string functionName, FuncArgInfo[] arguments,
            List <Instruction> instructions, Comment comment)
        {
            List <G25.VariableType> returnTypes  = new List <G25.VariableType>();
            List <G25.FloatType>    returnTypeFT = new List <G25.FloatType>(); // floating point types of return types

            Instruction.GetReturnType(instructions, returnTypes, returnTypeFT);

            // for now, assume only one return type is used?
            string returnType = "void";

            G25.CG.Shared.FuncArgInfo returnArgument = null;
            if (returnTypes.Count > 0)
            {
                G25.VariableType returnVT = returnTypes[0];
                G25.FloatType    returnFT = returnTypeFT[0];

                if (returnVT is G25.FloatType)
                {
                    returnVT = returnFT;
                }

                string returnTypeName = (returnVT is G25.MV) ? (returnVT as G25.MV).Name : (returnVT as FloatType).type;

                returnType = returnFT.GetMangledName(S, returnTypeName);

                if (S.OutputC())
                {
                    if (!(returnVT is G25.FloatType))
                    {
                        returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, returnFT, returnTypeName, false); // false = compute value
                    }
                }
            }

            WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment);
        } // end of WriteFunction()
Ejemplo n.º 10
0
        /// <summary>
        /// Writes all shortcuts for 'type'.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Used for namespace.</param>
        /// <param name="cgd">Not used yet.</param>
        /// <param name="FT">Float point type of 'type'.</param>
        /// <param name="type">The type for which the function should be written.</param>
        public static void WriteFunctionShortcuts(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type)
        {
            Dictionary <string, List <G25.Operator> > operatorMap = S.GetOperatorMap();
            Dictionary <string, bool> boundOperators = new Dictionary <string, bool>();

            foreach (G25.fgs fgs in S.m_functions)
            {
                if ((type is G25.SMV) && fgs.IsConverter(S))
                {
                    G25.SMV smv = (G25.SMV)type;
                    if (fgs.IsConverterSource(S, (G25.SMV)type, FT))
                    {
                        // write converter here . . .
                        //SB.AppendLine("// converter source here!");
                    }
                    else if (fgs.IsConverterDestination(S, smv, FT))
                    {
                        // write converter here . . .
                        Converter.WriteMemberConverter(SB, S, cgd, FT, fgs, (G25.SMV)S.GetType(fgs.ArgumentTypeNames[0]), smv);
                    }
                }
                else if (fgs.GetSupportedByPlugin() && (fgs.NbArguments >= 1) && (Array.IndexOf(fgs.FloatNames, FT.type) >= 0))
                {
                    // get function arguments
                    bool computeMultivectorValue    = false;
                    G25.CG.Shared.FuncArgInfo[] FAI = null;
                    try
                    {
                        FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, fgs, fgs.NbArguments, FT, "not set", computeMultivectorValue);
                    }
                    catch (Exception ex)
                    {
                        if ((type is G25.GMV) && (FT == S.m_floatTypes[0])) // only warn once
                        {
                            Console.WriteLine("Warning: cannot generate shortcut to " + fgs.ToString());
                        }
                        continue;
                    }

                    // if type matches, write the shortcut, and possibly an operator
                    if (FAI[0].TypeName.Equals(type.GetName()))
                    {
                        WriteFunctionShortcut(SB, S, cgd, FT, type, fgs, FAI);
                        if (S.OutputCSharpOrJava())
                        {
                            removeMvInterfaces(FAI); // arguments to operators need to be of the multivector type, not the multivector interface type
                        }
                        WriteOperatorShortcut(SB, S, cgd, FT, type, fgs, FAI, operatorMap, boundOperators);
                    }
                }
            }
        } // end of function WriteFunctionShortcuts()
Ejemplo n.º 11
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()
        {
            // get info on # arguments
            m_isUnit = IsApplyUnitVersor(m_fgs) || IsApplyVersorWI(m_fgs); // unit or inverse provided?
            NB_ARGS = GetNbArgs(m_fgs); // number of arguments (2 or 3)

            // fill in ArgumentTypeNames
            if (m_fgs.ArgumentTypeNames.Length == 0)
            {
                m_fgs.m_argumentTypeNames = new String[NB_ARGS];
                for (int i = 0; i < NB_ARGS; i++)
                    m_fgs.m_argumentTypeNames[i] = 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_gmvFunc = !(tmpFAI[0].IsScalarOrSMV() && tmpFAI[1].IsScalarOrSMV());

            m_versorMv = (G25.MV)tmpFAI[0].Type;
            m_subjectMv = (G25.MV)tmpFAI[1].Type;
            if (tmpFAI.Length > 2)
                m_inverseVersorMv = (G25.MV)tmpFAI[2].Type;

            { // get symbolic result
                // get grade of input blade:
                m_inputGradeUsage = tmpFAI[1].MultivectorValue[0].GradeUsage();

                // get basic transformed value
                m_versorValue = tmpFAI[0].MultivectorValue[0];
                m_reverseVersorValue = (IsApplyVersorWI(m_fgs)) ? tmpFAI[2].MultivectorValue[0] : RefGA.Multivector.Reverse(m_versorValue);
                m_transformedValue =
                    RefGA.Multivector.gp(
                    RefGA.Multivector.gp(m_versorValue, tmpFAI[1].MultivectorValue[0], m_M),
                    m_reverseVersorValue, m_M);

                // apply grade part selection
                m_transformedValue = m_transformedValue.ExtractGrade(RefGA.Multivector.GradeBitmapToArray(m_inputGradeUsage));

                // if rotor is not guaranteed by the user to be unit, compute norm squared
                if (!m_isUnit)
                    m_n2Value = RefGA.Multivector.ip(m_reverseVersorValue, m_versorValue, m_M, RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION);

                // round value if required by metric
                if (m_G25M.m_round)
                {
                    m_transformedValue = m_transformedValue.Round(1e-14);
                    if (m_n2Value != null)
                        m_n2Value = m_n2Value.Round(1e-14);
                }
            }

            // compute intermediate results, set return type
            if (m_gmvFunc) m_fgs.m_returnTypeName = m_gmv.Name; // gmv * gmv / gmv = gmv
            else
            {
                // 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_transformedValue).GetName();
            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Checks if an operator should be written for the combination of 'type' and 'fgs'.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Not used yet.</param>
        /// <param name="FT">Float point type of 'type'.</param>
        /// <param name="type">The type for which shortcuts should be written.</param>
        /// <param name="fgs"></param>
        /// <param name="FAI"></param>
        /// <param name="operatorMap"></param>
        /// <param name="boundOperators"></param>
        private static void WriteOperatorShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type,
                                                  G25.fgs fgs, FuncArgInfo[] FAI,
                                                  Dictionary <string, List <G25.Operator> > operatorMap, Dictionary <string, bool> boundOperators)
        {
            if (S.OutputJava() || S.OutputC())
            {
                return;                                // cannot override operators in Java or C
            }
            // check for, get entry in operatorMap for fgs.OutputName
            if (!operatorMap.ContainsKey(fgs.OutputName))
            {
                return;
            }
            List <G25.Operator> opList = operatorMap[fgs.OutputName];

            // check if number of arguments matches
            foreach (G25.Operator op in opList)
            {
                if (op.NbArguments == fgs.NbArguments)
                {
                    // check if this operator already bound to function with the same arguments
                    string uniqueOpArgId = op.Symbol;
                    for (int a = 0; a < fgs.NbArguments; a++)
                    {
                        uniqueOpArgId += "~_~" + fgs.m_argumentTypeNames[a];
                    }
                    if (boundOperators.ContainsKey(uniqueOpArgId))
                    {
                        continue;
                    }
                    else
                    {
                        boundOperators[uniqueOpArgId] = true;
                    }

                    WriteOperatorShortcut(SB, S, cgd, FT, type, fgs, FAI, op);
                }
            }
        }
Ejemplo n.º 13
0
        private static void WriteOperatorShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type,
                                                  G25.fgs fgs, FuncArgInfo[] FAI, G25.Operator op)
        {
            // C# does not allow return type of ++ or -- to be different from input type
            if (S.OutputCSharp() &&
                (op.IsIncrement() || op.IsDecrement()) &&
                (fgs.ReturnTypeName != type.GetName()))
            {
                return;
            }


            string operatorCall = getOperatorCall(S, fgs, FAI);

            SB.AppendLine("");

            int nbTabs = 1;

            // output comment
            new Comment("operator for " + operatorCall).Write(SB, S, nbTabs);

            bool        inline         = false;
            bool        staticFunc     = true;
            string      returnType     = FT.GetMangledName(S, fgs.ReturnTypeName);
            FuncArgInfo returnArgument = null;

            SB.Append('\t', nbTabs);
            Functions.WriteDeclaration(SB, S, cgd,
                                       inline, staticFunc, returnType, "operator " + op.Symbol,
                                       returnArgument, FAI);
            SB.AppendLine(" {");

            SB.Append('\t', nbTabs + 1);
            SB.Append("return ");
            SB.Append(operatorCall);
            SB.AppendLine(";");

            SB.Append('\t', nbTabs);
            SB.AppendLine("}");
        }
Ejemplo n.º 14
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)
                m_fgs.m_argumentTypeNames = new String[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc) m_fgs.m_returnTypeName = m_gmv.Name; // dual(gmv) = gmv
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                // get symbolic result
                m_reverseValue = RefGA.Multivector.Reverse(tmpFAI[0].MultivectorValue[0]);
                m_n2Value = RefGA.Multivector.gp(m_reverseValue, tmpFAI[0].MultivectorValue[0], m_M);
                if (m_G25M.m_round) m_n2Value = m_n2Value.Round(1e-14);

                if (m_n2Value.HasSymbolicScalars() || (!m_n2Value.IsScalar()) || m_n2Value.IsZero())
                {
                    m_inverseValue = RefGA.Multivector.gp(m_reverseValue,
                        RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(new RefGA.BasisBlade(0, 1.0, m_normSquaredName))));
                }
                else
                {
                    m_inverseValue = RefGA.Multivector.gp(m_reverseValue, new RefGA.Multivector(1.0 / m_n2Value.RealScalarPart()));
                    m_n2Value = null;
                }

                // 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_inverseValue).GetName();
            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Writes a shortcut for 'type', 'fgs'.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Not used yet.</param>
        /// <param name="FT">Float point type of 'type'.</param>
        /// <param name="type">The type for which shortcuts should be written.</param>
        /// <param name="fgs"></param>
        /// <param name="FAI"></param>
        public static void WriteFunctionShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type,
                                                 G25.fgs fgs, FuncArgInfo[] FAI)
        {
            int nbTabs = 1;

            FuncArgInfo[] tailFAI = getTail(FAI);

            string shortcutCall = getShortcutCall(S, fgs, tailFAI);

            SB.AppendLine("");

            // output comment
            new Comment("shortcut to " + shortcutCall).Write(SB, S, nbTabs);

            bool        inline         = false;
            bool        staticFunc     = false;
            string      returnType     = FT.GetMangledName(S, fgs.ReturnTypeName);
            FuncArgInfo returnArgument = null;

            SB.Append('\t', nbTabs);
            Functions.WriteDeclaration(SB, S, cgd,
                                       inline, staticFunc, returnType, fgs.OutputName,
                                       returnArgument, tailFAI);
            SB.AppendLine(" {");

            SB.Append('\t', nbTabs + 1);
            SB.Append("return ");
            SB.Append(shortcutCall);
            SB.AppendLine(";");

            SB.Append('\t', nbTabs);
            SB.AppendLine("}");
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Instruction for generating code for an assignment to a variable, with an optional declration of that same variable.
 /// </summary>
 /// <param name="nbTabs">How many tabs to put in front of code.</param>
 /// <param name="T">Type of assigned variable.</param>
 /// <param name="FT">Floating point type of coordinates of assigned variable.</param>
 /// <param name="mustCast">When assigning to variable, should the coordinates be cast to FT?</param>
 /// <param name="value">The assigned value.</param>
 /// <param name="name">Name of assigned variable.</param>
 /// <param name="ptr">Is the assigned variable a pointer?</param>
 /// <param name="declareVariable">If true, code for declraring the variable is also generated.</param>
 /// <param name="postOp">'post operation'. Currently allows for global multiplier (<c>"*"</c>) or divisor (<c>"/"</c>).</param>
 /// <param name="postOpValue">Value to use with 'post operation' (currently must be scalar).</param>
 public AssignInstruction(int nbTabs, G25.VariableType T, G25.FloatType FT, bool mustCast, RefGA.Multivector value, String name, bool ptr, bool declareVariable, String postOp, RefGA.Multivector postOpValue)
     : this(nbTabs, T, FT, mustCast, value, name, ptr, declareVariable)
 {
     m_postOp      = postOp;
     m_postOpValue = postOpValue;
 }
Ejemplo n.º 17
0
        }         // end of WriteFunction

        /// <summary>
        /// Computes the return type for exp(smv).
        /// Sets m_returnTypeName and m_returnType.
        /// </summary>
        protected void ComputeReturnTypeExpSmv(G25.CG.Shared.FuncArgInfo[] FAI, G25.FloatType FT)
        {
            m_returnTypeName = m_fgs.ReturnTypeName;
            if (m_returnTypeName.Length == 0)
            {
                // find out returntype
                G25.SMV inputType = FAI[0].Type as G25.SMV;
                { // determine tight return type (i.e., keep repeating the geometric product of the input type until no more new basis blades are found)
                    // We want to known which basis blades are present in inputType-to-the-power-of-infinity
                    // So which bases blades will be present in the return type?
                    bool[] present = new bool[1 << m_specification.m_dimension];
                    {
                        bool[] tried = new bool[(1 << m_specification.m_dimension) * (1 << m_specification.m_dimension)];

                        // init 'present' with the inputType
                        for (int i = 0; i < inputType.NbCoordinates; i++)
                        {
                            present[inputType.Group(0)[i].bitmap] = true;
                        }

                        // combine bitmaps (gp) until no more new bitmaps found
                        bool newBBfound = true;
                        while (newBBfound)
                        {
                            newBBfound = false;
                            for (uint i = 0; i < present.Length; i++)
                            {
                                if (!present[i])
                                {
                                    continue;
                                }
                                for (uint j = 0; j < present.Length; j++)
                                {
                                    if (!present[j])
                                    {
                                        continue;
                                    }
                                    if (tried[j * (1 << m_specification.m_dimension) + i])
                                    {
                                        continue;
                                    }

                                    // remember that we tried this combo of input blades:
                                    tried[j * (1 << m_specification.m_dimension) + i] = true;

                                    RefGA.Multivector M = RefGA.Multivector.gp(new RefGA.Multivector(new RefGA.BasisBlade(i)),
                                                                               new RefGA.Multivector(new RefGA.BasisBlade(j)), m_G25M.m_metric);

                                    for (int k = 0; k < M.BasisBlades.Length; k++)
                                    {
                                        uint b = M.BasisBlades[k].bitmap;
                                        if (!present[b])
                                        { // this bitmap wasn't found yet, so mark it as present
                                            newBBfound = true;
                                            present[b] = true;
                                        }
                                    }
                                }
                            }
                        } // end of combine bitmaps (gp) until no more new bitmaps found
                    }

                    // construct multivector of return type, get return type
                    {
                        System.Collections.ArrayList L = new System.Collections.ArrayList();
                        for (uint i = 0; i < present.Length; i++)
                        {
                            if (!present[i])
                            {
                                continue;
                            }
                            else
                            {
                                L.Add(new RefGA.BasisBlade(i, 1.0, "c" + i));
                            }
                        }
                        RefGA.Multivector RTMV = new RefGA.Multivector(L);
                        m_returnType     = CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, RTMV) as G25.SMV;
                        m_returnTypeName = m_returnType.GetName();
                    }
                }
            } // end of 'find out return type name'
            else
            {
                m_returnType = m_specification.GetType(m_returnTypeName);
            }
        } // end of ComputeReturnTypeExpSmv()
Ejemplo n.º 18
0
 /// <summary>
 /// Instruction for generating code for an assignment to or a return of a variable.
 /// 
 /// This version of the constructor allows for a 'post operation' to be applied to the 'value'.
 /// Because Gaigen 2.5 cannot (yet) find common subexpressions, it is hard to generate code like
 ///     <code>
 ///     A.c[0] = (expr) / n2;
 ///     A.c[1] = (expr) / n2;
 ///     etc
 ///     </code>
 /// because the division will distribute to all terms of expr. So instead you'd get:
 ///     <code>
 ///     A.c[0] = (expr1 / n2) + (expr2 / n2) + ... +  (exprn / n2);
 ///     A.c[1] = (expr1 / n2) + (expr2 / n2) + ... +  (exprn / n2);
 ///     etc
 ///     </code>
 /// So this hack allows one to specify a post
 /// operator (currently multiplier (<c>"*"</c>) or divisor (<c>"/"</c>) and a value to use for that purpose.
 /// </summary>
 /// <param name="nbTabs">How many tabs to put in front of code.</param>
 /// <param name="T">Type of assigned variable.</param>
 /// <param name="FT">Floating point type of coordinates of assigned variable.</param>
 /// <param name="mustCast">When assigning to variable, should the coordinates be cast to FT?</param>
 /// <param name="value">The assigned value.</param>
 /// <param name="postOp">'post operation'. Currently allows for global multiplier (<c>"*"</c>) or divisor (<c>"/"</c>).</param>
 /// <param name="postOpValue">Value to use with 'post operation' (currently must be scalar).</param>
 public AssignOrReturnInstruction(int nbTabs, G25.VariableType T, G25.FloatType FT, bool mustCast, RefGA.Multivector value, string postOp, RefGA.Multivector postOpValue)
     : base(nbTabs)
 {
     m_type = T;
     m_floatType = FT;
     m_mustCast = mustCast;
     m_value = value;
     m_postOp = postOp;
     m_postOpValue = postOpValue;
 }
Ejemplo n.º 19
0
        /// <summary>
        /// Computes the return type for exp(smv).
        /// Sets m_returnTypeName and m_returnType.
        /// </summary>
        protected void ComputeReturnTypeExpSmv(G25.CG.Shared.FuncArgInfo[] FAI, G25.FloatType FT)
        {
            m_returnTypeName = m_fgs.ReturnTypeName;
            if (m_returnTypeName.Length == 0)
            {
                // find out returntype
                G25.SMV inputType = FAI[0].Type as G25.SMV;
                { // determine tight return type (i.e., keep repeating the geometric product of the input type until no more new basis blades are found)
                    // We want to known which basis blades are present in inputType-to-the-power-of-infinity
                    // So which bases blades will be present in the return type?
                    bool[] present = new bool[1 << m_specification.m_dimension];
                    {
                        bool[] tried = new bool[(1 << m_specification.m_dimension) * (1 << m_specification.m_dimension)];

                        // init 'present' with the inputType
                        for (int i = 0; i < inputType.NbCoordinates; i++)
                        {
                            present[inputType.Group(0)[i].bitmap] = true;
                        }

                        // combine bitmaps (gp) until no more new bitmaps found
                        bool newBBfound = true;
                        while (newBBfound)
                        {
                            newBBfound = false;
                            for (uint i = 0; i < present.Length; i++)
                            {
                                if (!present[i]) continue;
                                for (uint j = 0; j < present.Length; j++)
                                {
                                    if (!present[j]) continue;
                                    if (tried[j * (1 << m_specification.m_dimension) + i]) continue;

                                    // remember that we tried this combo of input blades:
                                    tried[j * (1 << m_specification.m_dimension) + i] = true;

                                    RefGA.Multivector M = RefGA.Multivector.gp(new RefGA.Multivector(new RefGA.BasisBlade(i)),
                                        new RefGA.Multivector(new RefGA.BasisBlade(j)), m_G25M.m_metric);

                                    for (int k = 0; k < M.BasisBlades.Length; k++)
                                    {
                                        uint b = M.BasisBlades[k].bitmap;
                                        if (!present[b])
                                        { // this bitmap wasn't found yet, so mark it as present
                                            newBBfound = true;
                                            present[b] = true;
                                        }
                                    }
                                }
                            }
                        } // end of combine bitmaps (gp) until no more new bitmaps found
                    }

                    // construct multivector of return type, get return type
                    {
                        System.Collections.ArrayList L = new System.Collections.ArrayList();
                        for (uint i = 0; i < present.Length; i++)
                        {
                            if (!present[i]) continue;
                            else L.Add(new RefGA.BasisBlade(i, 1.0, "c" + i));
                        }
                        RefGA.Multivector RTMV = new RefGA.Multivector(L);
                        m_returnType = CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, RTMV) as G25.SMV;
                        m_returnTypeName = m_returnType.GetName();
                    }
                }
            } // end of 'find out return type name'
            else
            {
                m_returnType = m_specification.GetType(m_returnTypeName);
            }
        }
Ejemplo n.º 20
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()
        {
            // get info on # arguments
            m_isUnit = IsApplyUnitVersor(m_fgs) || IsApplyVersorWI(m_fgs); // unit or inverse provided?
            NB_ARGS  = GetNbArgs(m_fgs);                                   // number of arguments (2 or 3)

            // fill in ArgumentTypeNames
            if (m_fgs.ArgumentTypeNames.Length == 0)
            {
                m_fgs.m_argumentTypeNames = new String[NB_ARGS];
                for (int i = 0; i < NB_ARGS; i++)
                {
                    m_fgs.m_argumentTypeNames[i] = 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_gmvFunc = !(tmpFAI[0].IsScalarOrSMV() && tmpFAI[1].IsScalarOrSMV());


            m_versorMv  = (G25.MV)tmpFAI[0].Type;
            m_subjectMv = (G25.MV)tmpFAI[1].Type;
            if (tmpFAI.Length > 2)
            {
                m_inverseVersorMv = (G25.MV)tmpFAI[2].Type;
            }

            { // get symbolic result
                // get grade of input blade:
                m_inputGradeUsage = tmpFAI[1].MultivectorValue[0].GradeUsage();

                // get basic transformed value
                m_versorValue        = tmpFAI[0].MultivectorValue[0];
                m_reverseVersorValue = (IsApplyVersorWI(m_fgs)) ? tmpFAI[2].MultivectorValue[0] : RefGA.Multivector.Reverse(m_versorValue);
                m_transformedValue   =
                    RefGA.Multivector.gp(
                        RefGA.Multivector.gp(m_versorValue, tmpFAI[1].MultivectorValue[0], m_M),
                        m_reverseVersorValue, m_M);


                // apply grade part selection
                m_transformedValue = m_transformedValue.ExtractGrade(RefGA.Multivector.GradeBitmapToArray(m_inputGradeUsage));

                // if rotor is not guaranteed by the user to be unit, compute norm squared
                if (!m_isUnit)
                {
                    m_n2Value = RefGA.Multivector.ip(m_reverseVersorValue, m_versorValue, m_M, RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION);
                }

                // round value if required by metric
                if (m_G25M.m_round)
                {
                    m_transformedValue = m_transformedValue.Round(1e-14);
                    if (m_n2Value != null)
                    {
                        m_n2Value = m_n2Value.Round(1e-14);
                    }
                }
            }

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;            // gmv * gmv / gmv = gmv
            }
            else
            {
                // 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_transformedValue).GetName();
                }
            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 21
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)
            {
                m_fgs.m_argumentTypeNames = new String[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name; // sin/cos/sinh/cosh/exp(gmv) = gmv
                m_returnType           = m_gmv;
                m_inputTypeName        = m_gmv.Name;
                m_returnTypeName       = m_gmv.Name;
            }
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                try // exceptions are caught below -> in that case, do a series for the SMV
                {   // sin/cos/sinh/cosh/exp(smv bivector)
                    RefGA.Multivector value       = tmpFAI[0].MultivectorValue[0];
                    RefGA.Multivector squareValue = RefGA.Multivector.gp(value, value, m_M);

                    String userSetSquare = m_fgs.GetOption("square");
                    if (userSetSquare != null)
                    {
                        m_signOfSquare = (int)Math.Sign(Double.Parse(userSetSquare));
                    }
                    else
                    {
                        // the following line can throw an exception, which is caught below
                        double sqEval = RefGA.Symbolic.SymbolicUtil.EvaluateRandomSymbolicToScalar(squareValue);
                        m_signOfSquare = (int)Math.Sign(sqEval);
                    }
                    m_scalarSquare = true;

                    // compute alpha = sqrt(fabs(value^2))
                    m_alphaValue = RefGA.Symbolic.UnaryScalarOp.Sqrt(RefGA.Symbolic.UnaryScalarOp.Abs(squareValue));

                    // use hyperbolic sin / cos or regular sin / cos for shortcuts?
                    bool hyperbolic =
                        (((IsExp(m_fgs) || IsCosh(m_fgs) || IsSinh(m_fgs)) && (m_signOfSquare > 0)) ||
                         ((IsCos(m_fgs) || IsSin(m_fgs)) && (m_signOfSquare < 0)));

                    // compute mul for SIN and EXP (assuming alpha is not zero)
                    if (IsCos(m_fgs) || m_alphaValue.IsZero())
                    {
                        m_mulValue = RefGA.Multivector.ONE;
                    }
                    else if (m_signOfSquare == 0)
                    {
                        m_mulValue = RefGA.Multivector.ZERO;
                    }
                    else
                    {
                        if (hyperbolic)
                        {
                            m_mulValue = RefGA.Multivector.gp(
                                RefGA.Symbolic.UnaryScalarOp.Sinh(new RefGA.Multivector(m_alphaName)),
                                RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(m_alphaName)));
                        }
                        else
                        {
                            m_mulValue = RefGA.Multivector.gp(
                                RefGA.Symbolic.UnaryScalarOp.Sin(new RefGA.Multivector(m_alphaName)),
                                RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(m_alphaName)));
                        }
                    }


                    // compute sin, cos part
                    RefGA.Multivector cosValue = null, sinValue = null;

                    if (m_signOfSquare == 0)
                    {
                        cosValue = RefGA.Multivector.ONE;
                        sinValue = value;
                    }
                    else
                    {
                        sinValue = RefGA.Multivector.gp(value, new RefGA.Multivector(m_mulName));
                        if (hyperbolic)
                        {
                            cosValue = RefGA.Symbolic.UnaryScalarOp.Cosh(new RefGA.Multivector(m_alphaName));
                        }
                        else
                        {
                            cosValue = RefGA.Symbolic.UnaryScalarOp.Cos(new RefGA.Multivector(m_alphaName));
                        }
                    }

                    // compute return value
                    if (IsExp(m_fgs))
                    {
                        m_returnValue = RefGA.Multivector.Add(cosValue, sinValue);
                    }
                    else if (IsCos(m_fgs) || IsCosh(m_fgs))
                    {
                        m_returnValue = cosValue;
                    }
                    else if (IsSin(m_fgs) || IsSinh(m_fgs))
                    {
                        m_returnValue = sinValue;
                    }

                    // get name of return type
                    if (m_fgs.m_returnTypeName.Length == 0)
                    {
                        m_returnType           = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue);
                        m_fgs.m_returnTypeName = m_returnType.GetName();
                    }
                    else
                    {
                        m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
                    }
                }
                catch (System.Exception)
                { // sin/cos/sinh/cosh/exp(any SMV)
                    // determine return type
                    ComputeReturnTypeExpSmv(tmpFAI, FT);
                    m_inputTypeName        = tmpFAI[0].TypeName;
                    m_fgs.m_returnTypeName = m_returnTypeName;
                }
            }
        } // end of CompleteFGS()
Ejemplo n.º 22
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)
            {
                m_fgs.m_argumentTypeNames = new String[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;            // unit(gmv) = gmv
            }
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                // get symbolic result
                RefGA.Multivector value        = tmpFAI[0].MultivectorValue[0];
                RefGA.Multivector reverseValue = RefGA.Multivector.Reverse(value);
                RefGA.Multivector n2Value      = RefGA.Multivector.gp(reverseValue, value, m_M);
                m_nValue = n2Value;
                if (!m_M.IsPositiveDefinite())
                {
                    m_nValue = RefGA.Symbolic.UnaryScalarOp.Abs(m_nValue);
                }
                m_nValue = RefGA.Symbolic.UnaryScalarOp.Sqrt(m_nValue);

                // round value if required by metric
                if (m_G25M.m_round)
                {
                    m_nValue = m_nValue.Round(1e-14);
                }

                try // try to m_nValue = evaluate(m_nValue)
                {
                    m_nValue = m_nValue.SymbolicEval(new RefGA.Symbolic.HashtableSymbolicEvaluator());
                }
                catch (ArgumentException) { }

                if (m_nValue.HasSymbolicScalars() || (!m_nValue.IsScalar()) || m_nValue.IsZero())
                {
                    RefGA.Multivector inverseNValue = RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(normName));
                    m_returnValue = RefGA.Multivector.gp(value, inverseNValue);
                }
                else
                { // no extra step required
                    m_returnValue = RefGA.Multivector.gp(value, new RefGA.Multivector(1.0 / m_nValue.RealScalarPart()));
                    m_nValue      = null;
                }

                // 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();
                }
            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 23
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;
                }
            }
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Instruction for generating code for returning a  variable.
 /// </summary>
 /// <param name="nbTabs">How many tabs to put in front of code.</param>
 /// <param name="T">Type of assigned variable.</param>
 /// <param name="FT">Floating point type of coordinates of assigned variable.</param>
 /// <param name="mustCast">When assigning to variable, should the coordinates be cast to FT?</param>
 /// <param name="value">The assigned value.</param>
 /// <param name="postOp">'post operation'. Currently allows for global multiplier (<c>"*"</c>) or divisor (<c>"/"</c>).</param>
 /// <param name="postOpValue">Value to use with 'post operation' (currently must be scalar).</param>
 public ReturnInstruction(int nbTabs, G25.VariableType T, G25.FloatType FT, bool mustCast, RefGA.Multivector value, String postOp, RefGA.Multivector postOpValue)
     :
     base(nbTabs, T, FT, mustCast, value, postOp, postOpValue)
 {
 }
Ejemplo n.º 25
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)
                m_fgs.m_argumentTypeNames = new string[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc) m_fgs.m_returnTypeName = m_gmv.Name; // unit(gmv) = gmv
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                // get symbolic result
                m_grade0Value = tmpFAI[0].MultivectorValue[0].ExtractGrade(0);
                m_grade2Value = tmpFAI[0].MultivectorValue[0].ExtractGrade(2);
                RefGA.Multivector reverseGrade2Value = RefGA.Multivector.Reverse(m_grade2Value);
                m_grade2norm2Value = RefGA.Multivector.gp(reverseGrade2Value, m_grade2Value, m_M);

                m_returnValue = RefGA.Multivector.gp(m_grade2Value, new RefGA.Multivector(mulName)); // where mulName = atan2(sqrt(grade2norm2), grade0) / sqrt(grade2norm2)

                // 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();

            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 26
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)
            {
                m_fgs.m_argumentTypeNames = new String[] { m_gmv.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_gmvFunc = !(tmpFAI[0].IsScalarOrSMV() && tmpFAI[1].IsScalarOrSMV());
            m_smv1    = tmpFAI[0].Type as G25.SMV;
            m_smv2    = tmpFAI[1].Type as G25.SMV;


            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;            // gmv * gmv = gmv
            }
            else
            {
                // compute return value
                if (IsInverse(m_fgs))
                {
                    m_returnValue = RefGA.Multivector.ihp(tmpFAI[0].MultivectorValue[0], tmpFAI[1].MultivectorValue[0]);
                }
                else
                {
                    m_returnValue = RefGA.Multivector.hp(tmpFAI[0].MultivectorValue[0], tmpFAI[1].MultivectorValue[0]);
                }

                bool getReturnType = (m_fgs.m_returnTypeName.Length == 0);

                // get name of return type
                if (getReturnType)
                {
                    m_fgs.m_returnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName();
                }

                // This code corrects the result for the signs of the basis blade, and loops until the return type converges.
                // The reason for this code is that the hadamard product is not well-defined when the basis blades of the operands and the result do not match.
                while (true)
                {
                    G25.VariableType returnType = m_specification.GetType(m_fgs.m_returnTypeName);
                    if (returnType is G25.SMV)
                    {
                        G25.SMV           returnSMV            = returnType as G25.SMV;
                        RefGA.Multivector unitReturnSmv        = returnSMV.ToMultivectorValue();
                        RefGA.Multivector correctedReturnValue = RefGA.Multivector.ihp(m_returnValue, unitReturnSmv);
                        if (getReturnType)
                        {
                            string newReturnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName();
                            if (newReturnTypeName == m_fgs.m_returnTypeName)
                            {
                                m_returnValue = correctedReturnValue;
                                break;
                            }
                            else
                            {
                                m_fgs.m_returnTypeName = newReturnTypeName;
                            }
                        }
                        else
                        {
                            m_returnValue = correctedReturnValue;
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Ejemplo n.º 27
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)
                m_fgs.m_argumentTypeNames = new String[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc) m_fgs.m_returnTypeName = m_gmv.Name; // unit(gmv) = gmv
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                // get symbolic result
                RefGA.Multivector value = tmpFAI[0].MultivectorValue[0];
                RefGA.Multivector reverseValue = RefGA.Multivector.Reverse(value);
                RefGA.Multivector n2Value = RefGA.Multivector.gp(reverseValue, value, m_M);
                m_nValue = n2Value;
                if (!m_M.IsPositiveDefinite())
                    m_nValue = RefGA.Symbolic.UnaryScalarOp.Abs(m_nValue);
                m_nValue = RefGA.Symbolic.UnaryScalarOp.Sqrt(m_nValue);

                // round value if required by metric
                if (m_G25M.m_round) m_nValue = m_nValue.Round(1e-14);

                try // try to m_nValue = evaluate(m_nValue)
                {
                    m_nValue = m_nValue.SymbolicEval(new RefGA.Symbolic.HashtableSymbolicEvaluator());
                }
                catch (ArgumentException) { }

                if (m_nValue.HasSymbolicScalars() || (!m_nValue.IsScalar()) || m_nValue.IsZero())
                {
                    RefGA.Multivector inverseNValue = RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(normName));
                    m_returnValue = RefGA.Multivector.gp(value, inverseNValue);
                }
                else
                { // no extra step required
                    m_returnValue = RefGA.Multivector.gp(value, new RefGA.Multivector(1.0 / m_nValue.RealScalarPart()));
                    m_nValue = null;
                }

                // 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();

            }
            m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
        }
Ejemplo n.º 28
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)
                m_fgs.m_argumentTypeNames = new String[] { 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_gmvFunc = !tmpFAI[0].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name; // sin/cos/sinh/cosh/exp(gmv) = gmv
                m_returnType = m_gmv;
                m_inputTypeName = m_gmv.Name;
                m_returnTypeName = m_gmv.Name;
            }
            else
            {
                m_smv = tmpFAI[0].Type as G25.SMV;

                try  // exceptions are caught below -> in that case, do a series for the SMV
                { // sin/cos/sinh/cosh/exp(smv bivector)
                    RefGA.Multivector value = tmpFAI[0].MultivectorValue[0];
                    RefGA.Multivector squareValue = RefGA.Multivector.gp(value, value, m_M);

                    String userSetSquare = m_fgs.GetOption("square");
                    if (userSetSquare != null) m_signOfSquare = (int)Math.Sign(Double.Parse(userSetSquare));
                    else
                    {
                        // the following line can throw an exception, which is caught below
                        double sqEval = RefGA.Symbolic.SymbolicUtil.EvaluateRandomSymbolicToScalar(squareValue);
                        m_signOfSquare = (int)Math.Sign(sqEval);
                    }
                    m_scalarSquare = true;

                    // compute alpha = sqrt(fabs(value^2))
                    m_alphaValue = RefGA.Symbolic.UnaryScalarOp.Sqrt(RefGA.Symbolic.UnaryScalarOp.Abs(squareValue));

                    // use hyperbolic sin / cos or regular sin / cos for shortcuts?
                    bool hyperbolic =
                            (((IsExp(m_fgs) || IsCosh(m_fgs) || IsSinh(m_fgs)) && (m_signOfSquare > 0)) ||
                            ((IsCos(m_fgs) || IsSin(m_fgs)) && (m_signOfSquare < 0)));

                    // compute mul for SIN and EXP (assuming alpha is not zero)
                    if (IsCos(m_fgs) || m_alphaValue.IsZero()) m_mulValue = RefGA.Multivector.ONE;
                    else if (m_signOfSquare == 0) m_mulValue = RefGA.Multivector.ZERO;
                    else
                    {
                        if (hyperbolic)
                            m_mulValue = RefGA.Multivector.gp(
                                                            RefGA.Symbolic.UnaryScalarOp.Sinh(new RefGA.Multivector(m_alphaName)),
                                                            RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(m_alphaName)));
                        else m_mulValue = RefGA.Multivector.gp(
                                                            RefGA.Symbolic.UnaryScalarOp.Sin(new RefGA.Multivector(m_alphaName)),
                                                            RefGA.Symbolic.UnaryScalarOp.Inverse(new RefGA.Multivector(m_alphaName)));
                    }

                    // compute sin, cos part
                    RefGA.Multivector cosValue = null, sinValue = null;

                    if (m_signOfSquare == 0)
                    {
                        cosValue = RefGA.Multivector.ONE;
                        sinValue = value;
                    }
                    else
                    {
                        sinValue = RefGA.Multivector.gp(value, new RefGA.Multivector(m_mulName));
                        if (hyperbolic) cosValue = RefGA.Symbolic.UnaryScalarOp.Cosh(new RefGA.Multivector(m_alphaName));
                        else cosValue = RefGA.Symbolic.UnaryScalarOp.Cos(new RefGA.Multivector(m_alphaName));
                    }

                    // compute return value
                    if (IsExp(m_fgs)) m_returnValue = RefGA.Multivector.Add(cosValue, sinValue);
                    else if (IsCos(m_fgs) || IsCosh(m_fgs)) m_returnValue = cosValue;
                    else if (IsSin(m_fgs) || IsSinh(m_fgs)) m_returnValue = sinValue;

                    // get name of return type
                    if (m_fgs.m_returnTypeName.Length == 0)
                    {
                        m_returnType = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue);
                        m_fgs.m_returnTypeName = m_returnType.GetName();
                    }
                    else
                    {
                        m_returnType = m_specification.GetType(m_fgs.m_returnTypeName);
                    }

                }
                catch (System.Exception)
                { // sin/cos/sinh/cosh/exp(any SMV)
                    // determine return type
                    ComputeReturnTypeExpSmv(tmpFAI, FT);
                    m_inputTypeName = tmpFAI[0].TypeName;
                    m_fgs.m_returnTypeName = m_returnTypeName;
                }

            }
        }
Ejemplo n.º 29
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.
        /// 
        /// As the return type is required, many functions will also compute the return value and other info 
        /// needed for generating the code inside this function. These intermediate values are then
        /// stored in class variables so they can be reused in WriteFunction()
        /// </summary>
        public override void CompleteFGS()
        {
            NB_ARGS = m_fgs.NbArguments; // all arguments must be explicitly listed

            // 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);

            { // compute return value
                RefGA.Multivector no = GetOrigin(m_specification, m_fgs);
                RefGA.Multivector ni = GetInfinity(m_specification, m_fgs);

                // compose a vector value (the Euclidean part)
                RefGA.Multivector vectorValue = RefGA.Multivector.ZERO;
                if ((IsRandom(m_specification, m_fgs)) || (IsCoordBased(m_specification, m_fgs, FT)))
                {
                    m_returnValue = no;
                    for (int i = 0; i < m_specification.m_dimension - 2; i++)
                    {
                        string bvName = "e" + (i + 1).ToString(); // todo: this assumes a fixed name for the basis vectors. Make these names options?
                        int bvIdx = m_specification.GetBasisVectorIndex(bvName);
                        if (bvIdx < 0)
                            throw new G25.UserException("Cannot find basis vector " + bvName, XML.FunctionToXmlString(m_specification, m_fgs));

                        RefGA.Multivector basisVector = RefGA.Multivector.GetBasisVector(bvIdx);

                        if (IsRandom(m_specification, m_fgs))
                            vectorValue = RefGA.Multivector.Add(vectorValue, RefGA.Multivector.gp(new RefGA.Multivector("ce" + (i + 1).ToString()), basisVector));
                        else vectorValue = RefGA.Multivector.Add(vectorValue, RefGA.Multivector.gp(tmpFAI[i].MultivectorValue[0], basisVector));
                    }
                }
                else if (IsVectorBased(m_specification, m_fgs, FT))
                {
                    vectorValue = tmpFAI[0].MultivectorValue[0];
                    m_vectorType = tmpFAI[0].Type;
                }
                else if (IsFlatPointBased(m_specification, m_fgs, FT))
                {
                    m_flatPointType = tmpFAI[0].Type as G25.SMV;
                    RefGA.BasisBlade.InnerProductType lc = RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION;
                    RefGA.Multivector noni = RefGA.Multivector.OuterProduct(no, ni);
                    // scale = no^ni . pointPair
                    RefGA.Multivector scale =
                        RefGA.Multivector.InnerProduct(noni, tmpFAI[0].MultivectorValue[0], m_M, lc).ScalarPart();
                    if (m_G25M.m_round) scale = scale.Round(1e-14);

                    // sphere = no . pointPair
                    RefGA.Multivector sphere = RefGA.Multivector.InnerProduct(no, tmpFAI[0].MultivectorValue[0], m_M, lc);
                    // normalizedSphere = sphere / scale

                    bool needToNormalize = (scale.HasSymbolicScalars() || (scale.RealScalarPart() != 1.0));
                    RefGA.Multivector normalizedSphere = (needToNormalize) ? RefGA.Multivector.gp(sphere, RefGA.Symbolic.UnaryScalarOp.Inverse(scale)) : sphere;

                    // keep only euclidean vectors
                    RefGA.Multivector euclMultivector = getSumOfUnitEuclideanBasisVectors();
                    // vector = sphere-noni
                    m_pointPairVectorValue = RefGA.Multivector.hp(normalizedSphere, euclMultivector);
                    // round vector
                    if (m_G25M.m_round) m_pointPairVectorValue = m_pointPairVectorValue.Round(1e-14);

                    // get type
                    m_vectorType = (G25.SMV)G25.CG.Shared.SpecializedReturnType.FindTightestMatch(m_specification, m_pointPairVectorValue, FT);
                    if (m_vectorType == null)
                    {
                        throw new G25.UserException("Missing Euclidean vector type; cannot construct conformal point from " + m_fgs.ArgumentTypeNames[0], XML.FunctionToXmlString(m_specification, m_fgs));
                    }

                    // get 'value' (just a reference to the name of the variable where m_pointPairVectorValue will be stored.
                    bool pointer = false;
                    vectorValue = Symbolic.SMVtoSymbolicMultivector(m_specification, (G25.SMV)m_vectorType, VECTOR_NAME, pointer);
                }
                else
                {
                    throw new G25.UserException("Invalid arguments specified.", XML.FunctionToXmlString(m_specification, m_fgs));
                }

                { // add no and 0.5 vectorValue^2 ni
                    RefGA.Multivector vectorValueSquared = RefGA.Multivector.scp(vectorValue, vectorValue);
                    RefGA.Multivector niPart = RefGA.Multivector.gp(
                        RefGA.Multivector.gp(vectorValueSquared, ni), 0.5);
                    m_returnValue = RefGA.Multivector.Add(RefGA.Multivector.Add(no, vectorValue), niPart);
                }
            } // end of compute return value

            // 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();
        }
Ejemplo n.º 30
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.
        ///
        /// As the return type is required, many functions will also compute the return value and other info
        /// needed for generating the code inside this function. These intermediate values are then
        /// stored in class variables so they can be reused in WriteFunction()
        /// </summary>
        public override void CompleteFGS()
        {
            NB_ARGS = m_fgs.NbArguments; // all arguments must be explicitly listed

            // 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);

            { // compute return value
                RefGA.Multivector no = GetOrigin(m_specification, m_fgs);
                RefGA.Multivector ni = GetInfinity(m_specification, m_fgs);

                // compose a vector value (the Euclidean part)
                RefGA.Multivector vectorValue = RefGA.Multivector.ZERO;
                if ((IsRandom(m_specification, m_fgs)) || (IsCoordBased(m_specification, m_fgs, FT)))
                {
                    m_returnValue = no;
                    for (int i = 0; i < m_specification.m_dimension - 2; i++)
                    {
                        string bvName = "e" + (i + 1).ToString(); // todo: this assumes a fixed name for the basis vectors. Make these names options?
                        int    bvIdx  = m_specification.GetBasisVectorIndex(bvName);
                        if (bvIdx < 0)
                        {
                            throw new G25.UserException("Cannot find basis vector " + bvName, XML.FunctionToXmlString(m_specification, m_fgs));
                        }

                        RefGA.Multivector basisVector = RefGA.Multivector.GetBasisVector(bvIdx);

                        if (IsRandom(m_specification, m_fgs))
                        {
                            vectorValue = RefGA.Multivector.Add(vectorValue, RefGA.Multivector.gp(new RefGA.Multivector("ce" + (i + 1).ToString()), basisVector));
                        }
                        else
                        {
                            vectorValue = RefGA.Multivector.Add(vectorValue, RefGA.Multivector.gp(tmpFAI[i].MultivectorValue[0], basisVector));
                        }
                    }
                }
                else if (IsVectorBased(m_specification, m_fgs, FT))
                {
                    vectorValue  = tmpFAI[0].MultivectorValue[0];
                    m_vectorType = tmpFAI[0].Type;
                }
                else if (IsFlatPointBased(m_specification, m_fgs, FT))
                {
                    m_flatPointType = tmpFAI[0].Type as G25.SMV;
                    RefGA.BasisBlade.InnerProductType lc = RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION;
                    RefGA.Multivector noni = RefGA.Multivector.OuterProduct(no, ni);
                    // scale = no^ni . pointPair
                    RefGA.Multivector scale =
                        RefGA.Multivector.InnerProduct(noni, tmpFAI[0].MultivectorValue[0], m_M, lc).ScalarPart();
                    if (m_G25M.m_round)
                    {
                        scale = scale.Round(1e-14);
                    }

                    // sphere = no . pointPair
                    RefGA.Multivector sphere = RefGA.Multivector.InnerProduct(no, tmpFAI[0].MultivectorValue[0], m_M, lc);
                    // normalizedSphere = sphere / scale

                    bool needToNormalize = (scale.HasSymbolicScalars() || (scale.RealScalarPart() != 1.0));
                    RefGA.Multivector normalizedSphere = (needToNormalize) ? RefGA.Multivector.gp(sphere, RefGA.Symbolic.UnaryScalarOp.Inverse(scale)) : sphere;

                    // keep only euclidean vectors
                    RefGA.Multivector euclMultivector = getSumOfUnitEuclideanBasisVectors();
                    // vector = sphere-noni
                    m_pointPairVectorValue = RefGA.Multivector.hp(normalizedSphere, euclMultivector);
                    // round vector
                    if (m_G25M.m_round)
                    {
                        m_pointPairVectorValue = m_pointPairVectorValue.Round(1e-14);
                    }

                    // get type
                    m_vectorType = (G25.SMV)G25.CG.Shared.SpecializedReturnType.FindTightestMatch(m_specification, m_pointPairVectorValue, FT);
                    if (m_vectorType == null)
                    {
                        throw new G25.UserException("Missing Euclidean vector type; cannot construct conformal point from " + m_fgs.ArgumentTypeNames[0], XML.FunctionToXmlString(m_specification, m_fgs));
                    }

                    // get 'value' (just a reference to the name of the variable where m_pointPairVectorValue will be stored.
                    bool pointer = false;
                    vectorValue = Symbolic.SMVtoSymbolicMultivector(m_specification, (G25.SMV)m_vectorType, VECTOR_NAME, pointer);
                }
                else
                {
                    throw new G25.UserException("Invalid arguments specified.", XML.FunctionToXmlString(m_specification, m_fgs));
                }

                { // add no and 0.5 vectorValue^2 ni
                    RefGA.Multivector vectorValueSquared = RefGA.Multivector.scp(vectorValue, vectorValue);
                    RefGA.Multivector niPart             = RefGA.Multivector.gp(
                        RefGA.Multivector.gp(vectorValueSquared, ni), 0.5);
                    m_returnValue = RefGA.Multivector.Add(RefGA.Multivector.Add(no, vectorValue), niPart);
                }
            } // end of compute return value

            // 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();
            }
        } // end of CompleteFGS()