Browse Source

vector: minor cleanup of Hany's additional vector methods

la-knuth
Marcus Cuda 17 years ago
parent
commit
7e698cd2b7
  1. BIN
      src/FSharpUnitTests100602(1).vsp
  2. BIN
      src/FSharpUnitTests100602(2).vsp
  3. BIN
      src/FSharpUnitTests100602.vsp
  4. 237
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  5. 241
      src/Numerics/LinearAlgebra/Double/Vector.cs
  6. 36
      src/Numerics/Random/AbstractRandomNumberGenerator.cs
  7. 485
      src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs
  8. 633
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs
  9. 237
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

BIN
src/FSharpUnitTests100602(1).vsp

Binary file not shown.

BIN
src/FSharpUnitTests100602(2).vsp

Binary file not shown.

BIN
src/FSharpUnitTests100602.vsp

Binary file not shown.

237
src/Numerics/LinearAlgebra/Double/DenseVector.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -33,8 +29,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Distributions;
using NumberTheory; using NumberTheory;
using Properties; using Properties;
using Random;
using Threading; using Threading;
/// <summary> /// <summary>
@ -93,8 +91,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (vector == null) if (vector == null)
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
this.Data.Length, this.Data.Length,
index => this[index] = other[index]); index => this[index] = other[index]);
} }
else else
@ -287,8 +285,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (otherVector == null) if (otherVector == null)
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
this.Data.Length, this.Data.Length,
index => target[index] = this.Data[index]); index => target[index] = this.Data[index]);
} }
else else
@ -309,8 +307,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Data.Length, this.Data.Length,
index => this.Data[index] += scalar); index => this.Data[index] += scalar);
} }
@ -465,8 +463,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Data.Length, this.Data.Length,
index => this.Data[index] -= scalar); index => this.Data[index] -= scalar);
} }
@ -617,9 +615,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
var result = new DenseVector(this.Count); var result = new DenseVector(this.Count);
CommonParallel.For( CommonParallel.For(
0, 0,
this.Data.Length, this.Data.Length,
index => result[index] = -this.Data[index]); index => result[index] = -this.Data[index]);
return result; return result;
} }
@ -663,7 +661,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
return base.DotProduct(other); return base.DotProduct(other);
} }
return Control.LinearAlgebraProvider.DotProduct(this.Data, denseVector.Data); return Control.LinearAlgebraProvider.DotProduct(this.Data, denseVector.Data);
} }
@ -758,7 +756,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the absolute minimum element.</returns> /// <returns>The value of the absolute minimum element.</returns>
public override double AbsoluteMinimum() public override double AbsoluteMinimum()
{ {
return Math.Abs(this.Data[AbsoluteMinimumIndex()]); return Math.Abs(this.Data[this.AbsoluteMinimumIndex()]);
} }
/// <summary> /// <summary>
@ -767,11 +765,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of absolute minimum element.</returns> /// <returns>The index of absolute minimum element.</returns>
public override int AbsoluteMinimumIndex() public override int AbsoluteMinimumIndex()
{ {
int index = 0; var index = 0;
double min = System.Math.Abs(this.Data[index]); var min = Math.Abs(this.Data[index]);
for (int i = 1; i < Count; i++) for (var i = 1; i < this.Count; i++)
{ {
double test = System.Math.Abs(this.Data[i]); var test = Math.Abs(this.Data[i]);
if (test < min) if (test < min)
{ {
index = i; index = i;
@ -795,9 +793,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public override Vector SubVector(int index, int length) public override Vector SubVector(int index, int length)
{ {
if (index < 0 || index >= Count) if (index < 0 || index >= this.Count)
{ {
throw new ArgumentOutOfRangeException("start"); throw new ArgumentOutOfRangeException("index");
} }
if (length <= 0) if (length <= 0)
@ -805,16 +803,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("length"); throw new ArgumentOutOfRangeException("length");
} }
if (index + length > Count) if (index + length > this.Count)
{ {
throw new ArgumentOutOfRangeException("start"); throw new ArgumentOutOfRangeException("length");
} }
DenseVector result = new DenseVector(length); var result = new DenseVector(length);
CommonParallel.For( CommonParallel.For(
index, index,
index + length, index + length,
i => result.Data[i - index] = this.Data[i]); i => result.Data[i - index] = this.Data[i]);
return result; return result;
} }
@ -832,14 +830,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("values"); throw new ArgumentNullException("values");
} }
if (values.Length != Count) if (values.Length != this.Count)
{ {
throw new ArgumentException("values", Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "values");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
values.Length, values.Length,
i => this.Data[i] = values[i]); i => this.Data[i] = values[i]);
} }
@ -849,7 +847,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of maximum element.</returns> /// <returns>The value of maximum element.</returns>
public override double Maximum() public override double Maximum()
{ {
return this.Data[MaximumIndex()]; return this.Data[this.MaximumIndex()];
} }
/// <summary> /// <summary>
@ -858,9 +856,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of absolute maximum element.</returns> /// <returns>The index of absolute maximum element.</returns>
public override int MaximumIndex() public override int MaximumIndex()
{ {
int index = 0; var index = 0;
double max = this.Data[0]; var max = this.Data[0];
for (int i = 1; i < Count; i++) for (var i = 1; i < this.Count; i++)
{ {
if (max < this.Data[i]) if (max < this.Data[i])
{ {
@ -878,7 +876,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the minimum element.</returns> /// <returns>The value of the minimum element.</returns>
public override double Minimum() public override double Minimum()
{ {
return this.Data[MinimumIndex()]; return this.Data[this.MinimumIndex()];
} }
/// <summary> /// <summary>
@ -887,9 +885,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of minimum element.</returns> /// <returns>The index of minimum element.</returns>
public override int MinimumIndex() public override int MinimumIndex()
{ {
int index = 0; var index = 0;
double min = this.Data[0]; var min = this.Data[0];
for (int i = 1; i < Count; i++) for (var i = 1; i < this.Count; i++)
{ {
if (min > this.Data[i]) if (min > this.Data[i])
{ {
@ -908,7 +906,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double Sum() public override double Sum()
{ {
double result = 0; double result = 0;
for (int i = 0; i < Count; i++) for (var i = 0; i < this.Count; i++)
{ {
result += this.Data[i]; result += this.Data[i];
} }
@ -923,7 +921,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double SumMagnitudes() public override double SumMagnitudes()
{ {
double result = 0; double result = 0;
for (int i = 0; i < Count; i++) for (var i = 0; i < this.Count; i++)
{ {
result += Math.Abs(this.Data[i]); result += Math.Abs(this.Data[i]);
} }
@ -945,13 +943,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
DenseVector result = new DenseVector(Count); var result = new DenseVector(this.Count);
PointWiseMultiply(other, result); this.PointWiseMultiply(other, result);
return result; return result;
} }
@ -976,20 +974,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result.Data[index] = this.Data[index] * other.Data[index]); index => result.Data[index] = this.Data[index] * other.Data[index]);
} }
/// <summary> /// <summary>
@ -1006,13 +1004,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
DenseVector result = new DenseVector(Count); var result = new DenseVector(this.Count);
PointWiseAdd(other, result); this.PointWiseAdd(other, result);
return result; return result;
} }
@ -1037,20 +1035,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result.Data[index] = this.Data[index] + other.Data[index]); index => result.Data[index] = this.Data[index] + other.Data[index]);
} }
/// <summary> /// <summary>
@ -1067,13 +1065,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
DenseVector result = new DenseVector(Count); var result = new DenseVector(this.Count);
PointWiseSubtract(other, result); this.PointWiseSubtract(other, result);
return result; return result;
} }
@ -1098,20 +1096,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result.Data[index] = this.Data[index] - other.Data[index]); index => result.Data[index] = this.Data[index] - other.Data[index]);
} }
/// <summary> /// <summary>
@ -1128,13 +1126,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
DenseVector result = new DenseVector(Count); var result = new DenseVector(this.Count);
PointWiseDivide(other, result); this.PointWiseDivide(other, result);
return result; return result;
} }
@ -1159,20 +1157,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result.Data[index] = this.Data[index] / other.Data[index]); index => result.Data[index] = this.Data[index] / other.Data[index]);
} }
/// <summary> /// <summary>
@ -1195,51 +1193,63 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("v"); throw new ArgumentNullException("v");
} }
DenseMatrix matrix = new DenseMatrix(u.Count, v.Count); var matrix = new DenseMatrix(u.Count, v.Count);
CommonParallel.For( CommonParallel.For(
0, 0,
u.Count, u.Count,
i => CommonParallel.For(0, v.Count, j => matrix.At(i, j, u.Data[i] * v.Data[j]))); i => CommonParallel.For(0, v.Count, j => matrix.At(i, j, u.Data[i] * v.Data[j])));
return matrix; return matrix;
} }
/// <summary> /// <summary>
/// Generates vector with random elements /// Generates a vector with random elements
/// </summary> /// </summary>
/// <param name="n">Dimensionality of vector.</param> /// <param name="length">Number of elements in the vector.</param>
/// <param name="randomDistribution">Continuous Random Distribution or Source</param>
/// <returns> /// <returns>
/// An n-dimensional vector with uniformly distributed /// A vector with n-random elements distributed according
/// random elements in <c>[0, 1)</c> interval. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception>
public new virtual DenseVector Random(int n) public override Vector Random(int length, IContinuousDistribution randomDistribution)
{ {
// use any class which inherits the AbstractRandomNumberGenerator if (length < 0)
return Random(n, new MathNet.Numerics.Random.SystemCryptoRandomNumberGenerator()); {
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = (DenseVector)this.CreateVector(length);
for (var index = 0; index < v.Data.Length; index++)
{
v.Data[index] = randomDistribution.Sample();
}
return v;
} }
/// <summary> /// <summary>
/// Generates a vector with random elements /// Generates a vector with random elements
/// </summary> /// </summary>
/// <param name="n">Number of elements in the vector.</param> /// <param name="length">Number of elements in the vector.</param>
/// <param name="randomDistribution">Continuous Random Distribution or Source</param> /// <param name="randomDistribution">Continuous Random Distribution or Source</param>
/// <returns> /// <returns>
/// A vector with n-random elements distributed according /// A vector with n-random elements distributed according
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception>
public new virtual DenseVector Random(int n, MathNet.Numerics.Random.AbstractRandomNumberGenerator randomDistribution) public override Vector Random(int length, IDiscreteDistribution randomDistribution)
{ {
if (n < 0) if (length < 0)
{ {
throw new ArgumentException(Resources.ArgumentMustBePositive, "n"); throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = (DenseVector)this.CreateVector(length);
for (var index = 0; index < v.Data.Length; index++)
{
v.Data[index] = randomDistribution.Sample();
} }
DenseVector v = new DenseVector(n);
CommonParallel.For(
0,
v.Count,
index => v.Data[index] = randomDistribution.NextDouble());
return v; return v;
} }
@ -1265,7 +1275,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double Norm() public override double Norm()
{ {
var sum = 0.0; var sum = 0.0;
for (var i = 0; i < this.Data.Length; i++) for (var i = 0; i < this.Data.Length; i++)
{ {
sum = SpecialFunctions.Hypotenuse(sum, this.Data[i]); sum = SpecialFunctions.Hypotenuse(sum, this.Data[i]);
@ -1281,8 +1291,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double Norm1() public override double Norm1()
{ {
return CommonParallel.Aggregate( return CommonParallel.Aggregate(
0, 0,
this.Count, this.Count,
index => Math.Abs(this.Data[index])); index => Math.Abs(this.Data[index]));
} }
@ -1309,8 +1319,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var sum = CommonParallel.Aggregate( var sum = CommonParallel.Aggregate(
0, 0,
this.Count, this.Count,
index => Math.Pow(Math.Abs(this.Data[index]), p)); index => Math.Pow(Math.Abs(this.Data[index]), p));
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
@ -1323,35 +1333,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double NormInfinity() public override double NormInfinity()
{ {
return CommonParallel.Select( return CommonParallel.Select(
0, 0,
this.Count, this.Count,
(index, localData) => localData = Math.Max(localData, Math.Abs(this.Data[index])), (index, localData) => localData = Math.Max(localData, Math.Abs(this.Data[index])),
Math.Max); Math.Max);
/*double max = 0;
var syncLock = new object();
Parallel.ForEach(
Partitioner.Create(0, this.Count),
() => 0.0,
(range, loop, localData) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
localData = Math.Max(localData, Math.Abs(this.Data[i]));
}
return localData;
},
localResult =>
{
lock (syncLock)
{
max = Math.Max(max, localResult);
}
});
return max;*/
} }
#endregion #endregion

241
src/Numerics/LinearAlgebra/Double/Vector.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -34,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Distributions;
using Properties; using Properties;
using Threading; using Threading;
@ -133,8 +130,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => this[index] += scalar); index => this[index] += scalar);
} }
@ -212,8 +209,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => this[index] += other[index]); index => this[index] += other[index]);
} }
@ -277,8 +274,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => this[index] -= scalar); index => this[index] -= scalar);
} }
@ -356,8 +353,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => this[index] -= other[index]); index => this[index] -= other[index]);
} }
@ -421,8 +418,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => this[index] *= scalar); index => this[index] *= scalar);
} }
@ -562,13 +559,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
Vector result = CreateVector(Count); var result = this.CreateVector(this.Count);
PointWiseMultiply(other, result); this.PointWiseMultiply(other, result);
return result; return result;
} }
@ -593,20 +590,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result[index] = this[index] * other[index]); index => result[index] = this[index] * other[index]);
} }
/// <summary> /// <summary>
@ -623,13 +620,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
Vector result = CreateVector(Count); var result = this.CreateVector(this.Count);
PointWiseAdd(other, result); this.PointWiseAdd(other, result);
return result; return result;
} }
@ -654,22 +651,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result[index] = this[index] + other[index]); index => result[index] = this[index] + other[index]);
} }
/// <summary> /// <summary>
/// Pointwise subtarct this vector with another vector. /// Pointwise subtarct this vector with another vector.
/// </summary> /// </summary>
@ -684,13 +681,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
Vector result = CreateVector(Count); var result = this.CreateVector(this.Count);
PointWiseSubtract(other, result); this.PointWiseSubtract(other, result);
return result; return result;
} }
@ -715,20 +712,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result[index] = this[index] - other[index]); index => result[index] = this[index] - other[index]);
} }
/// <summary> /// <summary>
@ -745,13 +742,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
Vector result = CreateVector(Count); var result = this.CreateVector(this.Count);
PointWiseDivide(other, result); this.PointWiseDivide(other, result);
return result; return result;
} }
@ -776,20 +773,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (Count != other.Count) if (this.Count != other.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
if (Count != result.Count) if (this.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => result[index] = this[index] / other[index]); index => result[index] = this[index] / other[index]);
} }
/// <summary> /// <summary>
@ -812,27 +809,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("v"); throw new ArgumentNullException("v");
} }
DenseMatrix matrix = new DenseMatrix(u.Count, v.Count); var matrix = new DenseMatrix(u.Count, v.Count);
CommonParallel.For( CommonParallel.For(
0, 0,
u.Count, u.Count,
i => CommonParallel.For(0, v.Count, j => matrix.At(i, j, u[i] * v[j]))); i => CommonParallel.For(0, v.Count, j => matrix.At(i, j, u[i] * v[j])));
return matrix; return matrix;
} }
/// <summary> /// <summary>
/// Generates vector with random elements /// Generates a vector with random elements
/// </summary> /// </summary>
/// <param name="length">Dimensionality of vector.</param> /// <param name="length">Number of elements in the vector.</param>
/// <param name="randomDistribution">Continuous Random Distribution or Source</param>
/// <returns> /// <returns>
/// An n-dimensional vector with uniformly distributed /// A vector with n-random elements distributed according
/// random elements in <c>[0, 1)</c> interval. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception>
public virtual Vector Random(int length) public virtual Vector Random(int length, IContinuousDistribution randomDistribution)
{ {
// Just use any class which inherits the AbstractRandomNumberGenerator if (length < 0)
return Random(length, new MathNet.Numerics.Random.SystemCryptoRandomNumberGenerator()); {
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = this.CreateVector(length);
for (var index = 0; index < v.Count; index++)
{
v[index] = randomDistribution.Sample();
}
return v;
} }
/// <summary> /// <summary>
@ -845,18 +853,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non poisitive<see langword="null" />.</exception>
public virtual Vector Random(int length, MathNet.Numerics.Random.AbstractRandomNumberGenerator randomDistribution) public virtual Vector Random(int length, IDiscreteDistribution randomDistribution)
{ {
if (length < 0) if (length < 0)
{ {
throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
} }
Vector v = CreateVector(length); var v = this.CreateVector(length);
CommonParallel.For( for (var index = 0; index < v.Count; index++)
0, {
v.Count, v[index] = randomDistribution.Sample();
index => v[index] = randomDistribution.NextDouble()); }
return v; return v;
} }
@ -879,7 +888,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the absolute minimum element.</returns> /// <returns>The value of the absolute minimum element.</returns>
public virtual double AbsoluteMinimum() public virtual double AbsoluteMinimum()
{ {
return Math.Abs(this[AbsoluteMinimumIndex()]); return Math.Abs(this[this.AbsoluteMinimumIndex()]);
} }
/// <summary> /// <summary>
@ -888,11 +897,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of absolute minimum element.</returns> /// <returns>The index of absolute minimum element.</returns>
public virtual int AbsoluteMinimumIndex() public virtual int AbsoluteMinimumIndex()
{ {
int index = 0; var index = 0;
double min = System.Math.Abs(this[index]); var min = Math.Abs(this[index]);
for (int i = 1; i < Count; i++) for (var i = 1; i < this.Count; i++)
{ {
double test = System.Math.Abs(this[i]); var test = Math.Abs(this[i]);
if (test < min) if (test < min)
{ {
index = i; index = i;
@ -901,7 +910,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
return index; return index;
} }
/// <summary> /// <summary>
/// Returns the value of maximum element. /// Returns the value of maximum element.
@ -909,7 +918,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of maximum element.</returns> /// <returns>The value of maximum element.</returns>
public virtual double Maximum() public virtual double Maximum()
{ {
return this[MaximumIndex()]; return this[this.MaximumIndex()];
} }
/// <summary> /// <summary>
@ -918,9 +927,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of absolute maximum element.</returns> /// <returns>The index of absolute maximum element.</returns>
public virtual int MaximumIndex() public virtual int MaximumIndex()
{ {
int index = 0; var index = 0;
double max = this[0]; var max = this[0];
for (int i = 1; i < Count; i++) for (var i = 1; i < this.Count; i++)
{ {
if (max < this[i]) if (max < this[i])
{ {
@ -938,7 +947,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the minimum element.</returns> /// <returns>The value of the minimum element.</returns>
public virtual double Minimum() public virtual double Minimum()
{ {
return this[MinimumIndex()]; return this[this.MinimumIndex()];
} }
/// <summary> /// <summary>
@ -947,9 +956,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of minimum element.</returns> /// <returns>The index of minimum element.</returns>
public virtual int MinimumIndex() public virtual int MinimumIndex()
{ {
int index = 0; var index = 0;
double min = this[0]; var min = this[0];
for (int i = 1; i < Count; i++) for (var i = 1; i < this.Count; i++)
{ {
if (min > this[i]) if (min > this[i])
{ {
@ -968,7 +977,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual double Sum() public virtual double Sum()
{ {
double result = 0; double result = 0;
for (int i = 0; i < Count; i++) for (var i = 0; i < this.Count; i++)
{ {
result += this[i]; result += this[i];
} }
@ -983,13 +992,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual double SumMagnitudes() public virtual double SumMagnitudes()
{ {
double result = 0; double result = 0;
for (int i = 0; i < Count; i++) for (var i = 0; i < this.Count; i++)
{ {
result += Math.Abs(this[i]); result += Math.Abs(this[i]);
} }
return result; return result;
} }
#endregion #endregion
#region Arithmetic Operator Overloading #region Arithmetic Operator Overloading
@ -1227,10 +1237,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var sum = CommonParallel.Aggregate( var sum = CommonParallel.Aggregate(
0, 0,
this.Count, this.Count,
index => Math.Pow(Math.Abs(this[index]), p)); index => Math.Pow(Math.Abs(this[index]), p));
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }
@ -1243,36 +1253,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual double NormInfinity() public virtual double NormInfinity()
{ {
return CommonParallel.Select( return CommonParallel.Select(
0, 0,
this.Count, this.Count,
(index, localData) => localData = Math.Max(localData, Math.Abs(this[index])), (index, localData) => localData = Math.Max(localData, Math.Abs(this[index])),
Math.Max); Math.Max);
/*
var max = 0.0;
var syncLock = new object();
Parallel.ForEach(
Partitioner.Create(0, this.Count),
() => 0.0,
(range, loop, localData) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
localData = Math.Max(localData, Math.Abs(this[i]));
}
return localData;
},
localResult =>
{
lock (syncLock)
{
max = Math.Max(localResult, max);
}
});
return max;*/
} }
/// <summary> /// <summary>
@ -1341,8 +1325,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => target[index] = this[index]); index => target[index] = this[index]);
} }
@ -1394,15 +1378,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
this.CopyTo(tmpVector); this.CopyTo(tmpVector);
CommonParallel.For( CommonParallel.For(
0, 0,
count, count,
index => destination[destinationOffset + index] = tmpVector[offset + index]); index => destination[destinationOffset + index] = tmpVector[offset + index]);
} }
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
count, count,
index => destination[destinationOffset + index] = this[offset + index]); index => destination[destinationOffset + index] = this[offset + index]);
} }
} }
@ -1471,9 +1455,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public virtual Vector SubVector(int index, int length) public virtual Vector SubVector(int index, int length)
{ {
if (index < 0 || index >= Count) if (index < 0 || index >= this.Count)
{ {
throw new ArgumentOutOfRangeException("start"); throw new ArgumentOutOfRangeException("index");
} }
if (length <= 0) if (length <= 0)
@ -1481,16 +1465,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("length"); throw new ArgumentOutOfRangeException("length");
} }
if (index + length > Count) if (index + length > this.Count)
{ {
throw new ArgumentOutOfRangeException("start"); throw new ArgumentOutOfRangeException("index");
} }
Vector result = CreateVector(length); var result = this.CreateVector(length);
CommonParallel.For( CommonParallel.For(
index, index,
index + length, index + length,
i => result[i - index] = this[i]); i => result[i - index] = this[i]);
return result; return result;
} }
@ -1503,21 +1487,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <paramref name="values"/> is not the same size as this vector.</exception> /// <exception cref="ArgumentException">If <paramref name="values"/> is not the same size as this vector.</exception>
public virtual void SetValues(double[] values) public virtual void SetValues(double[] values)
{ {
if (values == null) if (values == null)
{ {
throw new ArgumentNullException("values"); throw new ArgumentNullException("values");
} }
if (values.Length != Count) if (values.Length != this.Count)
{ {
throw new ArgumentException("values", Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "values");
} }
CommonParallel.For( CommonParallel.For(
0, 0,
values.Length, values.Length,
i => this[i] = values[i]); i => this[i] = values[i]);
} }
#endregion #endregion
#region Implemented Interfaces #region Implemented Interfaces

36
src/Numerics/Random/AbstractRandomNumberGenerator.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -37,7 +33,7 @@ namespace MathNet.Numerics.Random
/// Abstract class for random number generators. This class introduces a layer between <see cref="System.Random"/> /// Abstract class for random number generators. This class introduces a layer between <see cref="System.Random"/>
/// and the Math.Net Numerics random number generators to provide thread safety. /// and the Math.Net Numerics random number generators to provide thread safety.
/// </summary> /// </summary>
public abstract class AbstractRandomNumberGenerator : System.Random public abstract class AbstractRandomNumberGenerator : Random
{ {
/// <summary> /// <summary>
/// A delegate type that represents a method that generates random numbers. /// A delegate type that represents a method that generates random numbers.
@ -55,15 +51,13 @@ namespace MathNet.Numerics.Random
/// </summary> /// </summary>
private readonly object _lock = new object(); private readonly object _lock = new object();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="AbstractRandomNumberGenerator"/> class using /// Initializes a new instance of the <see cref="AbstractRandomNumberGenerator"/> class using
/// the value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to set whether /// the value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to set whether
/// the instance is thread safe or not. /// the instance is thread safe or not.
/// </summary> /// </summary>
protected AbstractRandomNumberGenerator(): this(Control.ThreadSafeRandomNumberGenerators) protected AbstractRandomNumberGenerator() : this(Control.ThreadSafeRandomNumberGenerators)
{ {
} }
/// <summary> /// <summary>
@ -74,7 +68,7 @@ namespace MathNet.Numerics.Random
/// safe classes.</remarks> /// safe classes.</remarks>
protected AbstractRandomNumberGenerator(bool threadSafe) protected AbstractRandomNumberGenerator(bool threadSafe)
{ {
_sampleMethod = threadSafe ? (SampleMethod) ThreadSafeSample : DoSample; this._sampleMethod = threadSafe ? (SampleMethod)this.ThreadSafeSample : this.DoSample;
} }
/// <summary> /// <summary>
@ -91,11 +85,13 @@ namespace MathNet.Numerics.Random
{ {
throw new ArgumentException(Resources.ArgumentMustBePositive); throw new ArgumentException(Resources.ArgumentMustBePositive);
} }
var ret = new double[n]; var ret = new double[n];
for (int i = 0; i < ret.Length; i++) for (var i = 0; i < ret.Length; i++)
{ {
ret[i] = Sample(); ret[i] = this.Sample();
} }
return ret; return ret;
} }
@ -107,7 +103,7 @@ namespace MathNet.Numerics.Random
/// </returns> /// </returns>
public override int Next() public override int Next()
{ {
return (int)(Sample() * int.MaxValue); return (int)(this.Sample() * int.MaxValue);
} }
/// <summary> /// <summary>
@ -123,7 +119,7 @@ namespace MathNet.Numerics.Random
throw new ArgumentOutOfRangeException(Resources.ArgumentMustBePositive); throw new ArgumentOutOfRangeException(Resources.ArgumentMustBePositive);
} }
return (int) (Sample() % maxValue); return (int)(this.Sample() % maxValue);
} }
/// <summary> /// <summary>
@ -142,7 +138,7 @@ namespace MathNet.Numerics.Random
throw new ArgumentOutOfRangeException(Resources.ArgumentMinValueGreaterThanMaxValue); throw new ArgumentOutOfRangeException(Resources.ArgumentMinValueGreaterThanMaxValue);
} }
return (int) (Sample()*(maxValue - minValue)) + minValue; return (int)(this.Sample() * (maxValue - minValue)) + minValue;
} }
/// <summary> /// <summary>
@ -157,9 +153,9 @@ namespace MathNet.Numerics.Random
throw new ArgumentNullException("buffer"); throw new ArgumentNullException("buffer");
} }
for (int i = 0; i < buffer.Length; i++) for (var i = 0; i < buffer.Length; i++)
{ {
buffer[i] = (byte) (Next()%256); buffer[i] = (byte)(this.Next() % 256);
} }
} }
@ -169,18 +165,18 @@ namespace MathNet.Numerics.Random
/// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns> /// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns>
protected override double Sample() protected override double Sample()
{ {
return _sampleMethod(); return this._sampleMethod();
} }
/// <summary> /// <summary>
/// Thread safe version of <seealso cref="DoSample"/> which returns a random number between 0.0 and 1.0. /// Thread safe version of <seealso cref="DoSample"/> which returns a random number between 0.0 and 1.0.
/// </summary> /// </summary>
/// <returns></returns> /// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0</returns>
private double ThreadSafeSample() private double ThreadSafeSample()
{ {
lock(_lock) lock (this._lock)
{ {
return DoSample(); return this.DoSample();
} }
} }

485
src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -30,10 +26,10 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System.Collections.Generic;
using MbUnit.Framework;
using LinearAlgebra.Double;
using System; using System;
using System.Collections.Generic;
using LinearAlgebra.Double;
using MbUnit.Framework;
public class DenseVectorTests : VectorTests public class DenseVectorTests : VectorTests
{ {
@ -45,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
protected override Vector CreateVector(IList<double> data) protected override Vector CreateVector(IList<double> data)
{ {
var vector = new DenseVector(data.Count); var vector = new DenseVector(data.Count);
for(var index = 0; index < data.Count; index++) for (var index = 0; index < data.Count; index++)
{ {
vector[index] = data[index]; vector[index] = data[index];
} }
@ -57,8 +53,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateDenseVectorFromArray() public void CanCreateDenseVectorFromArray()
{ {
var data = new double[_data.Length]; var data = new double[this._data.Length];
System.Array.Copy(_data, data, _data.Length); Array.Copy(this._data, data, this._data.Length);
var vector = new DenseVector(data); var vector = new DenseVector(data);
Assert.AreSame(data, vector.Data); Assert.AreSame(data, vector.Data);
@ -66,6 +62,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
Assert.AreEqual(data[i], vector[i]); Assert.AreEqual(data[i], vector[i]);
} }
vector[0] = 100.0; vector[0] = 100.0;
Assert.AreEqual(100.0, data[0]); Assert.AreEqual(100.0, data[0]);
} }
@ -74,12 +71,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateDenseVectorFromAnotherDenseVector() public void CanCreateDenseVectorFromAnotherDenseVector()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
var other = new DenseVector(vector); var other = new DenseVector(vector);
Assert.AreNotSame(vector, other); Assert.AreNotSame(vector, other);
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(vector[i], other[i]); Assert.AreEqual(vector[i], other[i]);
} }
@ -89,11 +86,11 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateDenseVectorFromAnotherVector() public void CanCreateDenseVectorFromAnotherVector()
{ {
var vector = (Vector)new DenseVector(_data); var vector = (Vector)new DenseVector(this._data);
var other = new DenseVector(vector); var other = new DenseVector(vector);
Assert.AreNotSame(vector, other); Assert.AreNotSame(vector, other);
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(vector[i], other[i]); Assert.AreEqual(vector[i], other[i]);
} }
@ -103,10 +100,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateDenseVectorFromUserDefinedVector() public void CanCreateDenseVectorFromUserDefinedVector()
{ {
var vector = new UserDefinedVector(_data); var vector = new UserDefinedVector(this._data);
var other = new DenseVector(vector); var other = new DenseVector(vector);
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(vector[i], other[i]); Assert.AreEqual(vector[i], other[i]);
} }
@ -118,7 +115,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
var vector = new DenseVector(5, 5); var vector = new DenseVector(5, 5);
Assert.ForAll(vector, value => value == 5); Assert.ForAll(vector, value => value == 5);
} }
[Test] [Test]
[MultipleAsserts] [MultipleAsserts]
public void CanCreateDenseMatrix() public void CanCreateDenseMatrix()
@ -134,7 +131,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanConvertDenseVectorToArray() public void CanConvertDenseVectorToArray()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
var array = (double[])vector; var array = (double[])vector;
Assert.IsInstanceOfType(typeof(double[]), array); Assert.IsInstanceOfType(typeof(double[]), array);
Assert.AreSame(vector.Data, array); Assert.AreSame(vector.Data, array);
@ -154,7 +151,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanCallUnaryPlusOperatorOnDenseVector() public void CanCallUnaryPlusOperatorOnDenseVector()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
var other = +vector; var other = +vector;
Assert.AreSame(vector, other, "Should be the same vector"); Assert.AreSame(vector, other, "Should be the same vector");
} }
@ -163,26 +160,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanAddTwoDenseVectorsUsingOperator() public void CanAddTwoDenseVectorsUsingOperator()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
var other = new DenseVector(_data); var other = new DenseVector(this._data);
var result = vector + other; var result = vector + other;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified."); Assert.AreEqual(this._data[i], vector[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); Assert.AreEqual(this._data[i], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, result[i]); Assert.AreEqual(this._data[i] * 2.0, result[i]);
} }
} }
[Test] [Test]
public void CanCallUnaryNegationOperatorOnDenseVector() public void CanCallUnaryNegationOperatorOnDenseVector()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
var other = -vector; var other = -vector;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(-_data[i], other[i]); Assert.AreEqual(-this._data[i], other[i]);
} }
} }
@ -190,14 +187,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanSubtractTwoDenseVectorsUsingOperator() public void CanSubtractTwoDenseVectorsUsingOperator()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
var other = new DenseVector(_data); var other = new DenseVector(this._data);
var result = vector - other; var result = vector - other;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified."); Assert.AreEqual(this._data[i], vector[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); Assert.AreEqual(this._data[i], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, result[i]); Assert.AreEqual(0.0, result[i]);
} }
} }
@ -206,32 +203,32 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyDenseVectorByScalarUsingOperators() public void CanMultiplyDenseVectorByScalarUsingOperators()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
vector = vector * 2.0; vector = vector * 2.0;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i] * 2.0, vector[i]); Assert.AreEqual(this._data[i] * 2.0, vector[i]);
} }
vector = vector * 1.0; vector = vector * 1.0;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i] * 2.0, vector[i]); Assert.AreEqual(this._data[i] * 2.0, vector[i]);
} }
vector = new DenseVector(_data); vector = new DenseVector(this._data);
vector = 2.0 * vector; vector = 2.0 * vector;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i] * 2.0, vector[i]); Assert.AreEqual(this._data[i] * 2.0, vector[i]);
} }
vector = 1.0 * vector; vector = 1.0 * vector;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i] * 2.0, vector[i]); Assert.AreEqual(this._data[i] * 2.0, vector[i]);
} }
} }
@ -239,361 +236,30 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanDivideDenseVectorByScalarUsingOperators() public void CanDivideDenseVectorByScalarUsingOperators()
{ {
var vector = new DenseVector(_data); var vector = new DenseVector(this._data);
vector = vector / 2.0; vector = vector / 2.0;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i] / 2.0, vector[i]); Assert.AreEqual(this._data[i] / 2.0, vector[i]);
} }
vector = vector / 1.0; vector = vector / 1.0;
for (var i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(_data[i] / 2.0, vector[i]); Assert.AreEqual(this._data[i] / 2.0, vector[i]);
} }
} }
[Test] [Test]
public void CanFindAbsoluteMinimumIndexInDenseVector() public void CanCalculateDyadicProductForDenseVector()
{
DenseVector source = new DenseVector(_data);
int expected = 0;
int actual = source.AbsoluteMinimumIndex();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindAbsoluteMinimumInDenseVector()
{
DenseVector source = new DenseVector(_data);
double expected = 1;
double actual = source.AbsoluteMinimum();
Assert.AreEqual(expected, actual);
}
[Test]
[Row(0, 5)]
[Row(2, 2)]
[Row(1, 4)]
[Row(6, 10, ExpectedException = typeof(ArgumentOutOfRangeException))]
[Row(1, 10, ExpectedException = typeof(ArgumentOutOfRangeException))]
[Row(1, -10, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void CanCalculateSubVector(int index, int length)
{ {
DenseVector vector = new DenseVector(_data); var vector1 = this.CreateVector(this._data);
Vector sub = vector.SubVector(index, length); var vector2 = this.CreateVector(this._data);
Assert.AreEqual(length, sub.Count); Matrix m = Vector.DyadicProduct(vector1, vector2);
for (int i = 0; i < length; i++) for (var i = 0; i < vector1.Count; i++)
{ {
Assert.AreEqual(vector[i + index], sub[i]); for (var j = 0; j < vector2.Count; j++)
}
}
[Test]
public void CanFindMaximumIndexInDenseVector()
{
DenseVector vector = new DenseVector(_data);
int expected = 4;
int actual = vector.MaximumIndex();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMaximumInDenseVector()
{
DenseVector vector = new DenseVector(_data);
double expected = 5;
double actual = vector.Maximum();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMinimumIndexOfDenseVector()
{
DenseVector vector = new DenseVector(_data);
int expected = 0;
int actual = vector.MinimumIndex();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMinimumOfDenseVector()
{
DenseVector vector = new DenseVector(_data);
double expected = 1;
double actual = vector.Minimum();
Assert.AreEqual(expected, actual);
}
[Test]
public void SumOfDenseVector()
{
double[] testData = { -20, -10, 10, 20, 30, };
DenseVector vector = new DenseVector(testData);
double actual = vector.Sum();
double expected = 30;
Assert.AreEqual(expected, actual);
}
[Test]
public void SumMagnitudesOfDenseVector()
{
double[] testData = { -20, -10, 10, 20, 30, };
DenseVector vector = new DenseVector(testData);
double actual = vector.SumMagnitudes();
double expected = 90;
Assert.AreEqual(expected, actual);
}
[Test]
[ExpectedArgumentNullException]
public new void SetValuesWithNullParameterShouldThrowException()
{
DenseVector vector = new DenseVector(_data);
vector.SetValues(null);
}
[Test]
[ExpectedArgumentException]
public new void SetValuesWithNonEqualDataLengthShouldThrowException()
{
DenseVector vector = new DenseVector(_data.Length + 2);
vector.SetValues(_data);
}
[Test]
public new void PointWiseMultiply()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseMultiply(vector2, result);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] * _data[i], result[i]);
}
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseMultiplyWithOtherNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = null;
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseMultiply(vector2, result);
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseMultiplyWithResultNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = null;
vector1.PointWiseMultiply(vector2, result);
}
[Test]
[ExpectedArgumentException]
public new void PointWiseMultiplyWithInvalidResultLengthShouldThrowException()
{
Vector vector1 = new DenseVector(_data);
Vector vector2 = new DenseVector(_data);
Vector result = CreateVector(vector1.Count + 1);
vector1.PointWiseMultiply(vector2, result);
}
[Test]
public new void PointWiseMultiplyWithResult()
{
Vector vector1 = new DenseVector(_data);
Vector vector2 = new DenseVector(_data);
Vector result = vector1.PointWiseMultiply(vector2);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] * _data[i], result[i]);
}
}
[Test]
public new void PointWiseAdd()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseAdd(vector2, result);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] + _data[i], result[i]);
}
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseAddWithOtherNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = null;
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseAdd(vector2, result);
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseAddWithResultNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = null;
vector1.PointWiseAdd(vector2, result);
}
[Test]
[ExpectedArgumentException]
public new void PointWiseAddWithInvalidResultLengthShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count + 1);
vector1.PointWiseAdd(vector2, result);
}
[Test]
public new void PointWiseAddWithResult()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = vector1.PointWiseAdd(vector2);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] + _data[i], result[i]);
}
}
[Test]
public new void PointWiseSubtract()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseSubtract(vector2, result);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] - _data[i], result[i]);
}
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseSubtractWithOtherNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = null;
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseSubtract(vector2, result);
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseSubtractWithResultNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
Vector result = null;
vector1.PointWiseSubtract(vector2, result);
}
[Test]
[ExpectedArgumentException]
public new void PointWiseSubtractWithInvalidResultLengthShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count + 1);
vector1.PointWiseSubtract(vector2, result);
}
[Test]
public new void PointWiseSubtractWithResult()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = vector1.PointWiseSubtract(vector2);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] - _data[i], result[i]);
}
}
[Test]
public new void PointWiseDivide()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseDivide(vector2, result);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] / _data[i], result[i]);
}
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseDivideWithOtherNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = null;
DenseVector result = new DenseVector(vector1.Count);
vector1.PointWiseDivide(vector2, result);
}
[Test]
[ExpectedArgumentNullException]
public new void PointWiseDivideWithResultNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = null;
vector1.PointWiseDivide(vector2, result);
}
[Test]
[ExpectedArgumentException]
public new void PointWiseDivideWithInvalidResultLengthShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = new DenseVector(vector1.Count + 1);
vector1.PointWiseDivide(vector2, result);
}
[Test]
public new void PointWiseDivideWithResult()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
DenseVector result = vector1.PointWiseDivide(vector2);
for (int i = 0; i < vector1.Count; i++)
{
Assert.AreEqual(_data[i] / _data[i], result[i]);
}
}
[Test]
public new void CanCalculateDyadicProduct()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
Matrix m = DenseVector.DyadicProduct(vector1, vector2);
for (int i = 0; i < vector1.Count; i++)
{
for (int j = 0; j < vector2.Count; j++)
{ {
Assert.AreEqual(m[i, j], vector1[i] * vector2[j]); Assert.AreEqual(m[i, j], vector1[i] * vector2[j]);
} }
@ -602,53 +268,20 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public new void DyadicProductWithFirstParameterNullShouldThrowException() public void DyadicProducForDenseVectortWithFirstParameterNullShouldThrowException()
{ {
DenseVector vector1 = null; DenseVector vector1 = null;
DenseVector vector2 = new DenseVector(_data); var vector2 = this.CreateVector(this._data);
DenseVector.DyadicProduct(vector1, vector2);
}
[Test]
[ExpectedArgumentNullException]
public new void DyadicProductWithSecondParameterNullShouldThrowException()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = null;
Vector.DyadicProduct(vector1, vector2); Vector.DyadicProduct(vector1, vector2);
} }
[Test]
public new void CanCalculateTensorMultiply()
{
DenseVector vector1 = new DenseVector(_data);
DenseVector vector2 = new DenseVector(_data);
Matrix m = vector1.TensorMultiply(vector2);
for (int i = 0; i < vector1.Count; i++)
{
for (int j = 0; j < vector2.Count; j++)
{
Assert.AreEqual(m[i, j], vector1[i] * vector2[j]);
}
}
}
[Test] [Test]
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public new void TensorMultiplyWithNullParameterNullShouldThrowException() public void DyadicProductForDenseVectorWithSecondParameterNullShouldThrowException()
{ {
DenseVector vector1 = new DenseVector(_data); var vector1 = this.CreateVector(this._data);
DenseVector vector2 = null; DenseVector vector2 = null;
vector1.TensorMultiply(vector2); Vector.DyadicProduct(vector1, vector2);
}
[Test]
[ExpectedArgumentException]
public new void RandomWithNumberOfElementsLessThanZeroShouldThrowException()
{
DenseVector vector = new DenseVector(4);
vector = vector.Random(-3);
} }
} }
} }

633
src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs

File diff suppressed because it is too large

237
src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -30,28 +26,29 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System; using System;
using System.Collections.Generic;
using System.Globalization;
using LinearAlgebra.Double;
using MbUnit.Framework;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using Distributions;
using LinearAlgebra.Double;
using MbUnit.Framework;
[TestFixture] [TestFixture]
public abstract partial class VectorTests public abstract partial class VectorTests
{ {
protected readonly double[] _data = {1, 2, 3, 4, 5}; protected readonly double[] _data = { 1, 2, 3, 4, 5 };
[Test] [Test]
[MultipleAsserts] [MultipleAsserts]
public void CanCloneVector() public void CanCloneVector()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var clone = vector.Clone(); var clone = vector.Clone();
Assert.AreNotSame(vector, clone); Assert.AreNotSame(vector, clone);
Assert.AreEqual(vector.Count, clone.Count); Assert.AreEqual(vector.Count, clone.Count);
for (var index = 0; index < _data.Length; index++) for (var index = 0; index < this._data.Length; index++)
{ {
Assert.AreEqual(vector[index], clone[index]); Assert.AreEqual(vector[index], clone[index]);
} }
@ -61,12 +58,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCloneVectorUsingICloneable() public void CanCloneVectorUsingICloneable()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var clone = (Vector)((ICloneable)vector).Clone(); var clone = (Vector)((ICloneable)vector).Clone();
Assert.AreNotSame(vector, clone); Assert.AreNotSame(vector, clone);
Assert.AreEqual(vector.Count, clone.Count); Assert.AreEqual(vector.Count, clone.Count);
for (var index = 0; index < _data.Length; index++) for (var index = 0; index < this._data.Length; index++)
{ {
Assert.AreEqual(vector[index], clone[index]); Assert.AreEqual(vector[index], clone[index]);
} }
@ -75,7 +72,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanConvertVectorToString() public void CanConvertVectorToString()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var str = vector.ToString(); var str = vector.ToString();
var sep = CultureInfo.CurrentCulture.TextInfo.ListSeparator; var sep = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
Assert.AreEqual(string.Format("1{0}2{0}3{0}4{0}5", sep), str); Assert.AreEqual(string.Format("1{0}2{0}3{0}4{0}5", sep), str);
@ -85,8 +82,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCopyPartialVectorToAnother() public void CanCopyPartialVectorToAnother()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var other = CreateVector(_data.Length); var other = this.CreateVector(this._data.Length);
vector.CopyTo(other, 2, 2, 2); vector.CopyTo(other, 2, 2, 2);
@ -101,7 +98,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCopyPartialVectorToSelf() public void CanCopyPartialVectorToSelf()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
vector.CopyTo(vector, 0, 2, 2); vector.CopyTo(vector, 0, 2, 2);
Assert.AreEqual(1.0, vector[0]); Assert.AreEqual(1.0, vector[0]);
@ -115,12 +112,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCopyVectorToAnother() public void CanCopyVectorToAnother()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var other = CreateVector(_data.Length); var other = this.CreateVector(this._data.Length);
vector.CopyTo(other); vector.CopyTo(other);
for (var index = 0; index < _data.Length; index++) for (var index = 0; index < this._data.Length; index++)
{ {
Assert.AreEqual(vector[index], other[index]); Assert.AreEqual(vector[index], other[index]);
} }
@ -135,7 +132,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanCreateVector() public void CanCreateVector()
{ {
var expected = CreateVector(5); var expected = this.CreateVector(5);
var actual = expected.CreateVector(5); var actual = expected.CreateVector(5);
Assert.AreEqual(expected.GetType(), actual.GetType(), "vectors are same type."); Assert.AreEqual(expected.GetType(), actual.GetType(), "vectors are same type.");
} }
@ -143,20 +140,19 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanEnumerateOverVector() public void CanEnumerateOverVector()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
Assert.AreElementsEqual(_data, vector); Assert.AreElementsEqual(this._data, vector);
} }
[Test] [Test]
[MultipleAsserts] [MultipleAsserts]
public void CanEnumerateOverVectorUsingIEnumerable() public void CanEnumerateOverVectorUsingIEnumerable()
{ {
var enumerable = (IEnumerable)CreateVector(_data); var enumerable = (IEnumerable)this.CreateVector(this._data);
var index = 0; var index = 0;
foreach (var element in enumerable) foreach (var element in enumerable)
{ {
Assert.AreEqual(_data[index++], (double)element); Assert.AreEqual(this._data[index++], (double)element);
} }
} }
@ -164,9 +160,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanEquateVectors() public void CanEquateVectors()
{ {
var vector1 = CreateVector(_data); var vector1 = this.CreateVector(this._data);
var vector2 = CreateVector(_data); var vector2 = this.CreateVector(this._data);
var vector3 = CreateVector(4); var vector3 = this.CreateVector(4);
Assert.IsTrue(vector1.Equals(vector1)); Assert.IsTrue(vector1.Equals(vector1));
Assert.IsTrue(vector1.Equals(vector2)); Assert.IsTrue(vector1.Equals(vector2));
Assert.IsFalse(vector1.Equals(vector3)); Assert.IsFalse(vector1.Equals(vector3));
@ -177,71 +173,71 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void ThrowsArgumentExceptionIfSizeIsNotPositive() public void ThrowsArgumentExceptionIfSizeIsNotPositive()
{ {
Assert.Throws<ArgumentException>(() => CreateVector(-1)); Assert.Throws<ArgumentException>(() => this.CreateVector(-1));
Assert.Throws<ArgumentException>(() => CreateVector(0)); Assert.Throws<ArgumentException>(() => this.CreateVector(0));
} }
[Test] [Test]
public void TestingForEqualityWithNonVectorReturnsFalse() public void TestingForEqualityWithNonVectorReturnsFalse()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
Assert.IsFalse(vector.Equals(2)); Assert.IsFalse(vector.Equals(2));
} }
[Test] [Test]
public void CanTestForEqualityUsingObjectEquals() public void CanTestForEqualityUsingObjectEquals()
{ {
var vector1 = CreateVector(_data); var vector1 = this.CreateVector(this._data);
var vector2 = CreateVector(_data); var vector2 = this.CreateVector(this._data);
Assert.IsTrue(vector1.Equals((object)vector2)); Assert.IsTrue(vector1.Equals((object)vector2));
} }
[Test] [Test]
public void VectorGetHashCode() public void VectorGetHashCode()
{ {
var vector = CreateVector(new double[] { 1, 2, 3, 4 }); var vector = this.CreateVector(new double[] { 1, 2, 3, 4 });
Assert.AreEqual(2145910784, vector.GetHashCode()); Assert.AreEqual(2145910784, vector.GetHashCode());
} }
[Test] [Test]
public void GetIndexedEnumerator() public void GetIndexedEnumerator()
{ {
Vector vector = CreateVector(_data); var vector = this.CreateVector(this._data);
foreach (KeyValuePair<int, double> pair in vector.GetIndexedEnumerator()) foreach (var pair in vector.GetIndexedEnumerator())
{ {
Assert.AreEqual(_data[pair.Key], pair.Value); Assert.AreEqual(this._data[pair.Key], pair.Value);
} }
} }
[Test] [Test]
public void CanConvertVectorToArray() public void CanConvertVectorToArray()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var array = vector.ToArray(); var array = vector.ToArray();
Assert.AreElementsEqual(vector, array); Assert.AreElementsEqual(vector, array);
} }
[Test] [Test, Ignore]
[MultipleAsserts] [MultipleAsserts]
public void CanConvertVectorToColumnMatrix() public void CanConvertVectorToColumnMatrix()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var matrix = vector.ToColumnMatrix(); var matrix = vector.ToColumnMatrix();
Assert.AreEqual(vector.Count, matrix.RowCount); Assert.AreEqual(vector.Count, matrix.RowCount);
Assert.AreEqual(1, matrix.ColumnCount); Assert.AreEqual(1, matrix.ColumnCount);
for(var i = 0; i < vector.Count; i++) for (var i = 0; i < vector.Count; i++)
{ {
Assert.AreEqual(vector[i], matrix[i, 0]); Assert.AreEqual(vector[i], matrix[i, 0]);
} }
} }
[Test] [Test, Ignore]
[MultipleAsserts] [MultipleAsserts]
public void CanConvertVectorToRowMatrix() public void CanConvertVectorToRowMatrix()
{ {
var vector = CreateVector(_data); var vector = this.CreateVector(this._data);
var matrix = vector.ToRowMatrix(); var matrix = vector.ToRowMatrix();
Assert.AreEqual(vector.Count, matrix.ColumnCount); Assert.AreEqual(vector.Count, matrix.ColumnCount);
@ -252,32 +248,159 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.AreEqual(vector[i], matrix[0, i]); Assert.AreEqual(vector[i], matrix[0, i]);
} }
} }
[Test] [Test]
public void CanSetValues() public void CanSetValues()
{ {
Vector vector = CreateVector(_data); var vector = this.CreateVector(this._data);
vector.SetValues(_data); vector.SetValues(this._data);
for (int i = 0; i < _data.Length; i++) for (var i = 0; i < this._data.Length; i++)
{ {
Assert.AreEqual(vector[i], _data[i]); Assert.AreEqual(vector[i], this._data[i]);
} }
} }
[Test]
[Row(0, 5)]
[Row(2, 2)]
[Row(1, 4)]
[Row(6, 10, ExpectedException = typeof(ArgumentOutOfRangeException))]
[Row(1, 10, ExpectedException = typeof(ArgumentOutOfRangeException))]
[Row(1, -10, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void CanCalculateSubVector(int index, int length)
{
var vector = this.CreateVector(this._data);
var sub = vector.SubVector(index, length);
Assert.AreEqual(length, sub.Count);
for (var i = 0; i < length; i++)
{
Assert.AreEqual(vector[i + index], sub[i]);
}
}
[Test]
public void CanFindAbsoluteMinimumIndex()
{
var source = this.CreateVector(this._data);
var expected = 0;
var actual = source.AbsoluteMinimumIndex();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindAbsoluteMinimum()
{
var source = this.CreateVector(this._data);
double expected = 1;
var actual = source.AbsoluteMinimum();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMaximumIndex()
{
var vector = this.CreateVector(this._data);
var expected = 4;
var actual = vector.MaximumIndex();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMaximum()
{
var vector = this.CreateVector(this._data);
double expected = 5;
var actual = vector.Maximum();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMinimumIndex()
{
var vector = this.CreateVector(this._data);
var expected = 0;
var actual = vector.MinimumIndex();
Assert.AreEqual(expected, actual);
}
[Test]
public void CanFindMinimum()
{
var vector = this.CreateVector(this._data);
double expected = 1;
var actual = vector.Minimum();
Assert.AreEqual(expected, actual);
}
[Test]
[Row(0, 5)]
[Row(2, 2)]
[Row(1, 4)]
[Row(6, 10, ExpectedException = typeof(ArgumentOutOfRangeException))]
[Row(1, 10, ExpectedException = typeof(ArgumentOutOfRangeException))]
[Row(1, -10, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void CanGetSubVector(int index, int length)
{
var vector = this.CreateVector(this._data);
var sub = vector.SubVector(index, length);
Assert.AreEqual(length, sub.Count);
for (var i = 0; i < length; i++)
{
Assert.AreEqual(vector[i + index], sub[i]);
}
}
[Test]
public void CanSum()
{
double[] testData = { -20, -10, 10, 20, 30, };
var vector = CreateVector(testData);
var actual = vector.Sum();
double expected = 30;
Assert.AreEqual(expected, actual);
}
[Test]
public void CanSumMagnitudes()
{
double[] testData = { -20, -10, 10, 20, 30, };
var vector = CreateVector(testData);
var actual = vector.SumMagnitudes();
double expected = 90;
Assert.AreEqual(expected, actual);
}
[Test] [Test]
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void SetValuesWithNullParameterShouldThrowException() public void CanSetValuesWithNullParameterShouldThrowException()
{ {
Vector vector = CreateVector(_data); var vector = this.CreateVector(this._data);
vector.SetValues(null); vector.SetValues(null);
} }
[Test] [Test]
[ExpectedArgumentException] [ExpectedArgumentException]
public void SetValuesWithNonEqualDataLengthShouldThrowException() public void CanSetValuesWithNonEqualDataLengthShouldThrowException()
{
var vector = this.CreateVector(this._data.Length + 2);
vector.SetValues(this._data);
}
[Test]
[ExpectedArgumentException]
public void RandomWithNumberOfElementsLessThanZeroShouldThrowException()
{ {
Vector vector = CreateVector(_data.Length + 2); var vector = this.CreateVector(4);
vector.SetValues(_data); vector = vector.Random(-3, new ContinuousUniform());
} }
protected abstract Vector CreateVector(int size); protected abstract Vector CreateVector(int size);

Loading…
Cancel
Save