Browse Source

vector: cleaned up the vector class a little more. now starting the matrix class and the factorization classes

la-knuth
Marcus Cuda 16 years ago
parent
commit
fb943d5522
  1. 558
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  2. 64
      src/Numerics/LinearAlgebra/Generic/Common.cs
  3. 5
      src/Numerics/LinearAlgebra/Generic/Factorization/Svd.cs
  4. 311
      src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
  5. 186
      src/Numerics/LinearAlgebra/Generic/Matrix.cs
  6. 111
      src/Numerics/LinearAlgebra/Generic/Vector.cs
  7. 18
      src/Numerics/Numerics.csproj

558
src/Numerics/LinearAlgebra/Double/DenseMatrix.cs

@ -35,7 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary>
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
/// </summary>
public class DenseMatrix : Matrix<double>
public class DenseMatrix : Matrix
{
/// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
@ -242,7 +242,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double FrobeniusNorm()
{
var transpose = (DenseMatrix)Transpose();
var aat = this * transpose;
var aat = (DenseMatrix) (this * transpose);
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
@ -276,272 +276,45 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#region Elementary operations
/// <summary>
/// Adds another matrix to this matrix. The result will be written into this matrix.
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <param name="result">The matrix to store the result of add</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Add(Matrix<double> other)
protected override void DoAdd(Matrix<double> other, Matrix<double> result)
{
var m = other as DenseMatrix;
if (m == null)
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.Add(other);
base.DoAdd(other, result);
}
else
{
Add(m);
Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data);
}
}
/// <summary>
/// Adds another <see cref="DenseMatrix"/> to this matrix. The result will be written into this matrix.
/// </summary>
/// <param name="other">The <see cref="DenseMatrix"/> to add to this matrix.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public void Add(DenseMatrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
}
/// <summary>
/// Subtracts another matrix from this matrix. The result will be written into this matrix.
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Subtract(Matrix<double> other)
{
var m = other as DenseMatrix;
if (m == null)
{
base.Subtract(other);
}
else
{
Subtract(m);
}
}
/// <summary>
/// Subtracts another <see cref="DenseMatrix"/> from this matrix. The result will be written into this matrix.
/// </summary>
/// <param name="other">The <see cref="DenseMatrix"/> to subtract.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public void Subtract(DenseMatrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
}
/// <summary>
/// Multiplies each element of this matrix with a scalar.
/// </summary>
/// <param name="scalar">The scalar to multiply with.</param>
public override void Multiply(double scalar)
{
Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
}
/// <summary>
/// Multiplies this dense matrix with another dense matrix and places the results into the result dense matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the 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 <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix<double> other, Matrix<double> result)
/// <param name="result">The matrix to store the result of the subtraction.</param>
protected override void DoSubtract(Matrix<double> other, Matrix<double> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
var m = other as DenseMatrix;
var r = result as DenseMatrix;
if (m == null || r == null)
{
base.Multiply(other, result);
base.DoSubtract(other, result);
}
else
{
Control.LinearAlgebraProvider.MatrixMultiply(
Data,
RowCount,
ColumnCount,
m.Data,
m.RowCount,
m.ColumnCount,
r.Data);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix<double> Multiply(Matrix<double> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
var m = other as DenseMatrix;
if (m == null)
{
return base.Multiply(other);
}
var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
}
/// <summary>
/// Multiplies this dense matrix with transpose of another dense matrix and places the results into the result dense matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the 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 <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
var otherDense = other as DenseMatrix;
var resultDense = result as DenseMatrix;
if (otherDense == null || resultDense == null)
{
base.TransposeAndMultiply(other, result);
return;
}
if (ColumnCount != otherDense.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
if ((resultDense.RowCount != RowCount) || (resultDense.ColumnCount != otherDense.RowCount))
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose,
1.0,
Data,
RowCount,
ColumnCount,
otherDense.Data,
otherDense.RowCount,
otherDense.ColumnCount,
1.0,
resultDense.Data);
}
/// <summary>
/// Multiplies this matrix with transpose of another matrix and returns the result.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix<double> TransposeAndMultiply(Matrix<double> other)
{
var otherDense = other as DenseMatrix;
if (otherDense == null)
{
return base.TransposeAndMultiply(other);
}
if (ColumnCount != otherDense.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data);
}
var result = (DenseMatrix)CreateMatrix(RowCount, other.RowCount);
TransposeAndMultiply(other, result);
return result;
}
/// <summary>
/// Multiplies two dense matrices.
/// </summary>
/// <param name="leftSide">The left matrix to multiply.</param>
/// <param name="rightSide">The right matrix to multiply.</param>
/// <returns>The result of multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the dimensions of <paramref name="leftSide"/> or <paramref name="rightSide"/> don't conform.</exception>
public static DenseMatrix operator *(DenseMatrix leftSide, DenseMatrix rightSide)
{
if (leftSide == null)
{
throw new ArgumentNullException("leftSide");
}
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
return (DenseMatrix)leftSide.Multiply(rightSide);
}
#endregion
#region Static constructors for special matrices.
@ -567,14 +340,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion
/// <summary>
/// Negates each element of this matrix.
/// </summary>
public override void Negate()
{
Multiply(-1);
}
/// <summary>
/// Generates matrix with random elements.
/// </summary>
@ -651,61 +416,280 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return matrix;
}
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// Returns the conjugate transpose of this matrix.
/// </summary>
/// <returns>The conjugate transpose of this matrix.</returns>
public override Matrix<double> ConjugateTranspose()
{
return Transpose();
}
/* Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose,
1.0,
Data,
RowCount,
ColumnCount,
otherDense.Data,
otherDense.RowCount,
otherDense.ColumnCount,
1.0,
resultDense.Data);
*/
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected sealed override double AddT(double val1, double val2)
/// <param name="scalar">The scalar to multiply the matrix with.</param>
/// <param name="result">The matrix to store the result of the multiplication.</param>
protected override void DoMultiply(double scalar, Matrix<double> result)
{
return val1 + val2;
var denseResult = result as DenseMatrix;
if (denseResult == null)
{
base.DoMultiply(scalar, result);
}
else
{
Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
}
}
/// <summary>
/// Subtract two values T-T
/// Multiplies this matrix with a vector and places the results into the result vector.
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected sealed override double SubtractT(double val1, double val2)
/// <param name="rightSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoMultiply(Vector<double> rightSide, Vector<double> result)
{
return val1 - val2;
CommonParallel.For(
0,
RowCount,
i =>
{
var s = 0.0;
for (var j = 0; j != ColumnCount; j++)
{
s += At(i, j) * rightSide[j];
}
result[i] = s;
});
}
/// <summary>
/// Multiply two values T*T
/// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
/// <param name="leftSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoLeftMultiply(Vector<double> leftSide, Vector<double> result)
{
return val1 * val2;
CommonParallel.For(
0,
RowCount,
j =>
{
var s = 0.0;
for (var i = 0; i != leftSide.Count; i++)
{
s += leftSide[i] * At(i, j);
}
result[j] = s;
});
}
/// <summary>
/// Divide two values T/T
/// Multiplies this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected sealed override double DivideT(double val1, double val2)
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoMultiply(Matrix<double> other, Matrix<double> result)
{
return val1 / val2;
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoMultiply(other, result);
}
else
{
CommonParallel.For(
0,
RowCount,
j =>
{
for (var i = 0; i != other.ColumnCount; i++)
{
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
s += Data[(j * RowCount) + l] * denseOther.Data[(i * RowCount) + l];
}
result.At(j, i, s);
}
});
CommonParallel.For(
0,
RowCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
s += Data[(j * RowCount) + l] * denseOther.Data[(l * RowCount) + j];
}
denseResult.Data[(j * RowCount) + i] *= s;
}
});
}
}
/// <summary>
/// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
else
{
CommonParallel.For(
0,
RowCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
s += Data[(j * RowCount) + l] * denseOther.Data[(l * RowCount) + j];
}
denseResult.Data[(j * RowCount) + i] *= s;
}
});
}
}
/// <summary>
/// Take absolute value
/// Negate each element of this matrix and place the results into the result matrix.
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override double AbsoluteT(double val1)
/// <param name="result">The result of the negation.</param>
protected override void DoNegate(Matrix<double> result)
{
return Math.Abs(val1);
var denseResult = result as DenseMatrix;
if (denseResult == null)
{
base.DoNegate(result);
}
else
{
CommonParallel.For(
0,
RowCount,
i =>
{
for (var j = 0; j != ColumnCount; j++)
{
var index = (j * RowCount) + i;
denseResult.Data[index] =- Data[index];
}
});
}
}
/// <summary>
/// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
/// </summary>
/// <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>
protected override void DoPointwiseMultiply(Matrix<double> other, Matrix<double> result)
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoPointwiseMultiply(other, result);
}
else
{
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
var index = (j * RowCount) + i;
denseResult.Data[index] = Data[index] * denseOther.Data[index];
}
});
}
}
/// <summary>
/// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
/// </summary>
/// <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>
protected override void DoPointwiseDivide(Matrix<double> other, Matrix<double> result)
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoPointwiseDivide(other, result);
}
else
{
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
var index = (j * RowCount) + i;
denseResult.Data[index] = Data[index] / denseOther.Data[index];
}
});
}
}
/// <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>
public override double Trace()
{
if (RowCount != ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
return CommonParallel.Aggregate(0, RowCount, i => Data[(i * RowCount) + i]);
}
#endregion
}
}

64
src/Numerics/LinearAlgebra/Generic/Common.cs

@ -1,10 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// <copyright file="Common.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// 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
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Generic
{
using System;
/// <summary>
/// A setup functions to help simplify the generic code.
/// </summary>
internal static class Common
{
/// <summary>
@ -17,5 +43,35 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
{
return Math.Max(a, b);
}
/// <summary>
/// Sets the value of <c>1.0</c> for type T.
/// </summary>
/// <typeparam name="T">The type to return the value of 1.0 of.</typeparam>
/// <returns>The value of <c>1.0</c> for type T.</returns>
public static T SetOne<T>()
{
if (typeof(T) == typeof(System.Numerics.Complex))
{
return (T)(object)System.Numerics.Complex.One;
}
if (typeof(T) == typeof(Numerics.Complex32))
{
return (T)(object)Numerics.Complex32.One;
}
if (typeof(T) == typeof(double))
{
return (T)(object)1.0;
}
if (typeof(T) == typeof(float))
{
return (T)(object)1.0f;
}
throw new NotSupportedException();
}
}
}

5
src/Numerics/LinearAlgebra/Generic/Factorization/Svd.cs

@ -162,11 +162,12 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
/// Gets the two norm of the <see cref="Matrix{T}"/>.
/// </summary>
/// <returns>The 2-norm of the <see cref="Matrix{T}"/>.</returns>
public virtual double Norm2
public virtual T Norm2
{
get
{
return AbsoluteT(VectorS[0]);
throw new NotImplementedException();
//return AbsoluteT(VectorS[0]);
}
}

311
src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs

@ -40,12 +40,23 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
public abstract partial class Matrix<T>
{
/// <summary>
/// Adds another matrix to this matrix. The result will be written into this matrix.
/// The value of 1.0.
/// </summary>
private static readonly T One = Common.SetOne<T>();
/// <summary>
/// The value of 0.0.
/// </summary>
private static readonly T Zero = default(T);
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual void Add(Matrix<T> other)
public virtual Matrix<T> Add(Matrix<T> other)
{
if (other == null)
{
@ -57,25 +68,55 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
CommonParallel.For(
0,
RowCount,
i =>
{
for (var j = 0; j < ColumnCount; j++)
{
At(i, j, AddT(At(i, j), other.At(i, j)));
}
});
var result = CreateMatrix(RowCount, ColumnCount);
Add(other, result);
return result;
}
/// <summary>
/// Subtracts another matrix from this matrix. The result will be written into this matrix.
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <param name="result">The matrix to store the result of the addition.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual void Add(Matrix<T> other, Matrix<T> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
}
if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
}
DoAdd(other, result);
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <param name="result">The matrix to store the result of the addition.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
protected abstract void DoAdd(Matrix<T> other, Matrix<T> result);
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual void Subtract(Matrix<T> other)
public virtual Matrix<T> Subtract(Matrix<T> other)
{
if (other == null)
{
@ -87,46 +128,67 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
CommonParallel.For(
0,
RowCount,
i =>
{
for (var j = 0; j < ColumnCount; j++)
{
At(i, j, SubtractT(At(i, j), other.At(i, j)));
}
});
var result = CreateMatrix(RowCount, ColumnCount);
DoSubtract(other, result);
return result;
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <param name="result">The matrix to store the result of the subtraction.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual void Subtract(Matrix<T> other, Matrix<T> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
DoSubtract(other, result);
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <param name="result">The matrix to store the result of the subtraction.</param>
protected abstract void DoSubtract(Matrix<T> other, Matrix<T> result);
/// <summary>
/// Multiplies each element of this matrix with a scalar.
/// </summary>
/// <param name="scalar">The scalar to multiply with.</param>
public virtual void Multiply(T scalar)
/// <returns>The result of the multiplication.</returns>
public virtual Matrix<T> Multiply(T scalar)
{
if (IsOneT(scalar))
if (scalar.Equals(One))
{
return;
return Clone();
}
CommonParallel.For(
0,
RowCount,
i =>
{
for (var j = 0; j < ColumnCount; j++)
{
At(i, j, MultiplyT(At(i, j), scalar));
}
});
if (scalar.Equals(0.0))
{
return CreateMatrix(RowCount, ColumnCount);
}
var result = CreateMatrix(RowCount, ColumnCount);
Multiply(scalar, result);
return result;
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="scalar">The scalar to multiply the matrix with.</param>
/// <param name="result">The matrix to multiply.</param>
/// <param name="result">The matrix to store the result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void Multiply(T scalar, Matrix<T> result)
@ -146,10 +208,16 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "result");
}
CopyTo(result);
result.Multiply(scalar);
DoMultiply(scalar, result);
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="scalar">The scalar to multiply the matrix with.</param>
/// <param name="result">The matrix to store the result of the multiplication.</param>
protected abstract void DoMultiply(T scalar, Matrix<T> result);
/// <summary>
/// Multiplies this matrix by a vector and returns the result.
/// </summary>
@ -165,7 +233,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
/// <summary>
/// Multiplies this matrix with a vector and places the results into the result vactor.
/// Multiplies this matrix with a vector and places the results into the result vector.
/// </summary>
/// <param name="rightSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
@ -203,22 +271,17 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
else
{
CommonParallel.For(
0,
RowCount,
i =>
{
var s = default(T);
for (var j = 0; j != ColumnCount; j++)
{
s = AddT(s, MultiplyT(At(i, j), rightSide[j]));
}
result[i] = s;
});
DoMultiply(rightSide, result);
}
}
/// <summary>
/// Multiplies this matrix with a vector and places the results into the result vector.
/// </summary>
/// <param name="rightSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected abstract void DoMultiply(Vector<T> rightSide, Vector<T> result);
/// <summary>
/// Left multiply a matrix with a vector ( = vector * matrix ).
/// </summary>
@ -272,22 +335,17 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
else
{
CommonParallel.For(
0,
RowCount,
j =>
{
var s = default(T);
for (var i = 0; i != leftSide.Count; i++)
{
s = AddT(s, MultiplyT(leftSide[i], At(i, j)));
}
result[j] = s;
});
DoLeftMultiply(leftSide, result);
}
}
/// <summary>
/// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
/// </summary>
/// <param name="leftSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected abstract void DoLeftMultiply(Vector<T> leftSide, Vector<T> result);
/// <summary>
/// Multiplies this matrix with another matrix and places the results into the result matrix.
/// </summary>
@ -327,22 +385,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
else
{
CommonParallel.For(
0,
RowCount,
j =>
{
for (var i = 0; i != other.ColumnCount; i++)
{
var s = default(T);
for (var l = 0; l < ColumnCount; l++)
{
s = AddT(s, MultiplyT(At(j, l), other.At(l, i)));
}
result.At(j, i, s);
}
});
DoMultiply(other, result);
}
}
@ -370,6 +413,13 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
return result;
}
/// <summary>
/// Multiplies this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected abstract void DoMultiply(Matrix<T> other, Matrix<T> result);
/// <summary>
/// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
/// </summary>
@ -409,22 +459,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
else
{
CommonParallel.For(
0,
RowCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
var s = default(T);
for (var l = 0; l < ColumnCount; l++)
{
s = AddT(s, MultiplyT(At(i, l), other.At(j, l)));
}
result.At(i, j, AddT(s, result.At(i, j)));
}
});
DoTransposeAndMultiply(other, result);
}
}
@ -452,12 +487,23 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
return result;
}
/// <summary>
/// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected abstract void DoTransposeAndMultiply(Matrix<T> other, Matrix<T> result);
/// <summary>
/// Negate each element of this matrix.
/// </summary>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">if the result matrix's dimensions are not the same as this matrix.</exception>
public abstract void Negate();
/// <returns>A matrix containing the negated values.</returns>
public virtual Matrix<T> Negate()
{
var result = CreateMatrix(RowCount, ColumnCount);
Negate(result);
return result;
}
/// <summary>
/// Negate each element of this matrix and place the results into the result matrix.
@ -477,10 +523,15 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
CopyTo(result);
result.Negate();
DoNegate(result);
}
/// <summary>
/// Negate each element of this matrix and place the results into the result matrix.
/// </summary>
/// <param name="result">The result of the negation.</param>
protected abstract void DoNegate(Matrix<T> result);
/// <summary>
/// Adds two matrices together and returns the results.
/// </summary>
@ -739,16 +790,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
}
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
result.At(i, j, MultiplyT(At(i, j), other.At(i, j)));
}
});
DoPointwiseMultiply(other, result);
}
/// <summary>
@ -775,6 +817,13 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
return result;
}
/// <summary>
/// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
/// </summary>
/// <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>
protected abstract void DoPointwiseMultiply(Matrix<T> other, Matrix<T> result);
/// <summary>
/// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
/// </summary>
@ -806,18 +855,16 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
}
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < RowCount; i++)
{
result.At(i, j, DivideT(At(i, j), other.At(i, j)));
}
});
DoPointwiseDivide(other, result);
}
/// <summary>
/// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
/// </summary>
/// <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>
protected abstract void DoPointwiseDivide(Matrix<T> other, Matrix<T> result);
/// <summary>
/// Generates matrix with random elements.
/// </summary>
@ -849,17 +896,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// </summary>
/// <returns>The trace of this matrix</returns>
/// <exception cref="ArgumentException">If the matrix is not square</exception>
public virtual T Trace()
{
if (RowCount != ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var sum = default(T);
CommonParallel.For(0, RowCount, i => sum = AddT(sum, this[i, i]));
return sum;
}
public abstract T Trace();
/// <summary>
/// Calculates the rank of the matrix

186
src/Numerics/LinearAlgebra/Generic/Matrix.cs

@ -38,7 +38,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <summary>
/// Defines the base class for <c>Matrix</c> classes.
/// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
/// <typeparam name="T">Supported data types are <c>double</c>, <c>single</c>, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
[Serializable]
public abstract partial class Matrix<T> :
#if SILVERLIGHT
@ -119,7 +119,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <param name="column">
/// The column of the element.
/// </param>
/// <value>The double value to get or set.</value>
/// <value>The value to get or set.</value>
/// <remarks>This method is ranged checked. <see cref="At(int,int)"/> and <see cref="At(int,int,T)"/>
/// to get and set values without range checking.</remarks>
public virtual T this[int row, int column]
@ -1492,25 +1492,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// Returns the conjugate transpose of this matrix.
/// </summary>
/// <returns>The conjugate transpose of this matrix.</returns>
public virtual Matrix<T> ConjugateTranspose()
{
// In case of real return regulart transpose
if (typeof(T) == typeof(double) || (typeof(T) == typeof(float)))
{
return Transpose();
}
var ret = CreateMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
{
for (var i = 0; i < RowCount; i++)
{
ret.At(j, i, ConjugateT(At(i, j)));
}
}
return ret;
}
public abstract Matrix<T> ConjugateTranspose();
/// <summary>
/// Permute the rows of a matrix according to a permutation.
@ -1788,177 +1770,23 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <summary>Calculates the L1 norm.</summary>
/// <returns>The L1 norm of the matrix.</returns>
public virtual double L1Norm()
{
double norm = 0.0;
for (var j = 0; j < ColumnCount; j++)
{
var s = 0.0;
for (var i = 0; i < RowCount; i++)
{
s += AbsoluteT(At(i, j));
}
norm = Math.Max(norm, s);
}
return norm;
}
public abstract T L1Norm();
/// <summary>Calculates the L2 norm.</summary>
/// <returns>The L2 norm of the matrix.</returns>
/// <remarks>For sparse matrices, the L2 norm is computed using a dense implementation of singular value decomposition.
/// In a later release, it will be replaced with a sparse implementation.</remarks>
public virtual double L2Norm()
public virtual T L2Norm()
{
return Svd<T>.Create(this, false).Norm2;
}
/// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns>
public virtual double FrobeniusNorm()
{
var transpose = Transpose();
var aat = this * transpose;
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
{
norm += AbsoluteT(aat.At(i, i));
}
norm = Math.Sqrt(norm);
return norm;
}
public abstract T FrobeniusNorm();
/// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns>
public virtual double InfinityNorm()
{
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
{
var s = 0.0;
for (var j = 0; j < ColumnCount; j++)
{
s += AbsoluteT(At(i, j));
}
norm = Math.Max(norm, s);
}
return norm;
}
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected abstract T AddT(T val1, T val2);
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected abstract T SubtractT(T val1, T val2);
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected abstract T DivideT(T val1, T val2);
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source value</param>
/// <returns>True if one; otherwise <c>false</c></returns>
protected abstract double AbsoluteT(T val1);
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise <c>false</c></returns>
private static bool IsOneT(T val1)
{
if (typeof(T) == typeof(Complex))
{
object obj1 = val1;
return Complex.One.AlmostEqual((Complex)obj1);
}
if (typeof(T) == typeof(Complex32))
{
object obj1 = val1;
return Complex32.One.AlmostEqual((Complex32)obj1);
}
if (typeof(T) == typeof(double))
{
object obj1 = val1;
return 1.0.AlmostEqualInDecimalPlaces((double)obj1, 15);
}
if (typeof(T) == typeof(float))
{
object obj1 = val1;
return 1.0f.AlmostEqualInDecimalPlaces((float)obj1, 7);
}
throw new NotSupportedException();
}
/// <summary>
/// Conjugate complex value. In real case the same value is returned
/// </summary>
/// <param name="val1">Value to conjugate</param>
/// <returns>Conjugated value (complex) or the same (real)</returns>
private static T ConjugateT(T val1)
{
if (typeof(T) == typeof(Complex))
{
object obj = val1;
object conj = Complex.Conjugate((Complex)obj);
return (T)conj;
}
if (typeof(T) == typeof(Complex32))
{
object obj = val1;
object conj = ((Complex32)obj).Conjugate();
return (T)conj;
}
if (typeof(T) == typeof(double))
{
return val1;
}
if (typeof(T) == typeof(float))
{
return val1;
}
throw new NotSupportedException();
}
#endregion
public abstract T InfinityNorm();
}
}

111
src/Numerics/LinearAlgebra/Generic/Vector.cs

@ -55,9 +55,9 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
private static readonly T Zero = default(T);
/// <summary>
/// The value on 1.0 for type T.
/// The value of 1.0 for type T.
/// </summary>
private static readonly T One = SetOne();
private static readonly T One = Common.SetOne<T>();
/// <summary>
/// Initializes a new instance of the Vector class.
@ -143,7 +143,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
Add(scalar, result);
DoAdd(scalar, result);
return result;
}
@ -174,11 +174,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (!ReferenceEquals(this, result))
{
CopyTo(result);
}
DoAdd(scalar, result);
}
@ -233,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
Add(other, result);
DoAdd(other, result);
return result;
}
@ -270,15 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = Add(other);
tmp.CopyTo(result);
}
else
{
DoAdd(other, result);
}
DoAdd(other, result);
}
/// <summary>
@ -307,7 +294,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
Subtract(scalar, result);
DoSubtract(scalar, result);
return result;
}
@ -338,11 +325,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (!ReferenceEquals(this, result))
{
CopyTo(result);
}
DoSubtract(scalar, result);
}
@ -394,7 +376,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
Subtract(other, result);
DoSubtract(other, result);
return result;
}
@ -431,15 +413,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = Subtract(other);
tmp.CopyTo(result);
}
else
{
DoSubtract(other, result);
}
DoSubtract(other, result);
}
/// <summary>
@ -468,7 +442,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
Multiply(scalar, result);
DoMultiply(scalar, result);
return result;
}
@ -499,11 +473,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (!ReferenceEquals(this, result))
{
CopyTo(result);
}
DoMultiply(scalar, result);
}
@ -574,7 +543,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
Divide(scalar, result);
DoDivide(scalar, result);
return result;
}
@ -605,11 +574,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (!ReferenceEquals(this, result))
{
CopyTo(result);
}
DoDivide(scalar, result);
}
@ -644,7 +608,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
PointwiseMultiply(other, result);
DoPointwiseMultiply(other, result);
return result;
}
@ -679,15 +643,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = PointwiseMultiply(other);
tmp.CopyTo(result);
}
else
{
DoPointwiseMultiply(other, result);
}
DoPointwiseMultiply(other, result);
}
/// <summary>
@ -717,7 +673,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateVector(Count);
PointwiseDivide(other, result);
DoPointwiseDivide(other, result);
return result;
}
@ -752,15 +708,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = PointwiseDivide(other);
tmp.CopyTo(result);
}
else
{
DoPointwiseDivide(other, result);
}
DoPointwiseDivide(other, result);
}
/// <summary>
@ -829,7 +777,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <returns>
/// Matrix M[i,j] = this[i] * v[j].
/// </returns>
/// <seealso cref="OuterProduct"/>
/// <seealso cref="OuterProduct(Vector{T}, Vector{T})"/>
public Matrix<T> OuterProduct(Vector<T> v)
{
return OuterProduct(this, v);
@ -1586,34 +1534,5 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
{
CommonParallel.For(0, Count, index => this[index] = default(T));
}
/// <summary>
/// Sets the value of <c>1.0</c> for type T.
/// </summary>
/// <returns>The value of <c>1.0</c> for type T.</returns>
private static T SetOne()
{
if (typeof(T) == typeof(Complex))
{
return (T)(object)Complex.One;
}
if (typeof(T) == typeof(Complex32))
{
return (T)(object)Complex32.One;
}
if (typeof(T) == typeof(double))
{
return (T)(object)1.0;
}
if (typeof(T) == typeof(float))
{
return (T)(object)1.0f;
}
throw new NotSupportedException();
}
}
}

18
src/Numerics/Numerics.csproj

@ -127,19 +127,22 @@
<Compile Include="LinearAlgebra\Complex32\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Complex32\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Complex32\Vector.cs" />
<Compile Include="LinearAlgebra\Complex\DenseVector.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="LinearAlgebra\Complex\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Complex\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Complex\Matrix.cs" />
<Compile Include="LinearAlgebra\Complex\Vector.cs" />
<Compile Include="LinearAlgebra\Double\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Double\Matrix.cs" />
<Compile Include="LinearAlgebra\Double\Vector.cs" />
<Compile Include="LinearAlgebra\Generic\Common.cs" />
<Compile Include="LinearAlgebra\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\ArrayClass.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\ArrayFlags.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\DataType.cs" />
<Compile Include="LinearAlgebra\Complex32\DenseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex32\DenseVector.cs" />
<Compile Include="LinearAlgebra\Complex32\DiagonalMatrix.cs" />
<Compile Include="LinearAlgebra\Complex32\Factorization\DenseGramSchmidt.cs" />
<Compile Include="LinearAlgebra\Complex32\Factorization\DenseEvd.cs" />
<Compile Include="LinearAlgebra\Complex32\Factorization\DenseCholesky.cs" />
@ -168,11 +171,7 @@
<Compile Include="LinearAlgebra\Complex32\Solvers\StopCriterium\FailureStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\StopCriterium\IterationCountStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\StopCriterium\ResidualStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex32\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex32\SparseVector.cs" />
<Compile Include="LinearAlgebra\Complex\DenseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex\DenseVector.cs" />
<Compile Include="LinearAlgebra\Complex\DiagonalMatrix.cs" />
<Compile Include="LinearAlgebra\Complex\Factorization\DenseGramSchmidt.cs" />
<Compile Include="LinearAlgebra\Complex\Factorization\DenseEvd.cs" />
<Compile Include="LinearAlgebra\Complex\Factorization\DenseCholesky.cs" />
@ -201,11 +200,8 @@
<Compile Include="LinearAlgebra\Complex\Solvers\StopCriterium\FailureStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\StopCriterium\IterationCountStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\StopCriterium\ResidualStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex\SparseVector.cs" />
<Compile Include="LinearAlgebra\Double\DenseMatrix.cs" />
<Compile Include="LinearAlgebra\Double\DenseVector.cs" />
<Compile Include="LinearAlgebra\Double\DiagonalMatrix.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseGramSchmidt.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseEvd.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\UserEvd.cs" />
@ -216,9 +212,7 @@
<Compile Include="LinearAlgebra\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\IO\MatrixReader.cs" />
<Compile Include="LinearAlgebra\IO\MatrixWriter.cs" />
<Compile Include="LinearAlgebra\Single\DenseMatrix.cs" />
<Compile Include="LinearAlgebra\Single\DenseVector.cs" />
<Compile Include="LinearAlgebra\Single\DiagonalMatrix.cs" />
<Compile Include="LinearAlgebra\Single\Factorization\DenseGramSchmidt.cs" />
<Compile Include="LinearAlgebra\Single\Factorization\DenseEvd.cs" />
<Compile Include="LinearAlgebra\Single\Factorization\DenseCholesky.cs" />
@ -249,7 +243,6 @@
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\ResidualStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Single\SparseVector.cs" />
<Compile Include="LinearAlgebra\Generic\Factorization\Cholesky.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseCholesky.cs" />
@ -304,7 +297,6 @@
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs" />
<Compile Include="LinearAlgebra\Double\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Double\SparseVector.cs" />
<Compile Include="LinearAlgebra\Generic\Matrix.Arithmetic.cs" />
<Compile Include="LinearAlgebra\Generic\Matrix.cs" />

Loading…
Cancel
Save