Dryad/DryadLinqTests/Validate.cs

268 lines
10 KiB
C#

///-------------------------------------------------------------------------------------------------
// file: Validate.cs
//
// summary: Implements the validate class
///-------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
namespace BenchmarkFramework {
///-------------------------------------------------------------------------------------------------
/// <summary> Validation utils </summary>
///-------------------------------------------------------------------------------------------------
public class Validate {
public static void
Check<T>(
IEnumerable<T>[] ss,
IComparer<T> comparer = null,
bool sort = true,
bool verbose = false,
IComparer<T> sortcomparer = null
) {
if(ss.Length == 0) return;
if(comparer == null) {
comparer = Comparer<T>.Default;
if(comparer == null) {
throw new ArgumentNullException("Can't not be null.");
}
}
if(sortcomparer == null)
sortcomparer = comparer;
T[][] aa = new T[ss.Length][];
for(int i = 0; i < aa.Length; i++) {
aa[i] = ss[i].ToArray();
if(sort) Array.Sort(aa[i], sortcomparer);
}
int len = aa[0].Length;
for(int i = 1; i < aa.Length; i++) {
if(aa[i].Length != len) {
throw new Exception("Wrong number of elements.");
}
}
for(int i = 0; i < len; i++) {
T elem = aa[0][i];
for(int j = 1; j < aa.Length; j++) {
if(verbose) {
//TestOutput.WriteLine("Comparing {0} to {1}", elem.ToString(), aa[j][i].ToString());
}
if(comparer.Compare(elem, aa[j][i]) != 0) {
throw new Exception("Elements failed to match: " + elem + " != " + aa[j][i]);
}
}
}
}
//public static void
//GroupCheck<K, V>(
// IEnumerable<IGrouping<K, V>>[] ss,
// IComparer<K> kComparer = null,
// IComparer<V> vComparer = null
// ) {
// if(ss.Length == 0) return;
// if(kComparer == null) {
// kComparer = Comparer<K>.Default;
// if(kComparer == null) {
// throw new ArgumentNullException("Can't not be null.");
// }
// }
// if(vComparer == null) {
// vComparer = Comparer<V>.Default;
// if(vComparer == null) {
// throw new ArgumentNullException("Can't not be null.");
// }
// }
// IGrouping<K, V>[][] aa = new IGrouping<K, V>[ss.Length][];
// for(int i = 0; i < aa.Length; i++) {
// aa[i] = ss[i].ToArray();
// K[] keys = aa[i].Select(x => x.Key).ToArray();
// Array.Sort(keys, aa[i], kComparer);
// }
// int len = aa[0].Length;
// for(int i = 1; i < aa.Length; i++) {
// if(aa[i].Length != len) {
// throw new Exception("Wrong number of elements.");
// }
// }
// for(int i = 0; i < len; i++) {
// IEnumerable<V> elem = aa[0][i];
// for(int j = 1; j < aa.Length; j++) {
// Check(new IEnumerable<V>[] { elem, aa[j][i] }, vComparer);
// }
// }
//}
}
/*
///-------------------------------------------------------------------------------------------------
/// <summary> Tolerant float comparer. Floating point differences between
/// GPU and CPU cause the default comparer to fail sometimes even when
/// the result is correct. Use this comparer to introduce some tolerance
/// for this
/// </summary>
///
/// <remarks> Crossbac, 2/19/2013. </remarks>
///-------------------------------------------------------------------------------------------------
public class TolerantDoubleComparer : IComparer<double> {
Double EPSILON;
public TolerantDoubleComparer(Double _epsilon = 0.000001f) {
EPSILON = _epsilon;
}
public int Compare(Double a, Double b) {
Double delta = a - b;
if(Math.Abs(delta) <= EPSILON)
return 0;
return delta < 0.0f ? -1 : 1;
}
}
///-------------------------------------------------------------------------------------------------
/// <summary> Tolerant float comparer. Floating point differences between
/// GPU and CPU cause the default comparer to fail sometimes even when
/// the result is correct. Use this comparer to introduce some tolerance
/// for this
/// </summary>
///
/// <remarks> Crossbac, 2/19/2013. </remarks>
///-------------------------------------------------------------------------------------------------
public class TolerantFloatComparer : IComparer<float> {
float EPSILON;
public TolerantFloatComparer(float _epsilon = 0.000001f) {
EPSILON = _epsilon;
}
public int Compare(float a, float b) {
float delta = a - b;
if(Math.Abs(delta) <= EPSILON)
return 0;
return delta < 0.0f ? -1 : 1;
}
}
///-------------------------------------------------------------------------------------------------
/// <summary> Tolerant float comparer. Floating point differences between
/// GPU and CPU cause the default comparer to fail sometimes even when
/// the result is correct. Use this comparer to introduce some tolerance
/// for this
/// </summary>
///
/// <remarks> Crossbac, 2/19/2013. </remarks>
///-------------------------------------------------------------------------------------------------
public class TolerantVectorComparer : IComparer<Vector> {
float EPSILON;
public TolerantVectorComparer(float _epsilon = 0.0001f) {
EPSILON = _epsilon;
}
public int Compare(Vector a, Vector b) {
for(int i = 0; i < a.m_elems.Length; i++) {
float delta = a.m_elems[i] - b.m_elems[i];
if(Math.Abs(delta) > EPSILON)
return delta < 0.0f ? -1 : 1;
}
return 0;
}
}
///-------------------------------------------------------------------------------------------------
/// <summary> Interface for epsilon comparable single. </summary>
///
/// <remarks> Crossbac, 1/16/2014. </remarks>
///
/// <typeparam name="T"> Generic type parameter. </typeparam>
///-------------------------------------------------------------------------------------------------
public interface IEpsilonComparableSingle<T> {
int EpsilonCompare(T a, T b, float epsilon);
}
///-------------------------------------------------------------------------------------------------
/// <summary> Interface for epsilon comparable double. </summary>
///
/// <remarks> Crossbac, 1/16/2014. </remarks>
///
/// <typeparam name="T"> Generic type parameter. </typeparam>
///-------------------------------------------------------------------------------------------------
public interface IEpsilonComparableDouble<T> {
int EpsilonCompare(T a, T b, double epsilon);
}
///-------------------------------------------------------------------------------------------------
/// <summary> Tolerant float comparer. Floating point differences between
/// GPU and CPU cause the default comparer to fail sometimes even when
/// the result is correct. Use this comparer to introduce some tolerance
/// for this
/// </summary>
///
/// <remarks> Crossbac, 2/19/2013. </remarks>
///-------------------------------------------------------------------------------------------------
public class EpsilonComparer<T> : IComparer<T> where T : IEpsilonComparableSingle<T> {
float EPSILON;
public EpsilonComparer(float _epsilon = 0.0001f) {
EPSILON = _epsilon;
}
public int Compare(T a, T b) {
return a.EpsilonCompare(a, b, EPSILON);
}
}
///-------------------------------------------------------------------------------------------------
/// <summary> Tolerant float comparer for images. Floating point differences between
/// GPU and CPU cause the default comparer to fail sometimes even when
/// the result is correct. Use this comparer to introduce some tolerance
/// for this
/// </summary>
///
/// <remarks> Crossbac, 2/19/2013. </remarks>
///-------------------------------------------------------------------------------------------------
public class TolerantImageComparer : IComparer<Image> {
float EPSILON;
public TolerantImageComparer(float _epsilon = 0.0001f) {
EPSILON = _epsilon;
}
public int Compare(Image a, Image b) {
for(int i = 0; i < a.m_elems.Length; i++) {
float delta = a.m_elems[i] - b.m_elems[i];
if(Math.Abs(delta) > EPSILON)
return delta < 0.0f ? -1 : 1;
}
return 0;
}
}
/// <summary>
/// Compare two instances of Pair<int,int>.
/// Implement for concrete type as Pair<T1,T2> cannot straighforwardly implement IComparable.
/// </summary>
///
/// <remarks> jcurrey, 3/11/2013. </remarks>
public class PairIntIntComparer : IComparer<Pair<int, int>> {
public int Compare(Pair<int, int> a, Pair<int, int> b) {
int keyComparison = a.Key.CompareTo(b.Key);
if(keyComparison == 0) {
return a.Value.CompareTo(b.Value);
} else {
return keyComparison;
}
}
}
*/
}