Beispiel #1
0
        } // end of ComputeOmInitFromVectorsPlan()

        /// <summary>
        /// Computes the signs for the plan as computed by GetOmInitFromVectorsPlan().
        ///
        /// Because the basis blades in the domain of 'om' do not have to be in canonical order,
        /// there may be some signs required to correctly executed the plan
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <param name="plan"></param>
        /// <returns>signs for the plan</returns>
        public static double[][] ComputeOmInitFromVectorsSigns(Specification S, OM om, uint[][][] plan)
        {
            double[][] result = new double[S.m_dimension + 1][];

            for (int g = 1; g <= S.m_dimension; g++)
            {
                result[g] = new double[om.DomainForGrade(g).Length];
                for (int d = 0; d < om.DomainForGrade(g).Length; d++)
                {
                    // get domain blade we have to construct
                    RefGA.BasisBlade D = om.DomainForGrade(g)[d];

                    // follow the plan to construct the blade
                    RefGA.BasisBlade P = RefGA.BasisBlade.ONE;
                    for (int p = 0; p < plan[g][d].Length; p++)
                    {
                        G25.Tuple <RefGA.BasisBlade, int, int> info = GetDomainBladeInfo(S, om, plan[g][d][p]);
                        P = RefGA.BasisBlade.op(P, info.Value1);
                    }

                    // compute sign difference & store
                    double s = D.scale / P.scale;
                    result[g][d] = s;
                }
            }

            return(result);
        } // end of ComputeOmInitFromVectorsSigns()
Beispiel #2
0
        /// <summary>
        /// Returns a dictionary (value -> coordinateAccessString) that can be used to initialize a general OM to identity.
        ///
        /// Use the dictionary as follows: foreach(string str in dictionary.value) generateCode{str = dictionary.key}
        /// </summary>
        public static Dictionary <double, List <string> > GetGomIdentityInitCode(Specification S, G25.GOM gom, string gomName, string matrixName)
        {
            Dictionary <double, List <string> > nonZero = new Dictionary <double, List <string> >(); // collect a.m[...] = value in here, by value
            string refStr = (S.OutputC()) ? gomName + "->" : "";

            // figure out which elements need to get something assigned
            // for all blades in the domain, find matching blade in range, and add it to nonZero
            for (int g = 1; g < S.m_GOM.Domain.Length; g++)
            {
                for (int d = 0; d < S.m_GOM.Domain[g].Length; d++)
                {
                    RefGA.BasisBlade D = S.m_GOM.Domain[g][d];
                    for (int r = 0; r < S.m_GOM.Range[g].Length; r++)
                    {
                        RefGA.BasisBlade R = S.m_GOM.Domain[g][r];

                        if (D.bitmap == R.bitmap)
                        {
                            double val      = D.scale / R.scale;
                            string coordStr = refStr + matrixName + g + "[" + (r * S.m_GOM.Domain[g].Length + d) + "]";
                            if (!nonZero.ContainsKey(val))
                            {
                                nonZero[val] = new List <string>();
                            }
                            nonZero[val].Add(coordStr);
                            continue; // no need to search other blades in range
                        }
                    }
                }
            } // end of loop over all grades of the OM
            return(nonZero);
        }
Beispiel #3
0
        /// <summary>
        /// Takes a general multivector specification (G25.GMV) and converts it into a one symbolic multivector per group/grade part.
        ///
        /// The symbolic weights of the multivector are the coordinates of the GMV, labelled according to 'gmvName'.
        /// Currently, the indices start at zero for each group.
        /// </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="gmv">The specification of the general multivector.</param>
        /// <param name="gmvName">Name the variable should have.</param>
        /// <param name="ptr">Is 'gmvName' a pointer? (not used currently)</param>
        /// <param name="groupIdx">Index of group/grade to convert (use -1 for all groups)</param>
        /// <returns></returns>
        public static RefGA.Multivector[] GMVtoSymbolicMultivector(Specification S, G25.GMV gmv, String gmvName, bool ptr, int groupIdx)
        {
            RefGA.Multivector[] R = new RefGA.Multivector[gmv.NbGroups];

            //String accessStr = (ptr) ? "->" : ".";

            for (int g = 0; g < gmv.NbGroups; g++)
            {
                if ((groupIdx >= 0) && (g != groupIdx))
                {
                    continue;                                     // only one group requested?
                }
                RefGA.BasisBlade[] B = gmv.Group(g);
                RefGA.BasisBlade[] L = new RefGA.BasisBlade[B.Length];
                for (int i = 0; i < B.Length; i++)
                {
                    RefGA.BasisBlade b             = B[i];
                    String           fullCoordName = gmvName + "[" + i + "]";
                    // merge
                    L[i] = new RefGA.BasisBlade(b.bitmap, b.scale, fullCoordName);
                }
                R[g] = new RefGA.Multivector(L);
            }

            return(R);
        } // end of function GMVtoSymbolicMultivector()
Beispiel #4
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 #5
0
 public static void GenerateBasisElementsArray(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB)
 {
     G25.GMV gmv = S.m_GMV;
     // basis vectors in basis elements
     SB.AppendLine("const int " + S.m_namespace + "_basisElements[" + (1 << S.m_dimension) + "][" + (S.m_dimension + 1) + "] = {");
     {
         bool comma = false;
         for (int i = 0; i < gmv.NbGroups; i++)
         {
             for (int j = 0; j < gmv.Group(i).Length; j++)
             {
                 if (comma)
                 {
                     SB.Append(",\n");
                 }
                 RefGA.BasisBlade B = gmv.Group(i)[j];
                 SB.Append("\t{");
                 for (int k = 0; k < S.m_dimension; k++)
                 {
                     if ((B.bitmap & (1 << k)) != 0)
                     {
                         SB.Append(k + ", ");
                     }
                 }
                 SB.Append("-1}");
                 comma = true;
             }
         }
     }
     SB.AppendLine("");
     SB.AppendLine("};");
 }
Beispiel #6
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()
Beispiel #7
0
        } // end of ComputeOmInitFromVectorsSigns()

        /// <summary>
        /// Returns info about <c>bitmap</c>.
        ///
        /// If bitmap is not in the domain of <c>om</c>, the basis blade in the returned value will be null,
        /// and the domainIdx will be -1.
        ///
        /// If the grade of the bitmap is 1, the domainIdx will be -1 because it is
        /// assumed to be an input vector.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <param name="bitmap"></param>
        /// <returns><c>BasisBlade, grade, domainIdx</c> for <c>bitmap</c></returns>
        public static G25.Tuple <RefGA.BasisBlade, int, int> GetDomainBladeInfo(Specification S, OM om, uint bitmap)
        {
            int grade = (int)RefGA.Bits.BitCount(bitmap);

            if (grade == 1)  // basis vector
            {
                return(new G25.Tuple <RefGA.BasisBlade, int, int>(new RefGA.BasisBlade(bitmap), grade, -1));
            }

            // find the bitmap in the domain
            RefGA.BasisBlade B = null;
            int domainIdx      = -1;

            for (int i = 0; i < om.DomainForGrade(grade).Length; i++)
            {
                if (bitmap == om.DomainForGrade(grade)[i].bitmap)
                {
                    domainIdx = i;
                    B         = om.DomainForGrade(grade)[i];
                    break;
                }
            }

            return(new G25.Tuple <RefGA.BasisBlade, int, int>(B, grade, domainIdx));
        } // end of GetDomainBladeInfo()
Beispiel #8
0
        } // end of WriteSet()

        /// <summary>
        /// Writes a function to set an SMV struct to an array of specified coordinates, for all floating point types.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB  = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            declSB.AppendLine("");
            defSB.AppendLine("");

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    if (smv.NbNonConstBasisBlade == 0)
                    {
                        continue;
                    }

                    string typeName = FT.GetMangledName(S, smv.Name);
                    string funcName = typeName + "_setArray";
                    bool   mustCast = false;

                    string[] argTypename = new string[1] {
                        FT.type
                    };
                    string[] argName = new string[1] {
                        "A"
                    };

                    System.Collections.ArrayList L = new System.Collections.ArrayList();
                    for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
                    {
                        RefGA.BasisBlade B = smv.NonConstBasisBlade(i);
                        //argTypename[i] = FT.type;
                        String coordStr = argName[0] + "[" + i + "]";
                        //argName[i] = coordStr;
                        L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr));
                    }
                    RefGA.Multivector mvValue = new RefGA.Multivector(L);


                    G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options
                    F.InitArgumentPtrFromTypeNames(S);
                    F.SetArgumentPtr(0, true);                                                                                         // first argument is a pointer to array

                    bool computeMultivectorValue             = false;
                    G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue);
                    int nbArgs = 1; // one array of coordinates
                    G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue);


                    declSB.AppendLine("/** Sets " + typeName + " to specified coordinates */");

                    bool staticFunc = false;
                    G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd,
                                                                    S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue);
                }
            }
        } // end of WriteSetArray()
Beispiel #9
0
        }         // end of WriteLargestCoordinateFunctions()

        /// <summary>
        /// Writes code to extract the scalar part of an SMV via a non-member function.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteExtractScalarPart(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB  = (S.m_inlineFunctions) ? cgd.m_inlineDefSB : cgd.m_defSB;

            declSB.AppendLine("");
            defSB.AppendLine("");

            const string smvName = "x";
            const bool   ptr     = false;

            RefGA.BasisBlade scalarBlade = RefGA.BasisBlade.ONE;
            string           inlineStr   = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineFunctions, " ");


            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    string[] AS = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, smvName, ptr);

                    string className   = FT.GetMangledName(S, smv.Name);
                    string funcName    = "_" + FT.type;
                    string altFuncName = "_Float";
                    string comment     = "/// Returns scalar part of  " + className;

                    declSB.AppendLine(comment);
                    string funcDecl = FT.type + " " + funcName + "(const " + className + " &" + smvName + ")";
                    declSB.Append(funcDecl);
                    declSB.AppendLine(";");

                    declSB.AppendLine(comment);
                    string altFuncDecl = FT.type + " " + altFuncName + "(const " + className + " &" + smvName + ")";
                    declSB.Append(G25.CG.Shared.Util.GetInlineString(S, true, " ") + altFuncDecl + " {return " + funcName + "(" + smvName + "); }");
                    declSB.AppendLine(";");

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

                        int    elementIdx = smv.GetElementIdx(scalarBlade);
                        double multiplier = (elementIdx >= 0) ? 1.0 / smv.BasisBlade(0, elementIdx).scale : 1.0;

                        if ((elementIdx >= 0) && (!smv.IsCoordinateConstant(elementIdx)))
                        {
                            string multiplerString = (multiplier != 1.0) ? (FT.DoubleToString(S, multiplier) + " * ") : "";
                            defSB.AppendLine("\treturn " + multiplerString + AS[smv.BladeIdxToNonConstBladeIdx(elementIdx)] + ";");
                        }
                        else
                        {
                            double constValue = (elementIdx >= 0) ? smv.ConstBasisBladeValue(smv.BladeIdxToConstBladeIdx(elementIdx)) : 0.0;
                            defSB.AppendLine("\treturn " + FT.DoubleToString(S, multiplier * constValue) + ";");
                        }
                        defSB.AppendLine("}");
                    }
                } // end of loop over all smvs
            }     // end of loop over all float types
        }         // end of WriteExtractScalarPart()
Beispiel #10
0
        /// <summary>
        /// Utility function which takes a specialized multivector and returns an array of its variable
        /// RefGA.BasisBlades. I.e., extracts 'smv.NonConstBasisBlade()'
        /// </summary>
        /// <param name="smv">Specialized multivector.</param>
        /// <returns>Array of non-constant basis blades of 'smv'.</returns>
        public static RefGA.BasisBlade[] GetNonConstBladeList(G25.SMV smv)
        {
            RefGA.BasisBlade[] BL = new RefGA.BasisBlade[smv.NbNonConstBasisBlade];

            for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
                BL[i] = smv.NonConstBasisBlade(i);

            return BL;
        }
Beispiel #11
0
        /// <summary>
        /// Utility function which takes a specialized multivector and returns an array of its variable
        /// RefGA.BasisBlades. I.e., extracts 'smv.NonConstBasisBlade()'
        /// </summary>
        /// <param name="smv">Specialized multivector.</param>
        /// <returns>Array of non-constant basis blades of 'smv'.</returns>
        public static RefGA.BasisBlade[] GetNonConstBladeList(G25.SMV smv)
        {
            RefGA.BasisBlade[] BL = new RefGA.BasisBlade[smv.NbNonConstBasisBlade];

            for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
                BL[i] = smv.NonConstBasisBlade(i);

            return BL;
        }
Beispiel #12
0
 /// <returns>'L' convert to a double array</returns>
 public static RefGA.BasisBlade[][] ListToDoubleArray(List <List <RefGA.BasisBlade> > L)
 {
     RefGA.BasisBlade[][] A = new RefGA.BasisBlade[L.Count][];
     for (int i = 0; i < L.Count; i++)
     {
         A[i] = L[i].ToArray();
     }
     return(A);
 }
Beispiel #13
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() + " */");
            }
        }
Beispiel #14
0
        } // end of WriteLargestCoordinateFunctions()

        /// <summary>
        /// Writes getters and setters for the SMV coordinates..
        /// </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 'SMV'.</param>
        /// <param name="smv">The specialized multivector for which the struct should be written.</param>
        public static void WriteGetSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv)
        {
            int    nbTabs    = 1;
            string className = FT.GetMangledName(S, smv.Name);

            // for variable coordinates:
            for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
            {
                RefGA.BasisBlade B          = smv.NonConstBasisBlade(i);
                string           name       = smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames);
                string           accessName = G25.CG.Shared.SmvUtil.GetCoordAccessString(S, smv, i);

                // get
                string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate.";
                new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs);
                SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + name + "() { return " + accessName + ";}");

                // set
                string setComment = "Sets the " + B.ToString(S.m_basisVectorNames) + " coordinate.";
                new G25.CG.Shared.Comment(setComment).Write(SB, S, nbTabs);
                SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " void " + G25.CG.Shared.Main.SETTER_PREFIX + name + "(" + FT.type + " " + name + ") { " + accessName + " = " + name + ";}");
            }

            // for constant coordinates:
            for (int i = 0; i < smv.NbConstBasisBlade; i++)
            {
                RefGA.BasisBlade B = smv.ConstBasisBlade(i);
                // get
                string getComment = "Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate.";
                new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs);
                SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, smv.ConstBasisBladeValue(i)) + ";}");
            }

            // write a getter for the scalar which returns 0 if no scalar coordinate is present
            if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0)
            {
                RefGA.BasisBlade B          = RefGA.BasisBlade.ONE;
                string           getComment = "Returns the scalar coordinate (which is always 0).";
                new G25.CG.Shared.Comment(getComment).Write(SB, S, nbTabs);
                SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + " " + G25.CG.Shared.Main.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() { return " + FT.DoubleToString(S, 0.0) + ";}");
            }

            // getter for the coordinates (stored in array)
            if ((S.m_coordStorage == COORD_STORAGE.ARRAY) && (smv.NbNonConstBasisBlade > 0))
            {
                string constantName = G25.CG.Shared.SmvUtil.GetCoordinateOrderConstant(S, smv);
                string COORD_ORDER  = "coordOrder";

                new G25.CG.Shared.Comment("Returns array of coordinates.").
                SetParamComment(COORD_ORDER, "pass the value '" + className + "." + constantName + "'").
                Write(SB, S, nbTabs);
                SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " " + FT.type + "[] c(" + G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM + " " + COORD_ORDER + ") { return m_c;}");
            }
        }
Beispiel #15
0
        } // end of WriteSet()

        /// <summary>
        /// Writes a function to set an SMV struct to an array of specified coordinates, for all floating point types.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            defSB.AppendLine("");

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    if (smv.NbNonConstBasisBlade == 0)
                    {
                        continue;
                    }

                    string className = FT.GetMangledName(S, smv.Name);
                    string funcName  = className + "::set";
                    bool   mustCast  = false;

                    string[] argTypename = new string[2] {
                        G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM, FT.type
                    };
                    string[] argName = new string[2] {
                        "co", "A"
                    };

                    System.Collections.ArrayList L = new System.Collections.ArrayList();
                    for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
                    {
                        RefGA.BasisBlade B        = smv.NonConstBasisBlade(i);
                        String           coordStr = argName[1] + "[" + i + "]";
                        L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr));
                    }
                    RefGA.Multivector mvValue = new RefGA.Multivector(L);

                    G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options
                    F.InitArgumentPtrFromTypeNames(S);
                    F.SetArgumentPtr(1, true);                                                                                         // second argument is a pointer to array

                    bool computeMultivectorValue = false;
                    int  NB_ARGS = 2; // enum + one array of coordinates
                    G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, null, computeMultivectorValue);

                    string dstName = G25.CG.Shared.SmvUtil.THIS;
                    bool   dstPtr  = true;

                    bool staticFunc = false;
                    G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd,
                                                                    S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue);
                }
            }
        } // end of WriteSetArray()
Beispiel #16
0
        /// <summary>
        /// Writes a function to set an SMV struct to specified coordinates, for all floating point types.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteSetCoords(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            defSB.AppendLine("");

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    if (smv.NbNonConstBasisBlade == 0)
                    {
                        continue;
                    }

                    string className = FT.GetMangledName(S, smv.Name);
                    string funcName  = className + "::set";
                    bool   mustCast  = false;


                    System.Collections.ArrayList L = new System.Collections.ArrayList();
                    int      NB_ARGS     = 1 + smv.NbNonConstBasisBlade;
                    string[] argTypename = new String[NB_ARGS];
                    string[] argName     = new String[NB_ARGS];
                    argTypename[0] = G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM;
                    argName[0]     = "co";
                    for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
                    {
                        RefGA.BasisBlade B = smv.NonConstBasisBlade(i);
                        argTypename[i + 1] = FT.type;
                        string coordStr = "_" + smv.GetCoordLangID(i, S, COORD_STORAGE.VARIABLES);
                        argName[i + 1] = coordStr;
                        L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr));
                    }
                    RefGA.Multivector mvValue = new RefGA.Multivector(L);


                    G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options
                    F.InitArgumentPtrFromTypeNames(S);
                    bool computeMultivectorValue = false;
                    //G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue);
                    G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, null, computeMultivectorValue);

                    string dstName = G25.CG.Shared.SmvUtil.THIS;
                    bool   dstPtr  = true;

                    bool staticFunc = false;
                    G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd,
                                                                    S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue);
                }
            }
        } // end of WriteSet()
Beispiel #17
0
 /// <returns>'L' convert to a double array</returns>
 public static RefGA.BasisBlade[][] ListToDoubleArray(List <List <G25.rsbbp.BasisBlade> > L)
 {
     RefGA.BasisBlade[][] A = new RefGA.BasisBlade[L.Count][];
     for (int i = 0; i < L.Count; i++)
     {
         A[i] = new RefGA.BasisBlade[L[i].Count];
         for (int j = 0; j < L[i].Count; j++)
         {
             A[i][j] = L[i][j].GetBasisBlade;
         }
     }
     return(A);
 }
Beispiel #18
0
        } // end of WriteLargestCoordinateFunctions()

        /// <summary>
        /// Writes code to extract the scalar part of an SMV via a non-member function.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteExtractScalarPart(Specification S, G25.CG.Shared.CGdata cgd)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB  = (S.m_inlineFunctions) ? cgd.m_inlineDefSB : cgd.m_defSB;

            declSB.AppendLine("");
            defSB.AppendLine("");

            const string gmvName = "x";

            RefGA.BasisBlade scalarBlade = RefGA.BasisBlade.ONE;
            string           inlineStr   = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineFunctions, " ");

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                string className   = FT.GetMangledName(S, gmv.Name);
                string funcName    = "_" + FT.type;
                string altFuncName = "_Float";
                string comment     = "/// Returns scalar part of  " + className;

                declSB.AppendLine(comment);
                string funcDecl = FT.type + " " + funcName + "(const " + className + " &" + gmvName + ")";
                declSB.Append(funcDecl);
                declSB.AppendLine(";");

                declSB.AppendLine(comment);
                string altFuncDecl = FT.type + " " + altFuncName + "(const " + className + " &" + gmvName + ")";
                declSB.Append(G25.CG.Shared.Util.GetInlineString(S, true, " ") + altFuncDecl + " {return " + funcName + "(" + gmvName + "); }");
                declSB.AppendLine(";");

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

                    int    elementIdx = gmv.GetElementIdx(scalarBlade);
                    double multiplier = 1.0 / gmv.BasisBlade(0, elementIdx).scale;

                    string multiplerString = (multiplier != 1.0) ? (FT.DoubleToString(S, multiplier) + " * ") : "";

                    // this line assumes that the scalar is the first element of the first group (which is a requirement).
                    defSB.AppendLine("\treturn ((x.gu() & 1) != 0) ? " + multiplerString + "x.getC()[0] : " + FT.DoubleToString(S, 0.0) + ";");

                    defSB.AppendLine("}");
                }
            } // end of loop over all float types
        }     // end of WriteExtractScalarPart()
Beispiel #19
0
        } // end of WriteSetZero()

        /// <summary>
        /// Writes a function to set an SMV struct to a scalar coordinate, for all floating point types which have a non-constant scalar coordinate.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteSetScalar(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB  = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            declSB.AppendLine("");
            defSB.AppendLine("");

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    // if (smv.NbNonConstBasisBlade == 0) continue;
                    if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0)
                    {
                        continue;                                              // if no scalar coordinate, continue
                    }
                    string typeName = FT.GetMangledName(S, smv.Name);
                    string funcName = typeName + "_setScalar";
                    bool   mustCast = false;


                    System.Collections.ArrayList L = new System.Collections.ArrayList();
                    const int NB_COORDS            = 1;
                    string[]  argTypename          = new string[NB_COORDS];
                    string[]  argName = new string[NB_COORDS];
                    {
                        RefGA.BasisBlade B = RefGA.BasisBlade.ONE;
                        argTypename[0] = FT.type;
                        argName[0]     = "scalarVal";
                        L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, argName[0]));
                    }
                    RefGA.Multivector mvValue = new RefGA.Multivector(L);

                    G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options
                    F.InitArgumentPtrFromTypeNames(S);
                    bool computeMultivectorValue = false;
                    G25.CG.Shared.FuncArgInfo   returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue);
                    G25.CG.Shared.FuncArgInfo[] FAI            = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_COORDS, FT, null, computeMultivectorValue);

                    declSB.AppendLine("/** Sets " + typeName + " to a scalar value */");

                    bool staticFunc = false;
                    G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd,
                                                                    S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue);
                }
            }
        }
Beispiel #20
0
        }         // end of WriteLargestCoordinateFunctions()

        /// <summary>
        /// Writes code to extract the scalar part of an SMV
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteExtractScalarPart(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB  = (S.m_inlineFunctions) ? cgd.m_inlineDefSB : cgd.m_defSB;

            declSB.AppendLine("");
            defSB.AppendLine("");

            const String smvName = "x";
            const bool   ptr     = true;

            RefGA.BasisBlade scalarBlade = new RefGA.BasisBlade(1.0);


            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    String[] AS = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, smvName, ptr);

                    String typeName = FT.GetMangledName(S, smv.Name);
                    String funcName = typeName + "_" + FT.type;

                    declSB.AppendLine("/** Returns scalar part of  " + typeName + " */");
                    String funcDecl = FT.type + " " + funcName + "(const " + typeName + " *" + smvName + ")";

                    declSB.Append(funcDecl);
                    declSB.AppendLine(";");

                    defSB.Append(funcDecl);
                    {
                        defSB.AppendLine(" {");
                        int scalarCoordIdx = smv.GetElementIdx(scalarBlade);
                        if (scalarCoordIdx >= 0)
                        {
                            double multiplier      = 1.0 / smv.BasisBlade(0, scalarCoordIdx).scale;
                            string multiplerString = (multiplier != 1.0) ? (FT.DoubleToString(S, multiplier) + " * "): "";
                            defSB.AppendLine("\treturn " + multiplerString + AS[scalarCoordIdx] + ";");
                        }
                        else
                        {
                            defSB.AppendLine("\treturn " + FT.DoubleToString(S, 0.0) + ";");
                        }
                        defSB.AppendLine("}");
                    }
                } // end of loop over all smvs
            }     // end of loop over all float types
        }         // end of WriteExtractScalarPart()
Beispiel #21
0
        public static void GenerateBasisElementsArray(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            string accessModifierArr = Keywords.ConstArrayAccessModifier(S);

            G25.GMV gmv = S.m_GMV;
            // basis vectors in basis elements
            new G25.CG.Shared.Comment("This array of integers contains the order of basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what basis vectors are in the basis element at position [x]?").Write(SB, S, 1);
            SB.Append("\tpublic " + accessModifierArr + " int[][] BasisElements = ");
            if (S.m_gmvCodeGeneration == GMV_CODE.EXPAND)
            {
                SB.AppendLine("new int[][] {");
                {
                    bool comma = false;
                    for (int i = 0; i < gmv.NbGroups; i++)
                    {
                        for (int j = 0; j < gmv.Group(i).Length; j++)
                        {
                            if (comma)
                            {
                                SB.Append(",\n");
                            }
                            RefGA.BasisBlade B = gmv.Group(i)[j];
                            SB.Append("\t\tnew int[] {");
                            for (int k = 0; k < S.m_dimension; k++)
                            {
                                if ((B.bitmap & (1 << k)) != 0)
                                {
                                    SB.Append(k + ", ");
                                }
                            }
                            SB.Append("-1}");
                            comma = true;
                        }
                    }
                }
                SB.AppendLine("");
                SB.AppendLine("\t};");
            }
            else
            {
                SB.AppendLine(G25.CG.CSJ.Util.GetFunctionName(S, "initBasisElementsArray") + "();");
                SB.AppendLine();

                cgd.m_cog.EmitTemplate(SB, "initBasisElementsArray", "S=", S);
            }
        }
Beispiel #22
0
        /// <summary>
        /// 'Plans' how to initialize an outermorphism from vector images.
        ///
        /// The plan is returned in the form of nested array <c>uint[grade][domain][plan steps]</c>.
        /// The <c>plan steps</c> are the bitmaps of the basis blades that should be wedged together
        /// to form the basis blade for <c>grade,domain</c>.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="om"></param>
        /// <returns>plan for initialization of <c>om</c> from vector images.</returns>
        public static uint[][][] ComputeOmInitFromVectorsPlan(Specification S, OM om)
        {
            // keep track of which basis blades are available (domain vectors are the input, so they are always available)
            bool[] availableBasisBlades = new bool[1 << S.m_dimension];
            for (int i = 0; i < om.DomainVectors.Length; i++)
            {
                availableBasisBlades[om.DomainVectors[i].bitmap] = true;
            }

            // for each grade, figure out how to construct the basis blades of that grade from basis blades which are already available
            uint[][][] result = new uint[S.m_dimension + 1][][];
            for (int g = 1; g <= S.m_dimension; g++)
            {
                result[g] = new uint[om.DomainForGrade(g).Length][];
                for (int d = 0; d < om.DomainForGrade(g).Length; d++)
                {
                    RefGA.BasisBlade D = om.DomainForGrade(g)[d];
                    // find the largest part of D which is already known
                    List <uint> plan   = new List <uint>();
                    uint        bitmap = D.bitmap;
                    while (bitmap != 0)
                    {
                        // find first bit, plan it, see if the rest is available
                        uint lowestBitIdx = (uint)RefGA.Bits.LowestOneBit(bitmap);
                        uint lowestBitmap = (uint)(1 << (int)lowestBitIdx);
                        plan.Add(lowestBitmap);
                        bitmap ^= lowestBitmap;

                        if (availableBasisBlades[bitmap]) // if remaining bitmap has already been computed, use that
                        {
                            plan.Add(bitmap);
                            bitmap ^= bitmap;
                        }
                    }

                    // plan for this basis blade is done:
                    result[g][d] = plan.ToArray();
                    availableBasisBlades[D.bitmap] = true;
                }
            }

            return(result);
        } // end of ComputeOmInitFromVectorsPlan()
Beispiel #23
0
        /// <returns>a list of basis blades in canonical order, sorted by grade.
        /// Each entry in the outer list contains the basis blades for that grade.</returns>
        public List <List <G25.rsbbp.BasisBlade> > GetDefaultBasisBlades()
        {
            // allocate list for each grade
            List <List <G25.rsbbp.BasisBlade> > L = new List <List <G25.rsbbp.BasisBlade> >();

            for (int i = 0; i < m_spec.m_dimension + 1; i++)
            {
                L.Add(new List <G25.rsbbp.BasisBlade>());
            }

            // enumerate over all basis blades, add them to respective lists
            for (uint b = 0; b < (1 << m_spec.m_dimension); b++)
            {
                RefGA.BasisBlade B = new RefGA.BasisBlade(b);
                L[B.Grade()].Add(new G25.rsbbp.BasisBlade(B));
            }

            return(L);
        }
Beispiel #24
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()
Beispiel #25
0
        /// <returns>'L' convert to a single array</returns>
        public static RefGA.BasisBlade[] ListToSingleArray(List <List <G25.rsbbp.BasisBlade> > L)
        {
            // count total number of basis blades
            int cnt = 0;

            for (int i = 0; i < L.Count; i++)
            {
                cnt += L[i].Count;
            }

            // allocate, copy basis blades
            RefGA.BasisBlade[] A = new RefGA.BasisBlade[cnt];
            int idx = 0;

            for (int i = 0; i < L.Count; i++)
            {
                for (int j = 0; j < L[i].Count; j++)
                {
                    A[idx++] = L[i][j].GetBasisBlade;
                }
            }
            return(A);
        }
Beispiel #26
0
        /// <summary>
        /// Takes a general multivector specification (G25.GMV) and converts it into a one symbolic multivector per group/grade part.
        /// 
        /// The symbolic weights of the multivector are the coordinates of the GMV, labelled according to 'gmvName'.
        /// Currently, the indices start at zero for each group.
        /// </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="gmv">The specification of the general multivector.</param>
        /// <param name="gmvName">Name the variable should have.</param>
        /// <param name="ptr">Is 'gmvName' a pointer? (not used currently)</param>
        /// <param name="groupIdx">Index of group/grade to convert (use -1 for all groups)</param>
        /// <returns></returns>
        public static RefGA.Multivector[] GMVtoSymbolicMultivector(Specification S, G25.GMV gmv, String gmvName, bool ptr, int groupIdx)
        {
            RefGA.Multivector[] R = new RefGA.Multivector[gmv.NbGroups];

            //String accessStr = (ptr) ? "->" : ".";

            for (int g = 0; g < gmv.NbGroups; g++) {
                if ((groupIdx >= 0) && (g != groupIdx)) continue; // only one group requested?

                RefGA.BasisBlade[] B = gmv.Group(g);
                RefGA.BasisBlade[] L = new RefGA.BasisBlade[B.Length];
                for (int i = 0; i < B.Length; i++)
                {
                    RefGA.BasisBlade b = B[i];
                    String fullCoordName = gmvName + "[" + i + "]";
                    // merge
                    L[i] = new RefGA.BasisBlade(b.bitmap, b.scale, fullCoordName);
                }
                R[g] = new RefGA.Multivector(L);
            }

            return R;
        }
Beispiel #27
0
        /// <summary>
        /// Writes getters and setters for the SMV coordinates..
        /// </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 'SMV'.</param>
        /// <param name="smv">The specialized multivector for which the struct should be written.</param>
        public static void WriteGetSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SMV smv)
        {
            // write variable coordinates
            for (int i = 0; i < smv.NbNonConstBasisBlade; i++)
            {
                string name       = smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames);
                string accessName = G25.CG.Shared.SmvUtil.GetCoordAccessString(S, smv, i);

                SB.AppendLine("\t/// Returns the " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate.");
                SB.AppendLine("\tinline " + FT.type + " " + MainGenerator.GETTER_PREFIX + name + "() const { return " + accessName + ";}");
                SB.AppendLine("\t/// Sets the " + smv.NonConstBasisBlade(i).ToString(S.m_basisVectorNames) + " coordinate.");
                SB.AppendLine("\tinline void " + MainGenerator.SETTER_PREFIX + name + "(" + FT.type + " " + name + ") { " + accessName + " = " + name + ";}");
            }

            // write constant coordinates
            for (int i = 0; i < smv.NbConstBasisBlade; i++)
            {
                RefGA.BasisBlade B = smv.ConstBasisBlade(i);
                SB.AppendLine("\t/// Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate.");
                SB.AppendLine("\tinline " + FT.type + " " + MainGenerator.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() const { return " + FT.DoubleToString(S, smv.ConstBasisBladeValue(i)) + ";}");
            }

            // write a getter for the scalar which returns 0 if no scalar coordinate is present
            if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0)
            {
                RefGA.BasisBlade B = RefGA.BasisBlade.ONE;
                SB.AppendLine("\t/// Returns the scalar coordinate (which is always 0).");
                SB.AppendLine("\tinline " + FT.type + " " + MainGenerator.GETTER_PREFIX + B.ToLangString(S.m_basisVectorNames) + "() const { return " + FT.DoubleToString(S, 0.0) + ";}");
            }

            // getter for the coordinates (stored in array)
            if ((S.m_coordStorage == COORD_STORAGE.ARRAY) && (smv.NbNonConstBasisBlade > 0))
            {
                SB.AppendLine("\t/// Returns array of coordinates.");
                SB.AppendLine("\tinline const " + FT.type + " *getC(" + G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM + ") const { return m_c;}");
            }
        }
Beispiel #28
0
        } // end of WriteSetZero()

        /// <summary>
        /// Writes a function to set an SMV struct to a scalar coordinate, for all floating point types which have a non-constant scalar coordinate.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteSetScalar(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv)
        {
            //if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) return; // if no scalar coordinate, continue

            cgd.m_defSB.AppendLine("");

            //string className = FT.GetMangledName(S, smv.Name);
            string funcName = GMV.GetSetFuncName(S);
            bool   mustCast = false;

            System.Collections.ArrayList L = new System.Collections.ArrayList();
            const int NB_COORDS            = 1;

            string[] argTypename = new String[NB_COORDS];
            string[] argName     = new String[NB_COORDS];
            {
                RefGA.BasisBlade B = RefGA.BasisBlade.ONE;
                argTypename[0] = FT.type;
                argName[0]     = "scalarVal";
                L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, argName[0]));
            }
            RefGA.Multivector mvValue = new RefGA.Multivector(L);

            G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options
            F.InitArgumentPtrFromTypeNames(S);
            bool computeMultivectorValue = false;

            G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_COORDS, FT, null, computeMultivectorValue);

            string dstName = G25.CG.Shared.SmvUtil.THIS;
            bool   dstPtr  = false;

            bool staticFunc = false;

            G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd,
                                                            S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue);
        }
Beispiel #29
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);
        }
Beispiel #30
0
        /// <returns>'L' convert to a single array</returns>
        public static RefGA.BasisBlade[] ListToSingleArray(List<List<G25.rsbbp.BasisBlade>> L)
        {
            // count total number of basis blades
            int cnt = 0;
            for (int i = 0; i < L.Count; i++) cnt += L[i].Count;

            // allocate, copy basis blades
            RefGA.BasisBlade[] A = new RefGA.BasisBlade[cnt];
            int idx = 0;
            for (int i = 0; i < L.Count; i++) {
                for (int j = 0; j < L[i].Count; j++)
                    A[idx++] = L[i][j].GetBasisBlade;
            }
            return A;
        }
Beispiel #31
0
        /// <summary>
        /// Writes the 'explicit' declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'.
        /// 
        /// This function is called by the non-explicit version of the function.
        /// </summary>
        public void WriteExFunction(FloatType FT, string exFuncName)
        {
            G25.SMV smv = m_specification.GetSMV(m_SMVname);

            string randFuncCall = FT.DoubleToString(m_specification, -1.0) + " + " + FT.DoubleToString(m_specification, 2.0) + " * " + m_randomScalarFunc[FT.type] + "()";

            // construct a explicit FGS
            string[] exArgumentTypeNames = new string[] { FT.type, FT.type, FT.type };
            string[] exVariableNames = { m_fgs.ArgumentVariableNames[0], MINIMUM_NORM, LARGEST_COORDINATE };
            fgs exFgs = new fgs(m_fgs.Name, m_fgs.OutputName, m_fgs.ReturnTypeName, exArgumentTypeNames, exVariableNames, m_fgs.FloatNames, m_fgs.MetricName, m_fgs.Comment, m_fgs.Options);
            exFgs.InitArgumentPtrFromTypeNames(m_specification);

            bool computeMultivectorValue = false;
            int nbArgs = 3;
            G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, exFgs, nbArgs, FT, FT.type, computeMultivectorValue);

            // because of lack of overloading, function names include names of argument types
            //G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, exFgs, FAI);
            G25.fgs CF = new G25.fgs(exFgs, exFuncName);
            //string exFuncName = funcName;

            // setup code to recursively call exFuncName
            string exFuncCall = "";
            {
                StringBuilder exFuncCallSB = new StringBuilder();
                if (!m_specification.OutputC())
                    exFuncCallSB.Append("return ");

                exFuncCallSB.Append(exFuncName);
                exFuncCallSB.Append("(");
                if (m_specification.OutputC())
                {
                    exFuncCallSB.Append(fgs.RETURN_ARG_NAME);
                    exFuncCallSB.Append(", ");
                }
                for (int i = 0; i < exVariableNames.Length; i++)
                {
                    if (i > 0) exFuncCallSB.Append(", ");
                    exFuncCallSB.Append(exVariableNames[i]);
                }
                exFuncCallSB.AppendLine(");");
                if (m_specification.OutputC())
                {
                    exFuncCallSB.AppendLine("return;");
                }
                exFuncCall = exFuncCallSB.ToString();
            }

            // generate a random SMV:
            RefGA.Multivector randomSMV = null;

            // get highest grade and bitmap of
            int hg = smv.HighestGrade(); // what is the highest non-zero grade of the type?
            uint bvBitmap = smv.BasisVectorBitmap(); // which basis vectors are used in the type?

            // setup random value to be returned
            if (InitWithRandomCoordinates(m_specification, smv))
            {
                // set all coordinates to random values
                randomSMV = RefGA.Multivector.ZERO;
                for (int b = 0; b < smv.NbNonConstBasisBlade; b++)
                {
                    randomSMV = RefGA.Multivector.Add(randomSMV,
                        RefGA.Multivector.gp(new RefGA.Multivector(smv.NonConstBasisBlade(b)),
                        new RefGA.Multivector("r" + smv.NonConstBasisBlade(b).ToLangString(m_specification.m_basisVectorNames))));
                }
            }
            else
            {
                // set to geometric product of random vectors
                randomSMV = RefGA.Multivector.ONE;
                RefGA.Multivector randomVector;
                RefGA.BasisBlade[] B = new RefGA.BasisBlade[(int)RefGA.Bits.BitCount(bvBitmap)];
                for (int g = 0; g < hg; g++)
                {
                    int cnt = 0;
                    for (int v = 0; v < m_specification.m_dimension; v++)
                    {
                        if ((bvBitmap & (uint)(1 << v)) != 0)
                        {
                            B[cnt] = new RefGA.BasisBlade((uint)(1 << v), 1.0, "r" + g + "_" + m_specification.m_basisVectorNames[v]);
                            cnt++;
                        }
                    }
                    randomVector = new RefGA.Multivector(B);
                    randomSMV = RefGA.Multivector.gp(randomSMV, randomVector, m_G25M.m_metric);
                }

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

            // setup instructions
            System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>();
            {
                int nbTabs = 1;

                if (!smv.IsConstant())
                {
                    string smvTypeName = FT.GetMangledName(m_specification, m_SMVname);

                    // SMV tmp;
                    // double n, mul, lc;
                    if (m_specification.OutputCppOrC())
                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, smvTypeName + " tmp;"));
                    else I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, smvTypeName + " tmp = new " + smvTypeName  + "();"));
                    I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " n, mul, lc;"));
                    I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, CodeUtil.GetBoolType(m_specification) + " nullBlade;"));

                    // double rCoord = randomValue(), ....;
                    StringBuilder randSB = new StringBuilder();
                    randSB.Append(FT.type);
                    randSB.Append(" ");
                    if (InitWithRandomCoordinates(m_specification, smv))
                    { // random coordinates
                        for (int b = 0; b < smv.NbNonConstBasisBlade; b++)
                        {
                            if (b > 0) randSB.Append(", ");
                            randSB.Append("r" + smv.NonConstBasisBlade(b).ToLangString(m_specification.m_basisVectorNames));
                            randSB.Append(" = ");
                            randSB.Append(randFuncCall);
                        }
                    }
                    else
                    { // random vectors
                        bool first = true;
                        for (int g = 0; g < hg; g++)
                        {
                            for (int v = 0; v < m_specification.m_dimension; v++)
                            {
                                if (!first) randSB.Append(", "); first = false;
                                if ((g > 0) && (v == 0))
                                {
                                    randSB.AppendLine(""); // newline
                                    randSB.Append("\t\t");
                                }
                                randSB.Append("r" + g + "_" + m_specification.m_basisVectorNames[v]);
                                randSB.Append(" = ");
                                randSB.Append(randFuncCall);
                            }
                        }
                    }
                    randSB.Append(";");
                    I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, randSB.ToString()));

                    // SMV tmp = random;
                    bool mustCast = false;
                    bool randomPtr = false;
                    bool declareRandom = false;
                    I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smv, FT, mustCast, randomSMV, "tmp", randomPtr, declareRandom));

                    // n = norm_ret_scalar(tmp);
                    string emp = (m_specification.OutputC()) ? "&" : "";
                    I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "n = " + m_normFunc[FT.type] + "(" + emp + "tmp);"));

                    // lc = largestCoordinate(tmp);
                    if (m_specification.OutputC())
                    {
                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "lc = " + smvTypeName + "_largestCoordinate(&tmp);"));
                    }
                    else
                    {
                        string lcStr = "largestCoordinate";
                        if (m_specification.OutputCSharp()) lcStr = "LargestCoordinate";
                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "lc = tmp." + lcStr + "();"));
                    }

                    // null = (n == 0) && (lc ! 0)
                    if ((m_smvType.MvType == SMV.MULTIVECTOR_TYPE.ROTOR) || (m_smvType.MvType == SMV.MULTIVECTOR_TYPE.VERSOR))
                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "nullBlade = " + (m_specification.OutputC() ? "0" : "false") + ";"));
                    else I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "nullBlade = ((n == " + FT.DoubleToString(m_specification, 0.0) + ") && (lc != " + FT.DoubleToString(m_specification, 0.0) + "));"));

                    // test minimumNorm
                    I.Add(new CommentInstruction(nbTabs, "Recurse if generated random value has a norm below user-supplied limit, unless this is a null blade"));
                    I.Add(new G25.CG.Shared.IfElseInstruction(nbTabs, "(n < " + exVariableNames[1] + ") && (!nullBlade)",
                        new List<Instruction>() {new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, exFuncCall)},  // if instructions
                        new List<Instruction>())); // else instructions

                    // compute multiplier
                    string lcCondition = "(lc * " + CodeUtil.OpNameToLangString(m_specification, FT, "abs") + "(mul)) > largestCoordinate ";
                    I.Add(new CommentInstruction(nbTabs, "Compute multiplier"));
                    I.Add(new G25.CG.Shared.IfElseInstruction(nbTabs, "n < " + FT.DoubleToString(m_specification, 0.0001),
                        new List<Instruction>() { new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, "mul = " + FT.DoubleToString(m_specification, 1.0) + ";") }, // if instructions
                        new List<Instruction>() { // else instructions
                            new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, "mul = " + exFgs.ArgumentVariableNames[0] + " * (" + randFuncCall + ") / n;"),
                            new CommentInstruction(nbTabs+1, "Test largest coordinate"),
                            new G25.CG.Shared.IfElseInstruction(nbTabs+1, lcCondition,
                                new List<Instruction>() { new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 2, exFuncCall) },  // if instructions
                                new List<Instruction>())
                        }));

                    // test largest coordinate
                    //I.Add(new CommentInstruction(nbTabs, "Test largest coordinate"));
                    //I.Add(new G25.CG.Shared.IfElseInstruction(nbTabs, lcCondition,
                    //   new List<Instruction>() { new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, exFuncCall) },  // if instructions
                    //    new List<Instruction>())); // else instructions

                    // return tmp*mul;
                    I.Add(new CommentInstruction(nbTabs, "Apply multiplier, return"));
                    RefGA.Multivector tmpValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, smv, "tmp", false);
                    RefGA.Multivector returnValue = RefGA.Multivector.gp(tmpValue, new RefGA.Multivector("mul"));
                    I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, smv, FT, mustCast, returnValue));
                } // end of '!IsConstant()'?
                else
                {
                    // the user wants a 'random' constant: simply return the constant itself.
                    RefGA.Multivector returnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, smv, "tmp", false);
                    bool mustCast = false;
                    I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, smv, FT, mustCast, returnValue));
                }

            }

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

            // generate comment
            Comment comment = new Comment(exFgs.AddUserComment("Returns random " + m_SMVname + " with a scale in the interval [0, scale)"));

            bool staticFunc = Functions.OutputStaticFunctions(m_specification);
            G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, CF, m_specification.m_inlineFunctions, staticFunc, exFuncName, FAI, I, comment);
        }
Beispiel #32
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() + " */");
            }
        }
Beispiel #33
0
        public static void WriteSetMatrix(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som, bool transpose)
        {
            int NB_ARGS = 1;
            string[] argTypes = new string[NB_ARGS];
            string[] argNames = new string[NB_ARGS];
            argTypes[0] = FT.type;
            argNames[0] = "M";

            // construct image values
            RefGA.Multivector[] imageValue = new RefGA.Multivector[som.DomainVectors.Length];
            for (int d = 0; d < som.DomainVectors.Length; d++)
            {
                //imageValue[d] = RefGA.Multivector.ZERO;
                RefGA.BasisBlade[] IV = new RefGA.BasisBlade[som.RangeVectors.Length];
                for (int r = 0; r < som.RangeVectors.Length; r++)
                {
                    int matrixIdx = (transpose) ? (d * som.RangeVectors.Length + r) : (r * som.DomainVectors.Length + d);
                    string entryName = argNames[0] + "[" + matrixIdx + "]";
                    IV[r] = new RefGA.BasisBlade(som.RangeVectors[r].bitmap, 1.0, entryName);
                }
                imageValue[d] = new RefGA.Multivector(IV);
            }

            string typeName = FT.GetMangledName(S, som.Name);
            string funcName = GetFunctionName(S, typeName, "set", "_setMatrix");
            if (transpose) funcName = funcName + "Transpose";

            //argNames[0] = "*" + argNames[0]; // quick hack: add pointer to name instead of type!
            G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options
            F.InitArgumentPtrFromTypeNames(S);
            if (S.OutputCppOrC())
                F.m_argumentPtr[0] = true;
            else F.m_argumentArr[0] = true;
            bool computeMultivectorValue = false;
            G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue);

            G25.CG.Shared.FuncArgInfo returnArgument = null;
            if (S.OutputC())
                returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue);

            // setup instructions
            List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>();
            {
                bool mustCast = false;
                int nbTabs = 1;
                string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS;
                bool dstPtr = S.OutputCppOrC();
                bool declareDst = false;
                for (int g = 1; g < som.Domain.Length; g++)
                {
                    for (int c = 0; c < som.DomainForGrade(g).Length; c++)
                    {
                        G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c];
                        RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c];
                        RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade
                        for (uint v = 0; v < som.DomainVectors.Length; v++)
                        {
                            if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0)
                            {
                                value = RefGA.Multivector.op(value, imageValue[v]);
                            }
                        }

                        I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames)));
                        I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst));
                    }
                }

            }

            Comment comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix.");
            bool writeDecl = (S.OutputC());
            bool staticFunc = false;
            G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl);
        }
Beispiel #34
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 #35
0
        /// <summary>
        /// Writes an equality test function for specialized multivectors
        /// </summary>
        /// <param name="FT"></param>
        /// <param name="FAI"></param>
        /// <param name="F"></param>
        /// <param name="comment"></param>
        protected void WriteEqualsFunction(FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment)
        {
            // setup instructions
            List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>();

            // get a basis blade list which contains all basis blades (this is used in conjunction with GetAssignmentStrings())
            RefGA.BasisBlade[] BL = new RefGA.BasisBlade[1 << m_specification.m_dimension];
            for (uint bitmap = 0; bitmap < (uint)BL.Length; bitmap++)
                BL[bitmap] = new RefGA.BasisBlade(bitmap);

            // get string to access the coordinates of each basis blade wrt to the basis
            bool mustCast = false;
            bool writeZeros = false;
            string[] assStr1 = G25.CG.Shared.CodeUtil.GetAssignmentStrings(m_specification, FT, mustCast, BL, FAI[0].MultivectorValue[0], writeZeros);
            string[] assStr2 = G25.CG.Shared.CodeUtil.GetAssignmentStrings(m_specification, FT, mustCast, BL, FAI[1].MultivectorValue[0], writeZeros);

            string BOOL = CodeUtil.GetBoolType(m_specification);
            string TRUE = CodeUtil.GetTrueValue(m_specification);
            string FALSE = CodeUtil.GetFalseValue(m_specification);

            { // setup instructions
                // get tmp storage for 'difference'
                int nbTabs = 1;
                bool dDeclared = false;

                // for each assStr, subtract the other, see if difference is within limits
                for (int i = 0; i < BL.Length; i++)
                {
                    if ((assStr1[i] == null) && (assStr2[i] == null)) continue;
                    else if (assStr1[i] == null)
                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs,
                            "if ((" + assStr2[i] + " < -" + FAI[2].Name + ") || (" + assStr2[i] + " > " + FAI[2].Name + ")) return " + FALSE + "; /* " + BL[i].ToString(m_specification.m_basisVectorNames) + " */"));
                    else if (assStr2[i] == null)
                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs,
                            "if ((" + assStr1[i] + " < -" + FAI[2].Name + ") || (" + assStr1[i] + " > " + FAI[2].Name + ")) return " + FALSE + "; /* " + BL[i].ToString(m_specification.m_basisVectorNames) + " */"));
                    else
                    {
                        if (!dDeclared)
                        {
                            // declare a variable 'd', but only if required
                            I.Insert(0, new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " d;"));
                            dDeclared = true;
                        }

                        I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs,
                            "d = " + assStr1[i] + " - " + assStr2[i] + "; " +
                            "if ((d < -" + FAI[2].Name + ") || (d > " + FAI[2].Name + ")) return " + FALSE + "; /* " + BL[i].ToString(m_specification.m_basisVectorNames) + " */"));
                    }
                }
                // finally, return 1 if all check were OK
                I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "return " + TRUE + ";"));
            }

            // because of lack of overloading, function names include names of argument types
            G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, F, FAI);
            m_funcName[FT.type] = CF.OutputName;

            // setup return type and argument:
            string returnTypeName = BOOL;
            G25.CG.Shared.FuncArgInfo returnArgument = null;

            // write function
            bool staticFunc = Functions.OutputStaticFunctions(m_specification);
            G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, F, m_specification.m_inlineFunctions, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment);
        }
Beispiel #36
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 #37
0
        /// <summary>
        /// Writes code to extract the scalar part of an SMV
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        public static void WriteExtractScalarPart(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineFunctions) ? cgd.m_inlineDefSB : cgd.m_defSB;
            declSB.AppendLine("");
            defSB.AppendLine("");

            const String smvName = "x";
            const bool ptr = true;
            RefGA.BasisBlade scalarBlade = new RefGA.BasisBlade(1.0);

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                foreach (G25.SMV smv in S.m_SMV)
                {
                    String[] AS = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, smvName, ptr);

                    String typeName = FT.GetMangledName(S, smv.Name);
                    String funcName = typeName + "_" + FT.type;

                    declSB.AppendLine("/** Returns scalar part of  " + typeName + " */");
                    String funcDecl = FT.type + " " + funcName + "(const " + typeName + " *" + smvName + ")";

                    declSB.Append(funcDecl);
                    declSB.AppendLine(";");

                    defSB.Append(funcDecl);
                    {
                        defSB.AppendLine(" {");
                        int scalarCoordIdx = smv.GetElementIdx(scalarBlade);
                        if (scalarCoordIdx >= 0)
                        {
                            double multiplier = 1.0 / smv.BasisBlade(0, scalarCoordIdx).scale;
                            string multiplerString = (multiplier != 1.0) ? (FT.DoubleToString(S, multiplier) + " * "): "";
                            defSB.AppendLine("\treturn " + multiplerString + AS[scalarCoordIdx] + ";");
                        }
                        else defSB.AppendLine("\treturn " + FT.DoubleToString(S, 0.0) + ";");
                        defSB.AppendLine("}");
                    }
                } // end of loop over all smvs
            } // end of loop over all float types
        }
Beispiel #38
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 #39
0
        /// <returns>a list of basis blades in canonical order, sorted by grade.
        /// Each entry in the outer list contains the basis blades for that grade.</returns>
        public List<List<G25.rsbbp.BasisBlade>> GetDefaultBasisBlades()
        {
            // allocate list for each grade
            List<List<G25.rsbbp.BasisBlade>> L = new List<List<G25.rsbbp.BasisBlade>>();
            for (int i = 0; i < m_spec.m_dimension + 1; i++)
                L.Add(new List<G25.rsbbp.BasisBlade>());

            // enumerate over all basis blades, add them to respective lists
            for (uint b = 0; b < (1 << m_spec.m_dimension); b++)
            {
                RefGA.BasisBlade B = new RefGA.BasisBlade(b);
                L[B.Grade()].Add(new G25.rsbbp.BasisBlade(B));
            }

            return L;
        }
Beispiel #40
0
        /// <summary>
        /// Writes a function to set a GOM struct according to vector images, for all floating point types.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        /// <param name="FT">Float type.</param>
        /// <param name="matrixMode">When true, generates code for setting from matrix instead of vector images.</param>
        /// <param name="transpose">When this parameter is true and <c>matrixMode</c> is true, generates code for setting from transpose matrix.</param>
        public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, bool matrixMode, bool transpose)
        {
            G25.GOM gom = S.m_GOM;

            // get the 'plan' on how to initialize all domain basis blades efficiently:
            uint[][][] plan = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsPlan(S, gom);
            double[][] signs = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsSigns(S, gom, plan);

            // get range vector type
            G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, gom);

            // setup array of arguments, function specification, etc
            int NB_ARGS = (matrixMode) ? 1 : gom.DomainVectors.Length;
            string[] argTypes = new string[NB_ARGS], argNames = new string[NB_ARGS];
            RefGA.Multivector[] symbolicBBvalues = new RefGA.Multivector[1 << S.m_dimension]; // symbolic basis blade values go here
            if (matrixMode)
            {
                argTypes[0] = FT.type;
                argNames[0] = "M";

                // convert matrix columns to symbolic Multivector values
                for (int d = 0; d < gom.DomainVectors.Length; d++)
                {
                    RefGA.BasisBlade[] IV = new RefGA.BasisBlade[gom.RangeVectors.Length];
                    for (int r = 0; r < gom.RangeVectors.Length; r++)
                    {
                        int matrixIdx = (transpose) ? (d * gom.RangeVectors.Length + r) : (r * gom.DomainVectors.Length + d);
                        string entryName = argNames[0] + "[" + matrixIdx + "]";
                        IV[r] = new RefGA.BasisBlade(gom.RangeVectors[r].bitmap, 1.0, entryName);
                    }
                    symbolicBBvalues[gom.DomainVectors[d].bitmap] = new RefGA.Multivector(IV);
                }
            }
            else
            {
                for (int d = 0; d < NB_ARGS; d++)
                {
                    argTypes[d] = rangeVectorType.Name;
                    argNames[d] = "i" + gom.DomainVectors[d].ToLangString(S.m_basisVectorNames);
                    bool ptr = S.OutputC();

                    symbolicBBvalues[gom.DomainVectors[d].bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr);
                }
            }

            // generate function names for all grades (basis blade names not included)
            string typeName = FT.GetMangledName(S, gom.Name);
            string[] funcNames = GetSetFromLowerGradeFunctionNames(S, FT, matrixMode);

            // setup instructions (for main function, and subfunctions for grades)
            List<G25.CG.Shared.Instruction> mainI = new List<G25.CG.Shared.Instruction>();
            List<G25.CG.Shared.Instruction>[] bladeI = new List<G25.CG.Shared.Instruction>[1 << S.m_dimension];
            {
                bool mustCast = false;
                int nbTabs = 1;
                string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS;
                bool dstPtr = S.OutputCppOrC();
                bool declareDst = false;
                for (int g = 1; g < gom.Domain.Length; g++)
                {

                    for (int d = 0; d < gom.DomainForGrade(g).Length; d++)
                    {
                        G25.SMVOM smvOM = gom.DomainSmvForGrade(g)[d];
                        RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d];

                        if (g > 1)
                        {
                            bladeI[domainBlade.bitmap] = new List<G25.CG.Shared.Instruction>();

                            string funcCallCode = funcNames[g] + "_" + d + "(";
                            if (S.OutputC()) funcCallCode += G25.fgs.RETURN_ARG_NAME;
                            funcCallCode += ");";
                            mainI.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, funcCallCode));
                        }

                        // follow the plan
                        RefGA.Multivector value = new RefGA.Multivector(signs[g][d]);
                        uint[] P = plan[g][d];
                        for (int p = 0; p < P.Length; p++)
                            value = RefGA.Multivector.op(value, symbolicBBvalues[P[p]]);

                        // add instructions
                        List<G25.CG.Shared.Instruction> I = (g == 1) ? mainI : bladeI[domainBlade.bitmap];
                        I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames)));
                        I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst));

                        // store symbolic value
                        symbolicBBvalues[domainBlade.bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, dstName, dstPtr);
                    }
                }
            }

            // output grade > 1 functions
            if (cgd.generateOmInitCode(FT.type))
            {
                for (int g = 2; g < gom.Domain.Length; g++)
                {
                    for (int d = 0; d < gom.DomainForGrade(g).Length; d++)
                    {
                        RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d];

                        string funcName = funcNames[g] + "_" + d;
                        G25.fgs F = new G25.fgs(funcName, funcName, "", new string[0], new string[0], new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options
                        //F.InitArgumentPtrFromTypeNames(S);

                        bool computeMultivectorValue = false;

                        G25.CG.Shared.FuncArgInfo returnArgument = null;
                        if (S.OutputC())
                            returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue);

                        int nbArgs = 0;
                        G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, S.m_GMV.Name, computeMultivectorValue);

                        Comment comment;
                        comment = new Comment("Sets grade " + g + " part of outermorphism matrix based on lower grade parts.");
                        bool inline = false; // do not inline this potentially huge function
                        bool staticFunc = false;
                        bool writeDecl = S.OutputC();
                        G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcName, returnArgument, FAI, bladeI[domainBlade.bitmap], comment, writeDecl);
                    }
                }
            }

            { // output grade 1 function
                G25.fgs F = new G25.fgs(funcNames[1], funcNames[1], "", argTypes, argNames, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options
                F.InitArgumentPtrFromTypeNames(S);
                if (matrixMode)
                {
                    F.m_argumentPtr[0] = S.OutputCppOrC();
                    F.m_argumentArr[0] = S.OutputCSharpOrJava();
                }

                bool computeMultivectorValue = false;

                G25.CG.Shared.FuncArgInfo returnArgument = null;
                if (S.OutputC())
                    returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue);

                G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue);

                Comment comment;
                if (!matrixMode) comment = new Comment("Sets " + typeName + " from images of the domain vectors.");
                else comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix");
                bool inline = false; // do not inline this potentially huge function
                bool staticFunc = false;
                bool writeDecl = S.OutputC();
                G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcNames[1], returnArgument, FAI, mainI, comment, writeDecl);
            }
        }
Beispiel #41
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 #42
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)
            {
                if (m_specification.m_GOM == null)
                {
                    throw new G25.UserException("No general outermorphism type defined, while it is required because the type of the first argument was unspecified.");
                }
                m_fgs.m_argumentTypeNames = new String[] { m_specification.m_GOM.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_om      = (G25.OM)tmpFAI[0].Type;
            m_mv      = (G25.MV)tmpFAI[1].Type;
            m_gmvFunc = !tmpFAI[1].IsScalarOrSMV();

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                m_fgs.m_returnTypeName = m_gmv.Name;           // gmv + gmv = gmv
            }
            else
            {
                RefGA.Multivector inputValue = tmpFAI[1].MultivectorValue[0];

                // Compute m_returnValue:
                // Replace each basis blade in 'inputValue' with its value under the outermorphism.
                m_returnValue = RefGA.Multivector.ZERO;
                for (int i = 0; i < inputValue.BasisBlades.Length; i++)
                {
                    // get input blade and domain for that grade
                    RefGA.BasisBlade   inputBlade   = inputValue.BasisBlades[i];
                    RefGA.BasisBlade[] domainBlades = m_om.DomainForGrade(inputBlade.Grade());
                    for (int c = 0; c < domainBlades.Length; c++)
                    {
                        // if a match is found in the domain, add range vector to m_returnValue
                        if (domainBlades[c].bitmap == inputBlade.bitmap)
                        {
                            bool ptr = m_specification.OutputC();
                            RefGA.Multivector omColumnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, m_om.DomainSmvForGrade(inputBlade.Grade())[c], tmpFAI[0].Name, ptr);
                            RefGA.Multivector inputBladeScalarMultiplier  = new RefGA.Multivector(new RefGA.BasisBlade(inputBlade, 0));
                            RefGA.Multivector domainBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(domainBlades[c], 0));
                            m_returnValue = RefGA.Multivector.Add(m_returnValue,
                                                                  RefGA.Multivector.gp(
                                                                      RefGA.Multivector.gp(omColumnValue, inputBladeScalarMultiplier),
                                                                      domainBladeScalarMultiplier));
                            break; // no need to search the other domainBlades too
                        }
                    }
                }

                // 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();
                }
            }
        }
Beispiel #43
0
 /// <returns>'L' convert to a double array</returns>
 public static RefGA.BasisBlade[][] ListToDoubleArray(List<List<RefGA.BasisBlade>> L)
 {
     RefGA.BasisBlade[][] A = new RefGA.BasisBlade[L.Count][];
     for (int i = 0; i < L.Count; i++)
         A[i] = L[i].ToArray();
     return A;
 }
Beispiel #44
0
        /// <summary>
        /// Converts a scalar basis blade (with optional symbolic part) to a string in the output language of <c>S</c>.
        ///
        /// Some effort is made to output code which is close to that a human would write.
        /// </summary>
        /// <param name="S">Specification of algebra, used for output language, basis vector names, etc.</param>
        /// <param name="FT">Floating point type of output.</param>
        /// <param name="B">The basis blade.</param>
        /// <returns>String code representation of 'B'.</returns>
        public static string ScalarToLangString(G25.Specification S, G25.FloatType FT, RefGA.BasisBlade B)
        {
            string symScaleStr = "";

            { // convert symbolic part
                if (B.symScale != null)
                {
                    // symbolic scalar string goes in  symResult
                    System.Text.StringBuilder symResult = new System.Text.StringBuilder();
                    int tCnt = 0;
                    for (int t = 0; t < B.symScale.Length; t++)       // for each term ...*...*...+
                    {
                        Object[] T = (Object[])B.symScale[t].Clone(); // clone 'T' because IsolateInverses() might alter it!
                        if (T != null)                                // if term is not null
                        {
                            // first find all scalarop inverses
                            // turn those into a new term, but without inverses?
                            Object[] TI = IsolateInverses(T);

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

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

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

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

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

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

                // done
                return(numScaleStr);
            }
        } // end of function ScalarToLangString
Beispiel #45
0
 /// <returns>'L' convert to a double array</returns>
 public static RefGA.BasisBlade[][] ListToDoubleArray(List<List<G25.rsbbp.BasisBlade>> L)
 {
     RefGA.BasisBlade[][] A = new RefGA.BasisBlade[L.Count][];
     for (int i = 0; i < L.Count; i++) {
         A[i] = new RefGA.BasisBlade[L[i].Count];
         for (int j = 0; j < L[i].Count; j++)
             A[i][j] = L[i][j].GetBasisBlade;
     }
     return A;
 }