public void Add()
 {
     Assert.AreEqual(5, Arithmetic.InvokeOperator(Arithmetic.Operators.Add, 2, 3));
     Assert.AreEqual(5.5f, Arithmetic.InvokeOperator(Arithmetic.Operators.Add, 2.5f, 3.0f));
     Assert.AreEqual(
         new ValueType(5.0f, 4.0f),
         Arithmetic.InvokeOperator(Arithmetic.Operators.Add, new ValueType(3.0f, 2.0f), new ValueType(2.0f, 2.0f))
         );
 }
 public void Subtract()
 {
     Assert.AreEqual(3, Arithmetic.InvokeOperator(Arithmetic.Operators.Subtract, 5, 2));
     Assert.AreEqual(3.5f, Arithmetic.InvokeOperator(Arithmetic.Operators.Subtract, 5.5f, 2.0f));
     Assert.AreEqual(
         new ValueType(1.0f, 2.0f),
         Arithmetic.InvokeOperator(Arithmetic.Operators.Subtract, new ValueType(4.0f, 4.0f), new ValueType(3.0f, 2.0f))
         );
 }
 public void Divide()
 {
     Assert.AreEqual(2, Arithmetic.InvokeOperator(Arithmetic.Operators.Divide, 4, 2));
     Assert.AreEqual(2.25f, Arithmetic.InvokeOperator(Arithmetic.Operators.Divide, 4.5f, 2.0f));
     Assert.AreEqual(
         new ValueType(2.25f, 2.0f),
         Arithmetic.InvokeOperator(Arithmetic.Operators.Divide, new ValueType(4.5f, 4.0f), new ValueType(2.0f, 2.0f))
         );
 }
 public void Multiply()
 {
     Assert.AreEqual(4, Arithmetic.InvokeOperator(Arithmetic.Operators.Multiply, 2, 2));
     Assert.AreEqual(4.5f, Arithmetic.InvokeOperator(Arithmetic.Operators.Multiply, 2.25f, 2.0f));
     Assert.AreEqual(
         new ValueType(4.5f, 4.0f),
         Arithmetic.InvokeOperator(Arithmetic.Operators.Multiply, new ValueType(2.25f, 2.0f), new ValueType(2.0f, 2.0f))
         );
 }
Ejemplo n.º 5
0
        private static void CompileFallbackExpressions()
        {
            var m_sub       = Arithmetic.GetOperator <T, T>(Arithmetic.Operators.Subtract);
            var m_add       = Arithmetic.GetOperator <T, T>(Arithmetic.Operators.Add);
            var m_mul_float = Arithmetic.GetOperator <T, float>(Arithmetic.Operators.Multiply);

            _Linear = (a, b, x) => {
                return(m_add(a, m_mul_float(m_sub(b, a), x)));
            };

            _Cosine = (a, b, x) => {
                var temp = (1.0f - (float)Math.Cos(x * Math.PI)) * 0.5f;
                return(m_add(a, m_mul_float(m_sub(b, a), temp)));
            };

            _CubicP = (a, b, c, d) => {
                return(m_sub(m_sub(d, c), m_sub(a, b)));
            };

            _CubicR = (a, b, c, d, p, x, x2, x3) => {
                return(m_add(
                           m_add(
                               m_mul_float(p, x3),
                               m_mul_float(
                                   m_sub(
                                       m_sub(a, b),
                                       p
                                       ),
                                   x2
                                   )
                               ),
                           m_add(
                               m_mul_float(
                                   m_sub(c, a),
                                   x
                                   ),
                               b
                               )
                           ));
            };

            _Hermite = (a, u, d, v, t, t2, tSquared, s, s2, sSquared) => {
                return(m_sub(
                           m_add(
                               m_add(
                                   m_mul_float(a, sSquared * (1 + t2)),
                                   m_mul_float(d, tSquared * (1 + s2))
                                   ),
                               m_mul_float(u, sSquared * t)
                               ),
                           m_mul_float(v, s * tSquared)
                           ));
            };
        }
        public void CompileExpression()
        {
            Func <float, float> fn;

            Arithmetic.CompileExpression(
                (a) => a * 2.0f,
                out fn
                );

            Assert.AreEqual(fn(2.0f), 4.0f);
            Assert.AreEqual(fn(2), 4.0f);

            Arithmetic.CompileExpression(
                (a) => - a / 2.0f + 1.0f,
                out fn
                );

            Assert.AreEqual(fn(2.0f), 0.0f);
            Assert.AreEqual(fn(-1), 1.5f);

            Func <float, bool> cmp;

            Arithmetic.CompileExpression(
                (a) => a == 2.0f,
                out cmp
                );

            Assert.IsTrue(cmp(2.0f));
            Assert.IsTrue(cmp(2));
            Assert.IsFalse(cmp(3.0f));

            Func <ValueType, ValueType, bool> cmpvt;

            Arithmetic.CompileExpression(
                (a, b) => a == b,
                out cmpvt
                );

            ValueType vtA = new ValueType(1.0f, 1.0f);
            ValueType vtB = new ValueType(1.0f, 2.0f);

            Assert.IsTrue(cmpvt(vtA, vtA));
            Assert.IsFalse(cmpvt(vtA, vtB));

            Arithmetic.CompileExpression(
                (a) => Math.Cos(a),
                out fn
                );

            Assert.AreEqual(fn(5.0f), (float)Math.Cos(5.0f));
            Assert.AreEqual(fn(0.5f), (float)Math.Cos(0.5f));
        }
        public void CompileExpressionWithMixedTypes()
        {
            Func <ValueType, float, ValueType> mul;

            Arithmetic.CompileExpression(
                (a, b) => a * b,
                out mul
                );

            ValueType vt = new ValueType(1.0f, 1.0f);

            Assert.AreEqual(mul(vt, 2.0f), new ValueType(2.0f, 2.0f));
        }
        public void ThrowsIfParticularOperationNotImplemented()
        {
            try {
                Arithmetic.InvokeOperator(Arithmetic.Operators.Add, 2.0f, new ValueType(1.0f, 1.0f));
                Assert.Fail("Did not throw");
            } catch (InvalidOperationException ex) {
#if WINDOWS
                Assert.IsTrue(ex.Message.Contains("GenerateOperatorIL failed"));
#endif
            }

            try {
                Arithmetic.InvokeOperator(Arithmetic.Operators.Add, 2.0m, 1);
                Assert.Fail("Did not throw");
            } catch (InvalidOperationException ex) {
#if WINDOWS
                Assert.IsTrue(ex.Message.Contains("GenerateOperatorIL failed"));
#endif
            }
        }
Ejemplo n.º 9
0
        private static void CompileNativeExpressions()
        {
#if !DYNAMICMETHOD
            if (_Linear == null)
            {
                Arithmetic.CompileExpression(
                    (a, b, x) =>
                    a + ((b - a) * x),
                    out _Linear
                    );
            }

            // FIXME: This is the best we can do
            if (_Cosine == null)
            {
                Arithmetic.CompileExpression(
                    (a, b, x) =>
                    a + ((b - a) * ((1.0f - (float)Math.Cos(x * Math.PI)) * 0.5f)),
                    out _Cosine
                    );
            }

            if (_CubicP == null)
            {
                Arithmetic.CompileExpression(
                    (a, b, c, d) =>
                    (d - c) - (a - b),
                    out _CubicP
                    );
            }

            if (_CubicR == null)
            {
                Arithmetic.CompileExpression(
                    (a, b, c, d, p, x, x2, x3) =>
                    (p * x3) + ((a - b - p) * x2) + ((c - a) * x) + b,
                    out _CubicR
                    );
            }
#endif
        }
Ejemplo n.º 10
0
        public void PerformanceTest()
        {
            int numIterations = 20000;

            float[] r = new float[numIterations];
            float   numIterationsF = numIterations;
            float   a = 0.0f, b = 1.0f, c;

            var _add = Arithmetic.GetOperator <float, float>(Arithmetic.Operators.Add);
            var _mul = Arithmetic.GetOperator <float, float>(Arithmetic.Operators.Multiply);
            var _sub = Arithmetic.GetOperator <float, float>(Arithmetic.Operators.Subtract);

            _add(0.0f, 0.0f);
            _mul(0.0f, 0.0f);
            _sub(0.0f, 0.0f);

            Expression <Func <float, float, float, float> > expr = (A, B, C) => A + ((B - A) * C);
            Func <float, float, float, float> nativeExpr         = expr.Compile();
            Func <float, float, float, float> genericExpr;

            Arithmetic.CompileExpression(
                (A, B, C) => A + ((B - A) * C),
                out genericExpr
                );

            long start = Time.Ticks;

            for (int i = 0; i < numIterations; i++)
            {
                c    = (i / numIterationsF);
                r[i] = a + ((b - a) * c);
            }
            long end = Time.Ticks;

            Console.WriteLine("Native expression execution time: {0} ticks for {1} iterations ({2:0.000} ticks/iter)", end - start, numIterations, (end - start) / numIterationsF);

            start = Time.Ticks;
            for (int i = 0; i < numIterations; i++)
            {
                c    = (i / numIterationsF);
                r[i] = Arithmetic.InvokeOperator(Arithmetic.Operators.Add, a, Arithmetic.InvokeOperator(Arithmetic.Operators.Multiply, Arithmetic.InvokeOperator(Arithmetic.Operators.Subtract, b, a), c));
            }
            end = Time.Ticks;
            Console.WriteLine("Naive delegate generic execution time: {0} ticks for {1} iterations ({2:0.000} ticks/iter)", end - start, numIterations, (end - start) / numIterationsF);

            start = Time.Ticks;
            for (int i = 0; i < numIterations; i++)
            {
                c    = (i / numIterationsF);
                r[i] = _add(a, _mul(_sub(b, a), c));
            }
            end = Time.Ticks;
            Console.WriteLine("Cached delegate execution time: {0} ticks for {1} iterations ({2:0.000} ticks/iter)", end - start, numIterations, (end - start) / numIterationsF);

            start = Time.Ticks;
            for (int i = 0; i < numIterations; i++)
            {
                c    = (i / numIterationsF);
                r[i] = nativeExpr(a, b, c);
            }
            end = Time.Ticks;
            Console.WriteLine("Native expression delegate execution time: {0} ticks for {1} iterations ({2:0.000} ticks/iter)", end - start, numIterations, (end - start) / numIterationsF);

            start = Time.Ticks;
            for (int i = 0; i < numIterations; i++)
            {
                c    = (i / numIterationsF);
                r[i] = genericExpr(a, b, c);
            }
            end = Time.Ticks;
            Console.WriteLine("Generic expression delegate execution time: {0} ticks for {1} iterations ({2:0.000} ticks/iter)", end - start, numIterations, (end - start) / numIterationsF);
        }
Ejemplo n.º 11
0
 public void Modulus()
 {
     Assert.AreEqual(1, Arithmetic.InvokeOperator(Arithmetic.Operators.Modulo, 5, 2));
     Assert.AreEqual(1.25f, Arithmetic.InvokeOperator(Arithmetic.Operators.Modulo, 5.25f, 2.0f));
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Splits a hermite spline at a position.
        /// Note that this may produce more than two output splines in order to eliminate discontinuities.
        /// </summary>
        /// <param name="splitPosition">The position at which to split the spline.</param>
        /// <param name="output">The list that will receive the new splines created by the split (up to 4).</param>
        public static void SplitInto <T> (
            this HermiteSpline <T> spline,
            float splitPosition,
            List <HermiteSpline <T> > output
            )
            where T : struct
        {
            if ((splitPosition <= spline.Start) || (splitPosition >= spline.End))
            {
                output.Add(spline);
                return;
            }

            int count = spline.Count;
            int splitFirstPoint = spline.GetLowerIndexForPosition(splitPosition), splitSecondPoint = splitFirstPoint + 1;

            HermiteSpline <T> temp;

            if (splitFirstPoint > 0)
            {
                float position;
                T     value, velocity;

                output.Add(temp = new HermiteSpline <T>());
                for (int i = 0, end = splitFirstPoint; i <= end; i++)
                {
                    spline.GetValuesAtIndex(i, out position, out value, out velocity);
                    temp.Add(position, value, velocity);
                }
            }

            float firstPosition = spline.GetPositionAtIndex(splitFirstPoint), secondPosition = spline.GetPositionAtIndex(splitSecondPoint);
            float splitLocalPosition = (splitPosition - firstPosition) / (secondPosition - firstPosition);

            T a = spline.GetValueAtIndex(splitFirstPoint), d = spline.GetValueAtIndex(splitSecondPoint);
            T u = spline.GetDataAtIndex(splitFirstPoint).Velocity, v = spline.GetDataAtIndex(splitSecondPoint).Velocity;
            T b, c;

            CurveUtil.HermiteToCubic(ref a, ref u, ref d, ref v, out b, out c);

            var ab = Arithmetic.Lerp(a, b, splitLocalPosition);
            var bc = Arithmetic.Lerp(b, c, splitLocalPosition);
            var cd = Arithmetic.Lerp(c, d, splitLocalPosition);

            var ab_bc = Arithmetic.Lerp(ab, bc, splitLocalPosition);
            var bc_cd = Arithmetic.Lerp(bc, cd, splitLocalPosition);

            var midpoint = Arithmetic.Lerp(ab_bc, bc_cd, splitLocalPosition);

            T newA, newB, newC, newD, newU, newV;

            newA = a;
            newB = ab;
            newC = ab_bc;
            newD = midpoint;

            CurveUtil.CubicToHermite(ref newA, ref newB, ref newC, ref newD, out newU, out newV);

            output.Add(temp = new HermiteSpline <T>());
            temp.Add(
                firstPosition, newA, newU
                );
            temp.Add(
                splitPosition, newD, newV
                );

            newA = midpoint;
            newB = bc_cd;
            newC = cd;
            newD = d;

            CurveUtil.CubicToHermite(ref newA, ref newB, ref newC, ref newD, out newU, out newV);

            output.Add(temp = new HermiteSpline <T>());
            temp.Add(
                splitPosition, newA, newU
                );
            temp.Add(
                secondPosition, newD, newV
                );

            if (splitSecondPoint < (count - 1))
            {
                float position;
                T     value, velocity;

                output.Add(temp = new HermiteSpline <T>());
                for (int i = splitSecondPoint, end = count - 1; i <= end; i++)
                {
                    spline.GetValuesAtIndex(i, out position, out value, out velocity);
                    temp.Add(position, value, velocity);
                }
            }
        }
Ejemplo n.º 13
0
 static Operators()
 {
     Add = Arithmetic.GetOperator <T, T>(Arithmetic.Operators.Add);
     Sub = Arithmetic.GetOperator <T, T>(Arithmetic.Operators.Subtract);
     Mul = Arithmetic.GetOperator <T, float>(Arithmetic.Operators.Multiply);
 }
Ejemplo n.º 14
0
 static HermiteSpline()
 {
     _Sub = Arithmetic.GetOperator <T, T>(Arithmetic.Operators.Subtract);
     _Mul = Arithmetic.GetOperator <T, float>(Arithmetic.Operators.Multiply);
 }
Ejemplo n.º 15
0
 private static T TemporarySource(int index)
 {
     return(_TemporaryValues[Arithmetic.Wrap(index, 0, _NumTemporaryValues - 1)]);
 }