예제 #1
0
        /// <summary>
        /// Writes code for return m_name.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Specification of algebra.</param>
        /// <param name="cgd">Not used yet.</param>
        public override void Write(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            if (m_type is G25.FloatType)
            {
                AppendTabs(SB);

                // Temp hack to override the float type:
                G25.FloatType FT = m_floatType; //m_type as G25.FloatType;

                // Should postops still be applied?  ApplyPostOp(S, plugins, cog, BL, valueStr);
                // Not required so far?
                SB.AppendLine(CodeUtil.GenerateScalarReturnCode(S, FT, m_mustCast, m_value));
            }
            else if (m_type is G25.SMV)
            {
                if (S.OutputC())
                {
                    bool ptr             = true;
                    bool declareVariable = false;
                    new AssignInstruction(m_nbTabs, m_type, m_floatType, m_mustCast, m_value, G25.fgs.RETURN_ARG_NAME, ptr, declareVariable, m_postOp, m_postOpValue).Write(SB, S, cgd);
                }
                else
                {
                    G25.SMV            smv = m_type as G25.SMV;
                    RefGA.BasisBlade[] BL  = BasisBlade.GetNonConstBladeList(smv);
                    bool     writeZeros    = true;
                    string[] valueStr      = CodeUtil.GetAssignmentStrings(S, m_floatType, m_mustCast, BL, m_value, writeZeros);

                    // apply post operation (like "/ n2")
                    ApplyPostOp(S, cgd, BL, valueStr);

                    SB.AppendLine(CodeUtil.GenerateReturnCode(S, smv, m_floatType, valueStr, m_nbTabs, writeZeros));
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Applies 'm_postOp m_postOpValue' to 'valueStr'.
        /// </summary>
        /// <param name="S">Specification of algebra.</param>
        /// <param name="cgd">Not used yet.</param>
        /// <param name="valueStr">The array of value strings to which the postop should be applied</param>
        /// <param name="BL">Not used yet. May be used later on to known what basis blade each valueStr refers to.</param>
        public void ApplyPostOp(Specification S, G25.CG.Shared.CGdata cgd, RefGA.BasisBlade[] BL, String[] valueStr)
        {
            if (m_postOp == null)
            {
                return;
            }

            // TODO: currently only for *= and /=

            // get string of value:
            string postOpValueStr;

            RefGA.Multivector sc = m_postOpValue.ScalarPart();
            if (sc.IsZero())
            {
                postOpValueStr = CodeUtil.ScalarToLangString(S, m_floatType, RefGA.BasisBlade.ZERO);
            }
            else
            {
                postOpValueStr = CodeUtil.ScalarToLangString(S, m_floatType, sc.BasisBlades[0]);
            }

            // apply "m_postOp postOpValueStr" to all valueStr
            for (int i = 0; i < valueStr.Length; i++)
            {
                valueStr[i] = "(" + valueStr[i] + ")" + m_postOp + ((m_mustCast) ? m_floatType.castStr : "") + "(" + postOpValueStr + ")";
            }
        }
예제 #3
0
        /// <summary>
        /// Takes a specialized multivector specification (G25.SMV) and converts it into a symbolic multivector.
        /// The symbolic weights of the multivector are the coordinates of the SMV, labelled according to 'smvName'.
        ///
        /// An example is <c>A.c[0]*e1 + A.c[1]*e2 + A.c[2]*e3</c>.
        /// </summary>
        /// <param name="S">Specification of the algebra. Used for the access convention (. or ->) and for how to name the coordinates ([0] or e1, e2, e3).</param>
        /// <param name="smv">The specification of the specialized multivector.</param>
        /// <param name="smvName">Name the variable should have.</param>
        /// <param name="ptr">Is 'smvName' a pointer? This changes the way the variable is accessed.</param>
        /// <returns></returns>
        public static RefGA.Multivector SMVtoSymbolicMultivector(Specification S, G25.SMV smv, string smvName, bool ptr)
        {
            int idx = 0; // index into 'L'

            RefGA.BasisBlade[] L = new RefGA.BasisBlade[smv.NbConstBasisBlade + smv.NbNonConstBasisBlade];


            string[] AL = CodeUtil.GetAccessStr(S, smv, smvName, ptr);
            // get non-const coords
            for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
            {
                // get basis blade of coordinate
                RefGA.BasisBlade B = smv.NonConstBasisBlade(i);

                // merge
                L[idx++] = new RefGA.BasisBlade(B.bitmap, B.scale, AL[i]);
            }

            // get const coords
            for (int i = 0; i < smv.NbConstBasisBlade; i++)
            {
                // get value of coordinate
                double value = smv.ConstBasisBladeValue(i);

                // get basis blade of coordinate
                RefGA.BasisBlade B = smv.ConstBasisBlade(i);

                // merge
                L[idx++] = new RefGA.BasisBlade(B.bitmap, B.scale * value);
            }

            return(new RefGA.Multivector(L));
        } // end of SMVtoSymbolicMultivector()
예제 #4
0
        /// <summary>
        /// Writes a zero or equality test function for general multivectors,
        /// based on CASN parts code.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd"></param>
        /// <param name="FT"></param>
        /// <param name="FAI"></param>
        /// <param name="F"></param>
        /// <param name="comment"></param>
        /// <param name="writeZero">When true, a function to test for zero is written.</param>
        /// <returns>full (mangled) name of generated function</returns>
        public static string WriteEqualsOrZeroOrGradeBitmapFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT,
                                                                    G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F,
                                                                    Comment comment, G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE funcType)
        {
            // setup instructions
            System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>();
            int nbTabs = 1;

            // write this function:
            string code = "";

            if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.EQUALS)
            {
                code = G25.CG.Shared.CANSparts.GetEqualsCode(S, cgd, FT, FAI);
            }
            else if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.ZERO)
            {
                code = G25.CG.Shared.CANSparts.GetZeroCode(S, cgd, FT, FAI);
            }
            else if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.GRADE_BITMAP)
            {
                code = G25.CG.Shared.CANSparts.GetGradeBitmapCode(S, cgd, FT, FAI);
            }

            // add one instruction (verbatim code)
            I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code));

            // because of lack of overloading, function names include names of argument types
            G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI);

            // setup return type and argument:
            string returnTypeName = null;

            if (S.OutputC())
            {
                returnTypeName = G25.IntegerType.INTEGER;
            }
            else
            {
                if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.GRADE_BITMAP)
                {
                    returnTypeName = G25.IntegerType.INTEGER;
                }
                else
                {
                    returnTypeName = CodeUtil.GetBoolType(S);
                }
            }

            G25.CG.Shared.FuncArgInfo returnArgument = null;

            // write function
            bool inline     = false; // never inline GMV functions
            bool staticFunc = Functions.OutputStaticFunctions(S);

            G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment);

            return(CF.OutputName);
        }
예제 #5
0
        /// <summary>
        /// Writes code for m_name = m_value.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Specification of algebra.</param>
        /// <param name="cgd">Not used yet.</param>
        public override void Write(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            if (m_type is G25.SMV)
            {
                G25.SMV dstSmv = m_type as G25.SMV;

                if (m_declareVariable)
                {
                    SB.AppendLine("/* cannot yet assign and declare SMV type at the same time */");
                }

                RefGA.BasisBlade[] BL        = BasisBlade.GetNonConstBladeList(dstSmv);
                string[]           accessStr = CodeUtil.GetAccessStr(S, dstSmv, m_name, m_ptr);
                bool     writeZeros          = true;
                string[] valueStr            = CodeUtil.GetAssignmentStrings(S, m_floatType, m_mustCast, BL, m_value, writeZeros);

                // apply post operation (like "/ n2")
                ApplyPostOp(S, cgd, BL, valueStr);

                SB.AppendLine(CodeUtil.GenerateAssignmentCode(S, accessStr, valueStr, m_nbTabs, writeZeros));
            }
            else if (m_type is G25.FloatType)
            {
                // temp hack to override float type.
                G25.FloatType FT = this.m_floatType; // m_type as G25.FloatType;

                AppendTabs(SB);

                if (m_declareVariable)
                { // also declare the variable right here?
                    // output "/t type "
                    SB.Append(FT.type + " ");
                }

                // output name = ....;
                RefGA.BasisBlade[] BL = new RefGA.BasisBlade[1] {
                    RefGA.BasisBlade.ONE
                };
                String[] accessStr = new String[1] {
                    m_name
                };
                bool     writeZeros = true;
                String[] valueStr   = CodeUtil.GetAssignmentStrings(S, FT, m_mustCast, BL, m_value, writeZeros);

                // apply post operation (like "/ n2")
                ApplyPostOp(S, cgd, BL, valueStr);

                SB.AppendLine(CodeUtil.GenerateAssignmentCode(S, accessStr, valueStr, 0, writeZeros));
            }
            else
            {
                SB.AppendLine("/* to do: implement " + GetType().ToString() + " for type " + m_type.GetType().ToString() + " */");
            }
        }
예제 #6
0
        } // end of GetAccessStr()

        /// <summary>
        /// Generates code for returning a scalar value. The input is a scalar-valued multivector.
        /// </summary>
        /// <param name="S">Specification (used for output language).</param>
        /// <param name="FT">Floating point type which must be returned.</param>
        /// <param name="mustCast">Set to true if the returned value must be cast to <c>FT</c>, that is
        /// if you are not sure that the multivector has the same float type as the return type <c>FT</c>.</param>
        /// <param name="value">The symbolic multivector value to be returned.</param>
        /// <returns>Code for returning a scalar value.</returns>
        public static string GenerateScalarReturnCode(Specification S, FloatType FT, bool mustCast, RefGA.Multivector value)
        {
            if (value.IsZero())
            {
                return("return " + FT.DoubleToString(S, 0.0) + ";");
            }
            else
            {
                return("return " +
                       ((mustCast) ? (FT.castStr + "(") : "") +
                       CodeUtil.ScalarToLangString(S, FT, value.BasisBlades[0]) +
                       ((mustCast) ? ")" : "") +
                       ";");
            }
        } // end of GenerateScalarReturnCode()
예제 #7
0
        /// <summary>
        /// Generates code to assign <c>value</c> to a variable whose coordinate order is specified by <c>BL</c>.
        ///
        /// For example, <c>BL</c> could be <c>[e1, e2, e3]</c> and the multivector value <c>[e1 - 2e3]</c>.
        /// Then the returned array would be <c>["1", "0", "-2"]</c>.
        ///
        /// Parts of <c>value</c> that cannot be assigned to <c>BL</c> are silently ignored.
        ///
        /// Possibly, at some point we would like to generate some kind of warning?
        /// </summary>
        /// <param name="S">Specification of algebra (not used yet).</param>
        /// <param name="FT">Floating point type of assigned variable (used for casting strings).</param>
        /// <param name="mustCast">Set to true if a cast to 'FT' must be performed.</param>
        /// <param name="BL">Basis blades of assigned variable.</param>
        /// <param name="value">Multivector value to assign to the list of basis blades.
        /// Must not contain basis blades inside the symbolic scalars of the RefGA.BasisBlades.</param>
        /// <param name="writeZeros">When true, <c>"0"</c> will be returned when no value should be assigned
        /// to some coordinate. <c>null</c> otherwise.</param>
        /// <returns>An array of strings which tell you what to assign to each coordinate.</returns>
        public static String[] GetAssignmentStrings(Specification S, FloatType FT, bool mustCast, RefGA.BasisBlade[] BL,
                                                    RefGA.Multivector value, bool writeZeros)
        {
            String[] assignedStr = new String[BL.Length];
            int      idx         = 0;

            // for each non-const coord, find out what value is (loop through all entries in value)
            foreach (RefGA.BasisBlade B in BL)
            {
                // find same basisblade in 'value'
                foreach (RefGA.BasisBlade C in value.BasisBlades)
                {
                    if (C.bitmap == B.bitmap) // match found: get assignment string
                    {
                        // compute D = inverse(B) . C;
                        RefGA.BasisBlade Bi = (new RefGA.BasisBlade(B.bitmap, 1.0 / B.scale)).Reverse();
                        RefGA.BasisBlade D  = RefGA.BasisBlade.scp(Bi, C);

                        if (mustCast)
                        {
                            assignedStr[idx] = FT.castStr + "(" + CodeUtil.ScalarToLangString(S, FT, D) + ")";
                        }
                        else
                        {
                            assignedStr[idx] = CodeUtil.ScalarToLangString(S, FT, D);
                        }
                        break;
                    }
                }

                if (writeZeros && (assignedStr[idx] == null)) // has an assignment string been set?
                {
                    // no assignment: simply assign "0"
                    assignedStr[idx] = FT.DoubleToString(S, 0.0);
                }

                idx++;
            }
            return(assignedStr);
        } // end of GetAssignmentStrings()