Esempio n. 1
0
        /// <summary>
        /// Generates code for returning a scalar value. The input is a scalar-valued multivector.
        /// </summary>
        /// <param name="S">Specification (used for output language).</param>
        /// <param name="FT">Floating point type which must be returned.</param>
        /// <param name="mustCast">Set to true if the returned value must be cast to <c>FT</c>, that is
        /// if you are not sure that the multivector has the same float type as the return type <c>FT</c>.</param>
        /// <param name="value">The symbolic multivector value to be returned.</param>
        /// <returns>Code for returning a scalar value.</returns>
        public static string GenerateScalarReturnCode(Specification S, FloatType FT, bool mustCast, RefGA.Multivector value)
        {
            if (value.IsZero())
            {
                return "return " + FT.DoubleToString(S, 0.0) + ";";
            }
            else
            {

                return "return " +
                    ((mustCast) ? (FT.castStr + "(") : "") +
                    CodeUtil.ScalarToLangString(S, FT, value.BasisBlades[0]) +
                    ((mustCast) ? ")" : "") +
                    ";";
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Converts scalar part of 'value' to ouput language dependent string.
 /// </summary>
 private static string ScalarOpValueToLangString(G25.Specification S, G25.FloatType FT, RefGA.Multivector value)
 {
     if (!value.IsScalar()) throw new Exception("G25.CG.Shared.BasisBlade.ScalarOpValueToLangString(): value should be scalar, found: " + value.ToString(S.m_basisVectorNames));
     if (value.IsZero()) return ScalarToLangString(S, FT, RefGA.BasisBlade.ZERO);
     else return ScalarToLangString(S, FT, value.BasisBlades[0]);
 }
Esempio n. 3
0
        /// <summary>
        /// This function contains a function to find a tightly matching specialized multivector.
        /// Given a Multivector 'M', it find the best match which can contain it.
        /// 
        /// The function tries each SMV in the specification. It rates them as follows:
        /// -missing variable basis blade: disqualified
        /// -constant coordinate mismatch: disqualified
        /// -constant coordinate match: +1
        /// -excess variable coordinate : -1
        /// 
        /// If the symbolic multivector 'M' has a scalar return type, the function will insist on returning
        /// a scalar type! It will not (for example) return a rotor.
        /// </summary>
        /// <param name="S">Specification of algebra, used for the m_SMV</param>
        /// <param name="M">The multivector for which a matching SMV is sought.</param>
        /// <param name="FT">The preferred floating point type (only used when scalar is returned).</param>
        /// <returns>null when no match found; the selected G25.SMV or G25.FloatType otherwise.</returns>
        public static G25.VariableType FindTightestMatch(G25.Specification S, RefGA.Multivector M, FloatType FT)
        {
            G25.SMV bestSMV = null;
            const int LOWEST_RATING = -10000000; // rating of good-enough blades _can_ be negative, if they have excess variable coordinates
            int bestRating = LOWEST_RATING;

            const double EPSILON = 1e-6; // make this user controllable??

            foreach (G25.SMV smv in S.m_SMV)
            {
                int rating = 0;
                int nbConstMatched = 0; // number of elements from M.BasisBlades matched with const coordinates
                for (int i = 0; i < M.BasisBlades.Length; i++)
                {
                    // get blade, see if it is constant
                    RefGA.BasisBlade B = M.BasisBlades[i];
                    bool constant = (B.symScale == null);

                    // if constant, then try constant blades first
                    bool found = false; // set to true when matching basis blade is found
                    if (constant)
                    {
                        // loop over all constant basis blades
                        for (int j = 0; j < smv.NbConstBasisBlade; j++)
                        {
                            // get basis blade, compare bitmaps
                            RefGA.BasisBlade C = smv.ConstBasisBlade(j);
                            if (C.bitmap == B.bitmap)
                            {
                                if (Math.Abs(C.scale - B.scale) / Math.Abs(C.scale) > EPSILON)
                                {
                                    rating = LOWEST_RATING;
                                    break; // this break the outer loop (over 'i') too
                                }
                                else {
                                    rating++;
                                    nbConstMatched++;
                                    found = true;
                                    break;
                                }
                            }
                        }
                    }
                    if (rating == LOWEST_RATING) break;

                    // if no constant basis blade was found, loop over all variable basis blades
                    if (!found)
                    {
                        for (int j = 0; j < smv.NbNonConstBasisBlade; j++)
                        {
                            // get basis blade, compare bitmaps
                            RefGA.BasisBlade C = smv.NonConstBasisBlade(j);
                            if (C.bitmap == B.bitmap)
                            {
                                found = true;
                                break;
                            }
                        }
                    }

                    if (!found)
                    {// if neither constant nor variable basis blade found: no match
                        rating = LOWEST_RATING;
                        break;
                    }
                }

                // disqualify 'smv' when it has const coords not present in 'M'
                if (nbConstMatched < smv.NbConstBasisBlade)
                    rating = LOWEST_RATING;

                if (rating != LOWEST_RATING)
                {
                    // adjust rating for excess variable coordinates:
                    int nbNonConstCoords = M.BasisBlades.Length - nbConstMatched;
                    int nbExcess = smv.NbNonConstBasisBlade - nbNonConstCoords;
                    if (nbExcess > 0) rating -= nbExcess; // subtract 1 for each non-const coordinate that is in 'smv' without actually being useful
                }

                // keep best SMV so far
                if (rating > bestRating)
                {
                    bestRating = rating;
                    bestSMV = smv;
                }
            }

            if ((M.IsZero() || M.IsScalar()) && (bestRating < 0)) return FT; // insist on retuning a scalar type
            else return bestSMV;
        }