50 changed files with 3642 additions and 2196 deletions
@ -1,5 +1,7 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<repositories> |
|||
<repository path="..\src\FSharpPortableUnitTests\packages.config" /> |
|||
<repository path="..\src\FSharpUnitTests\packages.config" /> |
|||
<repository path="..\src\Numerics.IO\packages.config" /> |
|||
<repository path="..\src\UnitTests\packages.config" /> |
|||
</repositories> |
|||
@ -0,0 +1,34 @@ |
|||
namespace System.Numerics |
|||
|
|||
open System |
|||
|
|||
#if PORTABLE |
|||
|
|||
[<AutoOpen>] |
|||
module BigIntegerExtensions = |
|||
|
|||
let private parse str = |
|||
let len = String.length str |
|||
let rec build acc i = |
|||
if i = len then |
|||
acc |
|||
else |
|||
let c = str.[i] |
|||
let d = int c - int '0' |
|||
if 0 <= d && d <= 9 then |
|||
build (10I * acc + (bigint d)) (i+1) |
|||
else |
|||
raise (new FormatException("The value could not be parsed")) |
|||
build 0I 0 |
|||
|
|||
type BigInteger with |
|||
|
|||
static member Parse(text: string) = |
|||
let len = text.Length |
|||
if len = 0 then raise (new FormatException("The value could not be parsed")) |
|||
if text.[0..0] = "-" then |
|||
parse text.[1..len-1] |> bigint.Negate |
|||
else |
|||
parse text |
|||
|
|||
#endif |
|||
@ -0,0 +1,307 @@ |
|||
// First version copied from the F# Power Pack |
|||
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack/math/q.fs |
|||
// (c) Microsoft Corporation. All rights reserved |
|||
|
|||
#nowarn "44" // OK to use the "compiler only" function RangeGeneric |
|||
#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation |
|||
|
|||
namespace MathNet.Numerics |
|||
|
|||
open System |
|||
open System.Numerics |
|||
open System.Globalization |
|||
|
|||
module BigRationalLargeImpl = |
|||
let ZeroI = new BigInteger(0) |
|||
let OneI = new BigInteger(1) |
|||
let bigint (x:int) = new BigInteger(x) |
|||
let ToDoubleI (x:BigInteger) = double x |
|||
let ToInt32I (x:BigInteger) = int32 x |
|||
|
|||
open BigRationalLargeImpl |
|||
|
|||
[<CustomEquality; CustomComparison>] |
|||
type BigRationalLarge = |
|||
| Q of BigInteger * BigInteger // invariants: (p,q) in lowest form, q >= 0 |
|||
|
|||
override n.ToString() = |
|||
let (Q(p,q)) = n |
|||
if q.IsOne then p.ToString() |
|||
else p.ToString() + "/" + q.ToString() |
|||
|
|||
|
|||
static member Hash (Q(ap,aq)) = |
|||
// This hash code must be identical to the hash for BigInteger when the numbers coincide. |
|||
if aq.IsOne then ap.GetHashCode() else (ap.GetHashCode() <<< 3) + aq.GetHashCode() |
|||
|
|||
|
|||
override x.GetHashCode() = BigRationalLarge.Hash(x) |
|||
|
|||
static member Equals(Q(ap,aq), Q(bp,bq)) = |
|||
BigInteger.(=) (ap,bp) && BigInteger.(=) (aq,bq) // normal form, so structural equality |
|||
|
|||
static member LessThan(Q(ap,aq), Q(bp,bq)) = |
|||
BigInteger.(<) (ap * bq,bp * aq) |
|||
|
|||
// note: performance improvement possible here |
|||
static member Compare(p,q) = |
|||
if BigRationalLarge.LessThan(p,q) then -1 |
|||
elif BigRationalLarge.LessThan(q,p)then 1 |
|||
else 0 |
|||
|
|||
interface System.IComparable with |
|||
member this.CompareTo(obj:obj) = |
|||
match obj with |
|||
| :? BigRationalLarge as that -> BigRationalLarge.Compare(this,that) |
|||
| _ -> invalidArg "obj" "the object does not have the correct type" |
|||
|
|||
override this.Equals(that:obj) = |
|||
match that with |
|||
| :? BigRationalLarge as that -> BigRationalLarge.Equals(this,that) |
|||
| _ -> false |
|||
|
|||
member x.IsNegative = let (Q(ap,_)) = x in sign ap < 0 |
|||
member x.IsPositive = let (Q(ap,_)) = x in sign ap > 0 |
|||
|
|||
member x.Numerator = let (Q(p,_)) = x in p |
|||
member x.Denominator = let (Q(_,q)) = x in q |
|||
member x.Sign = (let (Q(p,_)) = x in sign p) |
|||
|
|||
static member ToDouble (Q(p,q)) = |
|||
ToDoubleI p / ToDoubleI q |
|||
|
|||
static member Normalize (p:BigInteger,q:BigInteger) = |
|||
if q.IsZero then |
|||
raise (System.DivideByZeroException()) (* throw for any x/0 *) |
|||
elif q.IsOne then |
|||
Q(p,q) |
|||
else |
|||
let k = BigInteger.GreatestCommonDivisor(p,q) |
|||
let p = p / k |
|||
let q = q / k |
|||
if sign q < 0 then Q(-p,-q) else Q(p,q) |
|||
|
|||
static member Rational (p:int,q:int) = BigRationalLarge.Normalize (bigint p,bigint q) |
|||
static member RationalZ (p,q) = BigRationalLarge.Normalize (p,q) |
|||
|
|||
static member Parse (str:string) = |
|||
let len = str.Length |
|||
if len=0 then invalidArg "str" "empty string"; |
|||
let j = str.IndexOf '/' |
|||
if j >= 0 then |
|||
let p = BigInteger.Parse (str.Substring(0,j)) |
|||
let q = BigInteger.Parse (str.Substring(j+1,len-j-1)) |
|||
BigRationalLarge.RationalZ (p,q) |
|||
else |
|||
let p = BigInteger.Parse str |
|||
BigRationalLarge.RationalZ (p,OneI) |
|||
|
|||
static member (~-) (Q(bp,bq)) = Q(-bp,bq) // still coprime, bq >= 0 |
|||
static member (+) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) + (bp * aq),aq * bq) |
|||
static member (-) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) - (bp * aq),aq * bq) |
|||
static member (*) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bp,aq * bq) |
|||
static member (/) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bq,aq * bp) |
|||
static member ( ~+ )(n1:BigRationalLarge) = n1 |
|||
|
|||
|
|||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] |
|||
module BigRationalLarge = |
|||
open System.Numerics |
|||
|
|||
let inv (Q(ap,aq)) = BigRationalLarge.Normalize(aq,ap) |
|||
|
|||
let pown (Q(p,q)) (n:int) = Q(BigInteger.Pow(p,n),BigInteger.Pow (q,n)) // p,q powers still coprime |
|||
|
|||
let equal (Q(ap,aq)) (Q(bp,bq)) = ap=bp && aq=bq // normal form, so structural equality |
|||
let lt a b = BigRationalLarge.LessThan(a,b) |
|||
let gt a b = BigRationalLarge.LessThan(b,a) |
|||
let lte (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(<=) (ap * bq,bp * aq) |
|||
let gte (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(>=) (ap * bq,bp * aq) |
|||
|
|||
let of_bigint z = BigRationalLarge.RationalZ(z,OneI) |
|||
let of_int n = BigRationalLarge.Rational(n,1) |
|||
|
|||
// integer part |
|||
let integer (Q(p,q)) = |
|||
let mutable r = BigInteger(0) |
|||
let d = BigInteger.DivRem (p,q,&r) // have p = d.q + r, |r| < |q| |
|||
if r < ZeroI |
|||
then d - OneI // p = (d-1).q + (r+q) |
|||
else d // p = d.q + r |
|||
|
|||
|
|||
//---------------------------------------------------------------------------- |
|||
// BigRational |
|||
//-------------------------------------------------------------------------- |
|||
|
|||
[<CustomEquality; CustomComparison>] |
|||
[<StructuredFormatDisplay("{StructuredDisplayString}N")>] |
|||
type BigRational = |
|||
| Z of BigInteger |
|||
| Q of BigRationalLarge |
|||
|
|||
static member ( + )(n1,n2) = |
|||
match n1,n2 with |
|||
| Z z ,Z zz -> Z (z + zz) |
|||
| Q q ,Q qq -> Q (q + qq) |
|||
| Z z ,Q qq -> Q (BigRationalLarge.of_bigint z + qq) |
|||
| Q q ,Z zz -> Q (q + BigRationalLarge.of_bigint zz) |
|||
|
|||
static member ( * )(n1,n2) = |
|||
match n1,n2 with |
|||
| Z z ,Z zz -> Z (z * zz) |
|||
| Q q ,Q qq -> Q (q * qq) |
|||
| Z z ,Q qq -> Q (BigRationalLarge.of_bigint z * qq) |
|||
| Q q ,Z zz -> Q (q * BigRationalLarge.of_bigint zz) |
|||
|
|||
static member ( - )(n1,n2) = |
|||
match n1,n2 with |
|||
| Z z ,Z zz -> Z (z - zz) |
|||
| Q q ,Q qq -> Q (q - qq) |
|||
| Z z ,Q qq -> Q (BigRationalLarge.of_bigint z - qq) |
|||
| Q q ,Z zz -> Q (q - BigRationalLarge.of_bigint zz) |
|||
|
|||
static member ( / )(n1,n2) = |
|||
match n1,n2 with |
|||
| Z z ,Z zz -> Q (BigRationalLarge.RationalZ(z,zz)) |
|||
| Q q ,Q qq -> Q (q / qq) |
|||
| Z z ,Q qq -> Q (BigRationalLarge.of_bigint z / qq) |
|||
| Q q ,Z zz -> Q (q / BigRationalLarge.of_bigint zz) |
|||
|
|||
static member ( ~- )(n1) = |
|||
match n1 with |
|||
| Z z -> Z (-z) |
|||
| Q q -> Q (-q) |
|||
|
|||
static member ( ~+ )(n1:BigRational) = n1 |
|||
|
|||
// nb. Q and Z hash codes must match up - see notes above |
|||
override n.GetHashCode() = |
|||
match n with |
|||
| Z z -> z.GetHashCode() |
|||
| Q q -> q.GetHashCode() |
|||
|
|||
override this.Equals(obj:obj) = |
|||
match obj with |
|||
| :? BigRational as that -> BigRational.(=)(this, that) |
|||
| _ -> false |
|||
|
|||
interface System.IComparable with |
|||
member n1.CompareTo(obj:obj) = |
|||
match obj with |
|||
| :? BigRational as n2 -> |
|||
if BigRational.(<)(n1, n2) then -1 elif BigRational.(=)(n1, n2) then 0 else 1 |
|||
| _ -> invalidArg "obj" "the objects are not comparable" |
|||
|
|||
static member FromInt (x:int) = Z (bigint x) |
|||
static member FromBigInt x = Z x |
|||
|
|||
static member Zero = BigRational.FromInt(0) |
|||
static member One = BigRational.FromInt(1) |
|||
|
|||
|
|||
static member PowN (n,i:int) = |
|||
match n with |
|||
| Z z -> Z (BigInteger.Pow (z,i)) |
|||
| Q q -> Q (BigRationalLarge.pown q i) |
|||
|
|||
static member op_Equality (n,nn) = |
|||
match n,nn with |
|||
| Z z ,Z zz -> BigInteger.(=) (z,zz) |
|||
| Q q ,Q qq -> (BigRationalLarge.equal q qq) |
|||
| Z z ,Q qq -> (BigRationalLarge.equal (BigRationalLarge.of_bigint z) qq) |
|||
| Q q ,Z zz -> (BigRationalLarge.equal q (BigRationalLarge.of_bigint zz)) |
|||
static member op_Inequality (n,nn) = not (BigRational.op_Equality(n,nn)) |
|||
|
|||
static member op_LessThan (n,nn) = |
|||
match n,nn with |
|||
| Z z ,Z zz -> BigInteger.(<) (z,zz) |
|||
| Q q ,Q qq -> (BigRationalLarge.lt q qq) |
|||
| Z z ,Q qq -> (BigRationalLarge.lt (BigRationalLarge.of_bigint z) qq) |
|||
| Q q ,Z zz -> (BigRationalLarge.lt q (BigRationalLarge.of_bigint zz)) |
|||
static member op_GreaterThan (n,nn) = |
|||
match n,nn with |
|||
| Z z ,Z zz -> BigInteger.(>) (z,zz) |
|||
| Q q ,Q qq -> (BigRationalLarge.gt q qq) |
|||
| Z z ,Q qq -> (BigRationalLarge.gt (BigRationalLarge.of_bigint z) qq) |
|||
| Q q ,Z zz -> (BigRationalLarge.gt q (BigRationalLarge.of_bigint zz)) |
|||
static member op_LessThanOrEqual (n,nn) = |
|||
match n,nn with |
|||
| Z z ,Z zz -> BigInteger.(<=) (z,zz) |
|||
| Q q ,Q qq -> (BigRationalLarge.lte q qq) |
|||
| Z z ,Q qq -> (BigRationalLarge.lte (BigRationalLarge.of_bigint z) qq) |
|||
| Q q ,Z zz -> (BigRationalLarge.lte q (BigRationalLarge.of_bigint zz)) |
|||
static member op_GreaterThanOrEqual (n,nn) = |
|||
match n,nn with |
|||
| Z z ,Z zz -> BigInteger.(>=) (z,zz) |
|||
| Q q ,Q qq -> (BigRationalLarge.gte q qq) |
|||
| Z z ,Q qq -> (BigRationalLarge.gte (BigRationalLarge.of_bigint z) qq) |
|||
| Q q ,Z zz -> (BigRationalLarge.gte q (BigRationalLarge.of_bigint zz)) |
|||
|
|||
|
|||
member n.IsNegative = |
|||
match n with |
|||
| Z z -> sign z < 0 |
|||
| Q q -> q.IsNegative |
|||
|
|||
member n.IsPositive = |
|||
match n with |
|||
| Z z -> sign z > 0 |
|||
| Q q -> q.IsPositive |
|||
|
|||
member n.Numerator = |
|||
match n with |
|||
| Z z -> z |
|||
| Q q -> q.Numerator |
|||
|
|||
member n.Denominator = |
|||
match n with |
|||
| Z _ -> OneI |
|||
| Q q -> q.Denominator |
|||
|
|||
member n.Sign = |
|||
if n.IsNegative then -1 |
|||
elif n.IsPositive then 1 |
|||
else 0 |
|||
|
|||
static member Abs(n:BigRational) = |
|||
if n.IsNegative then -n else n |
|||
|
|||
static member ToDouble(n:BigRational) = |
|||
match n with |
|||
| Z z -> ToDoubleI z |
|||
| Q q -> BigRationalLarge.ToDouble q |
|||
|
|||
static member ToBigInt(n:BigRational) = |
|||
match n with |
|||
| Z z -> z |
|||
| Q q -> BigRationalLarge.integer q |
|||
|
|||
static member ToInt32(n:BigRational) = |
|||
match n with |
|||
| Z z -> ToInt32I(z) |
|||
| Q q -> ToInt32I(BigRationalLarge.integer q) |
|||
|
|||
static member op_Explicit (n:BigRational) = BigRational.ToInt32 n |
|||
static member op_Explicit (n:BigRational) = BigRational.ToDouble n |
|||
static member op_Explicit (n:BigRational) = BigRational.ToBigInt n |
|||
|
|||
|
|||
override n.ToString() = |
|||
match n with |
|||
| Z z -> z.ToString() |
|||
| Q q -> q.ToString() |
|||
|
|||
member x.StructuredDisplayString = x.ToString() |
|||
|
|||
static member Parse(s:string) = Q (BigRationalLarge.Parse s) |
|||
|
|||
type BigNum = BigRational |
|||
type bignum = BigNum |
|||
|
|||
module NumericLiteralN = |
|||
let FromZero () = BigRational.Zero |
|||
let FromOne () = BigRational.One |
|||
let FromInt32 i = BigRational.FromInt i |
|||
let FromInt64 (i64:int64) = BigRational.FromBigInt (new BigInteger(i64)) |
|||
let FromString s = BigRational.Parse s |
|||
@ -0,0 +1,94 @@ |
|||
// First version copied from the F# Power Pack |
|||
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack/math/q.fsi |
|||
// (c) Microsoft Corporation 2005-2009. |
|||
|
|||
namespace MathNet.Numerics |
|||
|
|||
open System |
|||
open System.Numerics |
|||
|
|||
/// The type of arbitrary-sized rational numbers |
|||
[<Sealed>] |
|||
type BigRational = |
|||
/// Return the sum of two rational numbers |
|||
static member ( + ) : BigRational * BigRational -> BigRational |
|||
/// Return the product of two rational numbers |
|||
static member ( * ) : BigRational * BigRational -> BigRational |
|||
/// Return the difference of two rational numbers |
|||
static member ( - ) : BigRational * BigRational -> BigRational |
|||
/// Return the ratio of two rational numbers |
|||
static member ( / ) : BigRational * BigRational -> BigRational |
|||
/// Return the negation of a rational number |
|||
static member ( ~- ): BigRational -> BigRational |
|||
/// Return the given rational number |
|||
static member ( ~+ ): BigRational -> BigRational |
|||
|
|||
override ToString: unit -> string |
|||
override GetHashCode: unit -> int |
|||
interface System.IComparable |
|||
|
|||
/// Get zero as a rational number |
|||
static member Zero : BigRational |
|||
/// Get one as a rational number |
|||
static member One : BigRational |
|||
/// This operator is for use from other .NET languages |
|||
static member op_Equality : BigRational * BigRational -> bool |
|||
/// This operator is for use from other .NET languages |
|||
static member op_Inequality : BigRational * BigRational -> bool |
|||
/// This operator is for use from other .NET languages |
|||
static member op_LessThan: BigRational * BigRational -> bool |
|||
/// This operator is for use from other .NET languages |
|||
static member op_GreaterThan: BigRational * BigRational -> bool |
|||
/// This operator is for use from other .NET languages |
|||
static member op_LessThanOrEqual: BigRational * BigRational -> bool |
|||
/// This operator is for use from other .NET languages |
|||
static member op_GreaterThanOrEqual: BigRational * BigRational -> bool |
|||
|
|||
/// Return a boolean indicating if this rational number is strictly negative |
|||
member IsNegative: bool |
|||
/// Return a boolean indicating if this rational number is strictly positive |
|||
member IsPositive: bool |
|||
|
|||
/// Return the numerator of the normalized rational number |
|||
member Numerator: BigInteger |
|||
/// Return the denominator of the normalized rational number |
|||
member Denominator: BigInteger |
|||
|
|||
member StructuredDisplayString : string |
|||
|
|||
/// Return the absolute value of a rational number |
|||
static member Abs : BigRational -> BigRational |
|||
/// Return the sign of a rational number; 0, +1 or -1 |
|||
member Sign : int |
|||
/// Return the result of raising the given rational number to the given power |
|||
static member PowN : BigRational * int -> BigRational |
|||
/// Return the result of converting the given integer to a rational number |
|||
static member FromInt : int -> BigRational |
|||
/// Return the result of converting the given big integer to a rational number |
|||
static member FromBigInt : BigInteger -> BigRational |
|||
/// Return the result of converting the given rational number to a floating point number |
|||
static member ToDouble: BigRational -> float |
|||
/// Return the result of converting the given rational number to a big integer |
|||
static member ToBigInt: BigRational -> BigInteger |
|||
/// Return the result of converting the given rational number to an integer |
|||
static member ToInt32 : BigRational -> int |
|||
/// Return the result of converting the given rational number to a floating point number |
|||
static member op_Explicit : BigRational -> float |
|||
/// Return the result of converting the given rational number to a big integer |
|||
static member op_Explicit : BigRational -> BigInteger |
|||
/// Return the result of converting the given rational number to an integer |
|||
static member op_Explicit : BigRational -> int |
|||
/// Return the result of converting the string to a rational number |
|||
static member Parse: string -> BigRational |
|||
|
|||
type BigNum = BigRational |
|||
|
|||
type bignum = BigRational |
|||
|
|||
[<RequireQualifiedAccess>] |
|||
module NumericLiteralN = |
|||
val FromZero : unit -> BigRational |
|||
val FromOne : unit -> BigRational |
|||
val FromInt32 : int32 -> BigRational |
|||
val FromInt64 : int64 -> BigRational |
|||
val FromString : string -> BigRational |
|||
@ -0,0 +1,152 @@ |
|||
// First version copied from the F# Power Pack |
|||
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack/math/complex.fs |
|||
// (c) Microsoft Corporation 2005-2009. |
|||
|
|||
namespace MathNet.Numerics |
|||
|
|||
open Microsoft.FSharp.Math |
|||
open System |
|||
open System.Globalization |
|||
open System.Numerics |
|||
|
|||
type complex = Complex |
|||
type complex32 = Complex32 |
|||
|
|||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] |
|||
[<RequireQualifiedAccess>] |
|||
module Complex = |
|||
|
|||
let mkRect(a,b) = new Complex(a,b) |
|||
let mkPolar(a,b) = Complex.FromPolarCoordinates(a,b) |
|||
let cis b = mkPolar(1.0,b) |
|||
let ofComplex32 (x:complex32) = new Complex(float x.Real, float x.Imaginary) |
|||
|
|||
let zero = Complex.Zero |
|||
let one = Complex.One |
|||
let onei = Complex.ImaginaryOne |
|||
let pi = mkRect (Math.PI,0.0) |
|||
|
|||
let realPart (c:complex) = c.Real |
|||
let imagPart (c:complex) = c.Imaginary |
|||
let magnitude (c:complex) = c.Magnitude |
|||
let phase (c:complex) = c.Phase |
|||
|
|||
let neg (a:complex) = -a |
|||
let conjugate (c:complex) = c.Conjugate() |
|||
|
|||
let add (a:complex) (b:complex) = a + b |
|||
let sub (a:complex) (b:complex) = a - b |
|||
let mul (a:complex) (b:complex) = a * b |
|||
let div (x:complex) (y:complex) = x / y |
|||
|
|||
let smul (a:float) (b:complex) = new Complex(a * b.Real, a * b.Imaginary) |
|||
let muls (a:complex) (b:float) = new Complex(a.Real * b, a.Imaginary * b) |
|||
|
|||
let exp (x:complex) = Complex.Exp(x) |
|||
let ln x = Complex.Log(x) |
|||
let log10 x = Complex.Log10(x) |
|||
let log b x = Complex.Log(x,b) |
|||
let pow (power:complex) x = Complex.Pow(x,power) |
|||
let powf (power:float) x = Complex.Pow(x,power) |
|||
let sqr (x:complex) = x.Square() |
|||
let sqrt (x:complex) = x.SquareRoot() // numerically more stable than Complex.Sqrt |
|||
|
|||
let sin x = Complex.Sin(x) |
|||
let cos x = Complex.Cos(x) |
|||
let tan x = Complex.Tan(x) |
|||
let asin x = Complex.Asin(x) |
|||
let acos x = Complex.Acos(x) |
|||
let atan x = Complex.Atan(x) |
|||
let sinh x = Complex.Sinh(x) |
|||
let cosh x = Complex.Cosh(x) |
|||
let tanh x = Complex.Tanh(x) |
|||
|
|||
let sec (x:complex) = Trig.Secant(x) |
|||
let csc (x:complex) = Trig.Cosecant(x) |
|||
let cot (x:complex) = Trig.Cotangent(x) |
|||
let asec (x:complex) = Trig.InverseSecant(x) |
|||
let acsc (x:complex) = Trig.InverseCosecant(x) |
|||
let acot (x:complex) = Trig.InverseCotangent(x) |
|||
let sech (x:complex) = Trig.HyperbolicSecant(x) |
|||
let csch (x:complex) = Trig.HyperbolicCosecant(x) |
|||
let coth (x:complex) = Trig.HyperbolicCotangent(x) |
|||
|
|||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] |
|||
[<RequireQualifiedAccess>] |
|||
module Complex32 = |
|||
|
|||
let mkRect(a,b) = new Complex32(a,b) |
|||
let mkPolar(a,b) = Complex32.FromPolarCoordinates(a,b) |
|||
let cis b = mkPolar(1.0f,b) |
|||
let ofComplex (x:complex) = new Complex32(float32 x.Real, float32 x.Imaginary) |
|||
|
|||
let zero = Complex32.Zero |
|||
let one = Complex32.One |
|||
let onei = Complex32.ImaginaryOne |
|||
let pi = mkRect (float32 Math.PI,0.0f) |
|||
|
|||
let realPart (c:complex32) = c.Real |
|||
let imagPart (c:complex32) = c.Imaginary |
|||
let magnitude (c:complex32) = c.Magnitude |
|||
let phase (c:complex32) = c.Phase |
|||
|
|||
let neg (a:complex32) = -a |
|||
let conjugate (c:complex32) = c.Conjugate() |
|||
|
|||
let add (a:complex32) (b:complex32) = a + b |
|||
let sub (a:complex32) (b:complex32) = a - b |
|||
let mul (a:complex32) (b:complex32) = a * b |
|||
let div (x:complex32) (y:complex32) = x / y |
|||
|
|||
let smul (a:float32) (b:complex32) = new Complex32(a * b.Real, a * b.Imaginary) |
|||
let muls (a:complex32) (b:float32) = new Complex32(a.Real * b, a.Imaginary * b) |
|||
|
|||
let exp (x:complex32) = Complex32.Exp(x) |
|||
let ln x = Complex32.Log(x) |
|||
let log10 x = Complex32.Log10(x) |
|||
let log b x = Complex32.Log(x,b) |
|||
let pow (power:complex32) x = Complex32.Pow(x,power) |
|||
let powf (power:float32) x = Complex32.Pow(x,power) |
|||
let sqr (x:complex32) = x.Square() |
|||
let sqrt (x:complex32) = x.SquareRoot() // numerically more stable than Complex.Sqrt |
|||
|
|||
let sin x = Complex32.Sin(x) |
|||
let cos x = Complex32.Cos(x) |
|||
let tan x = Complex32.Tan(x) |
|||
let asin x = Complex32.Asin(x) |
|||
let acos x = Complex32.Acos(x) |
|||
let atan x = Complex32.Atan(x) |
|||
let sinh x = Complex32.Sinh(x) |
|||
let cosh x = Complex32.Cosh(x) |
|||
let tanh x = Complex32.Tanh(x) |
|||
|
|||
// no complex32 implementations available yet, fix once available |
|||
let sec (x:complex32) = ofComplex <| Trig.Secant(x.ToComplex()) |
|||
let csc (x:complex32) = ofComplex <| Trig.Cosecant(x.ToComplex()) |
|||
let cot (x:complex32) = ofComplex <| Trig.Cotangent(x.ToComplex()) |
|||
let asec (x:complex32) = ofComplex <| Trig.InverseSecant(x.ToComplex()) |
|||
let acsc (x:complex32) = ofComplex <| Trig.InverseCosecant(x.ToComplex()) |
|||
let acot (x:complex32) = ofComplex <| Trig.InverseCotangent(x.ToComplex()) |
|||
let sech (x:complex32) = ofComplex <| Trig.HyperbolicSecant(x.ToComplex()) |
|||
let csch (x:complex32) = ofComplex <| Trig.HyperbolicCosecant(x.ToComplex()) |
|||
let coth (x:complex32) = ofComplex <| Trig.HyperbolicCotangent(x.ToComplex()) |
|||
|
|||
[<AutoOpen>] |
|||
module ComplexExtensions = |
|||
|
|||
let complex x y = Complex.mkRect (x,y) |
|||
let complex32 x y = Complex32.mkRect (x,y) |
|||
|
|||
type Complex with |
|||
member x.r = x.Real |
|||
member x.i = x.Imaginary |
|||
|
|||
static member Create(a,b) = Complex.mkRect (a,b) |
|||
static member CreatePolar(a,b) = Complex.mkPolar (a,b) |
|||
|
|||
type Complex32 with |
|||
member x.r = x.Real |
|||
member x.i = x.Imaginary |
|||
|
|||
static member Create(a,b) = Complex32.mkRect (a,b) |
|||
static member CreatePolar(a,b) = Complex32.mkPolar (a,b) |
|||
@ -0,0 +1,253 @@ |
|||
// First version copied from the F# Power Pack |
|||
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack/math/complex.fsi |
|||
// (c) Microsoft Corporation 2005-2009. |
|||
|
|||
namespace MathNet.Numerics |
|||
|
|||
open System |
|||
open System.Numerics |
|||
|
|||
/// The type of complex numbers |
|||
type complex = Complex |
|||
type complex32 = Complex32 |
|||
|
|||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] |
|||
[<RequireQualifiedAccess>] |
|||
module Complex = |
|||
|
|||
/// Create a complex number using real and imaginary parts |
|||
val mkRect : float * float -> complex |
|||
/// Create a complex number using magnitude/phase polar coordinates |
|||
val mkPolar : float * float -> complex |
|||
/// A complex of magnitude 1 and the given phase and , i.e. cis x = mkPolar 1.0 x |
|||
val cis : float -> complex |
|||
|
|||
/// The complex number 0+0i |
|||
val zero : complex |
|||
/// The complex number 1+0i |
|||
val one : complex |
|||
/// The complex number 0+1i |
|||
val onei : complex |
|||
/// pi |
|||
val pi : complex |
|||
|
|||
/// The real part of a complex number |
|||
val realPart : complex -> float |
|||
/// The imaginary part of a complex number |
|||
val imagPart : complex -> float |
|||
/// The polar-coordinate magnitude of a complex number |
|||
val magnitude : complex -> float |
|||
/// The polar-coordinate phase of a complex number |
|||
val phase : complex -> float |
|||
|
|||
/// Unary negation of a complex number |
|||
val neg : complex -> complex |
|||
/// The conjugate of a complex number, i.e. x-yi |
|||
val conjugate : complex -> complex |
|||
|
|||
/// Add two complex numbers |
|||
val add : complex -> complex -> complex |
|||
/// Subtract one complex number from another |
|||
val sub : complex -> complex -> complex |
|||
/// Multiply two complex numbers |
|||
val mul : complex -> complex -> complex |
|||
/// Complex division of two complex numbers |
|||
val div : complex -> complex -> complex |
|||
|
|||
/// Multiply a scalar by a complex number |
|||
val smul : float -> complex -> complex |
|||
/// Multiply a complex number by a scalar |
|||
val muls : complex -> float -> complex |
|||
|
|||
/// exp(x) = e^x |
|||
val exp : complex -> complex |
|||
/// ln(x) is natural log (base e) |
|||
val ln : complex -> complex |
|||
/// log10(x) is common log (base 10) |
|||
val log10 : complex -> complex |
|||
/// log(base,x) is log with custom base |
|||
val log : float -> complex -> complex |
|||
/// pow(power,x) is the complex power |
|||
val pow : complex -> complex -> complex |
|||
/// pow(power,x) is the float power |
|||
val powf : float -> complex -> complex |
|||
/// sqr(x) is the square (power 2) |
|||
val sqr : complex -> complex |
|||
/// sqrt(x) and 0 <= phase(x) < pi |
|||
val sqrt : complex -> complex |
|||
|
|||
/// Sine |
|||
val sin : complex -> complex |
|||
/// Cosine |
|||
val cos : complex -> complex |
|||
/// Tagent |
|||
val tan : complex -> complex |
|||
/// Arc Sine |
|||
val asin : complex -> complex |
|||
/// Arc Cosine |
|||
val acos : complex -> complex |
|||
/// Arc Tagent |
|||
val atan : complex -> complex |
|||
/// Hyperbolic Sine |
|||
val sinh : complex -> complex |
|||
/// Hyperbolic Cosine |
|||
val cosh : complex -> complex |
|||
/// Hyperbolic Tagent |
|||
val tanh : complex -> complex |
|||
|
|||
/// Secant |
|||
val sec : complex -> complex |
|||
/// Cosecant |
|||
val csc : complex -> complex |
|||
/// Cotangent |
|||
val cot : complex -> complex |
|||
/// Arc Secant |
|||
val asec : complex -> complex |
|||
/// Arc Cosecant |
|||
val acsc : complex -> complex |
|||
/// Arc Cotangent |
|||
val acot : complex -> complex |
|||
/// Hyperbolic Secant |
|||
val sech : complex -> complex |
|||
/// Hyperbolic Cosecant |
|||
val csch : complex -> complex |
|||
/// Hyperbolic Cotangent |
|||
val coth : complex -> complex |
|||
|
|||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] |
|||
[<RequireQualifiedAccess>] |
|||
module Complex32 = |
|||
|
|||
/// Create a complex number using real and imaginary parts |
|||
val mkRect : float32 * float32 -> complex32 |
|||
/// Create a complex number using magnitude/phase polar coordinates |
|||
val mkPolar : float32 * float32 -> complex32 |
|||
/// A complex of magnitude 1 and the given phase and , i.e. cis x = mkPolar 1.0 x |
|||
val cis : float32 -> complex32 |
|||
|
|||
/// The complex number 0+0i |
|||
val zero : complex32 |
|||
/// The complex number 1+0i |
|||
val one : complex32 |
|||
/// The complex number 0+1i |
|||
val onei : complex32 |
|||
/// pi |
|||
val pi : complex32 |
|||
|
|||
/// The real part of a complex number |
|||
val realPart : complex32 -> float32 |
|||
/// The imaginary part of a complex number |
|||
val imagPart : complex32 -> float32 |
|||
/// The polar-coordinate magnitude of a complex number |
|||
val magnitude : complex32 -> float32 |
|||
/// The polar-coordinate phase of a complex number |
|||
val phase : complex32 -> float32 |
|||
|
|||
/// Unary negation of a complex number |
|||
val neg : complex32 -> complex32 |
|||
/// The conjugate of a complex number, i.e. x-yi |
|||
val conjugate : complex32 -> complex32 |
|||
|
|||
/// Add two complex numbers |
|||
val add : complex32 -> complex32 -> complex32 |
|||
/// Subtract one complex number from another |
|||
val sub : complex32 -> complex32 -> complex32 |
|||
/// Multiply two complex numbers |
|||
val mul : complex32 -> complex32 -> complex32 |
|||
/// Complex division of two complex numbers |
|||
val div : complex32 -> complex32 -> complex32 |
|||
|
|||
/// Multiply a scalar by a complex number |
|||
val smul : float32 -> complex32 -> complex32 |
|||
/// Multiply a complex number by a scalar |
|||
val muls : complex32 -> float32 -> complex32 |
|||
|
|||
/// exp(x) = e^x |
|||
val exp : complex32 -> complex32 |
|||
/// ln(x) is natural log (base e) |
|||
val ln : complex32 -> complex32 |
|||
/// log10(x) is common log (base 10) |
|||
val log10 : complex32 -> complex32 |
|||
/// log(base,x) is log with custom base |
|||
val log : float32 -> complex32 -> complex32 |
|||
/// pow(power,x) is the complex power |
|||
val pow : complex32 -> complex32 -> complex32 |
|||
/// pow(power,x) is the float power |
|||
val powf : float32 -> complex32 -> complex32 |
|||
/// sqr(x) is the square (power 2) |
|||
val sqr : complex32 -> complex32 |
|||
/// sqrt(x) and 0 <= phase(x) < pi |
|||
val sqrt : complex32 -> complex32 |
|||
|
|||
/// Sine |
|||
val sin : complex32 -> complex32 |
|||
/// Cosine |
|||
val cos : complex32 -> complex32 |
|||
/// Tagent |
|||
val tan : complex32 -> complex32 |
|||
/// Arc Sine |
|||
val asin : complex32 -> complex32 |
|||
/// Arc Cosine |
|||
val acos : complex32 -> complex32 |
|||
/// Arc Tagent |
|||
val atan : complex32 -> complex32 |
|||
/// Hyperbolic Sine |
|||
val sinh : complex32 -> complex32 |
|||
/// Hyperbolic Cosine |
|||
val cosh : complex32 -> complex32 |
|||
/// Hyperbolic Tagent |
|||
val tanh : complex32 -> complex32 |
|||
|
|||
/// Secant |
|||
val sec : complex32 -> complex32 |
|||
/// Cosecant |
|||
val csc : complex32 -> complex32 |
|||
/// Cotangent |
|||
val cot : complex32 -> complex32 |
|||
/// Arc Secant |
|||
val asec : complex32 -> complex32 |
|||
/// Arc Cosecant |
|||
val acsc : complex32 -> complex32 |
|||
/// Arc Cotangent |
|||
val acot : complex32 -> complex32 |
|||
/// Hyperbolic Secant |
|||
val sech : complex32 -> complex32 |
|||
/// Hyperbolic Cosecant |
|||
val csch : complex32 -> complex32 |
|||
/// Hyperbolic Cotangent |
|||
val coth : complex32 -> complex32 |
|||
|
|||
[<AutoOpen>] |
|||
module ComplexExtensions = |
|||
|
|||
/// Constructs a double precision complex number from both the real and imaginary part. |
|||
val complex : float -> float -> complex |
|||
|
|||
/// Constructs a single precision complex number from both the real and imaginary part. |
|||
val complex32 : float32 -> float32 -> complex32 |
|||
|
|||
/// The type of complex numbers stored as pairs of 64-bit floating point numbers in rectangular coordinates |
|||
type Complex with |
|||
|
|||
/// Create a complex number x+ij using rectangular coordinates |
|||
static member Create : float * float -> Complex |
|||
/// Create a complex number using magnitude/phase polar coordinates |
|||
static member CreatePolar : float * float -> Complex |
|||
|
|||
/// The real part of a complex number |
|||
member r: float |
|||
/// The imaginary part of a complex number |
|||
member i: float |
|||
|
|||
/// The type of complex numbers stored as pairs of 32-bit floating point numbers in rectangular coordinates |
|||
type Complex32 with |
|||
|
|||
/// Create a complex number x+ij using rectangular coordinates |
|||
static member Create : float32 * float32 -> Complex32 |
|||
/// Create a complex number using magnitude/phase polar coordinates |
|||
static member CreatePolar : float32 * float32 -> Complex32 |
|||
|
|||
/// The real part of a complex number |
|||
member r: float32 |
|||
/// The imaginary part of a complex number |
|||
member i: float32 |
|||
@ -0,0 +1,95 @@ |
|||
module MathNet.Numerics.Probability |
|||
|
|||
#nowarn "40" |
|||
|
|||
open System |
|||
open System.Collections |
|||
open System.Collections.Generic |
|||
open MathNet.Numerics |
|||
|
|||
type Outcome<'T> = { |
|||
Value: 'T |
|||
Probability : BigRational } |
|||
|
|||
type RandomVariable<'T> = Outcome<'T> seq |
|||
|
|||
// P(A AND B) = P(A | B) * P(B) |
|||
let private bind f dist = |
|||
dist |
|||
|> Seq.map (fun p1 -> |
|||
f p1.Value |
|||
|> Seq.map (fun p2 -> |
|||
{ Value = p2.Value; |
|||
Probability = |
|||
p1.Probability * p2.Probability})) |
|||
|> Seq.concat |
|||
|
|||
/// Inject a value into the RandomVariable type |
|||
let private returnM value = |
|||
Seq.singleton { Value = value ; Probability = 1N/1N } |
|||
|
|||
type RandomVariableBuilder() = |
|||
member this.Bind (r, f) = bind f r |
|||
member this.Return x = returnM x |
|||
member this.ReturnFrom x = x |
|||
|
|||
let randomVariable = RandomVariableBuilder() |
|||
|
|||
type CoinSide = |
|||
| Heads |
|||
| Tails |
|||
|
|||
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] |
|||
[<RequireQualifiedAccess>] |
|||
module RandomVariable = |
|||
|
|||
// Create some helpers |
|||
let toUniformDistribution seq = |
|||
let l = Seq.length seq |
|||
seq |
|||
|> Seq.map (fun e -> |
|||
{ Value = e; |
|||
Probability = 1N / bignum.FromInt l }) |
|||
|
|||
let probability dist = |
|||
dist |
|||
|> Seq.map (fun o -> o.Probability) |
|||
|> Seq.sum |
|||
|
|||
let certainly = returnM |
|||
let impossible<'a> :'a RandomVariable = toUniformDistribution [] |
|||
|
|||
let fairDice sides = toUniformDistribution [1..sides] |
|||
|
|||
let fairCoin = toUniformDistribution [Heads; Tails] |
|||
|
|||
let filter predicate dist = |
|||
dist |> Seq.filter (fun o -> predicate o.Value) |
|||
|
|||
let filterInAnyOrder items dist = |
|||
items |
|||
|> Seq.fold (fun d item -> filter (Seq.exists ((=) (item))) d) dist |
|||
|
|||
/// Transforms a RandomVariable value by using a specified mapping function. |
|||
let map f dist = |
|||
dist |
|||
|> Seq.map (fun o -> { Value = f o.Value; Probability = o.Probability }) |
|||
|
|||
let selectOne values = |
|||
[for e in values -> e,values |> Seq.filter ((<>) e)] |
|||
|> toUniformDistribution |
|||
|
|||
let rec selectMany n values = |
|||
match n with |
|||
| 0 -> certainly ([],values) |
|||
| _ -> |
|||
randomVariable { |
|||
let! (x,c1) = selectOne values |
|||
let! (xs,c2) = selectMany (n-1) c1 |
|||
return x::xs,c2} |
|||
|
|||
let select n values = |
|||
selectMany n values |
|||
|> map (fst >> List.rev) |
|||
|
|||
let remove items = Seq.filter (fun v -> Seq.forall ((<>) v) items) |
|||
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<configuration> |
|||
<runtime> |
|||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
|||
<dependentAssembly> |
|||
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> |
|||
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" /> |
|||
</dependentAssembly> |
|||
</assemblyBinding> |
|||
</runtime> |
|||
</configuration> |
|||
@ -0,0 +1,104 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
|||
<PropertyGroup> |
|||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
<ProjectGuid>90ce8e32-354e-4728-8fe6-87342f469321</ProjectGuid> |
|||
<OutputType>Library</OutputType> |
|||
<RootNamespace>FSharpPortableUnitTests</RootNamespace> |
|||
<AssemblyName>FSharpPortableUnitTests</AssemblyName> |
|||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
|||
<Name>FSharpPortableUnitTests</Name> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|||
<DebugSymbols>true</DebugSymbols> |
|||
<DebugType>full</DebugType> |
|||
<Optimize>false</Optimize> |
|||
<Tailcalls>false</Tailcalls> |
|||
<OutputPath>bin\Debug\</OutputPath> |
|||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|||
<WarningLevel>3</WarningLevel> |
|||
<DocumentationFile>bin\Debug\FSharpPortableUnitTests.XML</DocumentationFile> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|||
<DebugType>pdbonly</DebugType> |
|||
<Optimize>true</Optimize> |
|||
<Tailcalls>true</Tailcalls> |
|||
<OutputPath>bin\Release\</OutputPath> |
|||
<DefineConstants>TRACE</DefineConstants> |
|||
<WarningLevel>3</WarningLevel> |
|||
<DocumentationFile>bin\Release\FSharpPortableUnitTests.XML</DocumentationFile> |
|||
</PropertyGroup> |
|||
<PropertyGroup> |
|||
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion> |
|||
</PropertyGroup> |
|||
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" /> |
|||
<ItemGroup> |
|||
<None Include="packages.config" /> |
|||
<Compile Include="..\FSharpUnitTests\FsUnit.fs"> |
|||
<Link>FsUnit.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\VectorTests.fs"> |
|||
<Link>VectorTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\SparseVectorTests.fs"> |
|||
<Link>SparseVectorTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\DenseVectorTests.fs"> |
|||
<Link>DenseVectorTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\MatrixTests.fs"> |
|||
<Link>MatrixTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\SparseMatrixTests.fs"> |
|||
<Link>SparseMatrixTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\DenseMatrixTests.fs"> |
|||
<Link>DenseMatrixTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\Utilities.fs"> |
|||
<Link>Utilities.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\BigRationalTests.fs"> |
|||
<Link>BigRationalTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\RandomVariableTests.fs"> |
|||
<Link>RandomVariableTests.fs</Link> |
|||
</Compile> |
|||
<Compile Include="..\FSharpUnitTests\PokerTests.fs"> |
|||
<Link>PokerTests.fs</Link> |
|||
</Compile> |
|||
<None Include="App.config" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Reference Include="mscorlib" /> |
|||
<Reference Include="FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="nunit.framework, Version=2.6.2.12296, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77"> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="System" /> |
|||
<Reference Include="System.Core" /> |
|||
<Reference Include="System.Numerics" /> |
|||
<ProjectReference Include="..\FSharpPortable\FSharpPortable.fsproj"> |
|||
<Name>FSharpPortable</Name> |
|||
<Project>{f5f14d76-428d-43d7-8431-5b885f1ba419}</Project> |
|||
<Private>True</Private> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\Portable\Portable.csproj"> |
|||
<Name>Portable</Name> |
|||
<Project>{d877f358-a2d2-4cc3-a921-8aa5cf6187e8}</Project> |
|||
<Private>True</Private> |
|||
</ProjectReference> |
|||
</ItemGroup> |
|||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|||
Other similar extension points exist, see Microsoft.Common.targets. |
|||
<Target Name="BeforeBuild"> |
|||
</Target> |
|||
<Target Name="AfterBuild"> |
|||
</Target> |
|||
--> |
|||
</Project> |
|||
@ -0,0 +1,4 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<packages> |
|||
<package id="NUnit" version="2.6.2" targetFramework="net45" /> |
|||
</packages> |
|||
@ -1,6 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<startup> |
|||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> |
|||
</startup> |
|||
</configuration> |
|||
@ -0,0 +1,606 @@ |
|||
// First version copied from the F# Power Pack |
|||
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack.Unittests/BigRationalTests.fs |
|||
|
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open MathNet.Numerics |
|||
open NUnit.Framework |
|||
open System |
|||
open System.Collections |
|||
open System.Collections.Generic |
|||
open System.Numerics |
|||
|
|||
|
|||
[<TestFixture>] |
|||
type public BigRationalTests() = |
|||
|
|||
// BigRational Tests |
|||
// ================= |
|||
|
|||
// Notes: What cases to consider? |
|||
// For (p,q) cases q=0, q=1, q<>1. [UPDATE: remove (x,0)] |
|||
// For (p,q) when q=1 there could be 2 internal representations, either Z or Q. |
|||
// For (p,0) this value can be signed, corresponds to +/- infinity point. [Update: remove it] |
|||
// Hashes on (p,1) for both representations must agree. |
|||
// For binary operators, try for result with and without HCF (normalisation). |
|||
// Also: 0/0 is an acceptable representation. See normalisation code. [Update: remove it]. |
|||
|
|||
// Overrides to test: |
|||
// .ToString() |
|||
// .GetHashCode() |
|||
// .Equals() |
|||
// IComparable.CompareTo() |
|||
|
|||
// Misc construction. |
|||
let natA n = BigRational.FromInt n // internally Z |
|||
let natB n = (natA n / natA 7) * natA 7 // internally Q |
|||
let ratio p q = BigRational.FromInt p / BigRational.FromInt q |
|||
let (/%) b c = BigRational.FromBigInt b / BigRational.FromBigInt c |
|||
|
|||
// Misc test values |
|||
let q0 = natA 0 |
|||
let q1 = natA 1 |
|||
let q2 = natA 2 |
|||
let q3 = natA 3 |
|||
let q4 = natA 4 |
|||
let q5 = natA 5 |
|||
let minIntI = bigint System.Int32.MinValue |
|||
let maxIntI = bigint System.Int32.MaxValue |
|||
let ran = System.Random() |
|||
let nextZ n = bigint (ran.Next(n)) |
|||
|
|||
// A selection of test points. |
|||
let points = |
|||
// A selection of integer and reciprical points |
|||
let points = |
|||
[for i in -13I .. 13I -> i,1I] @ |
|||
[for i in -13I .. 13I -> 1I,i] |
|||
// Exclude x/0 |
|||
let points = [for p,q in points do if q <> 0I then yield p,q ] // PROPOSE: (q,0) never a valid Q value, filter them out of tests... |
|||
// Scale by various values, including into BigInt range |
|||
let scale (kp,kq) (p,q) = (p*kp,q*kq) |
|||
let scales k pqs = List.map (scale k) pqs |
|||
let points = List.concat [points; |
|||
scales (10000I,1I) points; |
|||
scales (1I,10000I) points; |
|||
scales (maxIntI,1I) points; |
|||
scales (1I,maxIntI) points; |
|||
] |
|||
points |
|||
let pointsNonZero = [for p,q in points do if p<>0I then yield p,q] // non zero points |
|||
|
|||
let makeQs p q = |
|||
if q = 1I && minIntI <= p && p <= maxIntI then |
|||
// (p,1) where p is int32 |
|||
let p32 = int32 p |
|||
[natA p32;natB p32;BigRational.FromBigInt p] // two reprs for int32 |
|||
else |
|||
[BigRational.FromBigInt p / BigRational.FromBigInt q] |
|||
|
|||
let miscQs = [for p,q in points do yield! makeQs p q] |
|||
|
|||
let product xs ys = [for x in xs do for y in ys do yield x,y] |
|||
let vector1s = [for z in points -> z] |
|||
let vector2s = product points points |
|||
|
|||
[<Test>] |
|||
member this.BasicTests1() = |
|||
check "generic format h" "1N" (sprintf "%A" 1N) |
|||
check "generic format q" "-1N" (sprintf "%A" (-1N)) |
|||
|
|||
test "vliwe98" (id -2N = - 2N) |
|||
test "d3oc002" (LanguagePrimitives.GenericZero<bignum> = 0N) |
|||
test "d3oc112w" (LanguagePrimitives.GenericOne<bignum> = 1N) |
|||
|
|||
check "weioj3h" (sprintf "%O" 3N) "3" |
|||
check "weioj3k" (sprintf "%O" (3N / 4N)) "3/4" |
|||
check "weioj3k" (sprintf "%O" (3N / 400000000N)) "3/400000000" |
|||
check "weioj3l" (sprintf "%O" (3N / 3N)) "1" |
|||
check "weioj3q" (sprintf "%O" (-3N)) "-3" |
|||
//check "weioj3w" (sprintf "%O" -3N) "-3" |
|||
check "weioj3e" (sprintf "%O" (-3N / -3N)) "1" |
|||
|
|||
// The reason why we do not use hardcoded values is the the representation may change based on the NetFx we are targeting. |
|||
// For example, when targeting NetFx4.0, the result is "-3E+61" instead of "-3000....0N" |
|||
let v = -30000000000000000000000000000000000000000000000000000000000000N |
|||
check "weioj3r" (sprintf "%O" v) ((box v).ToString()) |
|||
|
|||
|
|||
[<Test>] |
|||
member this.BasicTests2() = |
|||
|
|||
|
|||
// Test arithmetic ops: tests |
|||
let test2One name f check ((p,q),(pp,qq)) = |
|||
// There may be several ways to construct the test rationals |
|||
let zs = makeQs p q |
|||
let zzs = makeQs pp qq |
|||
let results = [for z in zs do for zz in zzs do yield f (z,zz)] |
|||
let refP,refQ = check (p,q) (pp,qq) |
|||
let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ |
|||
let resOK (result:BigRational) = |
|||
result.Numerator * refQ = refP * result.Denominator && |
|||
BigRational.Equals(refResult,result) |
|||
match List.tryFind (fun result -> not (resOK result)) results with |
|||
| None -> () // ok |
|||
| Some result -> printf "Test failed. %s (%A,%A) (%A,%A). Expected %A. Observed %A\n" name p q pp qq refResult result |
|||
reportFailure "cejkew09" |
|||
|
|||
let test2All name f check vectors = List.iter (test2One name f check) vectors |
|||
|
|||
// Test arithmetic ops: call |
|||
test2All "add" (BigRational.(+)) (fun (p,q) (pp,qq) -> (p*qq + q*pp,q*qq)) vector2s |
|||
test2All "sub" (BigRational.(-)) (fun (p,q) (pp,qq) -> (p*qq - q*pp,q*qq)) vector2s |
|||
test2All "mul" (BigRational.(*)) (fun (p,q) (pp,qq) -> (p*pp,q*qq)) vector2s // *) <-- for EMACS |
|||
test2All "div" (BigRational.(/)) (fun (p,q) (pp,qq) -> (p*qq,q*pp)) (product points pointsNonZero) |
|||
|
|||
|
|||
|
|||
[<Test>] |
|||
member this.RangeTests() = |
|||
// Test x0 .. dx .. x1 |
|||
let checkRange3 (x0:BigRational) dx x1 k = |
|||
let f (x:BigRational) = x * BigRational.FromBigInt k |> BigRational.ToBigInt |
|||
let rangeA = {x0 .. dx .. x1} |> Seq.map f |
|||
let rangeB = {f x0 .. f dx .. f x1} |
|||
//printf "Length=%d\n" (Seq.length rangeA) |
|||
let same = Seq.forall2 (=) rangeA rangeB |
|||
check (sprintf "Range3 %A .. %A .. %A scaled to %A" x0 dx x1 k) same true |
|||
|
|||
checkRange3 (0I /% 1I) (1I /% 7I) (100I /% 1I) (7I*1I) |
|||
checkRange3 (0I /% 1I) (1I /% 7I) (100I /% 11I) (7I*11I) |
|||
checkRange3 (1I /% 13I) (1I /% 7I) (100I /% 11I) (7I*11I*13I) |
|||
for i = 0 to 1000 do |
|||
let m = 1000 // max steps is -m to m in steps of 1/m i.e. 2.m^2 |
|||
let p0,q0 = nextZ m ,nextZ m + 1I |
|||
let p1,q1 = nextZ m ,nextZ m + 1I |
|||
let pd,qd = nextZ m + 1I,nextZ m + 1I |
|||
checkRange3 (p0 /% q0) (pd /% qd) (p1 /% q1) (q0 * q1 * qd) |
|||
|
|||
|
|||
// Test x0 .. x1 |
|||
let checkRange2 (x0:BigRational) x1 = |
|||
let z0 = BigRational.ToBigInt x0 |
|||
let z01 = BigRational.ToBigInt (x1 - x0) |
|||
let f (x:BigRational) = x |> BigRational.ToBigInt |
|||
let rangeA = [x0 .. x1] |> List.map f // range with each item rounded down |
|||
let rangeB = [z0 .. z0 + z01] // range of same length from the round down start point |
|||
check (sprintf "Range2: %A .. %A" x0 x1) rangeA rangeB |
|||
|
|||
checkRange2 (0I /% 1I) (100I /% 1I) |
|||
checkRange2 (0I /% 1I) (100I /% 11I) |
|||
checkRange2 (1I /% 13I) (100I /% 11I) |
|||
for i = 0 to 1000 do |
|||
let m = 10000 // max steps is -m to m in steps of 1 i.e. 2.m |
|||
let p0,q0 = nextZ m ,nextZ m + 1I |
|||
let p1,q1 = nextZ m ,nextZ m + 1I |
|||
checkRange2 (p0 /% q0) (p1 /% q1) //(q0 * q1 * qd) |
|||
|
|||
// ToString() |
|||
// Cases: integer, computed integer, rational<1, rational>1, +/-infinity, nan |
|||
(natA 1).ToString() |> check "ToString" "1" |
|||
(natA 0).ToString() |> check "ToString" "0" |
|||
(natA (-12)).ToString() |> check "ToString" "-12" |
|||
(natB 1).ToString() |> check "ToString" "1" |
|||
(natB 0).ToString() |> check "ToString" "0" |
|||
(natB (-12)).ToString() |> check "ToString" "-12" |
|||
(1I /% 3I).ToString() |> check "ToString" "1/3" |
|||
(12I /% 5I).ToString() |> check "ToString" "12/5" |
|||
//(13I /% 0I).ToString() |> check "ToString" "1/0" // + 1/0. Plan to make this invalid value |
|||
//(-13I /% 0I).ToString() |> check "ToString" "1/0" // - 1/0. Plan to make this invalid value |
|||
//(0I /% 0I).ToString() |> check "ToString" "0/0" // 0/0. Plan to make this invalid value |
|||
|
|||
// GetHashCode |
|||
// Cases: zero, integer, computed integer, computed by multiple routes. |
|||
let checkSameHashGeneric a b = check (sprintf "GenericHash %A %A" a b) (a.GetHashCode()) (b.GetHashCode()) |
|||
let checkSameHash (a:BigRational) (b:BigRational) = check (sprintf "BigRationalHash %A %A" a b) (a.GetHashCode()) (b.GetHashCode()); checkSameHashGeneric a b |
|||
|
|||
List.iter (fun n -> checkSameHash (natA n) (natB n)) [-10 .. 10] |
|||
List.iter (fun n -> checkSameHash n ((n * q3 + n * q2) / q5)) miscQs |
|||
|
|||
// bug 3488: should non-finite values be supported? |
|||
//let x = BigRational.FromBigInt (-1I) / BigRational.FromBigInt 0I |
|||
//let q2,q3,q5 = BigRational.FromInt 2,BigRational.FromInt 3,BigRational.FromInt 5 |
|||
//let x2 = (x * q2 + x * q3) / q5 |
|||
//x,x2,x = x2 |
|||
|
|||
// Test: Zero,One? |
|||
check "ZeroA" BigRational.Zero (natA 0) |
|||
check "ZeroA" BigRational.Zero (natA 0) |
|||
check "OneA" BigRational.One (natB 1) |
|||
check "OneB" BigRational.One (natB 1) |
|||
|
|||
[<Test>] |
|||
member this.BinaryAndUnaryOperators() = |
|||
// Test: generic bop |
|||
let testR2One name f check ((p,q),(pp,qq)) = |
|||
// There may be several ways to construct the test rationals |
|||
let zs = makeQs p q |
|||
let zzs = makeQs pp qq |
|||
let resultRef = check (p,q) (pp,qq) // : bool |
|||
let args = [for z in zs do for zz in zzs do yield (z,zz)] |
|||
match List.tryFind (fun (z,zz) -> resultRef <> f (z,zz)) args with |
|||
| None -> () // ok |
|||
| Some (z,zz) -> printf "Test failed. %s (%A,%A) (%A,%A) = %s %A %A. Expected %A.\n" name p q pp qq name z zz resultRef |
|||
reportFailure "cknwe9" |
|||
|
|||
// Test: generic uop |
|||
let testR1One name f check (p,q) = |
|||
// There may be several ways to construct the test rationals |
|||
let zs = makeQs p q |
|||
let resultRef = check (p,q) //: bool |
|||
match List.tryFind (fun z -> resultRef <> f z) zs with |
|||
| None -> () // ok |
|||
| Some z -> printf "Test failed. %s (%A,%A) = %s %A. Expected %A.\n" name p q name z resultRef |
|||
reportFailure "vekjkrejvre0" |
|||
|
|||
let testR2All name f check vectors = List.iter (testR2One name f check) vectors |
|||
let testR1All name f check vectors = List.iter (testR1One name f check) vectors |
|||
|
|||
// Test: relations |
|||
let sign (i:BigInteger) = BigInteger(i.Sign) |
|||
testR2All "=" BigRational.(=) (fun (p,q) (pp,qq) -> (p*qq = q*pp)) vector2s |
|||
testR2All "=" BigRational.op_Equality (fun (p,q) (pp,qq) -> (p*qq = q*pp)) vector2s |
|||
testR2All "!=" BigRational.op_Inequality (fun (p,q) (pp,qq) -> (p*qq <> q*pp)) vector2s |
|||
// p/q < pp/qq |
|||
// iff (p * sign q) / (q * sign q) < (pp * sign qq) / (qq * sign qq) |
|||
// iff (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q * sign q) since q*sign q is always +ve. |
|||
testR2All "<" BigRational.(<) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) < (pp * sign qq) * (q * sign q)) vector2s |
|||
testR2All ">" BigRational.(>) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) > (pp * sign qq) * (q * sign q)) vector2s |
|||
testR2All "<=" BigRational.(<=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) <= (pp * sign qq) * (q * sign q)) vector2s |
|||
testR2All ">=" BigRational.(>=) (fun (p,q) (pp,qq) -> (p * sign q) * (qq * sign qq) >= (pp * sign qq) * (q * sign q)) vector2s |
|||
|
|||
// System.IComparable tests |
|||
let BigRationalCompareTo (p:BigRational,q:BigRational) = (p :> System.IComparable).CompareTo(q) |
|||
testR2All "IComparable.CompareTo" BigRationalCompareTo (fun (p,q) (pp,qq) -> compare ((p * sign q) * (qq * sign qq)) ((pp * sign qq) * (q * sign q))) vector2s |
|||
|
|||
// Test: is negative, is positive |
|||
testR1All "IsNegative" (fun (x:BigRational) -> x.IsNegative) (fun (p,q) -> sign p * sign q = -1I) vector1s |
|||
testR1All "IsPositive" (fun (x:BigRational) -> x.IsPositive) (fun (p,q) -> sign p * sign q = 1I) vector1s |
|||
testR1All "IsZero" (fun (x:BigRational) -> x = q0) (fun (p,q) -> sign p = 0I) vector1s |
|||
|
|||
|
|||
let test1One name f check (p,q) = |
|||
// There may be several ways to construct the test rationals |
|||
let zs = makeQs p q |
|||
let results = [for z in zs -> f z] |
|||
let refP,refQ = check (p,q) |
|||
let refResult = BigRational.FromBigInt refP / BigRational.FromBigInt refQ |
|||
let resOK (result:BigRational) = |
|||
result.Numerator * refQ = refP * result.Denominator && |
|||
BigRational.Equals(refResult,result) |
|||
match List.tryFind (fun result -> not (resOK result)) results with |
|||
| None -> () // ok |
|||
| Some result -> printf "Test failed. %s (%A,%A). Expected %A. Observed %A\n" name p q refResult result |
|||
reportFailure "klcwe09wek" |
|||
|
|||
let test1All name f check vectors = List.iter (test1One name f check) vectors |
|||
|
|||
test1All "neg" (BigRational.(~-)) (fun (p,q) -> (-p,q)) vector1s |
|||
test1All "pos" (BigRational.(~+)) (fun (p,q) -> (p,q)) vector1s // why have ~+ ??? |
|||
|
|||
// Test: Abs,Sign |
|||
test1All "Abs" (BigRational.Abs) (fun (p,q) -> (abs p,abs q)) vector1s |
|||
testR1All "Sign" (fun (x:BigRational) -> x.Sign) (fun (p,q) -> check "NonZeroDenom" (sign q <> 0I) true; (sign p * sign q) |> int32) vector1s |
|||
|
|||
// Test: PowN |
|||
test1All "PowN(x,2)" (fun x -> BigRational.PowN(x,2)) (fun (p,q) -> (p*p,q*q)) vector1s |
|||
test1All "PowN(x,1)" (fun x -> BigRational.PowN(x,1)) (fun (p,q) -> (p,q)) vector1s |
|||
test1All "PowN(x,0)" (fun x -> BigRational.PowN(x,0)) (fun (p,q) -> (1I,1I)) vector1s |
|||
|
|||
// MatteoT: moved to numbersVS2008\test.ml |
|||
//test1All "PowN(x,200)" (fun x -> BigRational.PowN(x,200)) (fun (p,q) -> (BigInteger.Pow(p,200I),BigInteger.Pow(q,200I))) vector1s |
|||
|
|||
// MatteoT: moved to numbersVS2008\test.ml |
|||
//let powers = [0I .. 100I] |
|||
//powers |> List.iter (fun i -> test1All "PowN(x,i)" (fun x -> BigRational.PowN(x,int i)) (fun (p,q) -> (BigInteger.Pow(p,i),BigInteger.Pow(q,i))) vector1s) |
|||
|
|||
// Test: PowN with negative powers - expect exception |
|||
testR1All "PowN(x,-1)" (fun x -> throws (fun () -> BigRational.PowN(x,-1))) (fun (p,q) -> true) vector1s |
|||
testR1All "PowN(x,-4)" (fun x -> throws (fun () -> BigRational.PowN(x,-4))) (fun (p,q) -> true) vector1s |
|||
|
|||
|
|||
|
|||
[<TestFixture>] |
|||
type BigNumType() = |
|||
let g_positive1 = 1000000000000000000000000000000000018N |
|||
let g_positive2 = 1000000000000000000000000000000000000N |
|||
let g_negative1 = -1000000000000000000000000000000000018N |
|||
let g_negative2 = -1000000000000000000000000000000000000N |
|||
let g_negative3 = -1000000000000000000000000000000000036N |
|||
let g_zero = 0N |
|||
let g_normal = 88N |
|||
let g_bigintpositive = 1000000000000000000000000000000000018I |
|||
let g_bigintnegative = -1000000000000000000000000000000000018I |
|||
|
|||
// Interfaces |
|||
[<Test>] |
|||
member this.IComparable() = |
|||
// Legit IC |
|||
let ic = g_positive1 :> IComparable |
|||
Assert.AreEqual(ic.CompareTo(g_positive1),0) |
|||
checkThrowsArgumentException( fun () -> ic.CompareTo(g_bigintpositive) |> ignore) |
|||
|
|||
// Base class methods |
|||
[<Test>] |
|||
member this.ObjectToString() = |
|||
|
|||
// Currently the CLR 4.0 and CLR 2.0 behavior of BigInt.ToString is different, causing this test to fail. |
|||
|
|||
Assert.AreEqual(g_positive1.ToString(), |
|||
"1000000000000000000000000000000000018") |
|||
Assert.AreEqual(g_zero.ToString(),"0") |
|||
Assert.AreEqual(g_normal.ToString(),"88") |
|||
|
|||
// Static methods |
|||
[<Test>] |
|||
member this.Abs() = |
|||
Assert.AreEqual(bignum.Abs(g_negative1), g_positive1) |
|||
Assert.AreEqual(bignum.Abs(g_negative2), g_positive2) |
|||
Assert.AreEqual(bignum.Abs(g_positive1), g_positive1) |
|||
Assert.AreEqual(bignum.Abs(g_normal), g_normal) |
|||
Assert.AreEqual(bignum.Abs(g_zero), g_zero) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.FromBigInt() = |
|||
Assert.AreEqual(bignum.FromBigInt(g_bigintpositive), |
|||
g_positive1) |
|||
Assert.AreEqual(bignum.FromBigInt(g_bigintnegative), |
|||
g_negative1) |
|||
Assert.AreEqual(bignum.FromBigInt(0I),g_zero) |
|||
Assert.AreEqual(bignum.FromBigInt(88I),g_normal) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.FromInt() = |
|||
Assert.AreEqual(bignum.FromInt(2147483647), 2147483647N) |
|||
Assert.AreEqual(bignum.FromInt(-2147483648), -2147483648N) |
|||
Assert.AreEqual(bignum.FromInt(0), 0N) |
|||
Assert.AreEqual(bignum.FromInt(88), 88N) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.One() = |
|||
Assert.AreEqual(bignum.One,1N) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.Parse() = |
|||
Assert.AreEqual(bignum.Parse("100"), 100N) |
|||
Assert.AreEqual(bignum.Parse("-100"), -100N) |
|||
Assert.AreEqual(bignum.Parse("0"), g_zero) |
|||
Assert.AreEqual(bignum.Parse("88"), g_normal) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.PowN() = |
|||
Assert.AreEqual(bignum.PowN(100N,2), 10000N) |
|||
Assert.AreEqual(bignum.PowN(-3N,3), -27N) |
|||
Assert.AreEqual(bignum.PowN(g_zero,2147483647), 0N) |
|||
Assert.AreEqual(bignum.PowN(g_normal,0), 1N) |
|||
() |
|||
|
|||
|
|||
[<Test>] |
|||
member this.Sign() = |
|||
Assert.AreEqual(g_positive1.Sign, 1) |
|||
Assert.AreEqual(g_negative1.Sign, -1) |
|||
Assert.AreEqual(g_zero.Sign, 0) |
|||
Assert.AreEqual(g_normal.Sign, 1) |
|||
() |
|||
|
|||
|
|||
|
|||
[<Test>] |
|||
member this.ToBigInt() = |
|||
Assert.AreEqual(bignum.ToBigInt(g_positive1), g_bigintpositive) |
|||
Assert.AreEqual(bignum.ToBigInt(g_negative1), g_bigintnegative) |
|||
Assert.AreEqual(bignum.ToBigInt(g_zero), 0I) |
|||
Assert.AreEqual(bignum.ToBigInt(g_normal), 88I) |
|||
() |
|||
|
|||
|
|||
|
|||
[<Test>] |
|||
member this.ToDouble() = |
|||
Assert.AreEqual(bignum.ToDouble(179769N*1000000000000000N), 1.79769E+20) |
|||
Assert.AreEqual(bignum.ToDouble(-179769N*1000000000000000N), -1.79769E+20) |
|||
Assert.AreEqual(bignum.ToDouble(0N),0.0) |
|||
Assert.AreEqual(bignum.ToDouble(88N),88.0) |
|||
Assert.AreEqual(double(179769N*1000000000000000N), 1.79769E+20) |
|||
Assert.AreEqual(double(-179769N*1000000000000000N), -1.79769E+20) |
|||
Assert.AreEqual(double(0N),0.0) |
|||
Assert.AreEqual(double(88N),88.0) |
|||
() |
|||
|
|||
|
|||
[<Test>] |
|||
member this.ToInt32() = |
|||
Assert.AreEqual(bignum.ToInt32(2147483647N), 2147483647) |
|||
Assert.AreEqual(bignum.ToInt32(-2147483648N), -2147483648) |
|||
Assert.AreEqual(bignum.ToInt32(0N), 0) |
|||
Assert.AreEqual(bignum.ToInt32(88N), 88) |
|||
Assert.AreEqual(int32(2147483647N), 2147483647) |
|||
Assert.AreEqual(int32(-2147483648N), -2147483648) |
|||
Assert.AreEqual(int32(0N), 0) |
|||
Assert.AreEqual(int32(88N), 88) |
|||
|
|||
|
|||
|
|||
[<Test>] |
|||
member this.Zero() = |
|||
Assert.AreEqual(bignum.Zero,0N) |
|||
() |
|||
|
|||
// operator methods |
|||
[<Test>] |
|||
member this.test_op_Addition() = |
|||
|
|||
Assert.AreEqual(100N + 200N, 300N) |
|||
Assert.AreEqual((-100N) + (-200N), -300N) |
|||
Assert.AreEqual(g_positive1 + g_negative1, 0N) |
|||
Assert.AreEqual(g_zero + g_zero,0N) |
|||
Assert.AreEqual(g_normal + g_normal, 176N) |
|||
Assert.AreEqual(g_normal + g_normal, 176N) |
|||
() |
|||
|
|||
|
|||
|
|||
[<Test>] |
|||
member this.test_op_Division() = |
|||
Assert.AreEqual(g_positive1 / g_positive1, 1N) |
|||
Assert.AreEqual(-100N / 2N, -50N) |
|||
Assert.AreEqual(g_zero / g_positive1, 0N) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_Equality() = |
|||
|
|||
Assert.IsTrue((g_positive1 = g_positive1)) |
|||
Assert.IsTrue((g_negative1 = g_negative1)) |
|||
Assert.IsTrue((g_zero = g_zero)) |
|||
Assert.IsTrue((g_normal = g_normal)) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_GreaterThan() = |
|||
Assert.AreEqual((g_positive1 > g_positive2), true) |
|||
Assert.AreEqual((g_negative1 > g_negative2), false) |
|||
Assert.AreEqual((g_zero > g_zero), false) |
|||
Assert.AreEqual((g_normal > g_normal), false) |
|||
|
|||
|
|||
() |
|||
[<Test>] |
|||
member this.test_op_GreaterThanOrEqual() = |
|||
Assert.AreEqual((g_positive1 >= g_positive2), true) |
|||
Assert.AreEqual((g_positive2 >= g_positive1), false) |
|||
Assert.AreEqual((g_negative1 >= g_negative1), true) |
|||
Assert.AreEqual((0N >= g_zero), true) |
|||
|
|||
() |
|||
[<Test>] |
|||
member this.test_op_LessThan() = |
|||
Assert.AreEqual((g_positive1 < g_positive2), false) |
|||
Assert.AreEqual((g_negative1 < g_negative3), false) |
|||
Assert.AreEqual((0N < g_zero), false) |
|||
|
|||
() |
|||
[<Test>] |
|||
member this.test_op_LessThanOrEqual() = |
|||
Assert.AreEqual((g_positive1 <= g_positive2), false) |
|||
Assert.AreEqual((g_positive2 <= g_positive1), true) |
|||
Assert.AreEqual((g_negative1 <= g_negative1), true) |
|||
Assert.AreEqual((0N <= g_zero), true) |
|||
|
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_Multiply() = |
|||
Assert.AreEqual(3N * 5N, 15N) |
|||
Assert.AreEqual((-3N) * (-5N), 15N) |
|||
Assert.AreEqual((-3N) * 5N, -15N) |
|||
Assert.AreEqual(0N * 5N, 0N) |
|||
|
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_Range() = |
|||
let resultPos = [0N .. 2N] |
|||
let seqPos = [0N; 1N; 2N] |
|||
verifySeqsEqual resultPos seqPos |
|||
|
|||
let resultNeg = [-2N .. 0N] |
|||
let seqNeg = [-2N; -1N; 0N] |
|||
verifySeqsEqual resultNeg seqNeg |
|||
|
|||
let resultSmall = [0N ..5N] |
|||
let seqSmall = [0N; 1N; 2N; 3N; 4N; 5N] |
|||
verifySeqsEqual resultSmall seqSmall |
|||
|
|||
() |
|||
|
|||
|
|||
[<Test>] |
|||
member this.test_op_RangeStep() = |
|||
let resultPos = [0N .. 3N .. 6N] |
|||
let seqPos = [0N; 3N; 6N] |
|||
verifySeqsEqual resultPos seqPos |
|||
|
|||
let resultNeg = [-6N .. 3N .. 0N] |
|||
let seqNeg = [-6N; -3N; 0N] |
|||
verifySeqsEqual resultNeg seqNeg |
|||
|
|||
let resultSmall = [0N .. 3N .. 9N] |
|||
let seqSmall = [0N; 3N; 6N; 9N] |
|||
verifySeqsEqual resultSmall seqSmall |
|||
|
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_Subtraction() = |
|||
Assert.AreEqual(g_positive1 - g_positive2,18N) |
|||
Assert.AreEqual(g_negative1 - g_negative3,18N) |
|||
Assert.AreEqual(0N-g_positive1, g_negative1) |
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_UnaryNegation() = |
|||
Assert.AreEqual(-g_positive1, g_negative1) |
|||
Assert.AreEqual(-g_negative1, g_positive1) |
|||
Assert.AreEqual(-0N,0N) |
|||
|
|||
() |
|||
|
|||
[<Test>] |
|||
member this.test_op_UnaryPlus() = |
|||
Assert.AreEqual(+g_positive1,g_positive1) |
|||
Assert.AreEqual(+g_negative1,g_negative1) |
|||
Assert.AreEqual(+0N, 0N) |
|||
|
|||
() |
|||
|
|||
// instance methods |
|||
[<Test>] |
|||
member this.Denominator() = |
|||
Assert.AreEqual(g_positive1.Denominator, 1I) |
|||
Assert.AreEqual(g_negative1.Denominator, 1I) |
|||
Assert.AreEqual(0N.Denominator, 1I) |
|||
|
|||
() |
|||
|
|||
[<Test>] |
|||
member this.IsNegative() = |
|||
Assert.IsFalse(g_positive1.IsNegative) |
|||
Assert.IsTrue(g_negative1.IsNegative) |
|||
|
|||
Assert.IsFalse( 0N.IsNegative) |
|||
Assert.IsFalse(-0N.IsNegative) |
|||
|
|||
() |
|||
|
|||
|
|||
[<Test>] |
|||
member this.IsPositive() = |
|||
|
|||
Assert.IsTrue(g_positive1.IsPositive) |
|||
Assert.IsFalse(g_negative1.IsPositive) |
|||
|
|||
Assert.IsFalse( 0N.IsPositive) |
|||
Assert.IsFalse(-0N.IsPositive) |
|||
|
|||
() |
|||
|
|||
[<Test>] |
|||
member this.Numerator() = |
|||
Assert.AreEqual(g_positive1.Numerator, g_bigintpositive) |
|||
Assert.AreEqual(g_negative1.Numerator, g_bigintnegative) |
|||
Assert.AreEqual(0N.Numerator, 0I) |
|||
|
|||
() |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,51 @@ |
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open NUnit.Framework |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the dense matrix type. |
|||
module DenseMatrixTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.init`` () = |
|||
DenseMatrix.init 100 100 (fun i j -> float i * 100.0 + float j) |> should equal largeM |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.ofList`` () = |
|||
DenseMatrix.ofList [[0.3;0.3];[0.3;0.3]] |> should equal smallM |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.ofSeq`` () = |
|||
DenseMatrix.ofSeq (Seq.ofList [[0.3;0.3];[0.3;0.3]]) |> should equal smallM |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.ofArray2`` () = |
|||
DenseMatrix.ofArray2 (Array2D.create 2 2 0.3) |> should equal smallM |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.initDense`` () = |
|||
DenseMatrix.initDense 100 100 (seq { for i in 0 .. 99 do |
|||
for j in 0 .. 99 -> (i,j, float i * 100.0 + float j)}) |> should equal largeM |
|||
[<Test>] |
|||
let ``DenseMatrix.constDiag`` () = |
|||
DenseMatrix.constDiag 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100)) |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.diag`` () = |
|||
DenseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100)) |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.init_row`` () = |
|||
DenseMatrix.initRow 100 100 (fun i -> (DenseVector.init 100 (fun j -> float i * 100.0 + float j))) |> should equal largeM |
|||
|
|||
[<Test>] |
|||
let ``DenseMatrix.init_col`` () = |
|||
DenseMatrix.initCol 100 100 (fun j -> (DenseVector.init 100 (fun i -> float i * 100.0 + float j))) |> should equal largeM |
|||
@ -0,0 +1,35 @@ |
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open NUnit.Framework |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the dense vector type. |
|||
module DenseVectorTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallv = new DenseVector(5, 0.3 ) |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) |
|||
|
|||
[<Test>] |
|||
let ``DenseVector.init`` () = |
|||
DenseVector.init 100 (fun i -> float i / 100.0) |> should equal largev |
|||
|
|||
[<Test>] |
|||
let ``DenseVector.ofList`` () = |
|||
DenseVector.ofList [ for i in 0 .. 99 -> float i / 100.0 ] |> should equal largev |
|||
|
|||
[<Test>] |
|||
let ``DenseVector.ofSeq`` () = |
|||
DenseVector.ofSeq (seq { for i in 0 .. 99 -> float i / 100.0 }) |> should equal largev |
|||
|
|||
[<Test>] |
|||
let ``DenseVector.rangef`` () = |
|||
DenseVector.rangef 0.0 0.01 0.99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> 0.01 * float i |] ) ) |
|||
|
|||
[<Test>] |
|||
let ``DenseVector.range`` () = |
|||
DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) ) |
|||
@ -1,244 +1,70 @@ |
|||
(* |
|||
Copyright (c) 2008, Raymond W. Vernagus (R.Vernagus@gmail.com) |
|||
All rights reserved. |
|||
|
|||
Redistribution and use in source and binary forms, with or without modification, |
|||
are permitted provided that the following conditions are met: |
|||
|
|||
* Redistributions of source code must retain the above copyright notice, |
|||
this list of conditions and the following disclaimer. |
|||
* Redistributions in binary form must reproduce the above copyright notice, |
|||
this list of conditions and the following disclaimer in the documentation |
|||
and/or other materials provided with the distribution. |
|||
* Neither the name of Raymond W. Vernagus nor the names of FsUnit's |
|||
contributors may be used to endorse or promote products derived from this |
|||
software without specific prior written permission. |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
|||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|||
*) |
|||
namespace FsUnit |
|||
|
|||
open MathNet.Numerics |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
|
|||
type Result = |
|||
| Pass |
|||
| Fail of string |
|||
| Error of string |
|||
|
|||
type Expectation = |
|||
| True |
|||
| False |
|||
| Empty |
|||
| NullOrEmpty |
|||
| Null |
|||
| SameAs of obj |
|||
|
|||
type Spec = |
|||
abstract Check : unit -> Result |
|||
abstract NegatedMessage : string |
|||
|
|||
[<AutoOpen>] |
|||
module SpecOps = |
|||
let internal safeCheck f = |
|||
try |
|||
f() |
|||
with ex -> Error (ex.ToString()) |
|||
|
|||
let make f nmsg = |
|||
{ new Spec with |
|||
member this.Check() = safeCheck f |
|||
member this.NegatedMessage = nmsg } |
|||
|
|||
let check (s: Spec) = s.Check() |
|||
|
|||
let not' f x = |
|||
let s = f x |
|||
match check s with |
|||
| Pass -> make (fun () -> Fail s.NegatedMessage) "" |
|||
| Fail msg -> make (fun () -> Pass) msg |
|||
| Error msg -> make (fun () -> Error msg) msg |
|||
|
|||
let equal expected actual = |
|||
make (fun () -> |
|||
if actual.Equals(expected) |
|||
then Pass |
|||
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) |
|||
(sprintf "NOT Expected: %A\nActual: %A" expected actual) |
|||
|
|||
let have n lbl s = |
|||
make (fun() -> |
|||
let len = Seq.length s |
|||
if len = n |
|||
then Pass |
|||
else Fail (sprintf "Expected: %d %s\nActual: %d %s" n lbl len lbl)) |
|||
(sprintf "NOT Expected: %d %s\nActual: %d %s" n lbl n lbl) |
|||
|
|||
let contain x s = |
|||
make (fun () -> |
|||
let exists = s |> Seq.exists (fun x' -> x' = x) |
|||
if exists |
|||
then Pass |
|||
else Fail (sprintf "Expected %A to contain %A" s x)) |
|||
(sprintf "Did NOT expect %A to contain %A" s x) |
|||
|
|||
let raise'<'a when 'a :> System.Exception> f = |
|||
let expType = typeof<'a> |
|||
make (fun () -> |
|||
try |
|||
f() |
|||
Fail (sprintf "Expected %s but no exception was raised" expType.FullName) |
|||
with ex -> |
|||
let actualExType = ex.GetType() |
|||
if expType = actualExType |
|||
then Pass |
|||
else Fail (sprintf "Expected: %s\nActual: %s" expType.FullName actualExType.FullName)) |
|||
(sprintf "Did NOT expect %s to be raised" expType.FullName) |
|||
|
|||
let be expectation x = |
|||
let x = box x |
|||
let msg = sprintf "Expected: %A\nActual: %A" expectation x |
|||
let negmsg = sprintf "NOT Expected: %A\nActual: %A" expectation x |
|||
match expectation with |
|||
| True -> |
|||
make (fun () -> |
|||
if x = box true |
|||
then Pass |
|||
else Fail msg) |
|||
negmsg |
|||
| False -> |
|||
make (fun () -> |
|||
if x = box false |
|||
then Pass |
|||
else Fail msg) |
|||
negmsg |
|||
| Empty -> |
|||
make (fun () -> |
|||
if x = box System.String.Empty |
|||
then Pass |
|||
else Fail msg) |
|||
negmsg |
|||
| NullOrEmpty -> |
|||
make (fun () -> |
|||
if System.String.IsNullOrEmpty(x :?> string) |
|||
then Pass |
|||
else Fail msg) |
|||
negmsg |
|||
| Null -> |
|||
make (fun () -> |
|||
if x = null |
|||
then Pass |
|||
else Fail msg) |
|||
negmsg |
|||
| SameAs other -> |
|||
make (fun () -> |
|||
if System.Object.ReferenceEquals(x, other) |
|||
then Pass |
|||
else Fail (sprintf "Expected actual to be same reference as expected %A" other)) |
|||
(sprintf "Expected %A to have different reference than %A" x other) |
|||
|
|||
let array_equal (expected: float []) (actual: float []) = |
|||
make (fun () -> |
|||
let mutable f = true |
|||
for i=0 to expected.Length-1 do |
|||
f <- f && (expected.[i] = actual.[i]) |
|||
if f |
|||
then Pass |
|||
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) |
|||
(sprintf "NOT Expected: %A\nActual: %A" expected actual) |
|||
|
|||
let array2_equal (expected: float [,]) (actual: float [,]) = |
|||
make (fun () -> |
|||
let mutable f = true |
|||
for i=0 to expected.GetLength(0)-1 do |
|||
for j=0 to expected.GetLength(1)-1 do |
|||
f <- f && (expected.[i,j] = actual.[i,j]) |
|||
if f |
|||
then Pass |
|||
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) |
|||
(sprintf "NOT Expected: %A\nActual: %A" expected actual) |
|||
|
|||
let approximately_equal (places : int) (expected: float) (actual: float) = |
|||
make (fun () -> |
|||
if Precision.AlmostEqualInDecimalPlaces(actual, expected, places) |
|||
then Pass |
|||
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) |
|||
(sprintf "NOT Expected: %A\nActual: %A" expected actual) |
|||
|
|||
let approximately_vector_equal (places : int) (expected: #Vector<float>) (actual: #Vector<float>) = |
|||
make (fun () -> |
|||
let mutable f = true |
|||
for i=0 to expected.Count-1 do |
|||
f <- f && Precision.AlmostEqualInDecimalPlaces(expected.[i], actual.[i], places) |
|||
if f |
|||
then Pass |
|||
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) |
|||
(sprintf "NOT Expected: %A\nActual: %A" expected actual) |
|||
|
|||
let approximately_matrix_equal (places : int) (expected: #Matrix<float>) (actual: #Matrix<float>) = |
|||
make (fun () -> |
|||
let mutable f = true |
|||
for i=0 to expected.RowCount-1 do |
|||
for j=0 to expected.ColumnCount-1 do |
|||
f <- f && Precision.AlmostEqualInDecimalPlaces(expected.[i,j], actual.[i,j], places) |
|||
if f |
|||
then Pass |
|||
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) |
|||
(sprintf "NOT Expected: %A\nActual: %A" expected actual) |
|||
|
|||
module Results = |
|||
open Microsoft.FSharp.Text |
|||
|
|||
let internal currentResults = new ResizeArray<string * Result>() |
|||
|
|||
let add = currentResults.Add |
|||
|
|||
let passedCount () = |
|||
currentResults |
|||
|> Seq.filter (function _,Pass -> true | _ -> false) |
|||
|> Seq.length |
|||
|
|||
let failed () = |
|||
currentResults |
|||
|> Seq.filter (function _,Fail _ -> true | _ -> false) |
|||
|
|||
let failedCount () = |
|||
failed() |
|||
|> Seq.length |
|||
|
|||
let erred () = |
|||
currentResults |
|||
|> Seq.filter (function _,Error _ -> true | _ -> false) |
|||
|
|||
let erredCount () = |
|||
erred() |
|||
|> Seq.length |
|||
|
|||
let summary () = |
|||
let buff = new System.Text.StringBuilder() |
|||
buff.AppendFormat("{0} passed.\n{1} failed.\n{2} erred.", passedCount(), failedCount(), erredCount()) |> ignore |
|||
failed() |
|||
|> Seq.iter (function (lbl,Fail msg) -> buff.AppendFormat("\n----\nFailed: {0}\n{1}", lbl, msg) |> ignore | _ -> ()) |
|||
erred() |
|||
|> Seq.iter (function (lbl,Error msg) -> buff.AppendFormat("\n----\nErred: {0}\n{1}", lbl, msg) |> ignore | _ -> ()) |
|||
buff.ToString() |
|||
|
|||
|
|||
[<AutoOpen>] |
|||
module SpecHelpers = |
|||
let spec lbl s = (lbl, check s) |
|||
|
|||
let should f x = f x |
|||
|
|||
let specs lbl (results: seq<string * Result>) = |
|||
results |> Seq.iter (fun x -> Results.add x) |
|||
module FsUnit |
|||
open NUnit.Framework |
|||
open NUnit.Framework.Constraints |
|||
|
|||
let should (f : 'a -> #Constraint) x (y : obj) = |
|||
let c = f x |
|||
let y = |
|||
match y with |
|||
| :? (unit -> unit) -> box (TestDelegate(y :?> unit -> unit)) |
|||
| _ -> y |
|||
Assert.That(y, c) |
|||
|
|||
let equal x = EqualConstraint(x) |
|||
|
|||
let equalWithin tolerance x = equal(x).Within tolerance |
|||
|
|||
let contain x = ContainsConstraint(x) |
|||
|
|||
let haveLength n = Has.Length.EqualTo(n) |
|||
|
|||
let haveCount n = Has.Count.EqualTo(n) |
|||
|
|||
let be = id |
|||
|
|||
let Null = NullConstraint() |
|||
|
|||
let Empty = EmptyConstraint() |
|||
|
|||
let EmptyString = EmptyStringConstraint() |
|||
|
|||
let NullOrEmptyString = NullOrEmptyStringConstraint() |
|||
|
|||
let True = TrueConstraint() |
|||
|
|||
let False = FalseConstraint() |
|||
|
|||
let sameAs x = SameAsConstraint(x) |
|||
|
|||
let throw = Throws.TypeOf |
|||
|
|||
let greaterThan x = GreaterThanConstraint(x) |
|||
|
|||
let greaterThanOrEqualTo x = GreaterThanOrEqualConstraint(x) |
|||
|
|||
let lessThan x = LessThanConstraint(x) |
|||
|
|||
let lessThanOrEqualTo x = LessThanOrEqualConstraint(x) |
|||
|
|||
let shouldFail (f : unit -> unit) = |
|||
TestDelegate(f) |> should throw typeof<AssertionException> |
|||
|
|||
let endWith (s:string) = EndsWithConstraint s |
|||
|
|||
let startWith (s:string) = StartsWithConstraint s |
|||
|
|||
let ofExactType<'a> = ExactTypeConstraint(typeof<'a>) |
|||
|
|||
let instanceOfType<'a> = InstanceOfTypeConstraint(typeof<'a>) |
|||
|
|||
let NaN = NaNConstraint() |
|||
|
|||
let unique = UniqueItemsConstraint() |
|||
|
|||
let not' x = NotConstraint(x) |
|||
|
|||
let array_equal = equal |
|||
let array2_equal = equal |
|||
let approximately_equal tolerance = equalWithin (10.0 ** (float -tolerance)) |
|||
let approximately_vector_equal = approximately_equal |
|||
let approximately_matrix_equal = approximately_equal |
|||
|
|||
@ -0,0 +1,112 @@ |
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open NUnit.Framework |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the matrix type. |
|||
module MatrixTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) |
|||
let failingFoldBackM = DenseMatrix.init 2 3 (fun i j -> 1.0) |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.fold`` () = |
|||
Matrix.fold (fun a b -> a - b) 0.0 smallM |> should equal -1.2 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldBack`` () = |
|||
Matrix.foldBack (fun a b -> a - b) 0.0 smallM |> should equal 0.0 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldBackSummation`` () = |
|||
Matrix.foldBack( fun a b -> a + b) 0.0 failingFoldBackM |> should equal 6.0 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldi`` () = |
|||
Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.toArray2`` () = |
|||
Matrix.toArray2 smallM |> should array2_equal (Array2D.create 2 2 0.3) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.forall`` () = |
|||
Matrix.forall (fun x -> x = 0.3) smallM |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Matrix.exists`` () = |
|||
Matrix.exists (fun x -> x = 0.5) smallM |> should equal false |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foralli`` () = |
|||
Matrix.foralli (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Matrix.existsi`` () = |
|||
Matrix.existsi (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Matrix.map`` () = |
|||
Matrix.map (fun x -> 2.0 * x) smallM |> should equal (2.0 * smallM) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.mapi`` () = |
|||
Matrix.mapi (fun i j x -> float i * 100.0 + float j + x) largeM |> should equal (2.0 * largeM) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.mapCols`` () = |
|||
Matrix.mapCols (fun j col -> col.Add(float j)) smallM |> should (approximately_matrix_equal 14) (matrix [[0.3;1.3];[0.3;1.3]]) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.mapRows`` () = |
|||
Matrix.mapRows (fun i row -> row.Add(float i)) smallM |> should (approximately_matrix_equal 14) (matrix [[0.3;0.3];[1.3;1.3]]) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.inplaceAssign`` () = |
|||
let N = smallM.Clone() |
|||
Matrix.inplaceAssign (fun i j -> 0.0) N |
|||
N |> should equal (0.0 * smallM) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.inplaceMapi`` () = |
|||
let N = largeM.Clone() |
|||
Matrix.inplaceMapi (fun i j x -> 2.0 * (float i * 100.0 + float j) + x) N |
|||
N |> should equal (3.0 * largeM) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.nonZeroEntries`` () = |
|||
Seq.length (Matrix.nonZeroEntries smallM) |> should equal 4 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.sum`` () = |
|||
Matrix.sum smallM |> should equal 1.2 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.sumColsBy`` () = |
|||
Matrix.sumColsBy (fun j col -> col.[0] * col.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 11.0 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.sumRowsBy`` () = |
|||
Matrix.sumRowsBy (fun i row -> row.[0] * row.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 14.0 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldCol`` () = |
|||
Matrix.foldCol (+) 0.0 largeM 0 |> should equal 495000.0 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldRow`` () = |
|||
Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0 |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldByCol`` () = |
|||
Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>) |
|||
|
|||
[<Test>] |
|||
let ``Matrix.foldByRow`` () = |
|||
Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>) |
|||
@ -0,0 +1,98 @@ |
|||
module MathNet.Numerics.Tests.PokerTests |
|||
|
|||
open MathNet.Numerics |
|||
open MathNet.Numerics.Probability |
|||
open NUnit.Framework |
|||
open FsUnit |
|||
|
|||
type Rank = int |
|||
type Suit = | Spades | Hearts | Diamonds | Clubs |
|||
type Card = Rank * Suit |
|||
|
|||
let value = fst |
|||
let suit = snd |
|||
|
|||
let A,K,Q,J,T = 14,13,12,11,10 |
|||
let allRanksInSuit suit = [2..A] |> List.map (fun rank -> rank,suit) |
|||
let completeDeck = |
|||
[Spades; Hearts ; Diamonds; Clubs] |
|||
|> List.map allRanksInSuit |
|||
|> List.concat |
|||
|
|||
let isPair c1 c2 = value c1 = value c2 |
|||
let isSuited c1 c2 = suit c1 = suit c2 |
|||
let isConnected c1 c2 = |
|||
let v1,v2 = value c1,value c2 |
|||
(v1 - v2 |> abs |> (=) 1) || |
|||
(v1 = A && v2 = 2) || |
|||
(v1 = 2 && v2 = A) |
|||
|
|||
[<Test>] |
|||
let ``When drawing from a full deck, then the probability for an Ace should equal 4/52``() = |
|||
completeDeck |
|||
|> RandomVariable.selectOne |
|||
|> RandomVariable.map fst |
|||
|> RandomVariable.filter (fun card -> value card = A) |
|||
|> RandomVariable.probability |
|||
|> should equal (4N/52N) |
|||
|
|||
[<Test>] |
|||
let ``When drawing from a full deck, then the probability should equal 1/52``() = |
|||
completeDeck |
|||
|> RandomVariable.selectOne |
|||
|> RandomVariable.map fst |
|||
|> RandomVariable.filter ((=) (A,Spades)) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/52N) |
|||
|
|||
[<Test>] |
|||
let ``When drawing from a full deck, then the probability for the Ace of Clubs and Ace of Spaces (in order) should equal 1/52 * 1/51``() = |
|||
completeDeck |
|||
|> RandomVariable.select 2 |
|||
|> RandomVariable.filter ((=) [A,Clubs; A,Spades]) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/52N * 1N/51N) |
|||
|
|||
[<Test>] |
|||
let ``When drawing from a full deck, then the probability for the Ace of Clubs and Ace of Spaces (in any order) should equal (1/52 * 1/51) * 2``() = |
|||
completeDeck |
|||
|> RandomVariable.select 2 |
|||
|> RandomVariable.filterInAnyOrder [A,Clubs; A,Spades] |
|||
|> RandomVariable.probability |
|||
|> should equal ((1N/52N * 1N/51N) * 2N) |
|||
|
|||
[<Test>] |
|||
let ``When drawing the Ace of Spades and the Ace of Clubs, then the probability for drawing another Ace should equal 2/50``() = |
|||
completeDeck |
|||
|> RandomVariable.remove [A,Clubs; A,Spades] |
|||
|> RandomVariable.toUniformDistribution |
|||
|> RandomVariable.filter (fun card -> value card = A) |
|||
|> RandomVariable.probability |
|||
|> should equal (2N/50N) |
|||
|
|||
|
|||
[<Test>] |
|||
let ``When drawing from the full deck, then the probability for drawing a Pair preflop should equal 1/17``() = |
|||
completeDeck |
|||
|> RandomVariable.select 2 |
|||
|> RandomVariable.filter (fun (c1::c2::_) -> isPair c1 c2) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/17N) |
|||
|
|||
[<Test>] |
|||
let ``When drawing from the full deck, then the probability for drawing Suited Connectors should equal 1/25``() = |
|||
completeDeck |
|||
|> RandomVariable.select 2 |
|||
|> RandomVariable.filter (fun (c1::c2::_) -> isSuited c1 c2 && isConnected c1 c2) |
|||
|> RandomVariable.probability |
|||
|> should equal (2N/51N) |
|||
|
|||
[<Test>] |
|||
let ``When holding 3 Spades after the flop, than the probability for drawing a flush should equal 10/47*9/46``() = |
|||
completeDeck |
|||
|> RandomVariable.remove [A,Clubs; A,Spades] // preflop |
|||
|> RandomVariable.remove [2,Clubs; 3,Spades; 7,Spades] // flop |
|||
|> RandomVariable.select 2 |
|||
|> RandomVariable.filter (fun (c1::c2::_) -> suit c1 = Spades && suit c2 = Spades) |
|||
|> RandomVariable.probability |
|||
|> should equal (10N/47N*9N/46N) |
|||
@ -1,223 +0,0 @@ |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the dense vector type. |
|||
let DenseVectorTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallv = new DenseVector(5, 0.3 ) |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) |
|||
|
|||
specs "DenseVector" [ |
|||
spec "DenseVector.init" |
|||
(DenseVector.init 100 (fun i -> float i / 100.0) |> should equal largev) |
|||
spec "DenseVector.ofList" |
|||
(DenseVector.ofList [ for i in 0 .. 99 -> float i / 100.0 ] |> should equal largev) |
|||
spec "DenseVector.ofSeq" |
|||
(DenseVector.ofSeq (seq { for i in 0 .. 99 -> float i / 100.0 }) |> should equal largev) |
|||
spec "DenseVector.rangef" |
|||
(DenseVector.rangef 0.0 0.01 0.99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> 0.01 * float i |] ) )) |
|||
spec "DenseVector.range" |
|||
(DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) )) |
|||
] |
|||
|
|||
|
|||
/// Unit tests for the sparse vector type. |
|||
let SparseVectorTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector<float> |
|||
|
|||
specs "SparseVector" [ |
|||
spec "SparseVector.ofList" |
|||
((SparseVector.ofList 5 [ (1,0.3) ] :> Vector<float>) |> should equal smallv) |
|||
spec "SparseVector.ofSeq" |
|||
((SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector<float>) |> should equal smallv) |
|||
] |
|||
|
|||
|
|||
/// Unit tests for the vector type. |
|||
let VectorTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallv = new DenseVector( [|0.3;0.3;0.3;0.3;0.3|] ) :> Vector<float> |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) :> Vector<float> |
|||
|
|||
specs "Vector" [ |
|||
spec "Vector.toArray" |
|||
(Vector.toArray smallv |> should array_equal [|0.3;0.3;0.3;0.3;0.3|]) |
|||
spec "Vector.toList" |
|||
(Vector.toList smallv |> should equal [0.3;0.3;0.3;0.3;0.3]) |
|||
spec "Vector.mapInPlace" |
|||
( let w = smallv.Clone() |
|||
Vector.mapInPlace (fun x -> 2.0 * x) w |
|||
w |> should equal (2.0 * smallv)) |
|||
spec "Vector.mapiInPlace" |
|||
( let w = largev.Clone() |
|||
Vector.mapiInPlace (fun i x -> float i / 100.0) w |
|||
w |> should equal (largev)) |
|||
spec "Vector.addInPlace" |
|||
( let w = largev.Clone() |
|||
Vector.addInPlace w largev |
|||
w |> should equal (2.0 * largev)) |
|||
spec "Vector.subInPlace" |
|||
( let w = largev.Clone() |
|||
Vector.subInPlace w largev |
|||
w |> should equal (0.0 * largev)) |
|||
spec "Vector.map" |
|||
(Vector.map (fun x -> 2.0 * x) largev |> should equal (2.0 * largev)) |
|||
spec "Vector.mapi" |
|||
(Vector.mapi (fun i x -> float i / 100.0) largev |> should equal largev) |
|||
spec "Vector.fold" |
|||
(Vector.fold (fun a b -> a - b) 0.0 smallv |> should equal -1.5) |
|||
spec "Vector.foldBack" |
|||
(Vector.foldBack (fun a b -> a - b) 0.0 smallv |> should equal 0.0) |
|||
spec "Vector.foldi" |
|||
(Vector.foldi (fun i a b -> a + b) 0.0 smallv |> should equal 1.5) |
|||
spec "Vector.forall" |
|||
(Vector.forall (fun x -> x = 0.3) smallv |> should equal true) |
|||
spec "Vector.exists" |
|||
(Vector.exists (fun x -> x = 0.3) smallv |> should equal true) |
|||
spec "Vector.foralli" |
|||
(Vector.foralli (fun i x -> x = 0.3 && i < 5) smallv |> should equal true) |
|||
spec "Vector.existsi" |
|||
(Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true) |
|||
spec "Vector.scan" |
|||
(Vector.scan (fun acc x -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|0.3;0.6;0.9;1.2;1.5|] ) :> Vector<float>) ) |
|||
spec "Vector.scanBack" |
|||
(Vector.scanBack (fun x acc -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|1.5;1.2;0.9;0.6;0.3|] ) :> Vector<float>) ) |
|||
spec "Vector.reduce" |
|||
(Vector.reduce (fun acc x -> acc ** x) smallv |> should approximately_equal 14 0.990295218585507) |
|||
spec "Vector.reduceBack" |
|||
(Vector.reduceBack (fun x acc -> x ** acc) smallv |> should approximately_equal 14 0.488911287726319) |
|||
spec "Vector.insert" |
|||
(Vector.insert 2 0.5 smallv |> should approximately_vector_equal 14 (new DenseVector ( [|0.3;0.3;0.5;0.3;0.3;0.3|] ) :> Vector<float>) ) |
|||
] |
|||
|
|||
|
|||
/// Unit tests for the matrix type. |
|||
let MatrixTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) |
|||
let failingFoldBackM = DenseMatrix.init 2 3 (fun i j -> 1.0) |
|||
|
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) |
|||
|
|||
specs "Matrix" [ |
|||
spec "Matrix.fold" |
|||
(Matrix.fold (fun a b -> a - b) 0.0 smallM |> should equal -1.2) |
|||
spec "Matrix.foldBack" |
|||
(Matrix.foldBack (fun a b -> a - b) 0.0 smallM |> should equal 0.0) |
|||
spec "Matrix.foldBackSummation" |
|||
(Matrix.foldBack( fun a b -> a + b) 0.0 failingFoldBackM |> should equal 6.0) |
|||
spec "Matrix.foldi" |
|||
(Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2) |
|||
spec "Matrix.toArray2" |
|||
(Matrix.toArray2 smallM |> should array2_equal (Array2D.create 2 2 0.3)) |
|||
spec "Matrix.forall" |
|||
(Matrix.forall (fun x -> x = 0.3) smallM |> should equal true) |
|||
spec "Matrix.exists" |
|||
(Matrix.exists (fun x -> x = 0.5) smallM |> should equal false) |
|||
spec "Matrix.foralli" |
|||
(Matrix.foralli (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true) |
|||
spec "Matrix.existsi" |
|||
(Matrix.existsi (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true) |
|||
spec "Matrix.map" |
|||
(Matrix.map (fun x -> 2.0 * x) smallM |> should equal (2.0 * smallM)) |
|||
spec "Matrix.mapi" |
|||
(Matrix.mapi (fun i j x -> float i * 100.0 + float j + x) largeM |> should equal (2.0 * largeM)) |
|||
spec "Matrix.mapCols" |
|||
(Matrix.mapCols (fun j col -> col.Add(float j)) smallM |> should approximately_matrix_equal 14 (matrix [[0.3;1.3];[0.3;1.3]])) |
|||
spec "Matrix.mapRows" |
|||
(Matrix.mapRows (fun i row -> row.Add(float i)) smallM |> should approximately_matrix_equal 14 (matrix [[0.3;0.3];[1.3;1.3]])) |
|||
spec "Matrix.inplaceAssign" |
|||
( let N = smallM.Clone() |
|||
Matrix.inplaceAssign (fun i j -> 0.0) N |
|||
N |> should equal (0.0 * smallM)) |
|||
spec "Matrix.inplaceMapi" |
|||
( let N = largeM.Clone() |
|||
Matrix.inplaceMapi (fun i j x -> 2.0 * (float i * 100.0 + float j) + x) N |
|||
N |> should equal (3.0 * largeM)) |
|||
spec "Matrix.nonZeroEntries" |
|||
(Seq.length (Matrix.nonZeroEntries smallM) |> should equal 4) |
|||
spec "Matrix.sum" |
|||
(Matrix.sum smallM |> should equal 1.2) |
|||
spec "Matrix.sumColsBy" |
|||
(Matrix.sumColsBy (fun j col -> col.[0] * col.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 11.0) |
|||
spec "Matrix.sumRowsBy" |
|||
(Matrix.sumRowsBy (fun i row -> row.[0] * row.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 14.0) |
|||
spec "Matrix.foldCol" |
|||
(Matrix.foldCol (+) 0.0 largeM 0 |> should equal 495000.0) |
|||
spec "Matrix.foldRow" |
|||
(Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0) |
|||
spec "Matrix.foldByCol" |
|||
(Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>)) |
|||
spec "Matrix.foldByRow" |
|||
(Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>)) |
|||
] |
|||
|
|||
|
|||
/// Unit tests for the dense matrix type. |
|||
let DenseMatrixTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) |
|||
|
|||
specs "DenseMatrix" [ |
|||
spec "DenseMatrix.init" |
|||
(DenseMatrix.init 100 100 (fun i j -> float i * 100.0 + float j) |> should equal largeM) |
|||
spec "DenseMatrix.ofList" |
|||
(DenseMatrix.ofList [[0.3;0.3];[0.3;0.3]] |> should equal smallM) |
|||
spec "DenseMatrix.ofSeq" |
|||
(DenseMatrix.ofSeq (Seq.ofList [[0.3;0.3];[0.3;0.3]]) |> should equal smallM) |
|||
spec "DenseMatrix.ofArray2" |
|||
(DenseMatrix.ofArray2 (Array2D.create 2 2 0.3) |> should equal smallM) |
|||
spec "DenseMatrix.initDense" |
|||
(DenseMatrix.initDense 100 100 (seq { for i in 0 .. 99 do |
|||
for j in 0 .. 99 -> (i,j, float i * 100.0 + float j)}) |> should equal largeM) |
|||
spec "DenseMatrix.constDiag" |
|||
(DenseMatrix.constDiag 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100))) |
|||
spec "DenseMatrix.diag" |
|||
(DenseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100))) |
|||
spec "DenseMatrix.init_row" |
|||
(DenseMatrix.initRow 100 100 (fun i -> (DenseVector.init 100 (fun j -> float i * 100.0 + float j))) |> should equal largeM) |
|||
spec "DenseMatrix.init_col" |
|||
(DenseMatrix.initCol 100 100 (fun j -> (DenseVector.init 100 (fun i -> float i * 100.0 + float j))) |> should equal largeM) |
|||
] |
|||
|
|||
|
|||
/// Unit tests for the sparse matrix type. |
|||
let SparseMatrixTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallM = DenseMatrix.init 4 4 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix<float> |
|||
|
|||
specs "SparseMatrix" [ |
|||
spec "SparseMatrix.ofList" |
|||
((SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM) |
|||
spec "SparseMatrix.ofSeq" |
|||
((SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> should equal smallM) |
|||
spec "SparseMatrix.constDiag" |
|||
(SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100))) |
|||
spec "SparseMatrix.diag" |
|||
(SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100))) |
|||
] |
|||
|
|||
|
|||
/// Report on errors and success and exit. |
|||
printfn "F# Test Results:" |
|||
printfn "%s" (Results.summary()) |
|||
|
|||
let code = if Results.erredCount() > 0 || Results.failedCount() > 0 then -1 else 0;; |
|||
exit code;; |
|||
@ -0,0 +1,79 @@ |
|||
module MathNet.Numerics.Tests.RandomVariableTests |
|||
|
|||
open MathNet.Numerics |
|||
open MathNet.Numerics.Probability |
|||
open NUnit.Framework |
|||
open FsUnit |
|||
|
|||
[<Test>] |
|||
let ``When creating a empty randomVariable, then the probability should be 1``() = |
|||
let actual = randomVariable { return () } |
|||
RandomVariable.probability actual |> should equal (1N/1N) |
|||
|
|||
let sumOfTwoFairDices = randomVariable { |
|||
let! d1 = RandomVariable.fairDice 6 |
|||
let! d2 = RandomVariable.fairDice 6 |
|||
return d1 + d2 } |
|||
|
|||
[<Test>] |
|||
let ``When creating two fair dices, then P(Sum of 2 dices = 7) should be 1/6``() = |
|||
sumOfTwoFairDices |
|||
|> RandomVariable.filter ((=) 7) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/6N) |
|||
|
|||
let fairCoinAndDice = randomVariable { |
|||
let! d = RandomVariable.fairDice 6 |
|||
let! c = RandomVariable.fairCoin |
|||
return d,c } |
|||
|
|||
[<Test>] |
|||
let ``When creating a fair coin and a fair dice, then P(Heads) should be 1/2``() = |
|||
fairCoinAndDice |
|||
|> RandomVariable.filter (fun (_,c) -> c = Heads) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/2N) |
|||
|
|||
[<Test>] |
|||
let ``When creating a fair coin and a fair dice, then P(Heads and dice > 3) should be 1/4``() = |
|||
fairCoinAndDice |
|||
|> RandomVariable.filter (fun (d,c) -> c = Heads && d > 3) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/4N) |
|||
|
|||
// MontyHall Problem |
|||
// See Martin Erwig and Steve Kollmansberger's paper |
|||
// "Functional Pearls: Probabilistic functional programming in Haskell" |
|||
|
|||
type Outcome = |
|||
| Car |
|||
| Goat |
|||
|
|||
let firstChoice = RandomVariable.toUniformDistribution [Car; Goat; Goat] |
|||
|
|||
let switch firstCoice = |
|||
match firstCoice with |
|||
| Car -> |
|||
// If you had the car and you switch ==> you lose since there are only goats left |
|||
RandomVariable.certainly Goat |
|||
| Goat -> |
|||
// If you had the goat, the host has to take out another goat ==> you win |
|||
RandomVariable.certainly Car |
|||
|
|||
[<Test>] |
|||
let ``When making the first choice in a MontyHall situation, the chances to win should be 1/3``() = |
|||
firstChoice |
|||
|> RandomVariable.filter ((=) Car) |
|||
|> RandomVariable.probability |
|||
|> should equal (1N/3N) |
|||
|
|||
let montyHallWithSwitch = randomVariable { |
|||
let! firstDoor = firstChoice |
|||
return! switch firstDoor } |
|||
|
|||
[<Test>] |
|||
let ``When switching in a MontyHall situation, the chances to win should be 2/3``() = |
|||
montyHallWithSwitch |
|||
|> RandomVariable.filter ((=) Car) |
|||
|> RandomVariable.probability |
|||
|> should equal (2N/3N) |
|||
@ -0,0 +1,28 @@ |
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open NUnit.Framework |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the sparse matrix type. |
|||
module SparseMatrixTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallM = DenseMatrix.init 4 4 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix<float> |
|||
|
|||
[<Test>] |
|||
let ``SparseMatrix.ofList`` () = |
|||
(SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM |
|||
|
|||
[<Test>] |
|||
let ``SparseMatrix.ofSeq`` () = |
|||
(SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> should equal smallM |
|||
|
|||
[<Test>] |
|||
let ``SparseMatrix.constDiag`` () = |
|||
SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100)) |
|||
|
|||
[<Test>] |
|||
let ``SparseMatrix.diag`` () = |
|||
SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100)) |
|||
@ -0,0 +1,21 @@ |
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open NUnit.Framework |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the sparse vector type. |
|||
module SparseVectorTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector<float> |
|||
|
|||
[<Test>] |
|||
let ``SparseVector.ofList`` () = |
|||
(SparseVector.ofList 5 [ (1,0.3) ] :> Vector<float>) |> should equal smallv |
|||
|
|||
[<Test>] |
|||
let ``SparseVector.ofSeq`` () = |
|||
(SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector<float>) |> should equal smallv |
|||
|
|||
@ -0,0 +1,128 @@ |
|||
// First version copied from the F# Power Pack |
|||
// https://raw.github.com/fsharp/powerpack/master/src/FSharp.PowerPack.Unittests/Utilities.fs |
|||
|
|||
namespace MathNet.Numerics.Tests |
|||
open NUnit.Framework |
|||
open System |
|||
open System.Collections.Generic |
|||
|
|||
[<AutoOpen>] |
|||
module Utilities = |
|||
let test msg b = Assert.IsTrue(b, "MiniTest '" + msg + "'") |
|||
let logMessage msg = |
|||
System.Console.WriteLine("LOG:" + msg) |
|||
// System.Diagnostics.Trace.WriteLine("LOG:" + msg) |
|||
let check msg v1 v2 = test msg (v1 = v2) |
|||
let reportFailure msg = Assert.Fail msg |
|||
let numActiveEnumerators = ref 0 |
|||
let throws f = try f() |> ignore; false with e -> true |
|||
|
|||
let countEnumeratorsAndCheckedDisposedAtMostOnceAtEnd (seq: seq<'a>) = |
|||
let enumerator() = |
|||
numActiveEnumerators := !numActiveEnumerators + 1; |
|||
let disposed = ref false in |
|||
let endReached = ref false in |
|||
let ie = seq.GetEnumerator() in |
|||
{ new System.Collections.Generic.IEnumerator<'a> with |
|||
member x.Current = |
|||
test "rvlrve0" (not !endReached); |
|||
test "rvlrve1" (not !disposed); |
|||
ie.Current |
|||
member x.Dispose() = |
|||
test "rvlrve2" !endReached; |
|||
test "rvlrve4" (not !disposed); |
|||
numActiveEnumerators := !numActiveEnumerators - 1; |
|||
disposed := true; |
|||
ie.Dispose() |
|||
interface System.Collections.IEnumerator with |
|||
member x.MoveNext() = |
|||
test "rvlrve0" (not !endReached); |
|||
test "rvlrve3" (not !disposed); |
|||
endReached := not (ie.MoveNext()); |
|||
not !endReached |
|||
member x.Current = |
|||
test "qrvlrve0" (not !endReached); |
|||
test "qrvlrve1" (not !disposed); |
|||
box ie.Current |
|||
member x.Reset() = |
|||
ie.Reset() |
|||
} in |
|||
|
|||
{ new seq<'a> with |
|||
member x.GetEnumerator() = enumerator() |
|||
interface System.Collections.IEnumerable with |
|||
member x.GetEnumerator() = (enumerator() :> _) } |
|||
|
|||
let countEnumeratorsAndCheckedDisposedAtMostOnce (seq: seq<'a>) = |
|||
let enumerator() = |
|||
let disposed = ref false in |
|||
let endReached = ref false in |
|||
let ie = seq.GetEnumerator() in |
|||
numActiveEnumerators := !numActiveEnumerators + 1; |
|||
{ new System.Collections.Generic.IEnumerator<'a> with |
|||
member x.Current = |
|||
test "qrvlrve0" (not !endReached); |
|||
test "qrvlrve1" (not !disposed); |
|||
ie.Current |
|||
member x.Dispose() = |
|||
test "qrvlrve4" (not !disposed); |
|||
numActiveEnumerators := !numActiveEnumerators - 1; |
|||
disposed := true; |
|||
ie.Dispose() |
|||
interface System.Collections.IEnumerator with |
|||
member x.MoveNext() = |
|||
test "qrvlrve0" (not !endReached); |
|||
test "qrvlrve3" (not !disposed); |
|||
endReached := not (ie.MoveNext()); |
|||
not !endReached |
|||
member x.Current = |
|||
test "qrvlrve0" (not !endReached); |
|||
test "qrvlrve1" (not !disposed); |
|||
box ie.Current |
|||
member x.Reset() = |
|||
ie.Reset() |
|||
} in |
|||
|
|||
{ new seq<'a> with |
|||
member x.GetEnumerator() = enumerator() |
|||
interface System.Collections.IEnumerable with |
|||
member x.GetEnumerator() = (enumerator() :> _) } |
|||
|
|||
// Verifies two sequences are equal (same length, equiv elements) |
|||
let verifySeqsEqual seq1 seq2 = |
|||
if Seq.length seq1 <> Seq.length seq2 then Assert.Fail() |
|||
|
|||
let zippedElements = Seq.zip seq1 seq2 |
|||
if zippedElements |> Seq.forall (fun (a, b) -> a = b) |
|||
then () |
|||
else Assert.Fail() |
|||
|
|||
/// Check that the lamda throws an exception of the given type. Otherwise |
|||
/// calls Assert.Fail() |
|||
let private checkThrowsExn<'a when 'a :> exn> (f : unit -> unit) = |
|||
let funcThrowsAsExpected = |
|||
try |
|||
let _ = f () |
|||
false // Did not throw! |
|||
with |
|||
| :? 'a |
|||
-> true // Thew null ref, OK |
|||
| _ -> false // Did now throw a null ref exception! |
|||
if funcThrowsAsExpected |
|||
then () |
|||
else Assert.Fail() |
|||
|
|||
// Illegitimate exceptions. Once we've scrubbed the library, we should add an |
|||
// attribute to flag these exception's usage as a bug. |
|||
let checkThrowsNullRefException f = checkThrowsExn<NullReferenceException> f |
|||
let checkThrowsIndexOutRangException f = checkThrowsExn<IndexOutOfRangeException> f |
|||
|
|||
// Legit exceptions |
|||
let checkThrowsNotSupportedException f = checkThrowsExn<NotSupportedException> f |
|||
let checkThrowsArgumentException f = checkThrowsExn<ArgumentException> f |
|||
let checkThrowsArgumentNullException f = checkThrowsExn<ArgumentNullException> f |
|||
let checkThrowsKeyNotFoundException f = checkThrowsExn<KeyNotFoundException> f |
|||
let checkThrowsDivideByZeroException f = checkThrowsExn<DivideByZeroException> f |
|||
let checkThrowsInvalidOperationExn f = checkThrowsExn<InvalidOperationException> f |
|||
|
|||
|
|||
@ -0,0 +1,103 @@ |
|||
namespace MathNet.Numerics.Tests |
|||
|
|||
open NUnit.Framework |
|||
open FsUnit |
|||
open MathNet.Numerics.LinearAlgebra.Generic |
|||
open MathNet.Numerics.LinearAlgebra.Double |
|||
|
|||
/// Unit tests for the vector type. |
|||
module VectorTests = |
|||
|
|||
/// A small uniform vector. |
|||
let smallv = new DenseVector([|0.3;0.3;0.3;0.3;0.3|]) :> Vector<float> |
|||
|
|||
/// A large vector with increasingly large entries |
|||
let largev = new DenseVector(Array.init 100 (fun i -> float i / 100.0)) :> Vector<float> |
|||
|
|||
[<Test>] |
|||
let ``Vector.toArray`` () = |
|||
Vector.toArray smallv |> should array_equal [|0.3;0.3;0.3;0.3;0.3|] |
|||
|
|||
[<Test>] |
|||
let ``Vector.toList`` () = |
|||
Vector.toList smallv |> should equal [0.3;0.3;0.3;0.3;0.3] |
|||
|
|||
[<Test>] |
|||
let ``Vector.mapInPlace`` () = |
|||
let w = smallv.Clone() |
|||
Vector.mapInPlace (fun x -> 2.0 * x) w |
|||
w |> should equal (2.0 * smallv) |
|||
|
|||
[<Test>] |
|||
let ``Vector.mapiInPlace`` () = |
|||
let w = largev.Clone() |
|||
Vector.mapiInPlace (fun i x -> float i / 100.0) w |
|||
w |> should equal (largev) |
|||
|
|||
[<Test>] |
|||
let ``Vector.addInPlace`` () = |
|||
let w = largev.Clone() |
|||
Vector.addInPlace w largev |
|||
w |> should equal (2.0 * largev) |
|||
|
|||
[<Test>] |
|||
let ``Vector.subInPlace`` () = |
|||
let w = largev.Clone() |
|||
Vector.subInPlace w largev |
|||
w |> should equal (0.0 * largev) |
|||
|
|||
[<Test>] |
|||
let ``Vector.map`` () = |
|||
Vector.map (fun x -> 2.0 * x) largev |> should equal (2.0 * largev) |
|||
|
|||
[<Test>] |
|||
let ``Vector.mapi`` () = |
|||
Vector.mapi (fun i x -> float i / 100.0) largev |> should equal largev |
|||
|
|||
[<Test>] |
|||
let ``Vector.fold`` () = |
|||
Vector.fold (fun a b -> a - b) 0.0 smallv |> should equal -1.5 |
|||
|
|||
[<Test>] |
|||
let ``Vector.foldBack`` () = |
|||
Vector.foldBack (fun a b -> a - b) 0.0 smallv |> should equal 0.0 |
|||
|
|||
[<Test>] |
|||
let ``Vector.foldi`` () = |
|||
Vector.foldi (fun i a b -> a + b) 0.0 smallv |> should equal 1.5 |
|||
|
|||
[<Test>] |
|||
let ``Vector.forall`` () = |
|||
Vector.forall (fun x -> x = 0.3) smallv |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Vector.exists`` () = |
|||
Vector.exists (fun x -> x = 0.3) smallv |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Vector.foralli`` () = |
|||
Vector.foralli (fun i x -> x = 0.3 && i < 5) smallv |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Vector.existsi`` () = |
|||
Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true |
|||
|
|||
[<Test>] |
|||
let ``Vector.scan`` () = |
|||
Vector.scan (fun acc x -> acc + x) smallv |> should (approximately_vector_equal 14) (new DenseVector( [|0.3;0.6;0.9;1.2;1.5|] ) :> Vector<float>) |
|||
|
|||
[<Test>] |
|||
let ``Vector.scanBack`` () = |
|||
Vector.scanBack (fun x acc -> acc + x) smallv |> should (approximately_vector_equal 14) (new DenseVector( [|1.5;1.2;0.9;0.6;0.3|] ) :> Vector<float>) |
|||
|
|||
[<Test>] |
|||
let ``Vector.reduce`` () = |
|||
Vector.reduce (fun acc x -> acc ** x) smallv |> should (approximately_equal 14) 0.990295218585507 |
|||
|
|||
[<Test>] |
|||
let ``Vector.reduceBack`` () = |
|||
Vector.reduceBack (fun x acc -> x ** acc) smallv |> should (approximately_equal 14) 0.488911287726319 |
|||
|
|||
[<Test>] |
|||
let ``Vector.insert`` () = |
|||
Vector.insert 2 0.5 smallv |> should (approximately_vector_equal 14) (new DenseVector ( [|0.3;0.3;0.5;0.3;0.3;0.3|] ) :> Vector<float>) |
|||
@ -0,0 +1,4 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<packages> |
|||
<package id="NUnit" version="2.6.2" targetFramework="net40" /> |
|||
</packages> |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,16 @@ |
|||
#if PORTABLE
|
|||
using System; |
|||
|
|||
namespace MathNet.Numerics |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] |
|||
public class TargetedPatchingOptOutAttribute : Attribute |
|||
{ |
|||
public string Reason { get; private set; } |
|||
public TargetedPatchingOptOutAttribute(string reason) |
|||
{ |
|||
Reason = reason; |
|||
} |
|||
} |
|||
} |
|||
#endif
|
|||
Loading…
Reference in new issue