コード例 #1
0
        /// <summary>
        /// Evaluates a Multivector to a summary of its expected value (-1, 0, 1).
        /// The function uses a Symbolic.RandomSymbolicEvaluator to randomly evaluate
        /// <paramref name="A"/>. If the results are consistently negative, zero or
        /// positive then -1, 0 or 1 is returned. Otherwise an exception is thrown.
        /// </summary>
        /// <param name="A">The multivector to evaluate</param>
        /// <returns>-1, 0 or 1</returns>
        /// <remarks>
        /// Used by Multivector.Exp(), Multivector.Cos() and Multivector.Sin() to see
        /// if the input bivector has a scalar square.
        /// </remarks>
        public static double EvaluateRandomSymbolicToScalar(Multivector A)
        {
            double EPS     = 1e-4;
            int    NB_ITER = 100;
            int    REQ     = 98;

            Symbolic.RandomSymbolicEvaluator RSE = new Symbolic.RandomSymbolicEvaluator(-100.0, 100.0);
            int pos = 0, neg = 0, zero = 0;

            for (int i = 0; i < NB_ITER; i++)
            {
                Multivector E          = A.SymbolicEval(RSE);
                double      scalarPart = E.RealScalarPart();
                Multivector theRest    = Multivector.Subtract(E, scalarPart);
                if (Math.Abs(theRest.Norm_e().RealScalarPart()) > Math.Abs(scalarPart) * EPS)
                {
                    throw new Exception("Multivector did not evaluate to scalar");
                }

                if (scalarPart > EPS)
                {
                    pos++;
                }
                else if (scalarPart < -EPS)
                {
                    neg++;
                }
                else
                {
                    zero++;
                }
            }

            if (pos >= REQ)
            {
                return(1.0);
            }
            else if (zero >= REQ)
            {
                return(0.0);
            }
            else if (neg >= REQ)
            {
                return(-1.0);
            }
            else
            {
                throw new Exception("Multivector did not evaluate to a consistent value");
            }
        }
コード例 #2
0
        /// <summary>
        /// Substitutes all symbolic scalars for doubles (as evaluated by <paramref name="E"/>)
        /// and evaluates the symbolic ScalarOps. E.g. sqrt(2.0) would evaluate to 1.4142...
        /// </summary>
        /// <param name="E">SymbolicEvaluator used to evaluate the symbolic scalars</param>
        /// <returns></returns>
        public double SymbolicEval(RefGA.Symbolic.SymbolicEvaluator E)
        {
            Multivector A = m_value1.SymbolicEval(E);
            Multivector B = m_value2.SymbolicEval(E);

            if (!(A.IsScalar() && B.IsScalar()))
            {
                throw new ArgumentException("BinaryScalarOp.SymbolicEval: argument is not scalar");
            }
            double a = A.RealScalarPart();
            double b = B.RealScalarPart();

            if (m_opName == ATAN2)
            {
                return(Math.Atan2(a, b));
            }
            else
            {
                throw new ArgumentException("BinaryScalarOp.SymbolicEval: unknown opname " + m_opName);
            }
        }
コード例 #3
0
        /// <summary>
        /// Substitutes all symbolic scalars for doubles (as evaluated by <paramref name="E"/>)
        /// and evaluates the symbolic ScalarOps. E.g. sqrt(2.0) would evaluate to 1.4142...
        /// </summary>
        /// <param name="E">SymbolicEvaluator used to evaluate the symbolic scalars</param>
        /// <returns></returns>
        public double SymbolicEval(RefGA.Symbolic.SymbolicEvaluator E)
        {
            Multivector V = m_value.SymbolicEval(E);

            if (!V.IsScalar())
            {
                throw new ArgumentException("UnaryScalarOp.SymbolicEval: argument is not scalar");
            }
            double v = V.RealScalarPart();

            if (m_opName == INVERSE)
            {
                if (v == 0.0)
                {
                    throw new ArgumentException("UnaryScalarOp.SymbolicEval: divide by zero");
                }
                return(1.0 / v);
            }
            else if (m_opName == SQRT)
            {
                if (v < 0.0)
                {
                    throw new ArgumentException("UnaryScalarOp.SymbolicEval: square root of negative value");
                }
                else
                {
                    return(Math.Sqrt(v));
                }
            }
            else if (m_opName == EXP)
            {
                return(Math.Exp(v));
            }
            else if (m_opName == LOG)
            {
                if (v <= 0.0)
                {
                    throw new ArgumentException("UnaryScalarOp.SymbolicEval: logarithm of value <= 0");
                }
                else
                {
                    return(Math.Log(v));
                }
            }
            else if (m_opName == SIN)
            {
                return(Math.Sin(v));
            }
            else if (m_opName == COS)
            {
                return(Math.Cos(v));
            }
            else if (m_opName == TAN)
            {
                // how to detect bad input (1/2 pi, etc)?
                return(Math.Tan(v));
            }
            else if (m_opName == SINH)
            {
                return(Math.Sinh(v));
            }
            else if (m_opName == COSH)
            {
                return(Math.Cosh(v));
            }
            else if (m_opName == TANH)
            {
                return(Math.Tanh(v));
            }
            else if (m_opName == ABS)
            {
                return(Math.Abs(v));
            }
            else
            {
                throw new ArgumentException("UnaryScalarOp.SymbolicEval: unknown opname " + m_opName);
            }
        }