Пример #1
0
        /// <param name="S"></param>
        /// <param name="FT"></param>
        /// <param name="M"></param>
        /// <param name="d">1 -> generate dual, d = 0 -> generate undual</param>
        /// <param name="g1"></param>
        /// <param name="gd"></param>
        /// <param name="name1"></param>
        /// <param name="name2"></param>
        /// <param name="name3"></param>
        /// <returns>The code to compute a (un)dual at runtime using the geometric product tables.</returns>
        public static string GetRuntimeDualCode(G25.Specification S, G25.FloatType FT, G25.Metric M,
                                                int d, int g1, int gd,
                                                string name1, string name2, string name3)
        {
            // get pseudoscalar
            RefGA.Multivector I = RefGA.Multivector.GetPseudoscalar(S.m_dimension);
            if (d == 1) // if dual: use inverse I
            {
                I = RefGA.Multivector.VersorInverse(I, M.m_metric);
            }

            // get grade/group of pseudoscalar in GMV
            int g2 = S.m_GMV.GetGroupIdx(I.BasisBlades[0]);

            // get sign of pseudo scalar basis blade in GMV:
            double IbladeSign = S.m_GMV.Group(g2)[0].scale;

            string tmpArrayCode;

            if (S.OutputCppOrC())
            {
                tmpArrayCode = "\t" + FT.type + " " + name2 + "[1] = {" + FT.DoubleToString(S, IbladeSign * I.BasisBlades[0].scale) + "};\n";
            }
            else
            {
                tmpArrayCode = "\t\t" + FT.type + "[] " + name2 + " = new " + FT.type + "[]{" + FT.DoubleToString(S, IbladeSign * I.BasisBlades[0].scale) + "};\n\t";
            }

            return
                (tmpArrayCode +
                 "\t" + GPparts.GetGPpartFunctionName(S, FT, M, g1, g2, gd) + "(" + name1 + ", " + name2 + ", " + name3 + ");\n");
        }
Пример #2
0
        }         // end of WriteGMVtoSMVcopy()

        private static void WriteCoordExtractFunction(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB  = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

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

            string varName = "A";

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

            string funcName = gmvTypeName + "_" + bladeName;

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

            string comment = "/** Returns the " + B.ToString(S.m_basisVectorNames) + " coordinate of '" + varName + "' */";

//                    declSB.AppendLine("/* group : " + groupIdx + " element: " + elementIdx + "*/");
            declSB.AppendLine(comment);
            declSB.Append(funcDecl);
            declSB.AppendLine(";");

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

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

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

                defSB.Append(floatFuncDecl);
                defSB.AppendLine(" {");
                defSB.AppendLine("\treturn " + funcName + "(" + varName + ");");
                defSB.AppendLine("}");
            }
        }
Пример #3
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}");
        }
Пример #4
0
        }     // end of WriteGMVtoSMVcopy()

        private static void WriteGetCoordFunction(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
                                                  string gmvTypeName, int groupIdx, int elementIdx, RefGA.BasisBlade B)
        {
            string bladeName = B.ToLangString(S.m_basisVectorNames);

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

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

            int nbTabs = 1;

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

            SB.Append(funcDecl);
            SB.AppendLine(" {");
            SB.AppendLine("\t\treturn (m_c[" + groupIdx + "] == null) ? " +
                          FT.DoubleToString(S, 0.0) + ": " +
                          "m_c[" + groupIdx + "][" + elementIdx + "];");
            SB.AppendLine("\t}");
        }
Пример #5
0
        /// <summary>
        /// Writes a function to set an GOM struct to identity, for all floating point types.
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <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 point type of 'GOM'.</param>
        public static void WriteSetIdentity(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT)
        {
            SB.AppendLine("");

            string omName     = "a";
            string matrixName = "m_m"; // todo: centralize this name

            Dictionary <double, List <string> > nonZero = G25.CG.Shared.OMinit.GetGomIdentityInitCode(S, S.m_GOM, omName, matrixName);

            //string className = FT.GetMangledName(S, S.m_GOM.Name);
            string funcName = Util.GetFunctionName(S, "setIdentity");

            SB.AppendLine("\t" + Keywords.PublicAccessModifier(S) + " void " + funcName + "() {");
            for (int g = 1; g < S.m_GOM.Domain.Length; g++)
            {
                int s = S.m_GOM.Domain[g].Length * S.m_GOM.Range[g].Length;
                SB.AppendLine("\t\t" + G25.CG.Shared.Util.GetSetToZeroCode(S, FT, matrixName + g, s));
            } // end of loop over all grades of the OM

            // do the nonZero assignments:
            foreach (KeyValuePair <double, List <string> > kvp in nonZero)
            {
                SB.Append("\t\t");
                int cnt = 0;
                foreach (string coordStr in kvp.Value)
                {
                    SB.Append(coordStr + " = ");
                    cnt++;
                    if ((cnt % 8) == 0)
                    {
                        SB.Append("\n\t\t\t");
                    }
                }
                SB.AppendLine(FT.DoubleToString(S, kvp.Key) + ";");
            }

            SB.AppendLine("\t}");
        } // end of WriteSetIdentity()
Пример #6
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
Пример #7
0
        } // end of GetAssignmentStrings()

        /// <summary>
        /// Used internally by ScalarToLangString().
        ///
        /// Emits on term (+ ....) of a blade value. Contains some optimizations
        /// to avoid stuff like <c>+-1.0</c>.
        /// </summary>
        protected static int EmitTerm(G25.Specification S, G25.FloatType FT, Object[] T, int tCnt, StringBuilder symResult)
        {
            // make stuff below a function
            bool plusEmitted = false;
            int  pCnt        = 0;              // number of non-null terms in 'T'

            for (int p = 0; p < T.Length; p++) // for each product ...*
            {
                if (T[p] != null)
                {
                    if ((!plusEmitted) && (tCnt > 0))
                    {
                        symResult.Append("+");
                        plusEmitted = true;
                    }
                    if ((pCnt > 0) && (symResult.Length > 0) && (!((symResult[symResult.Length - 1] == '-') || (symResult[symResult.Length - 1] == '+'))))
                    {
                        symResult.Append("*");
                    }

                    System.Object O = T[p];
                    if ((O is System.Double) ||
                        (O is System.Single) ||
                        (O is System.Int16) ||
                        (O is System.Int32) ||
                        (O is System.Int64)) // etc . . . (all number types)
                    {
                        double val = (double)O;
                        if ((val == -1.0) && (p == 0) && (T.Length > 1))
                        {                                                   // when multiplying with -1.0, output only a '-', IF the term is the first (p==0) and more terms follow (T.Length > 1)
                            if (symResult.Length > 0)
                            {                                               // when val = -1, output code which is better for humans, instead of -1.0 * ...
                                if (symResult[symResult.Length - 1] == '+') // change '+' to '-'
                                {
                                    symResult[symResult.Length - 1] = '-';
                                }
                                else
                                {
                                    symResult.Append("-");
                                }
                            }
                            else
                            {
                                symResult.Append("-");
                            }
                        }
                        else if ((val == 1.0) && (p == 0) && (T.Length > 1))
                        { // when multiplying with 1.0, output nothing IF the term is the first (p==0) and more terms follow (T.Length > 1)
                          // do nothing
                        }
                        else
                        {
                            symResult.Append(FT.DoubleToString(S, (double)O));
                        }
                    }
                    else if (O is UnaryScalarOp)
                    {
                        UnaryScalarOp USO = (UnaryScalarOp)O;
                        symResult.Append(UnaryScalarOpToLangString(S, FT, USO));
                    }
                    else if (O is BinaryScalarOp)
                    {
                        BinaryScalarOp BSO = (BinaryScalarOp)O;
                        symResult.Append(BinaryScalarOpToLangString(S, FT, BSO));
                    }
                    else if (O is RefGA.BasisBlade)
                    {
                        symResult.Append(ScalarToLangString(S, FT, (RefGA.BasisBlade)O));
                    }
                    else if (O is RefGA.Multivector)
                    {
                        RefGA.Multivector mv   = (RefGA.Multivector)O;
                        StringBuilder     mvSB = new StringBuilder();
                        mvSB.Append("(");
                        bool first = true;
                        foreach (RefGA.BasisBlade B in mv.BasisBlades)
                        {
                            if (!first)
                            {
                                mvSB.Append(" + ");
                            }
                            first = false;
                            mvSB.Append(ScalarToLangString(S, FT, B));
                        }

                        mvSB.Append(")");

                        symResult.Append(mvSB);
                    }
                    else
                    {
                        symResult.Append(O.ToString());
                    }

                    pCnt++;
                }
            }
            return(pCnt);
        }
Пример #8
0
        } // end of WriteSetVectorImages()

        private static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm)
        {
            StringBuilder declSB      = cgd.m_declSB;
            StringBuilder defSB       = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;
            string        srcTypeName = FT.GetMangledName(S, srcOm.Name);
            string        dstTypeName = FT.GetMangledName(S, dstOm.Name);

            // write comment
            declSB.AppendLine("/** Copies a " + srcTypeName + " to a " + dstTypeName);
            declSB.AppendLine(" * Warning 1: coordinates which cannot be represented are silenty lost");
            declSB.AppendLine(" * Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.");
            declSB.AppendLine(" */");

            string funcName = srcTypeName + "_to_" + dstTypeName;

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

            string funcDecl = inlineStr + "void " + funcName + "(" + dstTypeName + " *dst, const " + srcTypeName + " *src)";

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

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

                Dictionary <Tuple <int, int, int>, Tuple <int, int, double> > D = dstOm.getMapping(srcOm);

                StringBuilder copySB    = new StringBuilder();
                List <string> setToZero = new List <string>();

                // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null
                // Do not use foreach() on D because we want to fill in coordinates in their proper order.
                for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++)
                {
                    for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++)
                    {
                        for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++)
                        {
                            Tuple <int, int, int> key = new Tuple <int, int, int>(gradeIdx, somDomainIdx, somRangeIdx);

                            int    somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx);
                            string dstString    = "dst->m" + gradeIdx + "[" + somMatrixIdx + "] = ";
                            if (D.ContainsKey(key))
                            {
                                Tuple <int, int, double> value = D[key];
                                int    gomMatrixIdx            = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2);
                                double multiplier       = value.Value3;
                                string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * ");

                                copySB.AppendLine("\t" + dstString + multiplierString + " src->m" + gradeIdx + "[" + gomMatrixIdx + "];");
                            }
                            else
                            {
                                setToZero.Add(dstString);
                            }
                        }
                    }
                }

                // append copy statements
                defSB.Append(copySB);

                // append statements to set coordinates to zero
                if (setToZero.Count > 0)
                {
                    int cnt = 0;
                    defSB.Append("\t");
                    foreach (string str in setToZero)
                    {
                        defSB.Append(str);
                        cnt++;
                        if (cnt > 8)
                        {
                            cnt = 0;
                            defSB.AppendLine("");
                            defSB.Append("\t\t");
                        }
                    }
                    defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";");
                }

                defSB.AppendLine("}");
            }
        }
Пример #9
0
        } // end of WriteGMVtoSMVcopy()

        /// <summary>
        /// Writes code for abs largest coordinate
        /// </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 WriteLargestCoordinateFunctions(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv)
        {
            StringBuilder defSB = cgd.m_defSB;

            defSB.AppendLine("");

            const string smvName = G25.CG.Shared.SmvUtil.THIS;
            const bool   ptr     = false;

            string fabsFunc = G25.CG.Shared.CodeUtil.OpNameToLangString(S, FT, RefGA.Symbolic.UnaryScalarOp.ABS);

            string[] AS = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, smvName, ptr);

            RefGA.BasisBlade maxBasisBlade = smv.AbsoluteLargestConstantBasisBlade();

            //string className = FT.GetMangledName(S, smv.Name);

            for (int _returnBitmap = 0; _returnBitmap <= 1; _returnBitmap++)
            {
                bool returnBitmap = (_returnBitmap != 0);

                // write comment
                int nbTabs = 1;
                if (returnBitmap)
                {
                    new G25.CG.Shared.Comment("Returns the absolute largest coordinate,\nand the corresponding basis blade bitmap.").Write(defSB, S, nbTabs);
                }
                else
                {
                    new G25.CG.Shared.Comment("Returns the absolute largest coordinate.").Write(defSB, S, nbTabs);
                }

                string funcName = Util.GetFunctionName(S, ((returnBitmap) ? "largestBasisBlade" : "largestCoordinate"));

                string funcDecl;
                if ((S.OutputCSharp()) && returnBitmap)
                {
                    funcDecl = FT.type + " " + funcName + "(int bm) ";
                }
                else if ((S.OutputJava()) && returnBitmap)
                {
                    funcDecl = FT.type + "[] " + funcName + "() ";
                }
                else
                {
                    funcDecl = FT.type + " " + funcName + "()";
                }

                string FINAL = (S.OutputJava()) ? "final " : "";
                defSB.Append("\tpublic " + FINAL + funcDecl);
                {
                    defSB.AppendLine(" {");

                    if ((S.OutputJava()) && returnBitmap)
                    {
                        defSB.AppendLine("\t\tint bm;");
                    }

                    int startIdx = 0;
                    if (maxBasisBlade != null)
                    {
                        defSB.AppendLine("\t\t" + FT.type + " maxValue = " + FT.DoubleToString(S, Math.Abs(maxBasisBlade.scale)) + ";");
                        if (returnBitmap)
                        {
                            defSB.AppendLine("\t\tbm = " + maxBasisBlade.bitmap + ";");
                        }
                    }
                    else
                    {
                        defSB.AppendLine("\t\t" + FT.type + " maxValue = " + fabsFunc + "(" + AS[0] + ");");
                        if (returnBitmap)
                        {
                            defSB.AppendLine("\t\tbm = 0;");
                        }
                        startIdx = 1;
                    }

                    for (int c = startIdx; c < smv.NbNonConstBasisBlade; c++)
                    {
                        defSB.Append("\t\tif (" + fabsFunc + "(" + AS[c] + ") > maxValue) { maxValue = " + fabsFunc + "(" + AS[c] + "); ");
                        if (returnBitmap)
                        {
                            defSB.Append("bm = " + smv.NonConstBasisBlade(c).bitmap + "; ");
                        }
                        defSB.AppendLine("}");
                    }

                    if ((S.OutputJava()) && returnBitmap)
                    {
                        defSB.AppendLine("\t\treturn new " + FT.type + "[]{maxValue, (" + FT.type + ")bm};");
                    }
                    else
                    {
                        defSB.AppendLine("\t\treturn maxValue;");
                    }
                    defSB.AppendLine("\t}");
                }
            }
        } // end of WriteLargestCoordinateFunctions()
Пример #10
0
        } // end of WriteSetCopyCrossFloat()

        /// <summary>
        /// Writes functions to copy GMVs to SMVs
        /// </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 WriteGMVtoSMVcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv)
        {
            StringBuilder defSB = cgd.m_defSB;

            G25.GMV gmv          = S.m_GMV;
            string  srcClassName = FT.GetMangledName(S, gmv.Name);

            //string dstClassName = FT.GetMangledName(S, smv.Name);

            bool dstPtr = false;

            string[] smvAccessStr = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr);

            string funcName = GMV.GetSetFuncName(S);

            string FINAL    = (S.OutputJava()) ? "final " : "";
            string funcDecl = "\tpublic " + FINAL + "void " + funcName + "(" + FINAL + srcClassName + " src)";

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

                // get a dictionary which tells you for each basis blade of 'smv' where it is in 'gmv'
                // A dictionary from <smv group, smv element> to <gmv group, gmv element>
                Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv);

                // what is the highest group of the 'gmv' that must be (partially) copied to the 'smv'
                int highestGroup = -1;
                foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D)
                {
                    if (KVP.Value.Value1 > highestGroup)
                    {
                        highestGroup = KVP.Value.Value1;
                    }
                }

                // generate code for each group
                for (int g = 0; g <= highestGroup; g++)
                {
                    // determine if group 'g' is to be copied to smv:
                    bool groupIsUsedBySMV = false;
                    foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D)
                    {
                        // KVP.Key = SMV<group, element>
                        // KVP.Value = GMV<group, element>
                        if (KVP.Value.Value1 == g)
                        {
                            if (!smv.IsCoordinateConstant(KVP.Key.Value2))
                            {
                                groupIsUsedBySMV = true;
                                break;
                            }
                        }
                    }

                    // if group is present in GMV:
                    if (groupIsUsedBySMV)
                    {
                        defSB.AppendLine("\t\tif (src.c()[" + g + "] != null) {");
                        defSB.AppendLine("\t\t\t" + FT.type + "[] ptr = src.c()[" + g + "];");
                        bool mustCast             = false;
                        bool srcPtr               = true;
                        int  nbTabs               = 3;
                        RefGA.Multivector[] value = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, "ptr", srcPtr, g);
                        bool   writeZeros         = false;
                        string str = G25.CG.Shared.CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr, value[g], nbTabs, writeZeros);
                        defSB.Append(str);
                        defSB.AppendLine("\t\t}");

                        defSB.AppendLine("\t\telse {");
                        foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D)
                        {
                            if ((KVP.Value.Value1 == g) && (!smv.IsCoordinateConstant(KVP.Key.Value2)))
                            {
                                // translate KVP.Key.Value2 to non-const idx, because the accessStrs are only about non-const blades blades!
                                int bladeIdx = smv.BladeIdxToNonConstBladeIdx(KVP.Key.Value2);
                                defSB.AppendLine("\t\t\t" + smvAccessStr[bladeIdx] + " = " + FT.DoubleToString(S, 0.0) + ";");
                            }
                        }
                        defSB.AppendLine("\t\t}");
                    }
                }
                defSB.AppendLine("\t}");
            }
        } // end of WriteGMVtoSMVcopy()