using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Azimuth.UnitTests { public class RobustAccumulatorTests : UnitTestSharp.TestFixture { RobustAccumulator accumulator; public override void TestSetup() { accumulator = new RobustAccumulator(); } public void Basic() { accumulator.Add(1); accumulator.Add(2); accumulator.Add(3); accumulator.Add(4); CheckEqual(10, accumulator.ComputedSum.Value); } public void CancellationError_Scalars() { Scalar sum = 0; sum += Scalar.Epsilon; sum += 10; sum += -10; CheckEqual(0, sum.Value); } public void CancellationError() { accumulator.Add(Scalar.Epsilon); accumulator.Add(1); accumulator.Add(-1); CheckEqual(Scalar.Epsilon, accumulator.ComputedSum.Value); } public void List() { var list = new Scalar[] { 1e-20, 1, -1 }; accumulator.AddList(list); CheckEqual(1e-20, accumulator.ComputedSum.Value); } public void MulBasic() { accumulator.Add(2); accumulator.Mul(2); accumulator.Mul(3); accumulator.Mul(4); CheckEqual(48, accumulator.ComputedSum); } public void Mul_CancellationError_Scalars() { Scalar product = 1+2*Scalar.Epsilon; product *= 1.0/Scalar.FuzzyEqualityEpsilon; product *= Scalar.FuzzyEqualityEpsilon; CheckEqual(1, product.Value); } public void Mul_CancellationError() { accumulator.Add(1 + 2 * Scalar.Epsilon); accumulator.Mul(1.0 / Scalar.FuzzyEqualityEpsilon); accumulator.Mul(Scalar.FuzzyEqualityEpsilon); CheckEqual(1 + 2 * Scalar.Epsilon, accumulator.ComputedSum.Value); } public void QuadBasic() { // 2*tt + 4*t + 6, t = 3 -> 36 accumulator.AddQuadratic(2, 4, 6, 3); CheckEqual(36, accumulator.ComputedSum.Value); } public void Quad_CancellationError_Scalars() { Scalar t = 1.9999999885924187; Scalar sum = 0; sum += 1.25; sum *= t; sum += -5; sum *= t; sum += 6; sum -= 1; CheckEqual(0, sum.Value); } public void Quad_CancellationError() { Scalar t = 1.9999999885924187; accumulator.AddQuadratic(1.25, -5, 6, t); accumulator.Add(-1); CheckNotEqual(0, accumulator.ComputedSum.Value); } public void AccumulatorAdd() { var accum2 = new RobustAccumulator(); accum2.Add(1); accum2.Add(Scalar.Epsilon); accumulator.Add(-1); accumulator.Add(accum2); CheckEqual(Scalar.Epsilon, accumulator.ComputedSum.Value); } public class Subtraction : UnitTestSharp.TestFixture { public void Basic_Scalar() { var robustAccumulator = new RobustAccumulator(); robustAccumulator.Sub(4); CheckEqual(-4, robustAccumulator.ComputedSum); } public void Zero() { var robustAccumulator = new RobustAccumulator(); robustAccumulator.Sub(0); CheckEqual(0, robustAccumulator.ComputedSum); } public void Negative() { var robustAccumulator = new RobustAccumulator(); robustAccumulator.Sub(-4); CheckEqual(4, robustAccumulator.ComputedSum); } public void CancellationError() { var accumulator = new RobustAccumulator(); accumulator.Add(Scalar.Epsilon); accumulator.Add(1); accumulator.Sub(1); CheckEqual(Scalar.Epsilon, accumulator.ComputedSum.Value); } } } }