Browse Source

merged Hany additions

la-knuth
Marcus Cuda 17 years ago
parent
commit
690f625e1e
  1. 83
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  2. 430
      src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs
  3. 1024
      src/Numerics/LinearAlgebra/Double/Matrix.cs
  4. 4
      src/Numerics/LinearAlgebra/Double/Vector.cs
  5. 547
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs
  6. 991
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
  7. 6
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

83
src/Numerics/LinearAlgebra/Double/DenseMatrix.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
@ -48,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int order) public DenseMatrix(int order)
: base(order) : base(order)
{ {
Data = new double[order * order]; this.Data = new double[order * order];
} }
/// <summary> /// <summary>
@ -63,7 +59,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns) public DenseMatrix(int rows, int columns)
: base(rows, columns) : base(rows, columns)
{ {
Data = new double[rows * columns]; this.Data = new double[rows * columns];
} }
/// <summary> /// <summary>
@ -79,10 +75,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns, double value) public DenseMatrix(int rows, int columns, double value)
: base(rows, columns) : base(rows, columns)
{ {
Data = new double[rows * columns]; this.Data = new double[rows * columns];
for (var i = 0; i < Data.Length; i++) for (var i = 0; i < this.Data.Length; i++)
{ {
Data[i] = value; this.Data[i] = value;
} }
} }
@ -96,7 +92,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns, double[] array) public DenseMatrix(int rows, int columns, double[] array)
: base(rows, columns) : base(rows, columns)
{ {
Data = array; this.Data = array;
} }
/// <summary> /// <summary>
@ -109,12 +105,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
var rows = array.GetLength(0); var rows = array.GetLength(0);
var columns = array.GetLength(1); var columns = array.GetLength(1);
Data = new double[rows * columns]; this.Data = new double[rows * columns];
for (var i = 0; i < rows; i++) for (var i = 0; i < rows; i++)
{ {
for (var j = 0; j < columns; j++) for (var j = 0; j < columns; j++)
{ {
Data[(j * rows) + i] = array[i, j]; this.Data[(j * rows) + i] = array[i, j];
} }
} }
} }
@ -123,7 +119,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Gets the matrix's data. /// Gets the matrix's data.
/// </summary> /// </summary>
/// <value>The matrix's data.</value> /// <value>The matrix's data.</value>
internal double[] Data { get; private set; } internal double[] Data
{
get;
private set;
}
/// <summary> /// <summary>
/// Creates a <c>DenseMatrix</c> for the given number of rows and columns. /// Creates a <c>DenseMatrix</c> for the given number of rows and columns.
@ -168,7 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
public override double At(int row, int column) public override double At(int row, int column)
{ {
return Data[(column * RowCount) + row]; return this.Data[(column * this.RowCount) + row];
} }
/// <summary> /// <summary>
@ -185,7 +185,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </param> /// </param>
public override void At(int row, int column, double value) public override void At(int row, int column, double value)
{ {
Data[(column * RowCount) + row] = value; this.Data[(column * this.RowCount) + row] = value;
} }
/// <summary> /// <summary>
@ -193,7 +193,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
public override void Clear() public override void Clear()
{ {
Array.Clear(Data, 0, Data.Length); Array.Clear(this.Data, 0, this.Data.Length);
} }
/// <summary> /// <summary>
@ -202,15 +202,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose() public override Matrix Transpose()
{ {
DenseMatrix ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(this.ColumnCount, this.RowCount);
for (int j = 0; j < ColumnCount; j++) for (var j = 0; j < this.ColumnCount; j++)
{ {
int index = j * RowCount; var index = j * this.RowCount;
for (int i = 0; i < RowCount; i++) for (var i = 0; i < this.RowCount; i++)
{ {
ret.Data[i * ColumnCount + j] = Data[index + i]; ret.Data[(i * this.ColumnCount) + j] = this.Data[index + i];
} }
} }
return ret; return ret;
} }
@ -231,7 +232,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Add(m); this.Add(m);
} }
} }
@ -248,12 +249,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) if (other.RowCount != this.RowCount || other.ColumnCount != this.ColumnCount)
{ {
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
} }
Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data); Control.LinearAlgebraProvider.AddArrays(this.Data, other.Data, this.Data);
} }
/// <summary> /// <summary>
@ -271,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Subtract(m); this.Subtract(m);
} }
} }
@ -288,12 +289,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) if (other.RowCount != this.RowCount || other.ColumnCount != this.ColumnCount)
{ {
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
} }
Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data); Control.LinearAlgebraProvider.SubtractArrays(this.Data, other.Data, this.Data);
} }
/// <summary> /// <summary>
@ -302,7 +303,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="scalar">The scalar to multiply with.</param> /// <param name="scalar">The scalar to multiply with.</param>
public override void Multiply(double scalar) public override void Multiply(double scalar)
{ {
Control.LinearAlgebraProvider.ScaleArray(scalar, Data); Control.LinearAlgebraProvider.ScaleArray(scalar, this.Data);
} }
/// <summary> /// <summary>
@ -326,12 +327,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("result"); throw new ArgumentNullException("result");
} }
if (ColumnCount != other.RowCount) if (this.ColumnCount != other.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount) if (result.RowCount != this.RowCount || result.ColumnCount != other.ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -346,12 +347,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiply( Control.LinearAlgebraProvider.MatrixMultiply(
Data, this.Data,
RowCount, this.RowCount,
ColumnCount, this.ColumnCount,
m.Data, m.Data,
m.RowCount, m.RowCount,
m.ColumnCount, m.ColumnCount,
r.Data); r.Data);
} }
} }
@ -370,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
} }
if (ColumnCount != other.RowCount) if (this.ColumnCount != other.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -381,7 +382,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return base.Multiply(other); return base.Multiply(other);
} }
var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount); var result = (DenseMatrix)this.CreateMatrix(this.RowCount, other.ColumnCount);
Multiply(other, result); Multiply(other, result);
return result; return result;
} }
@ -417,22 +418,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion #endregion
#region Static constructors for special matrices. #region Static constructors for special matrices.
/// <summary> /// <summary>
/// Initializes a square <see cref="DenseMatrix"/> with all zero's except for ones on the diagonal. /// Initializes a square <see cref="DenseMatrix"/> with all zero's except for ones on the diagonal.
/// </summary> /// </summary>
/// <param name="order">the size of the square matrix.</param> /// <param name="order">the size of the square matrix.</param>
/// <returns>A dense identity matrix.</returns>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If <paramref name="order"/> is less than one. /// If <paramref name="order"/> is less than one.
/// </exception> /// </exception>
public static DenseMatrix Identity(int order) public static DenseMatrix Identity(int order)
{ {
var m = new DenseMatrix(order); var m = new DenseMatrix(order);
for (int i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
m[i, i] = 1.0; m[i, i] = 1.0;
} }
return m; return m;
} }
#endregion #endregion
} }
} }

430
src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.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
@ -31,6 +27,7 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
{ {
using System; using System;
using Distributions;
using Properties; using Properties;
using Threading; using Threading;
@ -58,8 +55,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.RowCount, this.RowCount,
i => i =>
{ {
for (var j = 0; j < this.ColumnCount; j++) for (var j = 0; j < this.ColumnCount; j++)
@ -88,8 +85,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.RowCount, this.RowCount,
i => i =>
{ {
for (var j = 0; j < this.ColumnCount; j++) for (var j = 0; j < this.ColumnCount; j++)
@ -111,8 +108,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
this.RowCount, this.RowCount,
i => i =>
{ {
for (var j = 0; j < this.ColumnCount; j++) for (var j = 0; j < this.ColumnCount; j++)
@ -204,8 +201,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
this.RowCount, this.RowCount,
i => i =>
{ {
double s = 0; double s = 0;
@ -215,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
result[i] = s; result[i] = s;
}); });
} }
} }
@ -273,8 +270,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
this.RowCount, this.RowCount,
j => j =>
{ {
double s = 0; double s = 0;
@ -284,7 +281,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
result[j] = s; result[j] = s;
}); });
} }
} }
@ -328,8 +325,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
this.RowCount, this.RowCount,
j => j =>
{ {
for (var i = 0; i != other.ColumnCount; i++) for (var i = 0; i != other.ColumnCount; i++)
@ -342,7 +339,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
result.At(j, i, s); result.At(j, i, s);
} }
}); });
} }
} }
@ -604,118 +601,110 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Concatenates this matrix with the given matrix. /// Pointwise multiplies this matrix with another matrix.
/// </summary> /// </summary>
/// <param name="right">The matrix to concatenate.</param> /// <param name="other">The matrix to pointwise multiply with this one.</param>
/// <returns>The combined matrix.</returns> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
public virtual Matrix Append(Matrix right) /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <returns>A new matrix that is the pointwise multiplication of this matrix and <paramref name="other"/>.</returns>
public virtual Matrix PointwiseMultiply(Matrix other)
{ {
if (right == null) if (other == null)
{ {
throw new ArgumentNullException("right"); throw new ArgumentNullException("other");
} }
if (right.RowCount != RowCount) if (this.ColumnCount != other.ColumnCount || this.RowCount != other.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixDimensions, "other");
} }
Matrix result = CreateMatrix(RowCount, ColumnCount + right.ColumnCount); var result = this.CreateMatrix(this.RowCount, this.ColumnCount);
Append(right, result); this.PointwiseMultiply(other, result);
return result; return result;
} }
/// <summary> /// <summary>
/// Concatenates this matrix with the given matrix and places the result into the result matrix. /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
/// </summary> /// </summary>
/// <param name="right">The matrix to concatenate.</param> /// <param name="other">The matrix to pointwise multiply with this one.</param>
/// <param name="result">The combined matrix.</param> /// <param name="result">The matrix to store the result of the pointwise multiplication.</param>
public virtual void Append(Matrix right, Matrix result) /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception>
public virtual void PointwiseMultiply(Matrix other, Matrix result)
{ {
if (right == null) if (other == null)
{ {
throw new ArgumentNullException("right"); throw new ArgumentNullException("other");
} }
if (right.RowCount != RowCount) if (result == null)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentNullException("result");
} }
if (result == null) if (this.ColumnCount != other.ColumnCount || this.RowCount != other.RowCount)
{ {
throw new ArgumentNullException("result"); throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
} }
if (result.ColumnCount != (ColumnCount + right.ColumnCount) || result.RowCount != RowCount) if (this.ColumnCount != result.ColumnCount || this.RowCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
} }
CommonParallel.Invoke( CommonParallel.For(
() => 0,
{ this.ColumnCount,
CommonParallel.For( j =>
0,
this.RowCount,
i =>
{
CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j)));
});
},
() =>
{ {
CommonParallel.For( for (var i = 0; i < this.RowCount; i++)
0, {
right.RowCount, result.At(i, j, this.At(i, j) * other.At(i, j));
i => }
{ });
CommonParallel.For(0, right.ColumnCount, j => result.At(i, j + ColumnCount, right.At(i, j)));
});
});
} }
/// <summary> /// <summary>
/// Stacks this matrix on top of the given matrix and places the result into the result matrix. /// Pointwise divide this matrix by another matrix.
/// </summary> /// </summary>
/// <param name="lower">The matrix to stack this matrix upon.</param> /// <param name="other">The matrix to pointwise subtract this one by.</param>
/// <returns>The combined matrix.</returns> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception> /// <returns>A new matrix that is the pointwise division of this matrix and <paramref name="other"/>.</returns>
public virtual Matrix Stack(Matrix lower) public virtual Matrix PointwiseDivide(Matrix other)
{ {
if (lower == null) if (other == null)
{ {
throw new ArgumentNullException("lower"); throw new ArgumentNullException("other");
} }
if (lower.ColumnCount != ColumnCount) if (this.ColumnCount != other.ColumnCount || this.RowCount != other.RowCount)
{ {
throw new ArgumentException("lower", Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixDimensions, "other");
} }
Matrix result = CreateMatrix(RowCount + lower.RowCount, ColumnCount); var result = this.CreateMatrix(this.RowCount, this.ColumnCount);
Stack(lower, result); this.PointwiseDivide(other, result);
return result; return result;
} }
/// <summary> /// <summary>
/// Stacks this matrix on top of the given matrix and places the result into the result matrix. /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
/// </summary> /// </summary>
/// <param name="lower">The matrix to stack this matrix upon.</param> /// <param name="other">The matrix to pointwise divide this one by.</param>
/// <param name="result">The combined matrix.</param> /// <param name="result">The matrix to store the result of the pointwise division.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
public virtual void Stack(Matrix lower, Matrix result) /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception>
public virtual void PointwiseDivide(Matrix other, Matrix result)
{ {
if (lower == null) if (other == null)
{
throw new ArgumentNullException("lower");
}
if (lower.ColumnCount != ColumnCount)
{ {
throw new ArgumentException("lower", Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentNullException("other");
} }
if (result == null) if (result == null)
@ -723,88 +712,176 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("result"); throw new ArgumentNullException("result");
} }
if (result.RowCount != (RowCount + lower.RowCount) || result.ColumnCount != ColumnCount) if (this.ColumnCount != other.ColumnCount || this.RowCount != other.RowCount)
{ {
throw new ArgumentException("result", Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
} }
CommonParallel.Invoke( if (this.ColumnCount != result.ColumnCount || this.RowCount != result.RowCount)
() => {
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
}
CommonParallel.For(
0,
this.ColumnCount,
j =>
{ {
CommonParallel.For( for (var i = 0; i < this.RowCount; i++)
0, {
this.RowCount, result.At(i, j, this.At(i, j) / other.At(i, j));
i => }
{ });
CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j))); }
});
}, /// <summary>
() => /// Generates matrix with random elements.
/// </summary>
/// <param name="numberOfRows">Number of rows.</param>
/// <param name="numberOfColumns">Number of columns.</param>
/// <param name="distribution">Continuous Random Distribution or Source</param>
/// <returns>
/// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
/// </returns>
/// <exception cref="ArgumentException">If the parameter numberOfRows is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter numberOfColumns is not positive.</exception>
public virtual Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = this.CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
this.ColumnCount,
j =>
{ {
CommonParallel.For( for (var i = 0; i < matrix.RowCount; i++)
0, {
lower.RowCount, matrix[i, j] = distribution.Sample();
i => }
{ });
CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j, lower.At(i, j)));
}); return matrix;
}
/// <summary>
/// Generates matrix with random elements.
/// </summary>
/// <param name="numberOfRows">Number of rows.</param>
/// <param name="numberOfColumns">Number of columns.</param>
/// <param name="distribution">Continuous Random Distribution or Source</param>
/// <returns>
/// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
/// </returns>
/// <exception cref="ArgumentException">If the parameter numberOfRows is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter numberOfColumns is not positive.</exception>
public virtual Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = this.CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
this.ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
}); });
return matrix;
} }
/// <summary> /// <summary>
/// Computes the trace of this matrix. /// Computes the trace of this matrix.
/// </summary> /// </summary>
/// <returns>The trace of this matrix</returns> /// <returns>The trace of this matrix</returns>
/// <exception cref=">ArgumentException">If the matrix is not square</exception> /// <exception cref="ArgumentException">If the matrix is not square</exception>
public virtual double Trace() public virtual double Trace()
{ {
if (RowCount != ColumnCount) if (this.RowCount != this.ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
double t = 0.0; return CommonParallel.Aggregate(0, this.RowCount, i => this[i, i]);
for (int i = 0; i < RowCount; i++) }
{
t += this[i, i];
}
return t; /// <summary>
/// Calculates the rank of the matrix
/// </summary>
/// <returns>effective numerical rank, obtained from SVD</returns>
public virtual int Rank()
{
throw new NotImplementedException();
}
/// <summary>Calculates the condition number of this matrix.</summary>
/// <returns>The condition number of the matrix.</returns>
/// <remarks>The condition number is calculated using singular value decomposition.</remarks>
public virtual double ConditionNumber()
{
throw new NotImplementedException();
}
/// <summary>Computes the determinant of this matrix.</summary>
/// <returns>The determinant of this matrix.</returns>
public virtual double Determinant()
{
throw new NotImplementedException();
} }
/// <summary> /// <summary>
/// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix, /// Computes the Kronecker product of this matrix with the given matrix. The new matrix is M-by-N
/// where M = this.Rows + lower.Rows and N = this.Columns + lower.Columns. /// with M = this.Rows * lower.Rows and N = this.Columns * lower.Columns.
/// The values of off the off diagonal matrices/blocks are set to zero.
/// </summary> /// </summary>
/// <param name="lower">The lower, right matrix.</param> /// <param name="other">The other matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception>
/// <returns>the combined matrix</returns> /// <returns>The kronecker product of the two matrices.</returns>
public virtual Matrix DiagonalStack(Matrix lower) public virtual Matrix KroneckerProduct(Matrix other)
{ {
if (lower == null) if (other == null)
{ {
throw new ArgumentNullException("lower"); throw new ArgumentNullException("other");
} }
Matrix result = CreateMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); var result = this.CreateMatrix(this.RowCount * other.RowCount, this.ColumnCount * other.ColumnCount);
DiagonalStack(lower, result); this.KroneckerProduct(other, result);
return result; return result;
} }
/// <summary> /// <summary>
/// Diagonally stacks his matrix on top of the given matrix and places the combined matrix into the result matrix. /// Computes the Kronecker product of this matrix with the given matrix. The new matrix is M-by-N
/// with M = this.Rows * lower.Rows and N = this.Columns * lower.Columns.
/// </summary> /// </summary>
/// <param name="lower">The lower, right matrix.</param> /// <param name="other">The other matrix.</param>
/// <param name="result">The combined matrix</param> /// <param name="result">The kronecker product of the two matrices.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns).</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows * lower.rows) x (this.Columns * lower.Columns).</exception>
public virtual void DiagonalStack(Matrix lower, Matrix result) public virtual void KroneckerProduct(Matrix other, Matrix result)
{ {
if (lower == null) if (other == null)
{ {
throw new ArgumentNullException("lower"); throw new ArgumentNullException("other");
} }
if (result == null) if (result == null)
@ -812,41 +889,80 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("result"); throw new ArgumentNullException("result");
} }
if (result.RowCount != RowCount + lower.RowCount || result.ColumnCount != ColumnCount + lower.ColumnCount) if (result.RowCount != (this.RowCount * other.RowCount) || result.ColumnCount != (this.ColumnCount * other.ColumnCount))
{ {
throw new ArgumentException("result", Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
} }
CommonParallel.Invoke( CommonParallel.For(
() => 0,
this.ColumnCount,
j =>
{ {
CommonParallel.For( for (var i = 0; i < this.RowCount; i++)
0, {
this.RowCount, result.SetSubMatrix(i * other.RowCount, other.RowCount, j * other.ColumnCount, other.ColumnCount, this.At(i, j) * other);
i => }
{ });
CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j))); }
});
}, /// <summary>
() => /// Normalizes the columns of a matrix.
/// </summary>
/// <param name="p">The norm under which to normalize the columns under.</param>
/// <returns>A normalized version of the matrix.</returns>
/// <exception cref="ArgumentOutOfRangeException">If the parameter p is not positive.</exception>
public virtual Matrix NormalizeColumns(int p)
{
if (p < 1)
{
throw new ArgumentOutOfRangeException("p", Resources.ArgumentMustBePositive);
}
var ret = this.Clone();
CommonParallel.For(
0,
this.ColumnCount,
i =>
{ {
CommonParallel.For( var coli = this.GetColumn(i);
0, var norm = coli.NormP(p);
lower.RowCount, for (var j = 0; j < this.RowCount; j++)
i => {
{ ret[j, i] = coli[j] / norm;
CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j + ColumnCount, lower.At(i, j))); }
});
}); });
return ret;
} }
/// <summary> /// <summary>
/// Calculates the rank of the matrix /// Normalizes the rows of a matrix.
/// </summary> /// </summary>
/// <returns>effective numerical rank, obtained from SVD</returns> /// <param name="p">The norm under which to normalize the rows under.</param>
public virtual int Rank() /// <returns>A normalized version of the matrix.</returns>
/// <exception cref="ArgumentOutOfRangeException">If the parameter p is not positive.</exception>
public virtual Matrix NormalizeRows(int p)
{ {
throw new NotImplementedException(); if (p < 1)
{
throw new ArgumentOutOfRangeException("p", Resources.ArgumentMustBePositive);
}
var ret = this.Clone();
CommonParallel.For(
0,
this.ColumnCount,
j =>
{
var rowj = this.GetRow(j);
var norm = rowj.NormP(p);
for (var i = 0; i < this.RowCount; i++)
{
ret[i, j] = rowj[j] / norm;
}
});
return ret;
} }
} }
} }

1024
src/Numerics/LinearAlgebra/Double/Matrix.cs

File diff suppressed because it is too large

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

@ -727,7 +727,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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, IContinuousDistribution randomDistribution) public virtual Vector Random(int length, IContinuousDistribution randomDistribution)
{ {
if (length < 0) if (length < 1)
{ {
throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
} }
@ -753,7 +753,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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, IDiscreteDistribution randomDistribution) public virtual Vector Random(int length, IDiscreteDistribution randomDistribution)
{ {
if (length < 0) if (length < 1)
{ {
throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
} }

547
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.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,9 +26,10 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System; using System;
using LinearAlgebra.Double; using Distributions;
using MbUnit.Framework; using LinearAlgebra.Double;
using MbUnit.Framework;
public abstract partial class MatrixTests public abstract partial class MatrixTests
{ {
@ -43,13 +40,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyWithScalar(double scalar) public void CanMultiplyWithScalar(double scalar)
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
var clone = matrix.Clone(); var clone = matrix.Clone();
clone.Multiply(scalar); clone.Multiply(scalar);
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]); Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]);
} }
@ -59,13 +56,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanMultiplyWithVector() public void CanMultiplyWithVector()
{ {
var A = testMatrices["Singular3x3"]; var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = A * x; var y = A * x;
Assert.AreEqual(A.RowCount, y.Count); Assert.AreEqual(A.RowCount, y.Count);
for (int i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
var ar = A.GetRow(i); var ar = A.GetRow(i);
var dot = ar * x; var dot = ar * x;
@ -76,12 +73,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanMultiplyWithVectorIntoResult() public void CanMultiplyWithVectorIntoResult()
{ {
var A = testMatrices["Singular3x3"]; var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = new DenseVector(3); var y = new DenseVector(3);
A.Multiply(x, y); A.Multiply(x, y);
for (int i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
var ar = A.GetRow(i); var ar = A.GetRow(i);
var dot = ar * x; var dot = ar * x;
@ -92,15 +89,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanMultiplyWithVectorIntoResultWhenUpdatingInputArgument() public void CanMultiplyWithVectorIntoResultWhenUpdatingInputArgument()
{ {
var A = testMatrices["Singular3x3"]; var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = x; var y = x;
A.Multiply(x, x); A.Multiply(x, x);
Assert.AreSame(y, x); Assert.AreSame(y, x);
y = new DenseVector(new double[] { 1.0, 2.0, 3.0 }); y = new DenseVector(new[] { 1.0, 2.0, 3.0 });
for (int i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
var ar = A.GetRow(i); var ar = A.GetRow(i);
var dot = ar * y; var dot = ar * y;
@ -112,8 +109,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void MultiplyWithVectorIntoResultFailsWhenResultIsNull() public void MultiplyWithVectorIntoResultFailsWhenResultIsNull()
{ {
var A = testMatrices["Singular3x3"]; var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
Vector y = null; Vector y = null;
A.Multiply(x, y); A.Multiply(x, y);
} }
@ -122,8 +119,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void MultiplyWithVectorIntoResultFailsWhenResultIsTooLarge() public void MultiplyWithVectorIntoResultFailsWhenResultIsTooLarge()
{ {
var A = testMatrices["Singular3x3"]; var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
Vector y = new DenseVector(4); Vector y = new DenseVector(4);
A.Multiply(x, y); A.Multiply(x, y);
} }
@ -135,12 +132,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanOperatorLeftMultiplyWithScalar(double scalar) public void CanOperatorLeftMultiplyWithScalar(double scalar)
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
var clone = matrix * scalar; var clone = matrix * scalar;
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]); Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]);
} }
@ -154,12 +151,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanOperatorRightMultiplyWithScalar(double scalar) public void CanOperatorRightMultiplyWithScalar(double scalar)
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
var clone = matrix * scalar; var clone = matrix * scalar;
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]); Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]);
} }
@ -173,13 +170,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyWithScalarIntoResult(double scalar) public void CanMultiplyWithScalarIntoResult(double scalar)
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
var result = matrix.Clone(); var result = matrix.Clone();
matrix.Multiply(scalar, result); matrix.Multiply(scalar, result);
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(matrix[i, j] * scalar, result[i, j]); Assert.AreEqual(matrix[i, j] * scalar, result[i, j]);
} }
@ -190,7 +187,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void MultiplyWithScalarIntoResultFailsWhenResultIsNull() public void MultiplyWithScalarIntoResultFailsWhenResultIsNull()
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix result = null; Matrix result = null;
matrix.Multiply(2.3, result); matrix.Multiply(2.3, result);
} }
@ -199,8 +196,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void MultiplyWithScalarFailsWhenResultHasMoreRows() public void MultiplyWithScalarFailsWhenResultHasMoreRows()
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix result = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Multiply(2.3, result); matrix.Multiply(2.3, result);
} }
@ -208,8 +205,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void MultiplyWithScalarFailsWhenResultHasMoreColumns() public void MultiplyWithScalarFailsWhenResultHasMoreColumns()
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix result = CreateMatrix(matrix.RowCount, matrix.ColumnCount + 1); var result = this.CreateMatrix(matrix.RowCount, matrix.ColumnCount + 1);
matrix.Multiply(2.3, result); matrix.Multiply(2.3, result);
} }
@ -218,7 +215,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OperatorLeftMultiplyWithScalarFailsWhenMatrixIsNull() public void OperatorLeftMultiplyWithScalarFailsWhenMatrixIsNull()
{ {
Matrix matrix = null; Matrix matrix = null;
Matrix result = 2.3 * matrix; var result = 2.3 * matrix;
} }
[Test] [Test]
@ -226,7 +223,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OperatorRightMultiplyWithScalarFailsWhenMatrixIsNull() public void OperatorRightMultiplyWithScalarFailsWhenMatrixIsNull()
{ {
Matrix matrix = null; Matrix matrix = null;
Matrix result = matrix * 2.3; var result = matrix * 2.3;
} }
[Test] [Test]
@ -234,14 +231,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void CanAddMatrix(string mtxA, string mtxB) public void CanAddMatrix(string mtxA, string mtxB)
{ {
var A = testMatrices[mtxA]; var A = this.testMatrices[mtxA];
var B = testMatrices[mtxB]; var B = this.testMatrices[mtxB];
Matrix matrix = A.Clone(); var matrix = A.Clone();
matrix.Add(B); matrix.Add(B);
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(matrix[i, j], A[i, j] + B[i, j]); Assert.AreEqual(matrix[i, j], A[i, j] + B[i, j]);
} }
@ -252,7 +249,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void AddMatrixThrowsExceptionWhenArgumentIsNull() public void AddMatrixThrowsExceptionWhenArgumentIsNull()
{ {
Matrix matrix = testMatrices["Singular4x4"]; var matrix = this.testMatrices["Singular4x4"];
Matrix other = null; Matrix other = null;
matrix.Add(other); matrix.Add(other);
} }
@ -261,8 +258,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddMatrixThrowsExceptionArgumentHasTooFewColumns() public void AddMatrixThrowsExceptionArgumentHasTooFewColumns()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"]; var other = this.testMatrices["Tall3x2"];
matrix.Add(other); matrix.Add(other);
} }
@ -270,8 +267,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddMatrixThrowsExceptionArgumentHasTooFewRows() public void AddMatrixThrowsExceptionArgumentHasTooFewRows()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"]; var other = this.testMatrices["Wide2x3"];
matrix.Add(other); matrix.Add(other);
} }
@ -280,15 +277,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void AddOperator(string mtxA, string mtxB) public void AddOperator(string mtxA, string mtxB)
{ {
var A = testMatrices[mtxA]; var A = this.testMatrices[mtxA];
var B = testMatrices[mtxB]; var B = this.testMatrices[mtxB];
Matrix result = A + B; var result = A + B;
for (int i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
for (int j = 0; j < A.ColumnCount; j++) for (var j = 0; j < A.ColumnCount; j++)
{ {
Assert.AreEqual(result[i,j], A[i, j] + B[i, j]); Assert.AreEqual(result[i, j], A[i, j] + B[i, j]);
} }
} }
} }
@ -298,35 +295,35 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void AddOperatorThrowsExceptionWhenLeftsideIsNull() public void AddOperatorThrowsExceptionWhenLeftsideIsNull()
{ {
Matrix matrix = null; Matrix matrix = null;
Matrix other = testMatrices["Singular3x3"]; var other = this.testMatrices["Singular3x3"];
Matrix result = matrix + other; var result = matrix + other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void AddOperatorThrowsExceptionWhenRightsideIsNull() public void AddOperatorThrowsExceptionWhenRightsideIsNull()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = null; Matrix other = null;
Matrix result = matrix + other; var result = matrix + other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddOperatorThrowsExceptionWhenRightsideHasTooFewColumns() public void AddOperatorThrowsExceptionWhenRightsideHasTooFewColumns()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"]; var other = this.testMatrices["Tall3x2"];
Matrix result = matrix + other; var result = matrix + other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddOperatorThrowsExceptionWhenRightsideHasTooFewRows() public void AddOperatorThrowsExceptionWhenRightsideHasTooFewRows()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"]; var other = this.testMatrices["Wide2x3"];
Matrix result = matrix + other; var result = matrix + other;
} }
[Test] [Test]
@ -334,14 +331,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void CanSubtractMatrix(string mtxA, string mtxB) public void CanSubtractMatrix(string mtxA, string mtxB)
{ {
var A = testMatrices[mtxA]; var A = this.testMatrices[mtxA];
var B = testMatrices[mtxB]; var B = this.testMatrices[mtxB];
Matrix matrix = A.Clone(); var matrix = A.Clone();
matrix.Subtract(B); matrix.Subtract(B);
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(matrix[i, j], A[i, j] - B[i, j]); Assert.AreEqual(matrix[i, j], A[i, j] - B[i, j]);
} }
@ -352,7 +349,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void SubtractMatrixThrowsExceptionWhenRightSideIsNull() public void SubtractMatrixThrowsExceptionWhenRightSideIsNull()
{ {
Matrix matrix = testMatrices["Singular4x4"]; var matrix = this.testMatrices["Singular4x4"];
Matrix other = null; Matrix other = null;
matrix.Subtract(other); matrix.Subtract(other);
} }
@ -361,8 +358,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewColumns() public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewColumns()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"]; var other = this.testMatrices["Tall3x2"];
matrix.Subtract(other); matrix.Subtract(other);
} }
@ -370,8 +367,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewRows() public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewRows()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"]; var other = this.testMatrices["Wide2x3"];
matrix.Subtract(other); matrix.Subtract(other);
} }
@ -380,13 +377,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void SubtractOperator(string mtxA, string mtxB) public void SubtractOperator(string mtxA, string mtxB)
{ {
var A = testMatrices[mtxA]; var A = this.testMatrices[mtxA];
var B = testMatrices[mtxB]; var B = this.testMatrices[mtxB];
Matrix result = A - B; var result = A - B;
for (int i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
for (int j = 0; j < A.ColumnCount; j++) for (var j = 0; j < A.ColumnCount; j++)
{ {
Assert.AreEqual(result[i, j], A[i, j] - B[i, j]); Assert.AreEqual(result[i, j], A[i, j] - B[i, j]);
} }
@ -398,35 +395,35 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void SubtractOperatorThrowsExceptionWhenLeftsideIsNull() public void SubtractOperatorThrowsExceptionWhenLeftsideIsNull()
{ {
Matrix matrix = null; Matrix matrix = null;
Matrix other = testMatrices["Singular3x3"]; var other = this.testMatrices["Singular3x3"];
Matrix result = matrix - other; var result = matrix - other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void SubtractOperatorThrowsExceptionWhenRightsideIsNull() public void SubtractOperatorThrowsExceptionWhenRightsideIsNull()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = null; Matrix other = null;
Matrix result = matrix - other; var result = matrix - other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewColumns() public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewColumns()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"]; var other = this.testMatrices["Tall3x2"];
Matrix result = matrix - other; var result = matrix - other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewRows() public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewRows()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"]; var other = this.testMatrices["Wide2x3"];
Matrix result = matrix - other; var result = matrix - other;
} }
[Test] [Test]
@ -438,16 +435,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyMatrixWithMatrix(string nameA, string nameB) public void CanMultiplyMatrixWithMatrix(string nameA, string nameB)
{ {
Matrix A = testMatrices[nameA]; var A = this.testMatrices[nameA];
Matrix B = testMatrices[nameB]; var B = this.testMatrices[nameB];
Matrix C = A * B; var C = A * B;
Assert.AreEqual(C.RowCount, A.RowCount); Assert.AreEqual(C.RowCount, A.RowCount);
Assert.AreEqual(C.ColumnCount, B.ColumnCount); Assert.AreEqual(C.ColumnCount, B.ColumnCount);
for (int i = 0; i < C.RowCount; i++) for (var i = 0; i < C.RowCount; i++)
{ {
for (int j = 0; j < C.ColumnCount; j++) for (var j = 0; j < C.ColumnCount; j++)
{ {
AssertHelpers.AlmostEqual(A.GetRow(i) * B.GetColumn(j), C[i, j], 15); AssertHelpers.AlmostEqual(A.GetRow(i) * B.GetColumn(j), C[i, j], 15);
} }
@ -458,9 +455,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void MultiplyMatrixMatrixFailsWhenSizesAreIncompatible() public void MultiplyMatrixMatrixFailsWhenSizesAreIncompatible()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"]; var other = this.testMatrices["Wide2x3"];
Matrix result = matrix * other; var result = matrix * other;
} }
[Test] [Test]
@ -468,17 +465,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void MultiplyMatrixMatrixFailsWhenLeftArgumentIsNull() public void MultiplyMatrixMatrixFailsWhenLeftArgumentIsNull()
{ {
Matrix matrix = null; Matrix matrix = null;
Matrix other = testMatrices["Wide2x3"]; var other = this.testMatrices["Wide2x3"];
Matrix result = matrix * other; var result = matrix * other;
} }
[Test] [Test]
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void MultiplyMatrixMatrixFailsWhenRightArgumentIsNull() public void MultiplyMatrixMatrixFailsWhenRightArgumentIsNull()
{ {
Matrix matrix = testMatrices["Wide2x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix other = null; Matrix other = null;
Matrix result = matrix * other; var result = matrix * other;
} }
[Test] [Test]
@ -490,17 +487,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyMatrixWithMatrixIntoResult(string nameA, string nameB) public void CanMultiplyMatrixWithMatrixIntoResult(string nameA, string nameB)
{ {
Matrix A = testMatrices[nameA]; var A = this.testMatrices[nameA];
Matrix B = testMatrices[nameB]; var B = this.testMatrices[nameB];
Matrix C = CreateMatrix(A.RowCount, B.ColumnCount); var C = this.CreateMatrix(A.RowCount, B.ColumnCount);
A.Multiply(B, C); A.Multiply(B, C);
Assert.AreEqual(C.RowCount, A.RowCount); Assert.AreEqual(C.RowCount, A.RowCount);
Assert.AreEqual(C.ColumnCount, B.ColumnCount); Assert.AreEqual(C.ColumnCount, B.ColumnCount);
for (int i = 0; i < C.RowCount; i++) for (var i = 0; i < C.RowCount; i++)
{ {
for (int j = 0; j < C.ColumnCount; j++) for (var j = 0; j < C.ColumnCount; j++)
{ {
AssertHelpers.AlmostEqual(A.GetRow(i) * B.GetColumn(j), C[i, j], 15); AssertHelpers.AlmostEqual(A.GetRow(i) * B.GetColumn(j), C[i, j], 15);
} }
@ -516,14 +513,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanNegate(string name) public void CanNegate(string name)
{ {
var matrix = testMatrices[name]; var matrix = this.testMatrices[name];
var copy = matrix.Clone(); var copy = matrix.Clone();
copy.Negate(); copy.Negate();
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(-matrix[i, j], copy[i, j]); Assert.AreEqual(-matrix[i, j], copy[i, j]);
} }
@ -539,14 +536,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanNegateIntoResult(string name) public void CanNegateIntoResult(string name)
{ {
var matrix = testMatrices[name]; var matrix = this.testMatrices[name];
var copy = matrix.Clone(); var copy = matrix.Clone();
matrix.Negate(copy); matrix.Negate(copy);
for (int i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
for (int j = 0; j < matrix.ColumnCount; j++) for (var j = 0; j < matrix.ColumnCount; j++)
{ {
Assert.AreEqual(-matrix[i, j], copy[i, j]); Assert.AreEqual(-matrix[i, j], copy[i, j]);
} }
@ -557,7 +554,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void NegateIntoResultFailsWhenResultIsNull() public void NegateIntoResultFailsWhenResultIsNull()
{ {
var matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix copy = null; Matrix copy = null;
matrix.Negate(copy); matrix.Negate(copy);
} }
@ -566,8 +563,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void NegateIntoResultFailsWhenResultHasMoreRows() public void NegateIntoResultFailsWhenResultHasMoreRows()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Negate(target); matrix.Negate(target);
} }
@ -575,242 +572,248 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void NegateIntoResultFailsWhenResultHasMoreColumns() public void NegateIntoResultFailsWhenResultHasMoreColumns()
{ {
Matrix matrix = testMatrices["Singular3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Negate(target); matrix.Negate(target);
} }
[Test] [Test]
public void Append() public void KroneckerProduct()
{ {
Matrix left = testMatrices["Singular3x3"]; var A = this.testMatrices["Wide2x3"];
Matrix right = testMatrices["Tall3x2"]; var B = this.testMatrices["Square3x3"];
Matrix result = left.Append(right); var result = this.CreateMatrix(A.RowCount * B.RowCount, A.ColumnCount * B.ColumnCount);
Assert.AreEqual(left.ColumnCount + right.ColumnCount, result.ColumnCount); A.KroneckerProduct(B, result);
Assert.AreEqual(left.RowCount, right.RowCount); for (var i = 0; i < A.RowCount; i++)
for (int i = 0; i < result.RowCount; i++)
{ {
for (int j = 0; j < result.ColumnCount; j++) for (var j = 0; j < A.ColumnCount; j++)
{ {
if (j < left.ColumnCount) for (var ii = 0; ii < B.RowCount; ii++)
{ {
Assert.AreEqual(left[i, j], result[i, j]); for (var jj = 0; jj < B.ColumnCount; jj++)
} {
else Assert.AreEqual(result[i * B.RowCount + ii, j * B.ColumnCount + jj], A[i, j] * B[ii, jj]);
{ }
Assert.AreEqual(right[i, j - left.ColumnCount], result[i, j]);
} }
} }
} }
} }
[Test] [Test]
[ExpectedArgumentNullException] public void KroneckerProductResult()
public void AppendWithRightParameterNullShouldThrowException()
{ {
Matrix left = testMatrices["Square3x3"]; var A = this.testMatrices["Wide2x3"];
Matrix right = null; var B = this.testMatrices["Square3x3"];
left.Append(right); var result = A.KroneckerProduct(B);
} for (var i = 0; i < A.RowCount; i++)
{
[Test] for (var j = 0; j < A.ColumnCount; j++)
[ExpectedArgumentNullException] {
public void AppendWithResultParameterNullShouldThrowException() for (var ii = 0; ii < B.RowCount; ii++)
{ {
Matrix left = testMatrices["Square3x3"]; for (var jj = 0; jj < B.ColumnCount; jj++)
Matrix right = testMatrices["Tall3x2"]; {
Matrix result = null; Assert.AreEqual(result[i * B.RowCount + ii, j * B.ColumnCount + jj], A[i, j] * B[ii, jj]);
left.Append(right, result); }
}
}
}
} }
[Test] [Test]
[ExpectedArgumentException] [Row(1)]
public void AppendingTwoMatricesWithDifferentRowCountShouldThrowException() [Row(2)]
[Row(-4, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void NormalizeColumns(int pValue)
{ {
Matrix left = testMatrices["Square3x3"]; var matrix = this.testMatrices["Singular3x3"];
Matrix right = testMatrices["Wide2x3"]; var result = matrix.NormalizeColumns(pValue);
Matrix result = left.Append(right); for (var j = 0; j < result.ColumnCount; j++)
{
var col = result.GetColumn(j);
Assert.AreApproximatelyEqual(1.0, col.NormP(pValue), 10e-12);
}
} }
[Test] [Test]
[ExpectedArgumentException] [Row(1)]
public void AppendingWithInvalidResultMatrixColumnsShouldThrowException() [Row(2)]
[Row(-3, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void NormalizeRows(int pValue)
{ {
Matrix left = testMatrices["Square3x3"]; var matrix = this.testMatrices["Singular3x3"].NormalizeRows(pValue);
Matrix right = testMatrices["Tall3x2"]; for (var i = 0; i < matrix.RowCount; i++)
Matrix result = CreateMatrix(3, 2); {
left.Append(right, result); var row = matrix.GetRow(i);
Assert.AreApproximatelyEqual(1.0, row.NormP(pValue), 10e-12);
}
} }
[Test] [Test]
public void Stack() public void PointwiseMultiplyResult()
{ {
Matrix top = testMatrices["Square3x3"]; foreach (var data in this.testMatrices.Values)
Matrix bottom = testMatrices["Wide2x3"];
Matrix result = top.Stack(bottom);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount, result.ColumnCount);
for (int i = 0; i < result.RowCount; i++)
{ {
for (int j = 0; j < result.ColumnCount; j++) var other = data.Clone();
var result = data.Clone();
data.PointwiseMultiply(other, result);
for (var i = 0; i < data.RowCount; i++)
{ {
if (i < top.RowCount) for (var j = 0; j < data.ColumnCount; j++)
{ {
Assert.AreEqual(result[i, j], top[i, j]); Assert.AreEqual(data[i, j] * other[i, j], result[i, j]);
} }
else }
result = data.PointwiseMultiply(other);
for (var i = 0; i < data.RowCount; i++)
{
for (var j = 0; j < data.ColumnCount; j++)
{ {
Assert.AreEqual(result[i, j], bottom[i - top.RowCount, j]); Assert.AreEqual(data[i, j] * other[i, j], result[i, j]);
} }
} }
} }
} }
[Test] [Test]
[ExpectedArgumentNullException] [ExpectedException(typeof(ArgumentNullException))]
public void StackWithBottomParameterNullShouldThrowException() public void PointwiseMultiplyWithNullOtherShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix bottom = null; Matrix other = null;
Matrix result = CreateMatrix(top.RowCount + top.RowCount, top.ColumnCount); var result = matrix.Clone();
top.Stack(bottom, result); matrix.PointwiseMultiply(other, result);
} }
[Test] [Test]
[ExpectedArgumentNullException] [ExpectedException(typeof(ArgumentNullException))]
public void StackWithResultParameterNullShouldThrowException() public void PointwiseMultiplyWithResultNullShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix bottom = testMatrices["Square3x3"]; var other = matrix.Clone();
Matrix result = null; matrix.PointwiseMultiply(other, null);
top.Stack(bottom, result);
} }
[Test] [Test]
[ExpectedArgumentException] [ExpectedException(typeof(ArgumentException))]
public void StackTwoMatricesWithDifferentColumnsShouldThrowException() public void PointwiseMultiplyWithInvalidOtherMatrixDimensionsShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix lower = testMatrices["Tall3x2"]; var other = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
Matrix result = CreateMatrix(top.RowCount + lower.RowCount, top.ColumnCount); var result = matrix.Clone();
top.Stack(lower, result); matrix.PointwiseMultiply(other, result);
} }
[Test] [Test]
[ExpectedArgumentException] [ExpectedException(typeof(ArgumentException))]
public void StackingWithInvalidResultMatrixRowsShouldThrowException() public void PointwiseMultiplyWithInvalidResultMatrixDimensionsShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix bottom = testMatrices["Wide2x3"]; var other = matrix.Clone();
Matrix result = CreateMatrix(1, 3); var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
top.Stack(bottom, result); matrix.PointwiseMultiply(other, result);
} }
[Test] [Test]
public void Trace() public void PointwiseDivideIResult()
{ {
Matrix matrix = testMatrices["Square3x3"]; foreach (var data in this.testMatrices.Values)
double trace = matrix.Trace(); {
Assert.AreEqual(6.6, trace); var other = data.Clone();
var result = data.Clone();
data.PointwiseDivide(other, result);
for (var i = 0; i < data.RowCount; i++)
{
for (var j = 0; j < data.ColumnCount; j++)
{
Assert.AreEqual(data[i, j] / other[i, j], result[i, j]);
}
}
result = data.PointwiseDivide(other);
for (var i = 0; i < data.RowCount; i++)
{
for (var j = 0; j < data.ColumnCount; j++)
{
Assert.AreEqual(data[i, j] / other[i, j], result[i, j]);
}
}
}
} }
[Test] [Test]
[ExpectedArgumentException] [ExpectedException(typeof(ArgumentNullException))]
public void TraceOfNonSquareMatrixShouldThrowException() public void PointwiseDivideWithNullOtherShouldThrowException()
{ {
Matrix matrix = testMatrices["Wide2x3"]; var matrix = this.testMatrices["Wide2x3"];
double trace = matrix.Trace(); Matrix other = null;
var result = matrix.Clone();
matrix.PointwiseDivide(other, result);
} }
[Test] [Test]
public void DiagonalStack() [ExpectedException(typeof(ArgumentNullException))]
public void PointwiseDivideWithResultNullShouldThrowException()
{ {
Matrix top = testMatrices["Tall3x2"]; var matrix = this.testMatrices["Wide2x3"];
Matrix bottom = testMatrices["Wide2x3"]; var other = matrix.Clone();
Matrix result = top.DiagonalStack(bottom); matrix.PointwiseDivide(other, null);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount); }
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
for (int i = 0; i < result.RowCount; i++) [Test]
{ [ExpectedException(typeof(ArgumentException))]
for (int j = 0; j < result.ColumnCount; j++) public void PointwiseDivideWithInvalidOtherMatrixDimensionsShouldThrowException()
{ {
if (i < top.RowCount && j < top.ColumnCount) var matrix = this.testMatrices["Wide2x3"];
{ var other = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
Assert.AreEqual(top[i, j], result[i, j]); var result = matrix.Clone();
} matrix.PointwiseDivide(other, result);
else if (i >= top.RowCount && j >= top.ColumnCount)
{
Assert.AreEqual(bottom[i - top.RowCount, j - top.ColumnCount], result[i, j]);
}
else
{
Assert.AreEqual(0, result[i, j]);
}
}
}
} }
[Test] [Test]
[ExpectedArgumentNullException] [ExpectedException(typeof(ArgumentException))]
public void DiagonalStackWithLowerNullShouldThrowException() public void PointwiseDivideWithInvalidResultMatrixDimensionsShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix lower = null; var other = matrix.Clone();
top.DiagonalStack(lower); var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.PointwiseDivide(other, result);
} }
[Test] [Test]
public void DiagonalStackWithPassingResult() [Row(0, ExpectedException = typeof(ArgumentException))]
[Row(-2, ExpectedException = typeof(ArgumentException))]
public void RandomWithNonPositiveNumberOfRowsShouldThrowException(int numberOfRows)
{ {
Matrix top = testMatrices["Tall3x2"]; var matrix = this.CreateMatrix(2, 3);
Matrix bottom = testMatrices["Wide2x3"]; matrix = matrix.Random(numberOfRows, 4, new ContinuousUniform());
Matrix result = CreateMatrix(top.RowCount + bottom.RowCount, top.ColumnCount + bottom.ColumnCount); }
top.DiagonalStack(bottom, result);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
for (int i = 0; i < result.RowCount; i++) [Test]
{ [Row(0, ExpectedException = typeof(ArgumentException))]
for (int j = 0; j < result.ColumnCount; j++) [Row(-2, ExpectedException = typeof(ArgumentException))]
{ public void RandomWithNonPositiveNumberOfRowsShouldThrowException2(int numberOfRows)
if (i < top.RowCount && j < top.ColumnCount) {
{ var matrix = this.CreateMatrix(2, 3);
Assert.AreEqual(top[i, j], result[i, j]); matrix = matrix.Random(numberOfRows, 4, new DiscreteUniform(0, 2));
}
else if (i >= top.RowCount && j >= top.ColumnCount)
{
Assert.AreEqual(bottom[i - top.RowCount, j - top.ColumnCount], result[i, j]);
}
else
{
Assert.AreEqual(0, result[i, j]);
}
}
}
} }
[Test] [Test]
[ExpectedArgumentNullException] public void Trace()
public void DiagonalStackWithResultNullShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Square3x3"];
Matrix lower = testMatrices["Wide2x3"]; var trace = matrix.Trace();
Matrix result = null; Assert.AreEqual(6.6, trace);
top.DiagonalStack(lower,result);
} }
[Test] [Test]
[ExpectedArgumentException] [ExpectedArgumentException]
public void DiagonalStackWithInvalidResultMatrixShouldThrowException() public void TraceOfNonSquareMatrixShouldThrowException()
{ {
Matrix top = testMatrices["Square3x3"]; var matrix = this.testMatrices["Wide2x3"];
Matrix lower = testMatrices["Wide2x3"]; var trace = matrix.Trace();
Matrix result = CreateMatrix(top.RowCount + lower.RowCount + 2, top.ColumnCount + lower.ColumnCount);
top.DiagonalStack(lower, result);
} }
} }
} }

991
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs

File diff suppressed because it is too large

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

@ -300,7 +300,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanFindAbsoluteMaximumIndex() public void CanFindAbsoluteMaximumIndex()
{ {
var source = this.CreateVector(this._data); var source = this.CreateVector(this._data);
var expected = 0; var expected = 4;
var actual = source.AbsoluteMaximumIndex(); var actual = source.AbsoluteMaximumIndex();
Assert.AreEqual(expected, actual); Assert.AreEqual(expected, actual);
} }
@ -309,7 +309,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanFindAbsoluteMaximum() public void CanFindAbsoluteMaximum()
{ {
var source = this.CreateVector(this._data); var source = this.CreateVector(this._data);
double expected = 1; double expected = 5;
var actual = source.AbsoluteMaximum(); var actual = source.AbsoluteMaximum();
Assert.AreEqual(expected, actual); Assert.AreEqual(expected, actual);
} }
@ -418,7 +418,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void RandomWithNumberOfElementsLessThanZeroShouldThrowException() public void RandomWithNumberOfElementsLessThanZeroShouldThrowException()
{ {
var vector = this.CreateVector(4); var vector = this.CreateVector(4);
vector = vector.Random(-3, new ContinuousUniform()); vector = vector.Random(-2, new ContinuousUniform());
} }
protected abstract Vector CreateVector(int size); protected abstract Vector CreateVector(int size);

Loading…
Cancel
Save