Browse Source

merged Hany additions

pull/36/head
Marcus Cuda 16 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://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -48,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int order)
: base(order)
{
Data = new double[order * order];
this.Data = new double[order * order];
}
/// <summary>
@ -63,7 +59,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns)
: base(rows, columns)
{
Data = new double[rows * columns];
this.Data = new double[rows * columns];
}
/// <summary>
@ -79,10 +75,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns, double value)
: base(rows, columns)
{
Data = new double[rows * columns];
for (var i = 0; i < Data.Length; i++)
this.Data = new double[rows * columns];
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)
: base(rows, columns)
{
Data = array;
this.Data = array;
}
/// <summary>
@ -109,12 +105,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
var rows = array.GetLength(0);
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 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.
/// </summary>
/// <value>The matrix's data.</value>
internal double[] Data { get; private set; }
internal double[] Data
{
get;
private set;
}
/// <summary>
/// Creates a <c>DenseMatrix</c> for the given number of rows and columns.
@ -168,7 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns>
public override double At(int row, int column)
{
return Data[(column * RowCount) + row];
return this.Data[(column * this.RowCount) + row];
}
/// <summary>
@ -185,7 +185,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </param>
public override void At(int row, int column, double value)
{
Data[(column * RowCount) + row] = value;
this.Data[(column * this.RowCount) + row] = value;
}
/// <summary>
@ -193,7 +193,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
public override void Clear()
{
Array.Clear(Data, 0, Data.Length);
Array.Clear(this.Data, 0, this.Data.Length);
}
/// <summary>
@ -202,15 +202,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose()
{
DenseMatrix ret = new DenseMatrix(ColumnCount, RowCount);
for (int j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(this.ColumnCount, this.RowCount);
for (var j = 0; j < this.ColumnCount; j++)
{
int index = j * RowCount;
for (int i = 0; i < RowCount; i++)
var index = j * this.RowCount;
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;
}
@ -231,7 +232,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
Add(m);
this.Add(m);
}
}
@ -248,12 +249,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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);
}
Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
Control.LinearAlgebraProvider.AddArrays(this.Data, other.Data, this.Data);
}
/// <summary>
@ -271,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
Subtract(m);
this.Subtract(m);
}
}
@ -288,12 +289,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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);
}
Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
Control.LinearAlgebraProvider.SubtractArrays(this.Data, other.Data, this.Data);
}
/// <summary>
@ -302,7 +303,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="scalar">The scalar to multiply with.</param>
public override void Multiply(double scalar)
{
Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
Control.LinearAlgebraProvider.ScaleArray(scalar, this.Data);
}
/// <summary>
@ -326,12 +327,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount)
if (this.ColumnCount != other.RowCount)
{
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);
}
@ -346,12 +347,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
Control.LinearAlgebraProvider.MatrixMultiply(
Data,
RowCount,
ColumnCount,
m.Data,
m.RowCount,
m.ColumnCount,
this.Data,
this.RowCount,
this.ColumnCount,
m.Data,
m.RowCount,
m.ColumnCount,
r.Data);
}
}
@ -370,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("other");
}
if (ColumnCount != other.RowCount)
if (this.ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
@ -381,7 +382,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return base.Multiply(other);
}
var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount);
var result = (DenseMatrix)this.CreateMatrix(this.RowCount, other.ColumnCount);
Multiply(other, result);
return result;
}
@ -417,22 +418,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion
#region Static constructors for special matrices.
/// <summary>
/// Initializes a square <see cref="DenseMatrix"/> with all zero's except for ones on the diagonal.
/// </summary>
/// <param name="order">the size of the square matrix.</param>
/// <returns>A dense identity matrix.</returns>
/// <exception cref="ArgumentException">
/// If <paramref name="order"/> is less than one.
/// </exception>
public static DenseMatrix Identity(int 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;
}
return m;
}
#endregion
}
}

430
src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -31,6 +27,7 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using Distributions;
using Properties;
using Threading;
@ -58,8 +55,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
this.RowCount,
0,
this.RowCount,
i =>
{
for (var j = 0; j < this.ColumnCount; j++)
@ -88,8 +85,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
this.RowCount,
0,
this.RowCount,
i =>
{
for (var j = 0; j < this.ColumnCount; j++)
@ -111,8 +108,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
this.RowCount,
0,
this.RowCount,
i =>
{
for (var j = 0; j < this.ColumnCount; j++)
@ -204,8 +201,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
CommonParallel.For(
0,
this.RowCount,
0,
this.RowCount,
i =>
{
double s = 0;
@ -215,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
result[i] = s;
});
});
}
}
@ -273,8 +270,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
CommonParallel.For(
0,
this.RowCount,
0,
this.RowCount,
j =>
{
double s = 0;
@ -284,7 +281,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
result[j] = s;
});
});
}
}
@ -328,8 +325,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
CommonParallel.For(
0,
this.RowCount,
0,
this.RowCount,
j =>
{
for (var i = 0; i != other.ColumnCount; i++)
@ -342,7 +339,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
result.At(j, i, s);
}
});
});
}
}
@ -604,118 +601,110 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Concatenates this matrix with the given matrix.
/// Pointwise multiplies this matrix with another matrix.
/// </summary>
/// <param name="right">The matrix to concatenate.</param>
/// <returns>The combined matrix.</returns>
public virtual Matrix Append(Matrix right)
/// <param name="other">The matrix to pointwise multiply with this one.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <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);
Append(right, result);
var result = this.CreateMatrix(this.RowCount, this.ColumnCount);
this.PointwiseMultiply(other, result);
return result;
}
/// <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>
/// <param name="right">The matrix to concatenate.</param>
/// <param name="result">The combined matrix.</param>
public virtual void Append(Matrix right, Matrix result)
/// <param name="other">The matrix to pointwise multiply with this one.</param>
/// <param name="result">The matrix to store the result of the pointwise multiplication.</param>
/// <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.RowCount,
i =>
{
CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j)));
});
},
() =>
CommonParallel.For(
0,
this.ColumnCount,
j =>
{
CommonParallel.For(
0,
right.RowCount,
i =>
{
CommonParallel.For(0, right.ColumnCount, j => result.At(i, j + ColumnCount, right.At(i, j)));
});
});
for (var i = 0; i < this.RowCount; i++)
{
result.At(i, j, this.At(i, j) * other.At(i, j));
}
});
}
/// <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>
/// <param name="lower">The matrix to stack this matrix upon.</param>
/// <returns>The combined matrix.</returns>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception>
public virtual Matrix Stack(Matrix lower)
/// <param name="other">The matrix to pointwise subtract this one by.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <returns>A new matrix that is the pointwise division of this matrix and <paramref name="other"/>.</returns>
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);
Stack(lower, result);
var result = this.CreateMatrix(this.RowCount, this.ColumnCount);
this.PointwiseDivide(other, result);
return result;
}
/// <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>
/// <param name="lower">The matrix to stack this matrix upon.</param>
/// <param name="result">The combined matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception>
public virtual void Stack(Matrix lower, Matrix result)
/// <param name="other">The matrix to pointwise divide this one by.</param>
/// <param name="result">The matrix to store the result of the pointwise division.</param>
/// <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 PointwiseDivide(Matrix other, Matrix result)
{
if (lower == null)
{
throw new ArgumentNullException("lower");
}
if (lower.ColumnCount != ColumnCount)
if (other == null)
{
throw new ArgumentException("lower", Resources.ArgumentMatrixSameColumnDimension);
throw new ArgumentNullException("other");
}
if (result == null)
@ -723,88 +712,176 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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(
0,
this.RowCount,
i =>
{
CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j)));
});
},
() =>
for (var i = 0; i < this.RowCount; i++)
{
result.At(i, j, this.At(i, j) / other.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(
0,
lower.RowCount,
i =>
{
CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j, lower.At(i, j)));
});
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
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>
/// Computes the trace of this matrix.
/// </summary>
/// <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()
{
if (RowCount != ColumnCount)
if (this.RowCount != this.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
double t = 0.0;
for (int i = 0; i < RowCount; i++)
{
t += this[i, i];
}
return CommonParallel.Aggregate(0, this.RowCount, i => 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>
/// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix,
/// where M = this.Rows + lower.Rows and N = this.Columns + lower.Columns.
/// The values of off the off diagonal matrices/blocks are set to zero.
/// 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>
/// <param name="lower">The lower, right matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <returns>the combined matrix</returns>
public virtual Matrix DiagonalStack(Matrix lower)
/// <param name="other">The other matrix.</param>
/// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception>
/// <returns>The kronecker product of the two matrices.</returns>
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);
DiagonalStack(lower, result);
var result = this.CreateMatrix(this.RowCount * other.RowCount, this.ColumnCount * other.ColumnCount);
this.KroneckerProduct(other, result);
return result;
}
/// <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>
/// <param name="lower">The lower, right matrix.</param>
/// <param name="result">The combined matrix</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <param name="other">The other matrix.</param>
/// <param name="result">The kronecker product of the two matrices.</param>
/// <exception cref="ArgumentNullException">If other 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>
public virtual void DiagonalStack(Matrix lower, Matrix result)
/// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows * lower.rows) x (this.Columns * lower.Columns).</exception>
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)
@ -812,41 +889,80 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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(
0,
this.RowCount,
i =>
{
CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j)));
});
},
() =>
for (var i = 0; i < this.RowCount; i++)
{
result.SetSubMatrix(i * other.RowCount, other.RowCount, j * other.ColumnCount, other.ColumnCount, this.At(i, j) * other);
}
});
}
/// <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(
0,
lower.RowCount,
i =>
{
CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j + ColumnCount, lower.At(i, j)));
});
var coli = this.GetColumn(i);
var norm = coli.NormP(p);
for (var j = 0; j < this.RowCount; j++)
{
ret[j, i] = coli[j] / norm;
}
});
return ret;
}
/// <summary>
/// Calculates the rank of the matrix
/// Normalizes the rows of a matrix.
/// </summary>
/// <returns>effective numerical rank, obtained from SVD</returns>
public virtual int Rank()
/// <param name="p">The norm under which to normalize the rows under.</param>
/// <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>
public virtual Vector Random(int length, IContinuousDistribution randomDistribution)
{
if (length < 0)
if (length < 1)
{
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>
public virtual Vector Random(int length, IDiscreteDistribution randomDistribution)
{
if (length < 0)
if (length < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}

547
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -30,9 +26,10 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
using System;
using LinearAlgebra.Double;
using MbUnit.Framework;
using System;
using Distributions;
using LinearAlgebra.Double;
using MbUnit.Framework;
public abstract partial class MatrixTests
{
@ -43,13 +40,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanMultiplyWithScalar(double scalar)
{
var matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
var clone = matrix.Clone();
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]);
}
@ -59,13 +56,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void CanMultiplyWithVector()
{
var A = testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 });
var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = A * x;
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 dot = ar * x;
@ -76,12 +73,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void CanMultiplyWithVectorIntoResult()
{
var A = testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 });
var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = new DenseVector(3);
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 dot = ar * x;
@ -92,15 +89,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void CanMultiplyWithVectorIntoResultWhenUpdatingInputArgument()
{
var A = testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 });
var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = x;
A.Multiply(x, x);
Assert.AreSame(y, x);
y = new DenseVector(new double[] { 1.0, 2.0, 3.0 });
for (int i = 0; i < A.RowCount; i++)
y = new DenseVector(new[] { 1.0, 2.0, 3.0 });
for (var i = 0; i < A.RowCount; i++)
{
var ar = A.GetRow(i);
var dot = ar * y;
@ -112,8 +109,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void MultiplyWithVectorIntoResultFailsWhenResultIsNull()
{
var A = testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 });
var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
Vector y = null;
A.Multiply(x, y);
}
@ -122,8 +119,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void MultiplyWithVectorIntoResultFailsWhenResultIsTooLarge()
{
var A = testMatrices["Singular3x3"];
var x = new DenseVector(new double[] { 1.0, 2.0, 3.0 });
var A = this.testMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
Vector y = new DenseVector(4);
A.Multiply(x, y);
}
@ -135,12 +132,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanOperatorLeftMultiplyWithScalar(double scalar)
{
var matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
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]);
}
@ -154,12 +151,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanOperatorRightMultiplyWithScalar(double scalar)
{
var matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
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]);
}
@ -173,13 +170,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanMultiplyWithScalarIntoResult(double scalar)
{
var matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
var result = matrix.Clone();
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]);
}
@ -190,7 +187,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void MultiplyWithScalarIntoResultFailsWhenResultIsNull()
{
var matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
Matrix result = null;
matrix.Multiply(2.3, result);
}
@ -199,8 +196,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void MultiplyWithScalarFailsWhenResultHasMoreRows()
{
var matrix = testMatrices["Singular3x3"];
Matrix result = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var matrix = this.testMatrices["Singular3x3"];
var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Multiply(2.3, result);
}
@ -208,8 +205,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void MultiplyWithScalarFailsWhenResultHasMoreColumns()
{
var matrix = testMatrices["Singular3x3"];
Matrix result = CreateMatrix(matrix.RowCount, matrix.ColumnCount + 1);
var matrix = this.testMatrices["Singular3x3"];
var result = this.CreateMatrix(matrix.RowCount, matrix.ColumnCount + 1);
matrix.Multiply(2.3, result);
}
@ -218,7 +215,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OperatorLeftMultiplyWithScalarFailsWhenMatrixIsNull()
{
Matrix matrix = null;
Matrix result = 2.3 * matrix;
var result = 2.3 * matrix;
}
[Test]
@ -226,7 +223,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OperatorRightMultiplyWithScalarFailsWhenMatrixIsNull()
{
Matrix matrix = null;
Matrix result = matrix * 2.3;
var result = matrix * 2.3;
}
[Test]
@ -234,14 +231,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")]
public void CanAddMatrix(string mtxA, string mtxB)
{
var A = testMatrices[mtxA];
var B = testMatrices[mtxB];
var A = this.testMatrices[mtxA];
var B = this.testMatrices[mtxB];
Matrix matrix = A.Clone();
var matrix = A.Clone();
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]);
}
@ -252,7 +249,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void AddMatrixThrowsExceptionWhenArgumentIsNull()
{
Matrix matrix = testMatrices["Singular4x4"];
var matrix = this.testMatrices["Singular4x4"];
Matrix other = null;
matrix.Add(other);
}
@ -261,8 +258,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddMatrixThrowsExceptionArgumentHasTooFewColumns()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"];
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Tall3x2"];
matrix.Add(other);
}
@ -270,8 +267,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddMatrixThrowsExceptionArgumentHasTooFewRows()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"];
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Wide2x3"];
matrix.Add(other);
}
@ -280,15 +277,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")]
public void AddOperator(string mtxA, string mtxB)
{
var A = testMatrices[mtxA];
var B = testMatrices[mtxB];
Matrix result = A + B;
for (int i = 0; i < A.RowCount; i++)
var A = this.testMatrices[mtxA];
var B = this.testMatrices[mtxB];
var result = A + B;
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()
{
Matrix matrix = null;
Matrix other = testMatrices["Singular3x3"];
Matrix result = matrix + other;
var other = this.testMatrices["Singular3x3"];
var result = matrix + other;
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void AddOperatorThrowsExceptionWhenRightsideIsNull()
{
Matrix matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
Matrix other = null;
Matrix result = matrix + other;
var result = matrix + other;
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddOperatorThrowsExceptionWhenRightsideHasTooFewColumns()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"];
Matrix result = matrix + other;
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Tall3x2"];
var result = matrix + other;
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddOperatorThrowsExceptionWhenRightsideHasTooFewRows()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"];
Matrix result = matrix + other;
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Wide2x3"];
var result = matrix + other;
}
[Test]
@ -334,14 +331,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")]
public void CanSubtractMatrix(string mtxA, string mtxB)
{
var A = testMatrices[mtxA];
var B = testMatrices[mtxB];
var A = this.testMatrices[mtxA];
var B = this.testMatrices[mtxB];
Matrix matrix = A.Clone();
var matrix = A.Clone();
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]);
}
@ -352,7 +349,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void SubtractMatrixThrowsExceptionWhenRightSideIsNull()
{
Matrix matrix = testMatrices["Singular4x4"];
var matrix = this.testMatrices["Singular4x4"];
Matrix other = null;
matrix.Subtract(other);
}
@ -361,8 +358,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewColumns()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"];
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Tall3x2"];
matrix.Subtract(other);
}
@ -370,8 +367,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewRows()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"];
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Wide2x3"];
matrix.Subtract(other);
}
@ -380,13 +377,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")]
public void SubtractOperator(string mtxA, string mtxB)
{
var A = testMatrices[mtxA];
var B = testMatrices[mtxB];
var A = this.testMatrices[mtxA];
var B = this.testMatrices[mtxB];
Matrix result = A - B;
for (int i = 0; i < A.RowCount; i++)
var result = A - B;
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]);
}
@ -398,35 +395,35 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void SubtractOperatorThrowsExceptionWhenLeftsideIsNull()
{
Matrix matrix = null;
Matrix other = testMatrices["Singular3x3"];
Matrix result = matrix - other;
var other = this.testMatrices["Singular3x3"];
var result = matrix - other;
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void SubtractOperatorThrowsExceptionWhenRightsideIsNull()
{
Matrix matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
Matrix other = null;
Matrix result = matrix - other;
var result = matrix - other;
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewColumns()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Tall3x2"];
Matrix result = matrix - other;
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Tall3x2"];
var result = matrix - other;
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewRows()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"];
Matrix result = matrix - other;
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Wide2x3"];
var result = matrix - other;
}
[Test]
@ -438,16 +435,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanMultiplyMatrixWithMatrix(string nameA, string nameB)
{
Matrix A = testMatrices[nameA];
Matrix B = testMatrices[nameB];
Matrix C = A * B;
var A = this.testMatrices[nameA];
var B = this.testMatrices[nameB];
var C = A * B;
Assert.AreEqual(C.RowCount, A.RowCount);
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);
}
@ -458,9 +455,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))]
public void MultiplyMatrixMatrixFailsWhenSizesAreIncompatible()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix other = testMatrices["Wide2x3"];
Matrix result = matrix * other;
var matrix = this.testMatrices["Singular3x3"];
var other = this.testMatrices["Wide2x3"];
var result = matrix * other;
}
[Test]
@ -468,17 +465,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void MultiplyMatrixMatrixFailsWhenLeftArgumentIsNull()
{
Matrix matrix = null;
Matrix other = testMatrices["Wide2x3"];
Matrix result = matrix * other;
var other = this.testMatrices["Wide2x3"];
var result = matrix * other;
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void MultiplyMatrixMatrixFailsWhenRightArgumentIsNull()
{
Matrix matrix = testMatrices["Wide2x3"];
var matrix = this.testMatrices["Wide2x3"];
Matrix other = null;
Matrix result = matrix * other;
var result = matrix * other;
}
[Test]
@ -490,17 +487,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanMultiplyMatrixWithMatrixIntoResult(string nameA, string nameB)
{
Matrix A = testMatrices[nameA];
Matrix B = testMatrices[nameB];
Matrix C = CreateMatrix(A.RowCount, B.ColumnCount);
var A = this.testMatrices[nameA];
var B = this.testMatrices[nameB];
var C = this.CreateMatrix(A.RowCount, B.ColumnCount);
A.Multiply(B, C);
Assert.AreEqual(C.RowCount, A.RowCount);
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);
}
@ -516,14 +513,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanNegate(string name)
{
var matrix = testMatrices[name];
var matrix = this.testMatrices[name];
var copy = matrix.Clone();
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]);
}
@ -539,14 +536,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanNegateIntoResult(string name)
{
var matrix = testMatrices[name];
var matrix = this.testMatrices[name];
var copy = matrix.Clone();
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]);
}
@ -557,7 +554,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void NegateIntoResultFailsWhenResultIsNull()
{
var matrix = testMatrices["Singular3x3"];
var matrix = this.testMatrices["Singular3x3"];
Matrix copy = null;
matrix.Negate(copy);
}
@ -566,8 +563,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void NegateIntoResultFailsWhenResultHasMoreRows()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var matrix = this.testMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Negate(target);
}
@ -575,242 +572,248 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void NegateIntoResultFailsWhenResultHasMoreColumns()
{
Matrix matrix = testMatrices["Singular3x3"];
Matrix target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var matrix = this.testMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Negate(target);
}
[Test]
public void Append()
public void KroneckerProduct()
{
Matrix left = testMatrices["Singular3x3"];
Matrix right = testMatrices["Tall3x2"];
Matrix result = left.Append(right);
Assert.AreEqual(left.ColumnCount + right.ColumnCount, result.ColumnCount);
Assert.AreEqual(left.RowCount, right.RowCount);
for (int i = 0; i < result.RowCount; i++)
var A = this.testMatrices["Wide2x3"];
var B = this.testMatrices["Square3x3"];
var result = this.CreateMatrix(A.RowCount * B.RowCount, A.ColumnCount * B.ColumnCount);
A.KroneckerProduct(B, result);
for (var i = 0; i < A.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]);
}
else
{
Assert.AreEqual(right[i, j - left.ColumnCount], result[i, j]);
for (var jj = 0; jj < B.ColumnCount; jj++)
{
Assert.AreEqual(result[i * B.RowCount + ii, j * B.ColumnCount + jj], A[i, j] * B[ii, jj]);
}
}
}
}
}
[Test]
[ExpectedArgumentNullException]
public void AppendWithRightParameterNullShouldThrowException()
public void KroneckerProductResult()
{
Matrix left = testMatrices["Square3x3"];
Matrix right = null;
left.Append(right);
}
[Test]
[ExpectedArgumentNullException]
public void AppendWithResultParameterNullShouldThrowException()
{
Matrix left = testMatrices["Square3x3"];
Matrix right = testMatrices["Tall3x2"];
Matrix result = null;
left.Append(right, result);
var A = this.testMatrices["Wide2x3"];
var B = this.testMatrices["Square3x3"];
var result = A.KroneckerProduct(B);
for (var i = 0; i < A.RowCount; i++)
{
for (var j = 0; j < A.ColumnCount; j++)
{
for (var ii = 0; ii < B.RowCount; ii++)
{
for (var jj = 0; jj < B.ColumnCount; jj++)
{
Assert.AreEqual(result[i * B.RowCount + ii, j * B.ColumnCount + jj], A[i, j] * B[ii, jj]);
}
}
}
}
}
[Test]
[ExpectedArgumentException]
public void AppendingTwoMatricesWithDifferentRowCountShouldThrowException()
[Row(1)]
[Row(2)]
[Row(-4, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void NormalizeColumns(int pValue)
{
Matrix left = testMatrices["Square3x3"];
Matrix right = testMatrices["Wide2x3"];
Matrix result = left.Append(right);
var matrix = this.testMatrices["Singular3x3"];
var result = matrix.NormalizeColumns(pValue);
for (var j = 0; j < result.ColumnCount; j++)
{
var col = result.GetColumn(j);
Assert.AreApproximatelyEqual(1.0, col.NormP(pValue), 10e-12);
}
}
[Test]
[ExpectedArgumentException]
public void AppendingWithInvalidResultMatrixColumnsShouldThrowException()
[Row(1)]
[Row(2)]
[Row(-3, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void NormalizeRows(int pValue)
{
Matrix left = testMatrices["Square3x3"];
Matrix right = testMatrices["Tall3x2"];
Matrix result = CreateMatrix(3, 2);
left.Append(right, result);
var matrix = this.testMatrices["Singular3x3"].NormalizeRows(pValue);
for (var i = 0; i < matrix.RowCount; i++)
{
var row = matrix.GetRow(i);
Assert.AreApproximatelyEqual(1.0, row.NormP(pValue), 10e-12);
}
}
[Test]
public void Stack()
public void PointwiseMultiplyResult()
{
Matrix top = testMatrices["Square3x3"];
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++)
foreach (var data in this.testMatrices.Values)
{
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]
[ExpectedArgumentNullException]
public void StackWithBottomParameterNullShouldThrowException()
[ExpectedException(typeof(ArgumentNullException))]
public void PointwiseMultiplyWithNullOtherShouldThrowException()
{
Matrix top = testMatrices["Square3x3"];
Matrix bottom = null;
Matrix result = CreateMatrix(top.RowCount + top.RowCount, top.ColumnCount);
top.Stack(bottom, result);
var matrix = this.testMatrices["Wide2x3"];
Matrix other = null;
var result = matrix.Clone();
matrix.PointwiseMultiply(other, result);
}
[Test]
[ExpectedArgumentNullException]
public void StackWithResultParameterNullShouldThrowException()
[ExpectedException(typeof(ArgumentNullException))]
public void PointwiseMultiplyWithResultNullShouldThrowException()
{
Matrix top = testMatrices["Square3x3"];
Matrix bottom = testMatrices["Square3x3"];
Matrix result = null;
top.Stack(bottom, result);
var matrix = this.testMatrices["Wide2x3"];
var other = matrix.Clone();
matrix.PointwiseMultiply(other, null);
}
[Test]
[ExpectedArgumentException]
public void StackTwoMatricesWithDifferentColumnsShouldThrowException()
[ExpectedException(typeof(ArgumentException))]
public void PointwiseMultiplyWithInvalidOtherMatrixDimensionsShouldThrowException()
{
Matrix top = testMatrices["Square3x3"];
Matrix lower = testMatrices["Tall3x2"];
Matrix result = CreateMatrix(top.RowCount + lower.RowCount, top.ColumnCount);
top.Stack(lower, result);
var matrix = this.testMatrices["Wide2x3"];
var other = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var result = matrix.Clone();
matrix.PointwiseMultiply(other, result);
}
[Test]
[ExpectedArgumentException]
public void StackingWithInvalidResultMatrixRowsShouldThrowException()
[ExpectedException(typeof(ArgumentException))]
public void PointwiseMultiplyWithInvalidResultMatrixDimensionsShouldThrowException()
{
Matrix top = testMatrices["Square3x3"];
Matrix bottom = testMatrices["Wide2x3"];
Matrix result = CreateMatrix(1, 3);
top.Stack(bottom, result);
var matrix = this.testMatrices["Wide2x3"];
var other = matrix.Clone();
var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.PointwiseMultiply(other, result);
}
[Test]
public void Trace()
public void PointwiseDivideIResult()
{
Matrix matrix = testMatrices["Square3x3"];
double trace = matrix.Trace();
Assert.AreEqual(6.6, trace);
foreach (var data in this.testMatrices.Values)
{
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]
[ExpectedArgumentException]
public void TraceOfNonSquareMatrixShouldThrowException()
[ExpectedException(typeof(ArgumentNullException))]
public void PointwiseDivideWithNullOtherShouldThrowException()
{
Matrix matrix = testMatrices["Wide2x3"];
double trace = matrix.Trace();
var matrix = this.testMatrices["Wide2x3"];
Matrix other = null;
var result = matrix.Clone();
matrix.PointwiseDivide(other, result);
}
[Test]
public void DiagonalStack()
[ExpectedException(typeof(ArgumentNullException))]
public void PointwiseDivideWithResultNullShouldThrowException()
{
Matrix top = testMatrices["Tall3x2"];
Matrix bottom = testMatrices["Wide2x3"];
Matrix result = top.DiagonalStack(bottom);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
var matrix = this.testMatrices["Wide2x3"];
var other = matrix.Clone();
matrix.PointwiseDivide(other, null);
}
for (int i = 0; i < result.RowCount; i++)
{
for (int j = 0; j < result.ColumnCount; j++)
{
if (i < top.RowCount && j < top.ColumnCount)
{
Assert.AreEqual(top[i, j], result[i, j]);
}
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]
[ExpectedException(typeof(ArgumentException))]
public void PointwiseDivideWithInvalidOtherMatrixDimensionsShouldThrowException()
{
var matrix = this.testMatrices["Wide2x3"];
var other = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var result = matrix.Clone();
matrix.PointwiseDivide(other, result);
}
[Test]
[ExpectedArgumentNullException]
public void DiagonalStackWithLowerNullShouldThrowException()
[ExpectedException(typeof(ArgumentException))]
public void PointwiseDivideWithInvalidResultMatrixDimensionsShouldThrowException()
{
Matrix top = testMatrices["Square3x3"];
Matrix lower = null;
top.DiagonalStack(lower);
var matrix = this.testMatrices["Wide2x3"];
var other = matrix.Clone();
var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.PointwiseDivide(other, result);
}
[Test]
public void DiagonalStackWithPassingResult()
[Row(0, ExpectedException = typeof(ArgumentException))]
[Row(-2, ExpectedException = typeof(ArgumentException))]
public void RandomWithNonPositiveNumberOfRowsShouldThrowException(int numberOfRows)
{
Matrix top = testMatrices["Tall3x2"];
Matrix bottom = testMatrices["Wide2x3"];
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);
var matrix = this.CreateMatrix(2, 3);
matrix = matrix.Random(numberOfRows, 4, new ContinuousUniform());
}
for (int i = 0; i < result.RowCount; i++)
{
for (int j = 0; j < result.ColumnCount; j++)
{
if (i < top.RowCount && j < top.ColumnCount)
{
Assert.AreEqual(top[i, j], result[i, j]);
}
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]
[Row(0, ExpectedException = typeof(ArgumentException))]
[Row(-2, ExpectedException = typeof(ArgumentException))]
public void RandomWithNonPositiveNumberOfRowsShouldThrowException2(int numberOfRows)
{
var matrix = this.CreateMatrix(2, 3);
matrix = matrix.Random(numberOfRows, 4, new DiscreteUniform(0, 2));
}
[Test]
[ExpectedArgumentNullException]
public void DiagonalStackWithResultNullShouldThrowException()
public void Trace()
{
Matrix top = testMatrices["Square3x3"];
Matrix lower = testMatrices["Wide2x3"];
Matrix result = null;
top.DiagonalStack(lower,result);
var matrix = this.testMatrices["Square3x3"];
var trace = matrix.Trace();
Assert.AreEqual(6.6, trace);
}
[Test]
[ExpectedArgumentException]
public void DiagonalStackWithInvalidResultMatrixShouldThrowException()
public void TraceOfNonSquareMatrixShouldThrowException()
{
Matrix top = testMatrices["Square3x3"];
Matrix lower = testMatrices["Wide2x3"];
Matrix result = CreateMatrix(top.RowCount + lower.RowCount + 2, top.ColumnCount + lower.ColumnCount);
top.DiagonalStack(lower, result);
var matrix = this.testMatrices["Wide2x3"];
var trace = matrix.Trace();
}
}
}

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

Loading…
Cancel
Save