Beispiel #1
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;
 }
Beispiel #2
0
        public static G25.VariableType CreateSyntheticSMVtype(Specification S, CGdata cgd, FloatType FT, RefGA.Multivector value)
        {
            // make up list of basis blades
            rsbbp.BasisBlade[] L = new rsbbp.BasisBlade[value.BasisBlades.Length];
            for (int i = 0 ; i < value.BasisBlades.Length; i++)
            {
                RefGA.BasisBlade B = value.BasisBlades[i];
                if (B.symScale == null) L[i] = new rsbbp.BasisBlade(new RefGA.BasisBlade(B.bitmap), B.scale); // constant value
                else L[i] = new rsbbp.BasisBlade(new RefGA.BasisBlade(B.bitmap)); // non-const value
            }

            // get other required info
            String name = "nameOfType";
            SMV.MULTIVECTOR_TYPE mvType = SMV.MULTIVECTOR_TYPE.MULTIVECTOR;
            String comment = "MISSING; PLEASE ADD TO SPECIFICATION";
            //String constantName = null;

            // create the type
            G25.SMV synSMV = new G25.SMV(name, L, mvType, comment);

            // throw exception
            throw new G25.UserException("Missing specialized multivector type.\n" +
                "Please add the following XML to the specification to fix the dependency:\n" +
                XML.SMVtoXmlString(S, synSMV));
        }
Beispiel #3
0
        /// <summary>
        /// Converts a <c>RefGA.Symbolic.BinaryScalarOpToLangString</c> to code.
        /// 
        /// Handles special cases (such as inversion) and understands floating point
        /// types (e.g., <c>fabsf()</c> is used for floats and <c>fabs()</c> is used for doubles in C.
        /// </summary>
        /// <param name="S">Used for output language.</param>
        /// <param name="FT">Floating point type used.</param>
        /// <param name="Op">The operation to convert to code.</param>
        /// <returns>Code for implementing <c>Op</c>c>.</returns>
        public static string BinaryScalarOpToLangString(G25.Specification S, G25.FloatType FT, RefGA.Symbolic.BinaryScalarOp Op)
        {
            string value1Str = ScalarOpValueToLangString(S, FT, Op.value1);
            string value2Str = ScalarOpValueToLangString(S, FT, Op.value2);

            return OpNameToLangString(S, FT, Op.opName) + "(" + value1Str + ", " + value2Str + ")";
        }
Beispiel #4
0
 protected void SanityCheckAllBladesPresent(RefGA.BasisBlade[][] L, int spaceDim, String[] bvNames, String domainOrRangeStr)
 {
     bool[] present = new bool[1 << spaceDim];
     for (int i = 0; i < L.Length; i++) {
         for (int j = 0; j < L[i].Length; j++)
         {
             present[L[i][j].bitmap] = true;
         }
     }
     for (int i = 0; i < present.Length; i++)
         if (!present[i])
             throw new G25.UserException("In outermorphism type " + Name + ":\n" +
                 "Missing basis blade '" + new RefGA.BasisBlade((uint)i).ToString(bvNames) + "' in " + domainOrRangeStr);
 }
Beispiel #5
0
        /// <summary>
        /// Converts a symbolic multivector value to a textual description of the specialized multivector 
        /// type that would be required to store that value. This is used for presenting error messages 
        /// to users when a suitable specialized type cannot be found for a specific multivector value.
        /// </summary>
        /// <param name="S">Specification, used for basis vector names.</param>
        /// <param name="value">The value to describe.</param>
        /// <returns>Textual description of the type that can store 'value'.</returns>
        public static String MultivectorToTypeDescription(G25.Specification S, RefGA.Multivector value)
        {
            StringBuilder SB = new StringBuilder();

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

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

                appendSpace = true;
            }
            return SB.ToString();
        }
Beispiel #6
0
 /// <summary>
 /// Returns the element index of basis blade 'B' or -1 when not represented by this MV.
 /// 
 /// Example: suppose you want to know the group and element index of B=e2^e3^no,
 /// then (assuming it is represented), it is in BasisBlade(groupIdx, elemIdx).
 /// </summary>
 /// <param name="B">The basis blade whose bitmap is looked up.</param>
 /// <returns>-1 if 'B' is cannot be represented by this MV, otherwise, the index of the element in the group.</returns>
 public int GetElementIdx(RefGA.BasisBlade B)
 {
     if ((B.bitmap >= m_bitmapToGroup.Length) || (m_bitmapToGroup[B.bitmap] < 0)) return -1;
     else return m_bitmapToGroup[B.bitmap] & 0xFFFF;
 }
Beispiel #7
0
 /// <returns>true if m_basisBlades matches 'L' (used to see if basis blades are in the default order and orientation).</returns>
 public bool CompareBasisBladeOrder(RefGA.BasisBlade[][] L)
 {
     if (L.Length != m_basisBlades.Length) return false;
     for (int i = 0; i < L.Length; i++)
     {
         if (L[i].Length != m_basisBlades[i].Length) return false;
         for (int j = 0; j < L[i].Length; j++)
             if ((L[i][j].CompareTo(m_basisBlades[i][j])) != 0)
                 return false;
     }
     return true;
 }
Beispiel #8
0
        private static void WriteGetCoordFunction(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

            string funcName = G25.CG.Shared.Main.GETTER_PREFIX + bladeName;

            string funcDecl = "\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + funcName + "() ";

            int nbTabs = 1;
            new G25.CG.Shared.Comment("Returns the " + bladeName + " coordinate of this " + gmvTypeName).Write(SB, S, nbTabs);

            SB.Append(funcDecl);
            SB.AppendLine(" {");
            SB.AppendLine("\t\treturn (m_c[" + groupIdx + "] == null) ? " +
                FT.DoubleToString(S, 0.0) + ": " +
                "m_c[" + groupIdx + "][" + elementIdx + "];");
            SB.AppendLine("\t}");
        }
Beispiel #9
0
        private static void WriteCoordExtractFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            String bladeName = B.ToLangString(S.m_basisVectorNames);

            string varName = "A";

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");

            string funcName = gmvTypeName + "_" + bladeName;

            string funcDecl = inlineStr + FT.type + " " + funcName + "(const " + gmvTypeName + " *" + varName + ")";

            string comment = "/** Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate of '" + varName + "' */";
            //                    declSB.AppendLine("/* group : " + groupIdx + " element: " + elementIdx + "*/");
            declSB.AppendLine(comment);
            declSB.Append(funcDecl);
            declSB.AppendLine(";");

            defSB.AppendLine("");
            defSB.Append(funcDecl);
            defSB.AppendLine(" {");
            defSB.AppendLine("\treturn (" + varName + "->gu & " + (1 << groupIdx) + ") ? " +
                varName + "->c[" + S.m_namespace + "_mvSize[" + varName + "->gu & " + ((1 << groupIdx) - 1) + "] + " + elementIdx + "] : " +
                FT.DoubleToString(S, 0.0) + ";");
            defSB.AppendLine("}");

            // add extract coord extract function for scalar
            if (B.Grade() == 0)
            {
                string floatFuncName = gmvTypeName + "_" + FT.type;
                string floatFuncDecl = inlineStr + FT.type + " " + floatFuncName + "(const " + gmvTypeName + " *" + varName + ")";

                declSB.AppendLine(comment);
                declSB.Append(floatFuncDecl);
                declSB.AppendLine(";");

                defSB.Append(floatFuncDecl);
                defSB.AppendLine(" {");
                defSB.AppendLine("\treturn " + funcName + "(" + varName + ");");
                defSB.AppendLine("}");
            }
        }
Beispiel #10
0
 /// <summary>
 /// Little helper function for the constructor.
 /// </summary>
 /// <returns>'basisBlades', but inside a newly allocated array of length 1.</returns>
 protected static RefGA.BasisBlade[][] ToDoubleArray(RefGA.BasisBlade[] basisBlades)
 {
     RefGA.BasisBlade[][] B = new RefGA.BasisBlade[1][];
     B[0] = basisBlades;
     return B;
 }
Beispiel #11
0
        private static void WriteSetCoordFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, StringBuilder SB,
            string gmvTypeName, int groupIdx, int elementIdx, int groupSize, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

            // do we inline this func?
            string inlineStr = "inline ";

            string funcName = MainGenerator.SETTER_PREFIX + bladeName;

            string coordName = "val";

            string funcDecl = "\t" + inlineStr + "void " + funcName + "(" + FT.type + " " + coordName + ") ";

            SB.AppendLine("\t/// Sets the " + bladeName + " coordinate of this " + gmvTypeName + ".");
            SB.Append(funcDecl);
            SB.AppendLine(" {");

            SB.AppendLine("\t\treserveGroup_" + groupIdx + "();");

            SB.AppendLine("\t\tm_c[" + S.m_namespace + "_mvSize[m_gu & " + ((1 << groupIdx) - 1) + "] + " + elementIdx + "] = " + coordName + ";");

            SB.AppendLine("\t}");
        }
Beispiel #12
0
 /// <summary>
 /// Returns the group index of basis blade 'B' or -1 when not represented by this MV.
 /// 
 /// Example: suppose you want to know the group and element index of B=e2^e3^no,
 /// then (assuming it is represented), it is in m_basisBlades[GetGroupIdx(B)][GetElementIdx(B)].
 /// </summary>
 /// <param name="B">The basis blade whose bitmap is looked up.</param>
 /// <returns>-1 if 'B' is cannot be represented by this MV, otherwise, the index of the group.</returns>
 public int GetGroupIdx(RefGA.BasisBlade B)
 {
     if ((B.bitmap >= m_bitmapToGroup.Length) || (m_bitmapToGroup[B.bitmap] < 0)) return -1;
     else return m_bitmapToGroup[B.bitmap] >> 16;
 }
Beispiel #13
0
 // false means 'not specialized'
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="name">The name of the multivector, for example "mv" or "rotor".</param>
 /// <param name="basisBlades">The basis blades, by group. Each entry in the array is a group of coordinates.</param>
 /// <param name="m">Memory allocation method.</param>
 public GMV(String name, RefGA.BasisBlade[][] basisBlades, MEM_ALLOC_METHOD m)
     : base(false, name, basisBlades)
 {
     m_memoryAllocationMethod = m;
 }
Beispiel #14
0
        /// <summary>
        /// Converts a <c>RefGA.Symbolic.UnaryScalarOp</c> to code.
        /// 
        /// Handles special cases (such as inversion) and understands floating point
        /// types (e.g., <c>fabsf()</c> is used for floats and <c>fabs()</c> is used for doubles in C.
        /// </summary>
        /// <param name="S">Used for output language.</param>
        /// <param name="FT">Floating point type used.</param>
        /// <param name="Op">The operation to convert to code.</param>
        /// <returns>Code for implementing <c>Op</c>c>.</returns>
        public static string UnaryScalarOpToLangString(G25.Specification S, G25.FloatType FT, RefGA.Symbolic.UnaryScalarOp Op)
        {
            string valueStr = ScalarOpValueToLangString(S, FT, Op.value);
            /*{
                if (!Op.value.IsScalar()) throw new Exception("G25.CG.Shared.BasisBlade.ScalarOpToLangString(): value should be scalar, found: " + Op.value.ToString(S.m_basisVectorNames));
                if (Op.value.IsZero()) valueStr = ScalarToLangString(S, FT, RefGA.BasisBlade.ZERO);
                else valueStr = ScalarToLangString(S, FT, Op.value.BasisBlades[0]);
            }*/

            if (Op.opName == UnaryScalarOp.INVERSE)
            {
                if (FT.type == "float") return "1.0f / (" + valueStr + ")";
                else if (FT.type == "double") return "1.0 / (" + valueStr + ")";
                else return FT.castStr + "1.0 / (" + valueStr + ")";
            }
            else
            {
                return OpNameToLangString(S, FT, Op.opName) + "(" + valueStr + ")";
            }
        }
Beispiel #15
0
        /// <summary>
        /// Converts a scalar basis blade (with optional symbolic part) to a string in the output language of <c>S</c>.
        /// 
        /// Some effort is made to output code which is close to that a human would write.
        /// </summary>
        /// <param name="S">Specification of algebra, used for output language, basis vector names, etc.</param>
        /// <param name="FT">Floating point type of output.</param>
        /// <param name="B">The basis blade.</param>
        /// <returns>String code representation of 'B'.</returns>
        public static string ScalarToLangString(G25.Specification S, G25.FloatType FT, RefGA.BasisBlade B)
        {
            string symScaleStr = "";
            { // convert symbolic part
                if (B.symScale != null)
                {
                    // symbolic scalar string goes in  symResult
                    System.Text.StringBuilder symResult = new System.Text.StringBuilder();
                    int tCnt = 0;
                    for (int t = 0; t < B.symScale.Length; t++) // for each term ...*...*...+
                    {
                        Object[] T = (Object[])B.symScale[t].Clone(); // clone 'T' because IsolateInverses() might alter it!
                        if (T != null) // if term is not null
                        {
                            // first find all scalarop inverses
                            // turn those into a new term, but without inverses?
                            Object[] TI = IsolateInverses(T);

                            // emit 'T'
                            int pCnt = EmitTerm(S, FT, T, tCnt, symResult);

                            if (TI != null)  // do we have to divide by a number of terms?
                            {
                                // emit '/(TI)'
                                symResult.Append("/(");
                                EmitTerm(S, FT, TI, 0, symResult);
                                symResult.Append(")");
                            }

                            if (pCnt > 0) tCnt++; // only increment number of terms when T was not empty
                        }
                    }

                    if (tCnt > 0)
                        symScaleStr = ((tCnt > 1) ? "(" : "") + symResult + ((tCnt > 1) ? ")" : "");
                }
            } // end of symbolic part

            // special cases when numerical scale is exactly +- 1
            if (B.scale == 1.0)
            {
                if (symScaleStr.Length > 0) return symScaleStr;
                else return FT.DoubleToString(S, 1.0);
            }
            else if (B.scale == -1.0)
            {
                if (symScaleStr.Length > 0) return "-" + symScaleStr;
                else return FT.DoubleToString(S, -1.0);
            }
            else
            {
                // get numerical part
                string numScaleStr = FT.DoubleToString(S, B.scale);

                // merge symbolic and numerical
                if (symScaleStr.Length > 0)
                    numScaleStr = numScaleStr + "*" + symScaleStr;

                // done
                return numScaleStr;
            }
        }
Beispiel #16
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;
        }
Beispiel #17
0
        /// <summary>
        /// Generates the code to assign a multivector value (which may have symbolic coordinates) to a specialized multivector.
        /// </summary>
        /// <param name="S">Specification of algebra. Used to known names of basis vector, output language, access strings, etc.</param>
        /// <param name="FT">Floating point type of destination.</param>
        /// <param name="mustCast">Set to true if a cast to 'FT' must be performed before assigned to 'dstName'.</param>
        /// <param name="dstSmv">Type of specialized multivector assigned to.</param>
        /// <param name="dstName">Name of specialized multivector assigned to.</param>
        /// <param name="dstPtr">Is the destination of pointer?</param>
        /// <param name="value">Multivector value to assign to the SMV. Must not contain basis blades inside the symbolic scalars.</param>
        /// <param name="nbTabs">Number of tabs to put before the code.</param>
        /// <param name="writeZeros">Some callers want to skip <c>"= 0.0"</c> assignments because they would be redundant. For
        /// example the caller may know that the destination is already set to zero. If so, set this argument to false and
        /// code for setting coordinates to 0 will not be generated.</param>
        /// <returns>String of code for dstName = value;</returns>
        public static string GenerateSMVassignmentCode(Specification S, FloatType FT, bool mustCast,
            G25.SMV dstSmv, String dstName, bool dstPtr, RefGA.Multivector value, int nbTabs, bool writeZeros)
        {
            RefGA.BasisBlade[] BL = BasisBlade.GetNonConstBladeList(dstSmv);
            string[] accessStr = GetAccessStr(S, dstSmv, dstName, dstPtr);
            string[] assignedStr = GetAssignmentStrings(S, FT, mustCast, BL, value, writeZeros);

            //int nbTabs = 1;
            return GenerateAssignmentCode(S, accessStr, assignedStr, nbTabs, writeZeros);
        }
Beispiel #18
0
        /// <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) ? ")" : "") +
                    ";";
            }
        }
Beispiel #19
0
 /// <summary>
 /// Computes which groups would be used to store the basis blades used in 'B'.
 /// </summary>
 /// <param name="B">A list of basis blades.</param>
 /// <returns>A bitmap representing the groups that would be used to store 'B'.</returns>
 public int GetGroupUsageBitmap(RefGA.BasisBlade[] B)
 {
     int gu = 0;
     foreach (BasisBlade b in B)
     {
         gu |= 1 << GetGroupIdx(b);
     }
     return gu;
 }
Beispiel #20
0
 /// <summary>
 /// Converts scalar part of 'value' to ouput language dependent string.
 /// </summary>
 private static string ScalarOpValueToLangString(G25.Specification S, G25.FloatType FT, RefGA.Multivector value)
 {
     if (!value.IsScalar()) throw new Exception("G25.CG.Shared.BasisBlade.ScalarOpValueToLangString(): value should be scalar, found: " + value.ToString(S.m_basisVectorNames));
     if (value.IsZero()) return ScalarToLangString(S, FT, RefGA.BasisBlade.ZERO);
     else return ScalarToLangString(S, FT, value.BasisBlades[0]);
 }
Beispiel #21
0
        // true means 'specialized'
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name">The name of the multivector, for example "mv" or "rotor".</param>
        /// <param name="basisBlades">The basis blades.</param>
        /// <param name="isConstant">Some coordinates may have constant values. If a coordinate is constant, its respective entry in isConstant is true (May be null).</param>
        /// <param name="constantValues">Some coordinates may have constant values. This array lists the values for each basis blade (May be null).</param>
        /// <param name="mvType">Type of multivector (</param>
        /// <param name="comment">A comment on the multivector type that may appear in the generated documentation. May be null.</param>
        public SMV(string name, RefGA.BasisBlade[] basisBlades, MULTIVECTOR_TYPE mvType, 
            bool[] isConstant, double[] constantValues, string comment)
            : base(true, name, ToDoubleArray(basisBlades))
        {
            // sanity check
            if (comment == null) comment = "";
            if (((isConstant != null) && (basisBlades.Length != isConstant.Length)) ||
                ((constantValues != null) && (basisBlades.Length != constantValues.Length)))
                throw new Exception("G25.SMV(): the 'isConstant' array or the 'constantValues' array do not match the length of the 'basisBlades' array");

            m_mvType = mvType;
            m_isConstant = (isConstant == null) ? new bool[basisBlades.Length]: (bool[])isConstant.Clone();
            m_constantValues = (constantValues == null) ? new double[basisBlades.Length] : (double[])constantValues.Clone();
            m_comment = comment;

            // count number of constant coordinates
            int nbConstant = GetNbConstantCoordinates();

            // sanity check number of constant coordinates
            /*if ((m_constantName != null) &&
                (nbConstant != basisBlades.Length) &&
                (nbConstant != m_constantValues.Length))
                throw new Exception("G25.SMV(): not all coordinates of the constant '" + m_constantName + "' are constant");*/

            InitConstBasisBladeIdx(nbConstant);
        }
Beispiel #22
0
 /// <summary>
 /// Constructor for a BasisBlade without a constant coordinate value
 /// </summary>
 public BasisBlade(RefGA.BasisBlade B)
 {
     m_basisBlade = B;
     m_isConstant = false;
     m_constantValue = 0.0;
 }
Beispiel #23
0
        private static void WriteGetCoordFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, StringBuilder SB,
            string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

            // do we inline this func?
            string inlineStr = "inline ";

            string funcName = MainGenerator.GETTER_PREFIX + bladeName;

            string funcDecl = "\t" + inlineStr + FT.type + " " + funcName + "() const";

            SB.AppendLine("\t/// Returns the " + bladeName + " coordinate of this " + gmvTypeName + ".");
            SB.Append(funcDecl);
            SB.AppendLine(" {");
            SB.AppendLine("\t\treturn (m_gu & " + (1 << groupIdx) + ") ? " +
                "m_c[" + S.m_namespace + "_mvSize[m_gu & " + ((1 << groupIdx) - 1) + "] + " + elementIdx + "] : " +
                FT.DoubleToString(S, 0.0) + ";");
            SB.AppendLine("\t}");
        }
Beispiel #24
0
 /// <summary>
 /// Constructor for a BasisBlade with a constant coordinate value
 /// </summary>
 /// <param name="B"></param>
 /// <param name="constantValue"></param>
 public BasisBlade(RefGA.BasisBlade B, double constantValue)
 {
     m_basisBlade = B;
     m_isConstant = true;
     m_constantValue = constantValue;
 }
Beispiel #25
0
 /// <summary>
 /// Substitutes all symbolic scalars for doubles (as evaluated by <paramref name="E"/>)
 /// and evaluates the symbolic ScalarOps. E.g. sqrt(2.0) would evaluate to 1.4142...
 /// </summary>
 /// <param name="E">SymbolicEvaluator used to evaluate the symbolic scalars</param>
 /// <returns></returns>
 public double SymbolicEval(RefGA.Symbolic.SymbolicEvaluator E)
 {
     Multivector A = m_value1.SymbolicEval(E);
     Multivector B = m_value2.SymbolicEval(E);
     if (!(A.IsScalar() && B.IsScalar())) throw new ArgumentException("BinaryScalarOp.SymbolicEval: argument is not scalar");
     double a = A.RealScalarPart();
     double b = B.RealScalarPart();
     if (m_opName == ATAN2)
     {
         return Math.Atan2(a, b);
     }
     else throw new ArgumentException("BinaryScalarOp.SymbolicEval: unknown opname " + m_opName);
 }
Beispiel #26
0
 /// <summary>
 /// Substitutes all symbolic scalars for doubles (as evaluated by <paramref name="E"/>)
 /// and evaluates the symbolic ScalarOps. E.g. sqrt(2.0) would evaluate to 1.4142...
 /// </summary>
 /// <param name="E">SymbolicEvaluator used to evaluate the symbolic scalars</param>
 /// <returns></returns>
 public double SymbolicEval(RefGA.Symbolic.SymbolicEvaluator E)
 {
     Multivector V = m_value.SymbolicEval(E);
     if (!V.IsScalar()) throw new ArgumentException("UnaryScalarOp.SymbolicEval: argument is not scalar");
     double v = V.RealScalarPart();
     if (m_opName == INVERSE) {
         if (v == 0.0) throw new ArgumentException("UnaryScalarOp.SymbolicEval: divide by zero");
         return 1.0 / v;
     }
     else if (m_opName == SQRT) {
         if (v < 0.0) throw new ArgumentException("UnaryScalarOp.SymbolicEval: square root of negative value");
         else return Math.Sqrt(v);
     }
     else if (m_opName == EXP) {
         return Math.Exp(v);
     }
     else if (m_opName == LOG) {
         if (v <= 0.0) throw new ArgumentException("UnaryScalarOp.SymbolicEval: logarithm of value <= 0");
         else return Math.Log(v);
     }
     else if (m_opName == SIN) {
         return Math.Sin(v);
     }
     else if (m_opName == COS) {
         return Math.Cos(v);
     }
     else if (m_opName == TAN) {
         // how to detect bad input (1/2 pi, etc)?
         return Math.Tan(v);
     }
     else if (m_opName == SINH)
     {
         return Math.Sinh(v);
     }
     else if (m_opName == COSH)
     {
         return Math.Cosh(v);
     }
     else if (m_opName == TANH)
     {
         return Math.Tanh(v);
     }
     else if (m_opName == ABS)
     {
         return Math.Abs(v);
     }
     else throw new ArgumentException("UnaryScalarOp.SymbolicEval: unknown opname " + m_opName);
 }
Beispiel #27
0
        private static void WriteSetCoordFunction(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            string gmvTypeName, int groupIdx, int elementIdx, int groupSize, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

            string funcName = G25.CG.Shared.Main.SETTER_PREFIX + bladeName;

            string coordName = "val";

            string funcDecl = "\t" + Keywords.PublicAccessModifier(S) + " void " + funcName + "(" + FT.type + " " + coordName + ") ";

            SB.AppendLine("\t/// Sets the " + bladeName + " coordinate of this " + gmvTypeName + ".");
            SB.Append(funcDecl);
            SB.AppendLine(" {");

            SB.AppendLine("\t\t" + GetReserveGroupString(S, groupIdx) + "();");

            SB.AppendLine("\t\tm_c[" + groupIdx + "][" + elementIdx + "] =  " + coordName + ";");

            SB.AppendLine("\t}");
        }
Beispiel #28
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="name">The name of the multivector (typically smvom_gradeX_columnY.</param>
 /// <param name="basisBlades">The basis blades.</param>
 /// <param name="parentOM">Parent outermorphism this SMVOM belongs to.</param>
 /// <param name="gradeOM">The grade this SMVOM is for.</param>
 /// <param name="columnOM">The column of the OM matrix this SMVOM  is for.</param>
 public SMVOM(String name, RefGA.BasisBlade[] basisBlades, G25.OM parentOM,
     int gradeOM, int columnOM)
     : base(name, basisBlades, MULTIVECTOR_TYPE.MULTIVECTOR, null, null, null)
 {
     m_parentOM = parentOM;
     m_gradeOM = gradeOM;
     m_columnOM = columnOM;
 }
Beispiel #29
0
        private static void WriteCoordSetFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, string gmvTypeName, int groupIdx, int elementIdx, int groupSize, RefGA.BasisBlade B)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            String bladeName = B.ToLangString(S.m_basisVectorNames);

            string varName = "A";
            string coordName = bladeName + "_coord";

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");

            string funcName = gmvTypeName + "_set_" + bladeName;

            string funcDecl = inlineStr + "void " + funcName + "(" + gmvTypeName + " *" + varName + ", " + FT.type + " " + coordName  + ")";

            declSB.AppendLine("/** Sets the " + B.ToString(S.m_basisVectorNames) + " coordinate of '" + varName + "' */");
            declSB.Append(funcDecl);
            declSB.AppendLine(";");

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

            defSB.AppendLine("\t" + gmvTypeName + "_reserveGroup_" + groupIdx + "(" + varName + ");");
            defSB.AppendLine("\t" + varName + "->c[" + S.m_namespace + "_mvSize[" + varName + "->gu & " + ((1 << groupIdx) - 1) + "] + " + elementIdx + "] = " + coordName + ";");
            defSB.AppendLine("}");
        }
Beispiel #30
0
        /// <summary>
        /// Constructor. Do not use directly. Use the constructors of G25.GMV and
        /// G25.SMV instead.
        /// 
        /// If the multivector is specialized, basisBlades.Length must be 1.
        /// </summary>
        /// <param name="specialized">Whether this is a specialized MV or not.</param>
        /// <param name="name">The name of the multivector, for example "mv" or "rotor".</param>
        /// <param name="basisBlades">The basis blades, by group. Each entry in the array is a group of coordinates. 
        /// Specialized multivector have only one group.</param>
        protected MV(bool specialized, String name, RefGA.BasisBlade[][] basisBlades)
        {
            if (specialized && (basisBlades.Length != 1))
                throw new Exception("G25.MV(): specialized multivector classes must have one group");

            m_specialized = specialized;
            m_name = name;
            m_basisBlades = new RefGA.BasisBlade[basisBlades.Length][];
            for (int i = 0; i < basisBlades.Length; i++)
            {
                m_basisBlades[i] = (RefGA.BasisBlade[])basisBlades[i].Clone();
            }

            { // init m_bitmapToGroup
                // get maximum dimension used in any of the basis blades:
                int maxDim = 0;
                for (int i = 0; i < m_basisBlades.Length; i++)
                {
                    for (int j = 0; j < m_basisBlades[i].Length; j++)
                    {
                        int d = RefGA.Bits.HighestOneBit(m_basisBlades[i][j].bitmap);
                        if (d > maxDim) maxDim = d;
                    }
                }
                // allocate m_bitmapToGroup, set all to -1
                m_bitmapToGroup = new int[1 << (maxDim+1)];
                for (int i = 0; i < m_bitmapToGroup.Length; i++)
                    m_bitmapToGroup[i] = -1;

                // mark used position with group and element index
                for (int i = 0; i < m_basisBlades.Length; i++)
                    for (int j = 0; j < m_basisBlades[i].Length; j++)
                        m_bitmapToGroup[m_basisBlades[i][j].bitmap] = (i << 16) | j;
            }
        }