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)) ); }
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 } }
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 }
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); }
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)); }
/// <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); } } }
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); }
static HermiteSpline() { _Sub = Arithmetic.GetOperator <T, T>(Arithmetic.Operators.Subtract); _Mul = Arithmetic.GetOperator <T, float>(Arithmetic.Operators.Multiply); }
private static T TemporarySource(int index) { return(_TemporaryValues[Arithmetic.Wrap(index, 0, _NumTemporaryValues - 1)]); }