forked from tsai/mathnet-numerics
Browse Source
Added F# DenseVector implementation Added the Histogram class Signed-off-by: jvangael <jurgen.vangael@gmail.com>la-knuth
9 changed files with 856 additions and 4 deletions
@ -0,0 +1,92 @@ |
|||||
|
// <copyright file="Apply.fs" company="Math.NET"> |
||||
|
// Math.NET Numerics, part of the Math.NET Project |
||||
|
// http://mathnet.opensourcedotnet.info |
||||
|
// |
||||
|
// Copyright (c) 2009 Math.NET |
||||
|
// |
||||
|
// Permission is hereby granted, free of charge, to any person |
||||
|
// obtaining a copy of this software and associated documentation |
||||
|
// files (the "Software"), to deal in the Software without |
||||
|
// restriction, including without limitation the rights to use, |
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
// copies of the Software, and to permit persons to whom the |
||||
|
// Software is furnished to do so, subject to the following |
||||
|
// conditions: |
||||
|
// |
||||
|
// The above copyright notice and this permission notice shall be |
||||
|
// included in all copies or substantial portions of the Software. |
||||
|
// |
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
|
// OTHER DEALINGS IN THE SOFTWARE. |
||||
|
// </copyright> |
||||
|
|
||||
|
open MathNet.Numerics |
||||
|
open MathNet.Numerics.LinearAlgebra.Double |
||||
|
|
||||
|
/// Flag to specify wether we want pretty printing or tab separated output. |
||||
|
let prettyPrint = false |
||||
|
|
||||
|
/// The size of the vector we want to map things for. |
||||
|
let N = 1000000 |
||||
|
/// The number of times we repeat a call. |
||||
|
let T = 10 |
||||
|
/// The list of all functions we want to test. |
||||
|
let FunctionList : (string * (float -> float) * (float -> float)) [] = |
||||
|
[| ("Cosine", cos, System.Math.Cos); |
||||
|
("Sine", sin, System.Math.Sin); |
||||
|
("Tangent", tan, System.Math.Tan); |
||||
|
("Inverse Cosine", acos, System.Math.Acos); |
||||
|
("Inverse Sine", asin, System.Math.Asin); |
||||
|
("Inverse Tangent", atan, System.Math.Atan); |
||||
|
("Hyperbolic Cosine", cosh, System.Math.Cosh); |
||||
|
("Hyperbolic Sine", sinh, System.Math.Sinh); |
||||
|
("Hyperbolic Tangent", tanh, System.Math.Tanh); |
||||
|
("Abs", abs, System.Math.Abs); |
||||
|
("Exp", exp, System.Math.Exp); |
||||
|
("Log", log, System.Math.Log); |
||||
|
("Sqrt", sqrt, System.Math.Sqrt); |
||||
|
("Error Function", SpecialFunctions.Erf, SpecialFunctions.Erf); |
||||
|
("Error Function Complement", SpecialFunctions.Erfc, SpecialFunctions.Erfc); |
||||
|
("Inverse Error Function", SpecialFunctions.ErfInv, SpecialFunctions.ErfInv); |
||||
|
("Inverse Error Function Complement", SpecialFunctions.ErfcInv, SpecialFunctions.ErfcInv) |] |
||||
|
|
||||
|
/// A vector with random entries. |
||||
|
let w = |
||||
|
let rnd = new Random.MersenneTwister() |
||||
|
(new DenseVector(Array.init N (fun _ -> rnd.NextDouble() * 10.0))) :> Vector |
||||
|
|
||||
|
/// A stopwatch to time the execution. |
||||
|
let sw = new System.Diagnostics.Stopwatch() |
||||
|
|
||||
|
|
||||
|
for (name, fs, dotnet) in FunctionList do |
||||
|
if prettyPrint then printfn "Running %s on an %d dimensional vector for %d iterations:" name N T |
||||
|
else printf "%s" name |
||||
|
|
||||
|
/// Perform the standard F# map function. |
||||
|
do |
||||
|
let v = w.Clone() |
||||
|
sw.Start() |
||||
|
for t in 1 .. T do Vector.mapInPlace fs v |
||||
|
sw.Stop() |
||||
|
if prettyPrint then printfn "\tVector.map (F#): %d milliseconds." sw.ElapsedMilliseconds |
||||
|
else printf "\t%d" sw.ElapsedMilliseconds |
||||
|
sw.Reset() |
||||
|
(* |
||||
|
/// Perform the Apply.Map function. |
||||
|
do |
||||
|
let v = w.Clone() |
||||
|
sw.Start() |
||||
|
for t in 1 .. T do v.Map(fun x -> dotnet x) |
||||
|
sw.Stop() |
||||
|
if prettyPrint then printfn "\tApply.Map (MKL): %d milliseconds." sw.ElapsedMilliseconds |
||||
|
else printf "\t%d" sw.ElapsedMilliseconds |
||||
|
sw.Reset()*) |
||||
|
|
||||
|
printfn "" |
||||
@ -0,0 +1,455 @@ |
|||||
|
// <copyright file="Histogram.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.Statistics |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Text; |
||||
|
using System.Collections.Generic; |
||||
|
using Properties; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A <see cref="Histogram"/> consists of a series of <see cref="Bucket"/>s,
|
||||
|
/// each representing a region limited by a lower bound (inclusive) and an upper bound (exclusive).
|
||||
|
/// </summary>
|
||||
|
[Serializable] |
||||
|
public class Bucket : IComparable<Bucket> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This <c>IComparer</c> performs comparisons between a point and a bucket.
|
||||
|
/// </summary>
|
||||
|
private sealed class PointComparer : IComparer<Bucket> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Compares a point and a bucket. The point will be encapsulated in a bucket with width 0.
|
||||
|
/// </summary>
|
||||
|
/// <param name="bkt1">The first bucket to compare.</param>
|
||||
|
/// <param name="bkt2">The second bucket to compare.</param>
|
||||
|
/// <returns>-1 when the point is less than this bucket, 0 when it is in this bucket and 1 otherwise.</returns>
|
||||
|
public int Compare(Bucket bkt1, Bucket bkt2) |
||||
|
{ |
||||
|
if (bkt2.Width == 0.0) |
||||
|
{ |
||||
|
return -bkt1.Contains(bkt2.LowerBound); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return -bkt2.Contains(bkt1.LowerBound); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static PointComparer pointComparer = new PointComparer(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Lower Bound of the Bucket.
|
||||
|
/// </summary>
|
||||
|
public double LowerBound { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Upper Bound of the Bucket.
|
||||
|
/// </summary>
|
||||
|
public double UpperBound { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The number of datapoints in the bucket.
|
||||
|
/// </summary>
|
||||
|
public double Count { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the Bucket class.
|
||||
|
/// </summary>
|
||||
|
public Bucket(double lowerBound, double upperBound) : this(lowerBound, upperBound, 0.0) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the Bucket class.
|
||||
|
/// </summary>
|
||||
|
public Bucket(double lowerBound, double upperBound, double count) |
||||
|
{ |
||||
|
if (lowerBound > upperBound) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(Resources.ArgumentLowerBoundLargerThanUpperBound); |
||||
|
} |
||||
|
|
||||
|
if (count < 0.0) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(Resources.ArgumentMustBePositive); |
||||
|
} |
||||
|
|
||||
|
LowerBound = lowerBound; |
||||
|
UpperBound = upperBound; |
||||
|
Count = count; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Width of the Bucket.
|
||||
|
/// </summary>
|
||||
|
public double Width |
||||
|
{ |
||||
|
get { return UpperBound - LowerBound; } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Default comparer.
|
||||
|
/// </summary>
|
||||
|
public static IComparer<Bucket> DefaultPointComparer |
||||
|
{ |
||||
|
get { return pointComparer; } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// This method check whether a point is contained within this bucket.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The point to check.</param>
|
||||
|
/// <returns>0 if the point falls within the bucket boundaries; -1 if the point is
|
||||
|
/// smaller than the bucket, +1 if the point is larger than the bucket.</returns>
|
||||
|
public int Contains(double x) |
||||
|
{ |
||||
|
if (LowerBound <= x) |
||||
|
{ |
||||
|
if (UpperBound > x) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Comparison of two disjoint buckets.
|
||||
|
/// </summary>
|
||||
|
public int CompareTo(Bucket bucket) |
||||
|
{ |
||||
|
if(this.UpperBound > bucket.LowerBound && this.LowerBound < bucket.LowerBound) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.PartialOrderException); |
||||
|
} |
||||
|
|
||||
|
if (Precision.AlmostEqual(this.UpperBound, bucket.UpperBound) |
||||
|
&& Precision.AlmostEqual(this.LowerBound, bucket.LowerBound)) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
if (bucket.UpperBound <= this.LowerBound) |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks whether two Buckets are equal; this method tolerates a difference in lowerbound, upperbound
|
||||
|
/// and count given by <seealso cref="Precsion.AlmostEqual"/>.
|
||||
|
/// </summary>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (!(obj is Bucket)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
Bucket b = (Bucket) obj; |
||||
|
return Precision.AlmostEqual(this.LowerBound, b.LowerBound) |
||||
|
&& Precision.AlmostEqual(this.UpperBound, b.UpperBound) |
||||
|
&& Precision.AlmostEqual(this.Count, b.Count); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides a hash code for this bucket.
|
||||
|
/// </summary>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
return LowerBound.GetHashCode() ^ UpperBound.GetHashCode() ^ Count.GetHashCode(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Formats a human-readable string for this bucket.
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return "[" + this.LowerBound + ";" + this.UpperBound + "]"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A class which computes histograms of data.
|
||||
|
/// </summary>
|
||||
|
[Serializable] |
||||
|
public class Histogram |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Contains all the <c>Bucket</c>s of the <c>Histogram</c>.
|
||||
|
/// </summary>
|
||||
|
List<Bucket> buckets; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Indicates whether the elements of <c>buckets</c> are currently sorted.
|
||||
|
/// </summary>
|
||||
|
bool areBucketsSorted; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the Histogram class.
|
||||
|
/// </summary>
|
||||
|
public Histogram() |
||||
|
{ |
||||
|
buckets = new List<Bucket>(); |
||||
|
areBucketsSorted = true; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Constructs a Histogram with a specific number of equally sized buckets. The upper and lower bound of the histogram
|
||||
|
/// will be set to the smallest and largest datapoint.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The datasequence to build a histogram on.</param>
|
||||
|
/// <param name="nbuckets">The number of buckets to use.</param>
|
||||
|
public Histogram(IEnumerable<double> data, int nbuckets) |
||||
|
: this() |
||||
|
{ |
||||
|
if (nbuckets < 1) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException("The number of bins in a histogram should be at least 1."); |
||||
|
} |
||||
|
|
||||
|
double lower = data.Minimum(); |
||||
|
double upper = data.Maximum().Increment(); |
||||
|
double width = (upper - lower) / nbuckets; |
||||
|
|
||||
|
// Add buckets for each bin.
|
||||
|
for (int n = 0; n < nbuckets; n++) |
||||
|
{ |
||||
|
AddBucket(new Bucket(lower + n * width, lower + (n + 1) * width)); |
||||
|
} |
||||
|
|
||||
|
AddData(data); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Constructs a Histogram with a specific number of equally sized buckets.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The datasequence to build a histogram on.</param>
|
||||
|
/// <param name="nbuckets">The number of buckets to use.</param>
|
||||
|
/// <param name="lower">The histogram lower bound.</param>
|
||||
|
/// <param name="upper">The histogram upper bound.</param>
|
||||
|
public Histogram(IEnumerable<double> data, int nbuckets, double lower, double upper) |
||||
|
: this() |
||||
|
{ |
||||
|
if (lower > upper) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException("The histogram lowerbound must be smaller than the upper bound."); |
||||
|
} |
||||
|
if (nbuckets < 1) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException("The number of bins in a histogram should be at least 1."); |
||||
|
} |
||||
|
|
||||
|
double width = (upper - lower) / nbuckets; |
||||
|
|
||||
|
// Add buckets for each bin.
|
||||
|
for (int n = 0; n < nbuckets; n++) |
||||
|
{ |
||||
|
AddBucket(new Bucket(lower + n * width, lower + (n + 1) * width)); |
||||
|
} |
||||
|
|
||||
|
AddData(data); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Add one data point to the histogram. If the datapoint falls outside the range of the histogram,
|
||||
|
/// the lowerbound or upperbound will automatically adapt.
|
||||
|
/// </summary>
|
||||
|
/// <param name="d">The datapoint which we want to add.</param>
|
||||
|
public void AddData(double d) |
||||
|
{ |
||||
|
if (d < this.LowerBound) |
||||
|
{ |
||||
|
this[0].LowerBound = d; |
||||
|
this[0].Count++; |
||||
|
} |
||||
|
else if (d > this.UpperBound) |
||||
|
{ |
||||
|
this[BucketCount - 1].UpperBound = d; |
||||
|
this[BucketCount - 1].Count++; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
GetBucketOf(d).Count++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Add a sequence of data point to the histogram. If the datapoint falls outside the range of the histogram,
|
||||
|
/// the lowerbound or upperbound will automatically adapt.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sequence of datapoints which we want to add.</param>
|
||||
|
public void AddData(IEnumerable<double> data) |
||||
|
{ |
||||
|
foreach (double d in data) |
||||
|
{ |
||||
|
AddData(d); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Adds a <c>Bucket</c> to the <c>Histogram</c>.
|
||||
|
/// </summary>
|
||||
|
public void AddBucket(Bucket bucket) |
||||
|
{ |
||||
|
buckets.Add(bucket); |
||||
|
areBucketsSorted = false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sort the buckets if needed.
|
||||
|
/// </summary>
|
||||
|
private void LazySort() |
||||
|
{ |
||||
|
if (!areBucketsSorted) |
||||
|
{ |
||||
|
buckets.Sort(); |
||||
|
areBucketsSorted = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the <c>Bucket</c> that contains the value <c>v</c>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="v">The point to search the bucket for.</param>
|
||||
|
/// <returns>The bucket containing the point.</returns>
|
||||
|
public Bucket GetBucketOf(double v) |
||||
|
{ |
||||
|
return buckets[GetBucketIndexOf(v)]; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the index in the <c>Histogram</c> of the <c>Bucket</c>
|
||||
|
/// that contains the value <c>v</c>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="v">The point to search the bucket index for.</param>
|
||||
|
/// <returns>The index of the bucket containing the point.</returns>
|
||||
|
public int GetBucketIndexOf(double v) |
||||
|
{ |
||||
|
// Sort if needed.
|
||||
|
LazySort(); |
||||
|
|
||||
|
// Binary search for the bucket index.
|
||||
|
int index = buckets.BinarySearch(new Bucket(v,v), Bucket.DefaultPointComparer); |
||||
|
|
||||
|
if(index < 0) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.ArgumentHistogramContainsNot); |
||||
|
} |
||||
|
|
||||
|
return index; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the lower bound of the histogram.
|
||||
|
/// </summary>
|
||||
|
public double LowerBound |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
LazySort(); |
||||
|
return buckets[0].LowerBound; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the upper bound of the histogram.
|
||||
|
/// </summary>
|
||||
|
public double UpperBound |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
LazySort(); |
||||
|
return buckets[buckets.Count-1].UpperBound; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <c>n</c>'th bucket.
|
||||
|
/// </summary>
|
||||
|
/// <param name="n">The index of the bucket to be returned.</param>
|
||||
|
/// <returns>The <c>n</c>'th bucket.</returns>
|
||||
|
public Bucket this[int n] |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
LazySort(); |
||||
|
return buckets[n]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the number of buckets.
|
||||
|
/// </summary>
|
||||
|
public int BucketCount |
||||
|
{ |
||||
|
get { return buckets.Count; } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the total number of datapoints in the histogram.
|
||||
|
/// </summary>
|
||||
|
public double DataCount |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
double totalCount = 0; |
||||
|
for(int i = 0; i < this.BucketCount; i++) |
||||
|
{ |
||||
|
totalCount += this[i].Count; |
||||
|
} |
||||
|
|
||||
|
return totalCount; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Prints the buckets contained in the <see cref="Histogram"/>.
|
||||
|
/// </summary>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
foreach(Bucket b in buckets) |
||||
|
{ |
||||
|
sb.Append(b.ToString()); |
||||
|
} |
||||
|
|
||||
|
return sb.ToString(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,250 @@ |
|||||
|
// <copyright file="HistogramTests.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.StatisticsTests |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using MbUnit.Framework; |
||||
|
using MathNet.Numerics.Statistics; |
||||
|
|
||||
|
[TestFixture] |
||||
|
public class HistogramTests |
||||
|
{ |
||||
|
#region BucketTests
|
||||
|
[Test] |
||||
|
public void CanCreateEmptyBucket() |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.0); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanCreateFilledBucket() |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.0, 10.0); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedArgumentOutOfRangeException] |
||||
|
public void EmptyBucketWithBadBoundsFails() |
||||
|
{ |
||||
|
var b = new Bucket(1.0, 0.5); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedArgumentOutOfRangeException] |
||||
|
public void EmptyBucketWithBadCountFails() |
||||
|
{ |
||||
|
var b = new Bucket(1.0, 0.5, -1.0); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetBucketWidth() |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.0, 10.0); |
||||
|
Assert.AreEqual(1.0, b.Width); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetBucketCount() |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.0, 10.0); |
||||
|
Assert.AreEqual(10.0, b.Count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetBucketLowerBound() |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.0, 10.0); |
||||
|
Assert.AreEqual(0.0, b.LowerBound); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetBucketUpperBound() |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.0, 10.0); |
||||
|
Assert.AreEqual(1.0, b.UpperBound); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row(1.0, 0)] |
||||
|
[Row(2.0, 1)] |
||||
|
[Row(-1.0, -1)] |
||||
|
public void ValidateContains(double x, int r) |
||||
|
{ |
||||
|
var b = new Bucket(0.0, 1.5, 10.0); |
||||
|
Assert.AreEqual(r, b.Contains(x)); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
|
||||
|
|
||||
|
#region
|
||||
|
[Test] |
||||
|
public void CanCreateEmptyHistogram() |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanAddBucket() |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
h.AddBucket(new Bucket(0.0, 1.0)); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row(0.0, 0)] |
||||
|
[Row(0.5, 0)] |
||||
|
[Row(1.0, 1)] |
||||
|
[Row(10.0, 3)] |
||||
|
[Row(10000.0, 4)] |
||||
|
public void CanGetBucketIndexOf(double x, double i) |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
h.AddBucket(new Bucket(0.0, 1.0)); |
||||
|
h.AddBucket(new Bucket(1.0, 2.0)); |
||||
|
h.AddBucket(new Bucket(2.0, 3.0)); |
||||
|
h.AddBucket(new Bucket(3.0, 20.0)); |
||||
|
h.AddBucket(new Bucket(20.0, Double.PositiveInfinity)); |
||||
|
Assert.AreEqual(i, h.GetBucketIndexOf(x)); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetBucketOf() |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
var b = new Bucket(0.0, 1.0); |
||||
|
h.AddBucket(b); |
||||
|
h.AddBucket(new Bucket(1.0, 2.0)); |
||||
|
h.AddBucket(new Bucket(2.0, 3.0)); |
||||
|
h.AddBucket(new Bucket(3.0, 20.0)); |
||||
|
h.AddBucket(new Bucket(20.0, Double.PositiveInfinity)); |
||||
|
|
||||
|
Assert.AreEqual(b, h.GetBucketOf(0.1)); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[MultipleAsserts] |
||||
|
public void ValidateItem() |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
var b = new Bucket(0.0, 1.0); |
||||
|
var c = new Bucket(3.0, 20.0); |
||||
|
h.AddBucket(b); |
||||
|
h.AddBucket(c); |
||||
|
h.AddBucket(new Bucket(1.0, 2.0)); |
||||
|
h.AddBucket(new Bucket(2.0, 3.0)); |
||||
|
h.AddBucket(new Bucket(20.0, Double.PositiveInfinity)); |
||||
|
|
||||
|
Assert.AreEqual(b, h[0]); |
||||
|
Assert.AreEqual(c, h[3]); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetBucketCountInHistogram() |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
h.AddBucket(new Bucket(0.0, 1.0)); |
||||
|
h.AddBucket(new Bucket(1.0, 2.0)); |
||||
|
h.AddBucket(new Bucket(2.0, 3.0)); |
||||
|
h.AddBucket(new Bucket(3.0, 20.0)); |
||||
|
h.AddBucket(new Bucket(20.0, Double.PositiveInfinity)); |
||||
|
|
||||
|
Assert.AreEqual(5, h.BucketCount); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanGetTotalCount() |
||||
|
{ |
||||
|
var h = new Histogram(); |
||||
|
h.AddBucket(new Bucket(0.0, 1.0, 1)); |
||||
|
h.AddBucket(new Bucket(1.0, 2.0, 1)); |
||||
|
h.AddBucket(new Bucket(2.0, 3.0, 1)); |
||||
|
h.AddBucket(new Bucket(3.0, 20.0, 1)); |
||||
|
h.AddBucket(new Bucket(20.0, Double.PositiveInfinity, 1)); |
||||
|
|
||||
|
Assert.AreEqual(5, h.DataCount); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanCreateEqualSpacedHistogram() |
||||
|
{ |
||||
|
var h = new Histogram(new double[] { 1.0, 5.0, 10.0 }, 2); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedArgumentException] |
||||
|
public void FailCreateEqualSpacedHistogramWithNoData() |
||||
|
{ |
||||
|
var h = new Histogram(new List<double>(), 10); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanCreateEqualSpacedHistogramWithGivenLowerAndUpperBound() |
||||
|
{ |
||||
|
var h = new Histogram(new double[] { 1.0, 5.0, 10.0 }, 2, 0.0, 20.0); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanAddDataSingle() |
||||
|
{ |
||||
|
var h = new Histogram(new double[] { 1.0, 5.0, 10.0 }, 2); |
||||
|
h.AddData(7.0); |
||||
|
Assert.AreEqual(2, h[1].Count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void CanAddDataList() |
||||
|
{ |
||||
|
var h = new Histogram(new double[] { 1.0, 5.0, 10.0 }, 2); |
||||
|
h.AddData(new double[] { 7.0, 8.0} ); |
||||
|
Assert.AreEqual(3, h[1].Count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void AddDataIncreasesUpperBound() |
||||
|
{ |
||||
|
var h = new Histogram(new double[] { 1.0, 5.0, 10.0 }, 2); |
||||
|
h.AddData(20.0); |
||||
|
Assert.AreEqual(2, h[1].Count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void AddDataDecreasesLowerBound() |
||||
|
{ |
||||
|
var h = new Histogram(new double[] { 1.0, 5.0, 10.0 }, 2); |
||||
|
h.AddData(0.0); |
||||
|
Assert.AreEqual(3, h[0].Count); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue