Browse Source

LA: Avoid cloning matrix factorization results at point of access

optimization-1
Christoph Ruegg 13 years ago
parent
commit
f3879199dd
  1. 1
      src/Examples/Interpolation/LinearBetweenPoints.cs
  2. 1
      src/Examples/Interpolation/RationalWithPoles.cs
  3. 1
      src/Examples/Interpolation/RationalWithoutPoles.cs
  4. 22
      src/Examples/LinearAlgebra/Factorization/Evd.cs
  5. 18
      src/Examples/LinearAlgebra/Factorization/Svd.cs
  6. 1
      src/Numerics/Distributions/MatrixNormal.cs
  7. 8
      src/Numerics/LinearAlgebra/Complex/Factorization/Cholesky.cs
  8. 14
      src/Numerics/LinearAlgebra/Complex/Factorization/DenseCholesky.cs
  9. 36
      src/Numerics/LinearAlgebra/Complex/Factorization/DenseEvd.cs
  10. 18
      src/Numerics/LinearAlgebra/Complex/Factorization/DenseGramSchmidt.cs
  11. 16
      src/Numerics/LinearAlgebra/Complex/Factorization/DenseQR.cs
  12. 22
      src/Numerics/LinearAlgebra/Complex/Factorization/DenseSvd.cs
  13. 14
      src/Numerics/LinearAlgebra/Complex/Factorization/Evd.cs
  14. 12
      src/Numerics/LinearAlgebra/Complex/Factorization/Svd.cs
  15. 50
      src/Numerics/LinearAlgebra/Complex/Factorization/UserCholesky.cs
  16. 86
      src/Numerics/LinearAlgebra/Complex/Factorization/UserEvd.cs
  17. 56
      src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs
  18. 24
      src/Numerics/LinearAlgebra/Complex/Factorization/UserQR.cs
  19. 186
      src/Numerics/LinearAlgebra/Complex/Factorization/UserSvd.cs
  20. 8
      src/Numerics/LinearAlgebra/Complex32/Factorization/Cholesky.cs
  21. 14
      src/Numerics/LinearAlgebra/Complex32/Factorization/DenseCholesky.cs
  22. 34
      src/Numerics/LinearAlgebra/Complex32/Factorization/DenseEvd.cs
  23. 18
      src/Numerics/LinearAlgebra/Complex32/Factorization/DenseGramSchmidt.cs
  24. 16
      src/Numerics/LinearAlgebra/Complex32/Factorization/DenseQR.cs
  25. 22
      src/Numerics/LinearAlgebra/Complex32/Factorization/DenseSvd.cs
  26. 14
      src/Numerics/LinearAlgebra/Complex32/Factorization/Evd.cs
  27. 12
      src/Numerics/LinearAlgebra/Complex32/Factorization/Svd.cs
  28. 50
      src/Numerics/LinearAlgebra/Complex32/Factorization/UserCholesky.cs
  29. 86
      src/Numerics/LinearAlgebra/Complex32/Factorization/UserEvd.cs
  30. 56
      src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs
  31. 24
      src/Numerics/LinearAlgebra/Complex32/Factorization/UserQR.cs
  32. 186
      src/Numerics/LinearAlgebra/Complex32/Factorization/UserSvd.cs
  33. 8
      src/Numerics/LinearAlgebra/Double/Factorization/Cholesky.cs
  34. 14
      src/Numerics/LinearAlgebra/Double/Factorization/DenseCholesky.cs
  35. 34
      src/Numerics/LinearAlgebra/Double/Factorization/DenseEvd.cs
  36. 18
      src/Numerics/LinearAlgebra/Double/Factorization/DenseGramSchmidt.cs
  37. 16
      src/Numerics/LinearAlgebra/Double/Factorization/DenseQR.cs
  38. 22
      src/Numerics/LinearAlgebra/Double/Factorization/DenseSvd.cs
  39. 14
      src/Numerics/LinearAlgebra/Double/Factorization/Evd.cs
  40. 12
      src/Numerics/LinearAlgebra/Double/Factorization/Svd.cs
  41. 50
      src/Numerics/LinearAlgebra/Double/Factorization/UserCholesky.cs
  42. 118
      src/Numerics/LinearAlgebra/Double/Factorization/UserEvd.cs
  43. 54
      src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs
  44. 24
      src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs
  45. 186
      src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs
  46. 13
      src/Numerics/LinearAlgebra/Factorization/Cholesky.cs
  47. 31
      src/Numerics/LinearAlgebra/Factorization/Evd.cs
  48. 20
      src/Numerics/LinearAlgebra/Factorization/QR.cs
  49. 40
      src/Numerics/LinearAlgebra/Factorization/Svd.cs
  50. 1
      src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
  51. 1
      src/Numerics/LinearAlgebra/Matrix.cs
  52. 8
      src/Numerics/LinearAlgebra/Single/Factorization/Cholesky.cs
  53. 14
      src/Numerics/LinearAlgebra/Single/Factorization/DenseCholesky.cs
  54. 34
      src/Numerics/LinearAlgebra/Single/Factorization/DenseEvd.cs
  55. 18
      src/Numerics/LinearAlgebra/Single/Factorization/DenseGramSchmidt.cs
  56. 16
      src/Numerics/LinearAlgebra/Single/Factorization/DenseQR.cs
  57. 22
      src/Numerics/LinearAlgebra/Single/Factorization/DenseSvd.cs
  58. 14
      src/Numerics/LinearAlgebra/Single/Factorization/Evd.cs
  59. 12
      src/Numerics/LinearAlgebra/Single/Factorization/Svd.cs
  60. 50
      src/Numerics/LinearAlgebra/Single/Factorization/UserCholesky.cs
  61. 118
      src/Numerics/LinearAlgebra/Single/Factorization/UserEvd.cs
  62. 54
      src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs
  63. 24
      src/Numerics/LinearAlgebra/Single/Factorization/UserQR.cs
  64. 186
      src/Numerics/LinearAlgebra/Single/Factorization/UserSvd.cs
  65. 2
      src/UnitTests/ArrayHelpers.cs
  66. 18
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs
  67. 2
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/GramSchmidtTests.cs
  68. 8
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/SvdTests.cs
  69. 1
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserCholeskyTests.cs
  70. 15
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs
  71. 3
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserGramSchmidtTests.cs
  72. 1
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserLUTests.cs
  73. 1
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserQRTests.cs
  74. 9
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserSvdTests.cs
  75. 1
      src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs
  76. 1
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs
  77. 1
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs
  78. 1
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs
  79. 1
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs
  80. 1
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs
  81. 1
      src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrix.cs
  82. 1
      src/UnitTests/LinearAlgebraTests/Complex/UserDefinedVector.cs
  83. 18
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs
  84. 2
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/GramSchmidtTests.cs
  85. 2
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/QRTests.cs
  86. 8
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/SvdTests.cs
  87. 1
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserCholeskyTests.cs
  88. 15
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs
  89. 3
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserGramSchmidtTests.cs
  90. 1
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserLUTests.cs
  91. 3
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserQRTests.cs
  92. 9
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserSvdTests.cs
  93. 1
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs
  94. 1
      src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs
  95. 1
      src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedVector.cs
  96. 16
      src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs
  97. 8
      src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs
  98. 1
      src/UnitTests/LinearAlgebraTests/Double/Factorization/UserCholeskyTests.cs
  99. 15
      src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs
  100. 1
      src/UnitTests/LinearAlgebraTests/Double/Factorization/UserGramSchmidtTests.cs

1
src/Examples/Interpolation/LinearBetweenPoints.cs

@ -26,7 +26,6 @@
using System; using System;
using MathNet.Numerics; using MathNet.Numerics;
using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random; using MathNet.Numerics.Random;
using MathNet.Numerics.Signals; using MathNet.Numerics.Signals;

1
src/Examples/Interpolation/RationalWithPoles.cs

@ -26,7 +26,6 @@
using System; using System;
using MathNet.Numerics; using MathNet.Numerics;
using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random; using MathNet.Numerics.Random;
using MathNet.Numerics.Signals; using MathNet.Numerics.Signals;

1
src/Examples/Interpolation/RationalWithoutPoles.cs

@ -26,7 +26,6 @@
using System; using System;
using MathNet.Numerics; using MathNet.Numerics;
using MathNet.Numerics.Interpolation;
using MathNet.Numerics.Random; using MathNet.Numerics.Random;
using MathNet.Numerics.Signals; using MathNet.Numerics.Signals;

22
src/Examples/LinearAlgebra/Factorization/Evd.cs

@ -87,27 +87,27 @@ namespace Examples.LinearAlgebra.FactorizationExamples
// 1. Eigen vectors // 1. Eigen vectors
Console.WriteLine(@"1. Eigen vectors"); Console.WriteLine(@"1. Eigen vectors");
Console.WriteLine(evd.EigenVectors().ToString("#0.00\t", formatProvider)); Console.WriteLine(evd.EigenVectors.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 2. Eigen values as a complex vector // 2. Eigen values as a complex vector
Console.WriteLine(@"2. Eigen values as a complex vector"); Console.WriteLine(@"2. Eigen values as a complex vector");
Console.WriteLine(evd.EigenValues().ToString("N", formatProvider)); Console.WriteLine(evd.EigenValues.ToString("N", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 3. Eigen values as the block diagonal matrix // 3. Eigen values as the block diagonal matrix
Console.WriteLine(@"3. Eigen values as the block diagonal matrix"); Console.WriteLine(@"3. Eigen values as the block diagonal matrix");
Console.WriteLine(evd.D().ToString("#0.00\t", formatProvider)); Console.WriteLine(evd.D.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 4. Multiply V by its transpose VT // 4. Multiply V by its transpose VT
var identity = evd.EigenVectors().TransposeAndMultiply(evd.EigenVectors()); var identity = evd.EigenVectors.TransposeAndMultiply(evd.EigenVectors);
Console.WriteLine(@"4. Multiply V by its transpose VT: V*VT = I"); Console.WriteLine(@"4. Multiply V by its transpose VT: V*VT = I");
Console.WriteLine(identity.ToString("#0.00\t", formatProvider)); Console.WriteLine(identity.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 5. Reconstruct initial matrix: A = V*D*V' // 5. Reconstruct initial matrix: A = V*D*V'
var reconstruct = evd.EigenVectors() * evd.D() * evd.EigenVectors().Transpose(); var reconstruct = evd.EigenVectors * evd.D * evd.EigenVectors.Transpose();
Console.WriteLine(@"5. Reconstruct initial matrix: A = V*D*V'"); Console.WriteLine(@"5. Reconstruct initial matrix: A = V*D*V'");
Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider)); Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
@ -142,33 +142,33 @@ namespace Examples.LinearAlgebra.FactorizationExamples
// 8. Eigen vectors // 8. Eigen vectors
Console.WriteLine(@"8. Eigen vectors"); Console.WriteLine(@"8. Eigen vectors");
Console.WriteLine(evd.EigenVectors().ToString("#0.00\t", formatProvider)); Console.WriteLine(evd.EigenVectors.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 9. Eigen values as a complex vector // 9. Eigen values as a complex vector
Console.WriteLine(@"9. Eigen values as a complex vector"); Console.WriteLine(@"9. Eigen values as a complex vector");
Console.WriteLine(evd.EigenValues().ToString("N", formatProvider)); Console.WriteLine(evd.EigenValues.ToString("N", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 10. Eigen values as the block diagonal matrix // 10. Eigen values as the block diagonal matrix
Console.WriteLine(@"10. Eigen values as the block diagonal matrix"); Console.WriteLine(@"10. Eigen values as the block diagonal matrix");
Console.WriteLine(evd.D().ToString("#0.00\t", formatProvider)); Console.WriteLine(evd.D.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 11. Multiply A * V // 11. Multiply A * V
var av = matrix * evd.EigenVectors(); var av = matrix * evd.EigenVectors;
Console.WriteLine(@"11. Multiply A * V"); Console.WriteLine(@"11. Multiply A * V");
Console.WriteLine(av.ToString("#0.00\t", formatProvider)); Console.WriteLine(av.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 12. Multiply V * D // 12. Multiply V * D
var vd = evd.EigenVectors() * evd.D(); var vd = evd.EigenVectors * evd.D;
Console.WriteLine(@"12. Multiply V * D"); Console.WriteLine(@"12. Multiply V * D");
Console.WriteLine(vd.ToString("#0.00\t", formatProvider)); Console.WriteLine(vd.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 13. Reconstruct non-symmetriv matrix A = V * D * Vinverse // 13. Reconstruct non-symmetriv matrix A = V * D * Vinverse
reconstruct = evd.EigenVectors() * evd.D() * evd.EigenVectors().Inverse(); reconstruct = evd.EigenVectors * evd.D * evd.EigenVectors.Inverse();
Console.WriteLine(@"13. Reconstruct non-symmetriv matrix A = V * D * Vinverse"); Console.WriteLine(@"13. Reconstruct non-symmetriv matrix A = V * D * Vinverse");
Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider)); Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();

18
src/Examples/LinearAlgebra/Factorization/Svd.cs

@ -87,12 +87,12 @@ namespace Examples.LinearAlgebra.FactorizationExamples
// 1. Left singular vectors // 1. Left singular vectors
Console.WriteLine(@"1. Left singular vectors"); Console.WriteLine(@"1. Left singular vectors");
Console.WriteLine(svd.U().ToString("#0.00\t", formatProvider)); Console.WriteLine(svd.U.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 2. Singular values as vector // 2. Singular values as vector
Console.WriteLine(@"2. Singular values as vector"); Console.WriteLine(@"2. Singular values as vector");
Console.WriteLine(svd.S().ToString("#0.00\t", formatProvider)); Console.WriteLine(svd.S.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 3. Singular values as diagonal matrix // 3. Singular values as diagonal matrix
@ -102,23 +102,23 @@ namespace Examples.LinearAlgebra.FactorizationExamples
// 4. Right singular vectors // 4. Right singular vectors
Console.WriteLine(@"4. Right singular vectors"); Console.WriteLine(@"4. Right singular vectors");
Console.WriteLine(svd.VT().ToString("#0.00\t", formatProvider)); Console.WriteLine(svd.VT.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 5. Multiply U matrix by its transpose // 5. Multiply U matrix by its transpose
var identinty = svd.U() * svd.U().Transpose(); var identinty = svd.U * svd.U.Transpose();
Console.WriteLine(@"5. Multiply U matrix by its transpose"); Console.WriteLine(@"5. Multiply U matrix by its transpose");
Console.WriteLine(identinty.ToString("#0.00\t", formatProvider)); Console.WriteLine(identinty.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 6. Multiply V matrix by its transpose // 6. Multiply V matrix by its transpose
identinty = svd.VT().TransposeAndMultiply(svd.VT()); identinty = svd.VT.TransposeAndMultiply(svd.VT);
Console.WriteLine(@"6. Multiply V matrix by its transpose"); Console.WriteLine(@"6. Multiply V matrix by its transpose");
Console.WriteLine(identinty.ToString("#0.00\t", formatProvider)); Console.WriteLine(identinty.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 7. Reconstruct initial matrix: A = U*Σ*VT // 7. Reconstruct initial matrix: A = U*Σ*VT
var reconstruct = svd.U() * svd.W() * svd.VT(); var reconstruct = svd.U * svd.W() * svd.VT;
Console.WriteLine(@"7. Reconstruct initial matrix: A = U*S*VT"); Console.WriteLine(@"7. Reconstruct initial matrix: A = U*S*VT");
Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider)); Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
@ -149,7 +149,7 @@ namespace Examples.LinearAlgebra.FactorizationExamples
// 12. Singular values as vector // 12. Singular values as vector
Console.WriteLine(@"12. Singular values as vector"); Console.WriteLine(@"12. Singular values as vector");
Console.WriteLine(svd.S().ToString("#0.00\t", formatProvider)); Console.WriteLine(svd.S.ToString("#0.00\t", formatProvider));
Console.WriteLine(); Console.WriteLine();
// 13. Singular values as diagonal matrix // 13. Singular values as diagonal matrix
@ -161,7 +161,7 @@ namespace Examples.LinearAlgebra.FactorizationExamples
try try
{ {
Console.WriteLine(@"14. Access to left singular vectors when partial SVD decomposition was performed"); Console.WriteLine(@"14. Access to left singular vectors when partial SVD decomposition was performed");
Console.WriteLine(svd.U().ToString("#0.00\t", formatProvider)); Console.WriteLine(svd.U.ToString("#0.00\t", formatProvider));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -173,7 +173,7 @@ namespace Examples.LinearAlgebra.FactorizationExamples
try try
{ {
Console.WriteLine(@"15. Access to right singular vectors when partial SVD decomposition was performed"); Console.WriteLine(@"15. Access to right singular vectors when partial SVD decomposition was performed");
Console.WriteLine(svd.VT().ToString("#0.00\t", formatProvider)); Console.WriteLine(svd.VT.ToString("#0.00\t", formatProvider));
} }
catch (Exception ex) catch (Exception ex)
{ {

1
src/Numerics/Distributions/MatrixNormal.cs

@ -31,7 +31,6 @@
using System; using System;
using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties; using MathNet.Numerics.Properties;
namespace MathNet.Numerics.Distributions namespace MathNet.Numerics.Distributions

8
src/Numerics/LinearAlgebra/Complex/Factorization/Cholesky.cs

@ -57,9 +57,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
get get
{ {
var det = Complex.One; var det = Complex.One;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
var d = CholeskyFactor.At(j, j); var d = Factor.At(j, j);
det *= d * d; det *= d * d;
} }
@ -75,9 +75,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
get get
{ {
var det = Complex.Zero; var det = Complex.Zero;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
det += 2.0 * CholeskyFactor.At(j, j).Ln(); det += 2.0 * Factor.At(j, j).Ln();
} }
return det; return det;

14
src/Numerics/LinearAlgebra/Complex/Factorization/DenseCholesky.cs

@ -74,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
var factor = (DenseMatrix)matrix.Clone(); var factor = (DenseMatrix)matrix.Clone();
Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount); Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount);
CholeskyFactor = factor; Factor = factor;
} }
/// <summary> /// <summary>
@ -106,9 +106,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseMatrix; var dinput = input as DenseMatrix;
@ -127,7 +127,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length); Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount);
} }
@ -155,9 +155,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -176,7 +176,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length); Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1);
} }
} }

36
src/Numerics/LinearAlgebra/Complex/Factorization/DenseEvd.cs

@ -79,9 +79,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matrices for eigenvalues and eigenvectors // Initialize matrices for eigenvalues and eigenvectors
MatrixEv = DenseMatrix.Identity(order); EigenVectors = DenseMatrix.Identity(order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new DenseVector(order); EigenValues = new DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -93,8 +93,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
} }
Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) MatrixEv).Values, Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) EigenVectors).Values,
((DenseVector) VectorEv).Values, ((DenseMatrix) MatrixD).Values); ((DenseVector) EigenValues).Values, ((DenseMatrix) D).Values);
} }
/// <summary> /// <summary>
@ -840,20 +840,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Complex[order]; var tmp = new Complex[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -865,10 +865,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i].Conjugate()*input.At(i, k); value += ((DenseMatrix) EigenVectors).Values[(j*order) + i].Conjugate()*input.At(i, k);
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -879,7 +879,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
Complex value = 0.0; Complex value = 0.0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -911,21 +911,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(VectorEv, result); throw Matrix.DimensionsDontMatch<ArgumentException>(EigenValues, result);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VH * b; // Symmetric case -> x = V * inv(λ) * VH * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Complex[order]; var tmp = new Complex[order];
Complex value; Complex value;
@ -936,10 +936,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i].Conjugate()*input[i]; value += ((DenseMatrix) EigenVectors).Values[(j*order) + i].Conjugate()*input[i];
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -950,7 +950,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
value = 0; value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result[j] = value; result[j] = value;

18
src/Numerics/LinearAlgebra/Complex/Factorization/DenseGramSchmidt.cs

@ -76,9 +76,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
Factorize(((DenseMatrix)MatrixQ).Values, MatrixQ.RowCount, MatrixQ.ColumnCount, ((DenseMatrix)MatrixR).Values); Factorize(((DenseMatrix)Q).Values, Q.RowCount, Q.ColumnCount, ((DenseMatrix)MatrixR).Values);
} }
/// <summary> /// <summary>
@ -156,13 +156,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -179,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin);
} }
/// <summary> /// <summary>
@ -201,15 +201,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -224,7 +224,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin);
} }
} }
} }

16
src/Numerics/LinearAlgebra/Complex/Factorization/DenseQR.cs

@ -87,15 +87,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = new DenseMatrix(matrix.RowCount); Q = new DenseMatrix(matrix.RowCount);
Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixQ).Values, Tau); ((DenseMatrix)Q).Values, Tau);
} }
else else
{ {
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = new DenseMatrix(matrix.ColumnCount); MatrixR = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix)MatrixQ).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix)Q).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixR).Values, Tau); ((DenseMatrix)MatrixR).Values, Tau);
} }
} }
@ -125,7 +125,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
@ -148,7 +148,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod);
} }
/// <summary> /// <summary>
@ -170,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
@ -193,7 +193,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod);
} }
} }
} }

22
src/Numerics/LinearAlgebra/Complex/Factorization/DenseSvd.cs

@ -73,10 +73,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
ComputeVectors = computeVectors; ComputeVectors = computeVectors;
var nm = Math.Min(matrix.RowCount, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount, matrix.ColumnCount);
VectorS = new DenseVector(nm); S = new DenseVector(nm);
MatrixU = new DenseMatrix(matrix.RowCount); U = new DenseMatrix(matrix.RowCount);
MatrixVT = new DenseMatrix(matrix.ColumnCount); VT = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values); Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values);
} }
/// <summary> /// <summary>
@ -109,13 +109,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -132,7 +132,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, input.ColumnCount, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, input.ColumnCount, dresult.Values);
} }
/// <summary> /// <summary>
@ -159,15 +159,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -182,7 +182,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, 1, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, 1, dresult.Values);
} }
} }
} }

14
src/Numerics/LinearAlgebra/Complex/Factorization/Evd.cs

@ -59,11 +59,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
get get
{ {
var det = Complex.One; var det = Complex.One;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
det *= VectorEv[i]; det *= EigenValues[i];
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
return 0; return 0;
} }
@ -82,9 +82,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
get get
{ {
var rank = 0; var rank = 0;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
continue; continue;
} }
@ -104,9 +104,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
get get
{ {
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
return false; return false;
} }

12
src/Numerics/LinearAlgebra/Complex/Factorization/Svd.cs

@ -66,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
get get
{ {
return VectorS.Count(t => !t.Magnitude.AlmostEqual(0.0)); return S.Count(t => !t.Magnitude.AlmostEqual(0.0));
} }
} }
@ -78,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
get get
{ {
return VectorS[0].Magnitude; return S[0].Magnitude;
} }
} }
@ -90,8 +90,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
get get
{ {
var tmp = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount) - 1; var tmp = Math.Min(U.RowCount, VT.ColumnCount) - 1;
return VectorS[0].Magnitude / VectorS[tmp].Magnitude; return S[0].Magnitude / S[tmp].Magnitude;
} }
} }
@ -102,13 +102,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
get get
{ {
if (MatrixU.RowCount != MatrixVT.ColumnCount) if (U.RowCount != VT.ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var det = Complex.One; var det = Complex.One;
foreach (var value in VectorS) foreach (var value in S)
{ {
det *= value; det *= value;
if (value.Magnitude.AlmostEqual(0.0)) if (value.Magnitude.AlmostEqual(0.0))

50
src/Numerics/LinearAlgebra/Complex/Factorization/UserCholesky.cs

@ -73,40 +73,40 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
CholeskyFactor = matrix.Clone(); Factor = matrix.Clone();
var tmpColumn = new Complex[CholeskyFactor.RowCount]; var tmpColumn = new Complex[Factor.RowCount];
// Main loop - along the diagonal // Main loop - along the diagonal
for (var ij = 0; ij < CholeskyFactor.RowCount; ij++) for (var ij = 0; ij < Factor.RowCount; ij++)
{ {
// "Pivot" element // "Pivot" element
var tmpVal = CholeskyFactor.At(ij, ij); var tmpVal = Factor.At(ij, ij);
if (tmpVal.Real > 0.0) if (tmpVal.Real > 0.0)
{ {
tmpVal = tmpVal.SquareRoot(); tmpVal = tmpVal.SquareRoot();
CholeskyFactor.At(ij, ij, tmpVal); Factor.At(ij, ij, tmpVal);
tmpColumn[ij] = tmpVal; tmpColumn[ij] = tmpVal;
// Calculate multipliers and copy to local column // Calculate multipliers and copy to local column
// Current column, below the diagonal // Current column, below the diagonal
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(i, ij, CholeskyFactor.At(i, ij) / tmpVal); Factor.At(i, ij, Factor.At(i, ij) / tmpVal);
tmpColumn[i] = CholeskyFactor.At(i, ij); tmpColumn[i] = Factor.At(i, ij);
} }
// Remaining columns, below the diagonal // Remaining columns, below the diagonal
DoCholeskyStep(CholeskyFactor, CholeskyFactor.RowCount, ij + 1, CholeskyFactor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads); DoCholeskyStep(Factor, Factor.RowCount, ij + 1, Factor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads);
} }
else else
{ {
throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
} }
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(ij, i, Complex.Zero); Factor.At(ij, i, Complex.Zero);
} }
} }
} }
@ -174,13 +174,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
for (var c = 0; c < result.ColumnCount; c++) for (var c = 0; c < result.ColumnCount; c++)
{ {
@ -191,10 +191,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result.At(k, c); sum -= Factor.At(i, k) * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -203,10 +203,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i).Conjugate() * result.At(k, c); sum -= Factor.At(k, i).Conjugate() * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
} }
} }
@ -235,13 +235,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
// Solve L*Y = B; // Solve L*Y = B;
Complex sum; Complex sum;
@ -250,10 +250,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
sum = result[i]; sum = result[i];
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result[k]; sum -= Factor.At(i, k) * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -262,10 +262,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
sum = result[i]; sum = result[i];
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i).Conjugate() * result[k]; sum -= Factor.At(k, i).Conjugate() * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
} }
} }

86
src/Numerics/LinearAlgebra/Complex/Factorization/UserEvd.cs

@ -79,9 +79,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matricies for eigenvalues and eigenvectors // Initialize matricies for eigenvalues and eigenvectors
MatrixEv = DenseMatrix.Identity(order); EigenVectors = DenseMatrix.Identity(order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new DenseVector(order); EigenValues = new DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -106,7 +106,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
VectorEv[i] = new Complex(d[i], e[i]); EigenValues[i] = new Complex(d[i], e[i]);
} }
} }
else else
@ -116,7 +116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
NonsymmetricReduceHessenberToRealSchur(matrixH, order); NonsymmetricReduceHessenberToRealSchur(matrixH, order);
} }
MatrixD.SetDiagonal(VectorEv); D.SetDiagonal(EigenValues);
} }
/// <summary> /// <summary>
@ -337,9 +337,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Accumulate transformation. // Accumulate transformation.
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
{ {
h = MatrixEv.At(k, i + 1).Real; h = EigenVectors.At(k, i + 1).Real;
MatrixEv.At(k, i + 1, (s * MatrixEv.At(k, i).Real) + (c * h)); EigenVectors.At(k, i + 1, (s * EigenVectors.At(k, i).Real) + (c * h));
MatrixEv.At(k, i, (c * MatrixEv.At(k, i).Real) - (s * h)); EigenVectors.At(k, i, (c * EigenVectors.At(k, i).Real) - (s * h));
} }
} }
@ -381,9 +381,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
d[i] = p; d[i] = p;
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
p = MatrixEv.At(j, i).Real; p = EigenVectors.At(j, i).Real;
MatrixEv.At(j, i, MatrixEv.At(j, k)); EigenVectors.At(j, i, EigenVectors.At(j, k));
MatrixEv.At(j, k, p); EigenVectors.At(j, k, p);
} }
} }
} }
@ -405,7 +405,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(i, j, MatrixEv.At(i, j).Real * tau[i].Conjugate()); EigenVectors.At(i, j, EigenVectors.At(i, j).Real * tau[i].Conjugate());
} }
} }
@ -420,14 +420,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var s = Complex.Zero; var s = Complex.Zero;
for (var k = 0; k < i; k++) for (var k = 0; k < i; k++)
{ {
s += MatrixEv.At(k, j) * matrixA[i, k]; s += EigenVectors.At(k, j) * matrixA[i, k];
} }
s = (s / h) / h; s = (s / h) / h;
for (var k = 0; k < i; k++) for (var k = 0; k < i; k++)
{ {
MatrixEv.At(k, j, MatrixEv.At(k, j) - s * matrixA[i, k].Conjugate()); EigenVectors.At(k, j, EigenVectors.At(k, j) - s * matrixA[i, k].Conjugate());
} }
} }
} }
@ -521,7 +521,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(i, j, i == j ? Complex.One : Complex.Zero); EigenVectors.At(i, j, i == j ? Complex.One : Complex.Zero);
} }
} }
@ -541,14 +541,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var g = Complex.Zero; var g = Complex.Zero;
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
g += ort[i].Conjugate() * MatrixEv.At(i, j); g += ort[i].Conjugate() * EigenVectors.At(i, j);
} }
// Double division avoids possible underflow // Double division avoids possible underflow
g /= norm; g /= norm;
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
MatrixEv.At(i, j, MatrixEv.At(i, j) + g * ort[i]); EigenVectors.At(i, j, EigenVectors.At(i, j) + g * ort[i]);
} }
} }
} }
@ -573,7 +573,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(j, i, MatrixEv.At(j, i) * y); EigenVectors.At(j, i, EigenVectors.At(j, i) * y);
} }
} }
} }
@ -619,7 +619,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (l == n) if (l == n)
{ {
matrixH[n, n] += exshift; matrixH[n, n] += exshift;
VectorEv[n] = matrixH[n, n]; EigenValues[n] = matrixH[n, n];
n--; n--;
iter = 0; iter = 0;
} }
@ -665,7 +665,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
s = matrixH[i, i - 1].Real; s = matrixH[i, i - 1].Real;
norm = SpecialFunctions.Hypotenuse(matrixH[i - 1, i - 1].Magnitude, s.Real); norm = SpecialFunctions.Hypotenuse(matrixH[i - 1, i - 1].Magnitude, s.Real);
x = matrixH[i - 1, i - 1] / norm; x = matrixH[i - 1, i - 1] / norm;
VectorEv[i - 1] = x; EigenValues[i - 1] = x;
matrixH[i - 1, i - 1] = norm; matrixH[i - 1, i - 1] = norm;
matrixH[i, i - 1] = new Complex(0.0, s.Real / norm); matrixH[i, i - 1] = new Complex(0.0, s.Real / norm);
@ -693,7 +693,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Inverse operation (columns). // Inverse operation (columns).
for (var j = l + 1; j <= n; j++) for (var j = l + 1; j <= n; j++)
{ {
x = VectorEv[j - 1]; x = EigenValues[j - 1];
for (var i = 0; i <= j; i++) for (var i = 0; i <= j; i++)
{ {
z = matrixH[i, j]; z = matrixH[i, j];
@ -713,10 +713,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
y = MatrixEv.At(i, j - 1); y = EigenVectors.At(i, j - 1);
z = MatrixEv.At(i, j); z = EigenVectors.At(i, j);
MatrixEv.At(i, j - 1, (x * y) + (matrixH[j, j - 1].Imaginary * z)); EigenVectors.At(i, j - 1, (x * y) + (matrixH[j, j - 1].Imaginary * z));
MatrixEv.At(i, j, (x.Conjugate() * z) - (matrixH[j, j - 1].Imaginary * y)); EigenVectors.At(i, j, (x.Conjugate() * z) - (matrixH[j, j - 1].Imaginary * y));
} }
} }
@ -729,7 +729,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
MatrixEv.At(i, n, MatrixEv.At(i, n) * s); EigenVectors.At(i, n, EigenVectors.At(i, n) * s);
} }
} }
} }
@ -758,7 +758,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (n = order - 1; n > 0; n--) for (n = order - 1; n > 0; n--)
{ {
x = VectorEv[n]; x = EigenValues[n];
matrixH[n, n] = 1.0; matrixH[n, n] = 1.0;
for (var i = n - 1; i >= 0; i--) for (var i = n - 1; i >= 0; i--)
@ -769,7 +769,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
z += matrixH[i, j] * matrixH[j, n]; z += matrixH[i, j] * matrixH[j, n];
} }
y = x - VectorEv[i]; y = x - EigenValues[i];
if (y.Real == 0.0 && y.Imaginary == 0.0) if (y.Real == 0.0 && y.Imaginary == 0.0)
{ {
y = eps * norm; y = eps * norm;
@ -797,10 +797,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
z = Complex.Zero; z = Complex.Zero;
for (var k = 0; k <= j; k++) for (var k = 0; k <= j; k++)
{ {
z += MatrixEv.At(i, k) * matrixH[k, j]; z += EigenVectors.At(i, k) * matrixH[k, j];
} }
MatrixEv.At(i, j, z); EigenVectors.At(i, j, z);
} }
} }
} }
@ -830,20 +830,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Complex[order]; var tmp = new Complex[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -855,10 +855,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j).Conjugate() * input.At(i, k); value += EigenVectors.At(i, j).Conjugate() * input.At(i, k);
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -869,7 +869,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
Complex value = 0.0; Complex value = 0.0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -901,21 +901,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(VectorEv, result); throw Matrix.DimensionsDontMatch<ArgumentException>(EigenValues, result);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VH * b; // Symmetric case -> x = V * inv(λ) * VH * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Complex[order]; var tmp = new Complex[order];
Complex value; Complex value;
@ -926,10 +926,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j).Conjugate() * input[i]; value += EigenVectors.At(i, j).Conjugate() * input[i];
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -940,7 +940,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
value = 0; value = 0;
for (int i = 0; i < order; i++) for (int i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result[j] = value; result[j] = value;

56
src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs

@ -69,36 +69,36 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
for (var k = 0; k < MatrixQ.ColumnCount; k++) for (var k = 0; k < Q.ColumnCount; k++)
{ {
var norm = MatrixQ.Column(k).L2Norm(); var norm = Q.Column(k).L2Norm();
if (norm == 0.0) if (norm == 0.0)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);
} }
MatrixR.At(k, k, norm); MatrixR.At(k, k, norm);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
MatrixQ.At(i, k, MatrixQ.At(i, k) / norm); Q.At(i, k, Q.At(i, k) / norm);
} }
for (var j = k + 1; j < MatrixQ.ColumnCount; j++) for (var j = k + 1; j < Q.ColumnCount; j++)
{ {
var dot = Complex.Zero; var dot = Complex.Zero;
for (int i = 0; i < MatrixQ.RowCount; i++) for (int i = 0; i < Q.RowCount; i++)
{ {
dot += MatrixQ.Column(k)[i].Conjugate() * MatrixQ.Column(j)[i]; dot += Q.Column(k)[i].Conjugate() * Q.Column(j)[i];
} }
MatrixR.At(k, j, dot); MatrixR.At(k, j, dot);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
var value = MatrixQ.At(i, j) - (MatrixQ.At(i, k) * dot); var value = Q.At(i, j) - (Q.At(i, k) * dot);
MatrixQ.At(i, j, value); Q.At(i, j, value);
} }
} }
} }
@ -129,13 +129,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -143,20 +143,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new Complex[MatrixQ.RowCount]; var column = new Complex[Q.RowCount];
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy.At(k, j); column[k] = inputCopy.At(k, j);
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
var s = Complex.Zero; var s = Complex.Zero;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -164,7 +164,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
@ -208,39 +208,39 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new Complex[MatrixQ.RowCount]; var column = new Complex[Q.RowCount];
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy[k]; column[k] = inputCopy[k];
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
var s = Complex.Zero; var s = Complex.Zero;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
inputCopy[k] /= MatrixR.At(k, k); inputCopy[k] /= MatrixR.At(k, k);
for (var i = 0; i < k; i++) for (var i = 0; i < k; i++)

24
src/Numerics/LinearAlgebra/Complex/Factorization/UserQR.cs

@ -80,11 +80,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); Q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount);
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
MatrixQ.At(i, i, 1.0f); Q.At(i, i, 1.0f);
} }
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
@ -96,33 +96,33 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.RowCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.RowCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
else else
{ {
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
MatrixQ = matrix.Clone(); Q = matrix.Clone();
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
{ {
u[i] = GenerateColumn(MatrixQ, i, i); u[i] = GenerateColumn(Q, i, i);
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i + 1, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i + 1, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
MatrixR = MatrixQ.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount); MatrixR = Q.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount);
MatrixQ.Clear(); Q.Clear();
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
MatrixQ.At(i, i, 1.0f); Q.At(i, i, 1.0f);
} }
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
@ -277,7 +277,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var s = Complex.Zero; var s = Complex.Zero;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -354,7 +354,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var s = Complex.Zero; var s = Complex.Zero;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;

186
src/Numerics/LinearAlgebra/Complex/Factorization/UserSvd.cs

@ -75,9 +75,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount);
var matrixCopy = matrix.Clone(); var matrixCopy = matrix.Clone();
VectorS = matrixCopy.CreateVector(nm); S = matrixCopy.CreateVector(nm);
MatrixU = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); U = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount);
MatrixVT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); VT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount);
const int maxiter = 1000; const int maxiter = 1000;
var e = new Complex[matrixCopy.ColumnCount]; var e = new Complex[matrixCopy.ColumnCount];
@ -100,26 +100,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (l < nct) if (l < nct)
{ {
// Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l]. // Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l].
VectorS[l] = Cnrm2Column(matrixCopy, matrixCopy.RowCount, l, l); S[l] = Cnrm2Column(matrixCopy, matrixCopy.RowCount, l, l);
if (VectorS[l].Magnitude != 0.0) if (S[l].Magnitude != 0.0)
{ {
if (matrixCopy.At(l, l).Magnitude != 0.0) if (matrixCopy.At(l, l).Magnitude != 0.0)
{ {
VectorS[l] = Csign(VectorS[l], matrixCopy.At(l, l)); S[l] = Csign(S[l], matrixCopy.At(l, l));
} }
CscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0 / VectorS[l]); CscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0 / S[l]);
matrixCopy.At(l, l, (Complex.One + matrixCopy.At(l, l))); matrixCopy.At(l, l, (Complex.One + matrixCopy.At(l, l)));
} }
VectorS[l] = -VectorS[l]; S[l] = -S[l];
} }
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
if (l < nct) if (l < nct)
{ {
if (VectorS[l].Magnitude != 0.0) if (S[l].Magnitude != 0.0)
{ {
// Apply the transformation. // Apply the transformation.
t = -Cdotc(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l); t = -Cdotc(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l);
@ -143,7 +143,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Place the transformation in u for subsequent back multiplication. // Place the transformation in u for subsequent back multiplication.
for (i = l; i < matrixCopy.RowCount; i++) for (i = l; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, matrixCopy.At(i, l)); U.At(i, l, matrixCopy.At(i, l));
} }
} }
@ -204,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Place the transformation in v for subsequent back multiplication. // Place the transformation in v for subsequent back multiplication.
for (i = lp1; i < matrixCopy.ColumnCount; i++) for (i = lp1; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, e[i]); VT.At(i, l, e[i]);
} }
} }
} }
@ -215,12 +215,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var nrtp1 = nrt + 1; var nrtp1 = nrt + 1;
if (nct < matrixCopy.ColumnCount) if (nct < matrixCopy.ColumnCount)
{ {
VectorS[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1)); S[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1));
} }
if (matrixCopy.RowCount < m) if (matrixCopy.RowCount < m)
{ {
VectorS[m - 1] = Complex.Zero; S[m - 1] = Complex.Zero;
} }
if (nrtp1 < m) if (nrtp1 < m)
@ -237,43 +237,43 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, j, Complex.Zero); U.At(i, j, Complex.Zero);
} }
MatrixU.At(j, j, Complex.One); U.At(j, j, Complex.One);
} }
for (l = nct - 1; l >= 0; l--) for (l = nct - 1; l >= 0; l--)
{ {
if (VectorS[l].Magnitude != 0.0) if (S[l].Magnitude != 0.0)
{ {
for (j = l + 1; j < ncu; j++) for (j = l + 1; j < ncu; j++)
{ {
t = -Cdotc(MatrixU, matrixCopy.RowCount, l, j, l) / MatrixU.At(l, l); t = -Cdotc(U, matrixCopy.RowCount, l, j, l) / U.At(l, l);
if (t != Complex.Zero) if (t != Complex.Zero)
{ {
for (var ii = l; ii < matrixCopy.RowCount; ii++) for (var ii = l; ii < matrixCopy.RowCount; ii++)
{ {
MatrixU.At(ii, j, MatrixU.At(ii, j) + (t * MatrixU.At(ii, l))); U.At(ii, j, U.At(ii, j) + (t * U.At(ii, l)));
} }
} }
} }
CscalColumn(MatrixU, matrixCopy.RowCount, l, l, -1.0); CscalColumn(U, matrixCopy.RowCount, l, l, -1.0);
MatrixU.At(l, l, Complex.One + MatrixU.At(l, l)); U.At(l, l, Complex.One + U.At(l, l));
for (i = 0; i < l; i++) for (i = 0; i < l; i++)
{ {
MatrixU.At(i, l, Complex.Zero); U.At(i, l, Complex.Zero);
} }
} }
else else
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, Complex.Zero); U.At(i, l, Complex.Zero);
} }
MatrixU.At(l, l, Complex.One); U.At(l, l, Complex.One);
} }
} }
} }
@ -290,12 +290,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
t = -Cdotc(MatrixVT, matrixCopy.ColumnCount, l, j, lp1) / MatrixVT.At(lp1, l); t = -Cdotc(VT, matrixCopy.ColumnCount, l, j, lp1) / VT.At(lp1, l);
if (t != Complex.Zero) if (t != Complex.Zero)
{ {
for (var ii = l; ii < matrixCopy.ColumnCount; ii++) for (var ii = l; ii < matrixCopy.ColumnCount; ii++)
{ {
MatrixVT.At(ii, j, MatrixVT.At(ii, j) + (t * MatrixVT.At(ii, l))); VT.At(ii, j, VT.At(ii, j) + (t * VT.At(ii, l)));
} }
} }
} }
@ -304,10 +304,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (i = 0; i < matrixCopy.ColumnCount; i++) for (i = 0; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, Complex.Zero); VT.At(i, l, Complex.Zero);
} }
MatrixVT.At(l, l, Complex.One); VT.At(l, l, Complex.One);
} }
} }
@ -315,11 +315,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (i = 0; i < m; i++) for (i = 0; i < m; i++)
{ {
Complex r; Complex r;
if (VectorS[i].Magnitude != 0.0) if (S[i].Magnitude != 0.0)
{ {
t = VectorS[i].Magnitude; t = S[i].Magnitude;
r = VectorS[i] / t; r = S[i] / t;
VectorS[i] = t; S[i] = t;
if (i < m - 1) if (i < m - 1)
{ {
e[i] = e[i] / r; e[i] = e[i] / r;
@ -327,7 +327,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
CscalColumn(MatrixU, matrixCopy.RowCount, i, 0, r); CscalColumn(U, matrixCopy.RowCount, i, 0, r);
} }
} }
@ -342,10 +342,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
t = e[i].Magnitude; t = e[i].Magnitude;
r = t / e[i]; r = t / e[i];
e[i] = t; e[i] = t;
VectorS[i + 1] = VectorS[i + 1] * r; S[i + 1] = S[i + 1] * r;
if (ComputeVectors) if (ComputeVectors)
{ {
CscalColumn(MatrixVT, matrixCopy.ColumnCount, i + 1, 0, r); CscalColumn(VT, matrixCopy.ColumnCount, i + 1, 0, r);
} }
} }
} }
@ -373,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
double test; double test;
for (l = m - 2; l >= 0; l--) for (l = m - 2; l >= 0; l--)
{ {
test = VectorS[l].Magnitude + VectorS[l + 1].Magnitude; test = S[l].Magnitude + S[l + 1].Magnitude;
ztest = test + e[l].Magnitude; ztest = test + e[l].Magnitude;
if (ztest.AlmostEqualInDecimalPlaces(test, 15)) if (ztest.AlmostEqualInDecimalPlaces(test, 15))
{ {
@ -403,10 +403,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
test = test + e[ls - 1].Magnitude; test = test + e[ls - 1].Magnitude;
} }
ztest = test + VectorS[ls].Magnitude; ztest = test + S[ls].Magnitude;
if (ztest.AlmostEqualInDecimalPlaces(test, 15)) if (ztest.AlmostEqualInDecimalPlaces(test, 15))
{ {
VectorS[ls] = Complex.Zero; S[ls] = Complex.Zero;
break; break;
} }
} }
@ -443,9 +443,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
for (var kk = l; kk < m - 1; kk++) for (var kk = l; kk < m - 1; kk++)
{ {
k = m - 2 - kk + l; k = m - 2 - kk + l;
t1 = VectorS[k].Real; t1 = S[k].Real;
Srotg(ref t1, ref f, out cs, out sn); Srotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
if (k != l) if (k != l)
{ {
f = -sn * e[k - 1].Real; f = -sn * e[k - 1].Real;
@ -454,7 +454,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
Csrot(MatrixVT, matrixCopy.ColumnCount, k, m - 1, cs, sn); Csrot(VT, matrixCopy.ColumnCount, k, m - 1, cs, sn);
} }
} }
@ -466,14 +466,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
e[l - 1] = Complex.Zero; e[l - 1] = Complex.Zero;
for (k = l; k < m; k++) for (k = l; k < m; k++)
{ {
t1 = VectorS[k].Real; t1 = S[k].Real;
Srotg(ref t1, ref f, out cs, out sn); Srotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
f = -sn * e[k].Real; f = -sn * e[k].Real;
e[k] = cs * e[k]; e[k] = cs * e[k];
if (ComputeVectors) if (ComputeVectors)
{ {
Csrot(MatrixU, matrixCopy.RowCount, k, l - 1, cs, sn); Csrot(U, matrixCopy.RowCount, k, l - 1, cs, sn);
} }
} }
@ -483,15 +483,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
case 3: case 3:
// Calculate the shift. // Calculate the shift.
var scale = 0.0; var scale = 0.0;
scale = Math.Max(scale, VectorS[m - 1].Magnitude); scale = Math.Max(scale, S[m - 1].Magnitude);
scale = Math.Max(scale, VectorS[m - 2].Magnitude); scale = Math.Max(scale, S[m - 2].Magnitude);
scale = Math.Max(scale, e[m - 2].Magnitude); scale = Math.Max(scale, e[m - 2].Magnitude);
scale = Math.Max(scale, VectorS[l].Magnitude); scale = Math.Max(scale, S[l].Magnitude);
scale = Math.Max(scale, e[l].Magnitude); scale = Math.Max(scale, e[l].Magnitude);
var sm = VectorS[m - 1].Real / scale; var sm = S[m - 1].Real / scale;
var smm1 = VectorS[m - 2].Real / scale; var smm1 = S[m - 2].Real / scale;
var emm1 = e[m - 2].Real / scale; var emm1 = e[m - 2].Real / scale;
var sl = VectorS[l].Real / scale; var sl = S[l].Real / scale;
var el = e[l].Real / scale; var el = e[l].Real / scale;
var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0; var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0;
var c = (sm * emm1) * (sm * emm1); var c = (sm * emm1) * (sm * emm1);
@ -520,24 +520,24 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
e[k - 1] = f; e[k - 1] = f;
} }
f = (cs * VectorS[k].Real) + (sn * e[k].Real); f = (cs * S[k].Real) + (sn * e[k].Real);
e[k] = (cs * e[k]) - (sn * VectorS[k]); e[k] = (cs * e[k]) - (sn * S[k]);
g = sn * VectorS[k + 1].Real; g = sn * S[k + 1].Real;
VectorS[k + 1] = cs * VectorS[k + 1]; S[k + 1] = cs * S[k + 1];
if (ComputeVectors) if (ComputeVectors)
{ {
Csrot(MatrixVT, matrixCopy.ColumnCount, k, k + 1, cs, sn); Csrot(VT, matrixCopy.ColumnCount, k, k + 1, cs, sn);
} }
Srotg(ref f, ref g, out cs, out sn); Srotg(ref f, ref g, out cs, out sn);
VectorS[k] = f; S[k] = f;
f = (cs * e[k].Real) + (sn * VectorS[k + 1].Real); f = (cs * e[k].Real) + (sn * S[k + 1].Real);
VectorS[k + 1] = (-sn * e[k]) + (cs * VectorS[k + 1]); S[k + 1] = (-sn * e[k]) + (cs * S[k + 1]);
g = sn * e[k + 1].Real; g = sn * e[k + 1].Real;
e[k + 1] = cs * e[k + 1]; e[k + 1] = cs * e[k + 1];
if (ComputeVectors && k < matrixCopy.RowCount) if (ComputeVectors && k < matrixCopy.RowCount)
{ {
Csrot(MatrixU, matrixCopy.RowCount, k, k + 1, cs, sn); Csrot(U, matrixCopy.RowCount, k, k + 1, cs, sn);
} }
} }
@ -548,34 +548,34 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Convergence. // Convergence.
case 4: case 4:
// Make the singular value positive // Make the singular value positive
if (VectorS[l].Real < 0.0) if (S[l].Real < 0.0)
{ {
VectorS[l] = -VectorS[l]; S[l] = -S[l];
if (ComputeVectors) if (ComputeVectors)
{ {
CscalColumn(MatrixVT, matrixCopy.ColumnCount, l, 0, -1.0); CscalColumn(VT, matrixCopy.ColumnCount, l, 0, -1.0);
} }
} }
// Order the singular value. // Order the singular value.
while (l != mn - 1) while (l != mn - 1)
{ {
if (VectorS[l].Real >= VectorS[l + 1].Real) if (S[l].Real >= S[l + 1].Real)
{ {
break; break;
} }
t = VectorS[l]; t = S[l];
VectorS[l] = VectorS[l + 1]; S[l] = S[l + 1];
VectorS[l + 1] = t; S[l + 1] = t;
if (ComputeVectors && l < matrixCopy.ColumnCount) if (ComputeVectors && l < matrixCopy.ColumnCount)
{ {
Swap(MatrixVT, matrixCopy.ColumnCount, l, l + 1); Swap(VT, matrixCopy.ColumnCount, l, l + 1);
} }
if (ComputeVectors && l < matrixCopy.RowCount) if (ComputeVectors && l < matrixCopy.RowCount)
{ {
Swap(MatrixU, matrixCopy.RowCount, l, l + 1); Swap(U, matrixCopy.RowCount, l, l + 1);
} }
l = l + 1; l = l + 1;
@ -589,7 +589,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
MatrixVT = MatrixVT.ConjugateTranspose(); VT = VT.ConjugateTranspose();
} }
// Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses // Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses
@ -601,10 +601,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
var tmp = matrixCopy.CreateVector(nm); var tmp = matrixCopy.CreateVector(nm);
for (i = 0; i < nm; i++) for (i = 0; i < nm; i++)
{ {
tmp[i] = VectorS[i]; tmp[i] = S[i];
} }
VectorS = tmp; S = tmp;
} }
} }
@ -830,46 +830,46 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var bn = input.ColumnCount; var bn = input.ColumnCount;
var tmp = new Complex[MatrixVT.ColumnCount]; var tmp = new Complex[VT.ColumnCount];
for (var k = 0; k < bn; k++) for (var k = 0; k < bn; k++)
{ {
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex.Zero; var value = Complex.Zero;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j).Conjugate() * input.At(i, k); value += U.At(i, j).Conjugate() * input.At(i, k);
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex.Zero; var value = Complex.Zero;
for (var i = 0; i < MatrixVT.ColumnCount; i++) for (var i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j).Conjugate() * tmp[i]; value += VT.At(i, j).Conjugate() * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -901,41 +901,41 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var tmp = new Complex[MatrixVT.ColumnCount]; var tmp = new Complex[VT.ColumnCount];
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex.Zero; var value = Complex.Zero;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j).Conjugate() * input[i]; value += U.At(i, j).Conjugate() * input[i];
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex.Zero; var value = Complex.Zero;
for (var i = 0; i < MatrixVT.ColumnCount; i++) for (var i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j).Conjugate() * tmp[i]; value += VT.At(i, j).Conjugate() * tmp[i];
} }
result[j] = value; result[j] = value;

8
src/Numerics/LinearAlgebra/Complex32/Factorization/Cholesky.cs

@ -53,9 +53,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
get get
{ {
var det = Complex32.One; var det = Complex32.One;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
var d = CholeskyFactor.At(j, j); var d = Factor.At(j, j);
det *= d * d; det *= d * d;
} }
@ -71,9 +71,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
get get
{ {
var det = Complex32.Zero; var det = Complex32.Zero;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
det += 2.0f * CholeskyFactor.At(j, j).NaturalLogarithm(); det += 2.0f * Factor.At(j, j).NaturalLogarithm();
} }
return det; return det;

14
src/Numerics/LinearAlgebra/Complex32/Factorization/DenseCholesky.cs

@ -68,7 +68,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
var factor = (DenseMatrix)matrix.Clone(); var factor = (DenseMatrix)matrix.Clone();
Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount); Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount);
CholeskyFactor = factor; Factor = factor;
} }
/// <summary> /// <summary>
@ -100,9 +100,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseMatrix; var dinput = input as DenseMatrix;
@ -121,7 +121,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length); Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount);
} }
@ -149,9 +149,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -170,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length); Array.Copy(dinput.Values, dresult.Values, dinput.Values.Length);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1);
} }
} }

34
src/Numerics/LinearAlgebra/Complex32/Factorization/DenseEvd.cs

@ -72,9 +72,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matrices for eigenvalues and eigenvectors // Initialize matrices for eigenvalues and eigenvectors
MatrixEv = DenseMatrix.Identity(order); EigenVectors = DenseMatrix.Identity(order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new Complex.DenseVector(order); EigenValues = new Complex.DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -86,8 +86,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
} }
Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) MatrixEv).Values, Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) EigenVectors).Values,
((Complex.DenseVector) VectorEv).Values, ((DenseMatrix) MatrixD).Values); ((Complex.DenseVector)EigenValues).Values, ((DenseMatrix)D).Values);
} }
/// <summary> /// <summary>
@ -833,20 +833,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Numerics.Complex32[order]; var tmp = new Numerics.Complex32[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -858,10 +858,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i].Conjugate()*input.At(i, k); value += ((DenseMatrix) EigenVectors).Values[(j*order) + i].Conjugate()*input.At(i, k);
} }
value /= (float) VectorEv[j].Real; value /= (float)EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -872,7 +872,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
Numerics.Complex32 value = 0.0f; Numerics.Complex32 value = 0.0f;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -904,13 +904,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -918,7 +918,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VH * b; // Symmetric case -> x = V * inv(λ) * VH * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Numerics.Complex32[order]; var tmp = new Numerics.Complex32[order];
Numerics.Complex32 value; Numerics.Complex32 value;
@ -929,10 +929,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i].Conjugate()*input[i]; value += ((DenseMatrix) EigenVectors).Values[(j*order) + i].Conjugate()*input[i];
} }
value /= (float) VectorEv[j].Real; value /= (float)EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -943,7 +943,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
value = 0; value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result[j] = value; result[j] = value;

18
src/Numerics/LinearAlgebra/Complex32/Factorization/DenseGramSchmidt.cs

@ -71,9 +71,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
Factorize(((DenseMatrix)MatrixQ).Values, MatrixQ.RowCount, MatrixQ.ColumnCount, ((DenseMatrix)MatrixR).Values); Factorize(((DenseMatrix)Q).Values, Q.RowCount, Q.ColumnCount, ((DenseMatrix)MatrixR).Values);
} }
/// <summary> /// <summary>
@ -151,13 +151,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -174,7 +174,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin);
} }
/// <summary> /// <summary>
@ -196,15 +196,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -219,7 +219,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin);
} }
} }
} }

16
src/Numerics/LinearAlgebra/Complex32/Factorization/DenseQR.cs

@ -82,15 +82,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = new DenseMatrix(matrix.RowCount); Q = new DenseMatrix(matrix.RowCount);
Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixQ).Values, Tau); ((DenseMatrix)Q).Values, Tau);
} }
else else
{ {
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = new DenseMatrix(matrix.ColumnCount); MatrixR = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix)MatrixQ).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix)Q).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixR).Values, Tau); ((DenseMatrix)MatrixR).Values, Tau);
} }
} }
@ -120,7 +120,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
@ -143,7 +143,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod);
} }
/// <summary> /// <summary>
@ -165,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
@ -188,7 +188,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod);
} }
} }
} }

22
src/Numerics/LinearAlgebra/Complex32/Factorization/DenseSvd.cs

@ -68,10 +68,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
ComputeVectors = computeVectors; ComputeVectors = computeVectors;
var nm = Math.Min(matrix.RowCount, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount, matrix.ColumnCount);
VectorS = new DenseVector(nm); S = new DenseVector(nm);
MatrixU = new DenseMatrix(matrix.RowCount); U = new DenseMatrix(matrix.RowCount);
MatrixVT = new DenseMatrix(matrix.ColumnCount); VT = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values); Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values);
} }
/// <summary> /// <summary>
@ -104,13 +104,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -127,7 +127,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, input.ColumnCount, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, input.ColumnCount, dresult.Values);
} }
/// <summary> /// <summary>
@ -154,15 +154,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -177,7 +177,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, 1, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, 1, dresult.Values);
} }
} }
} }

14
src/Numerics/LinearAlgebra/Complex32/Factorization/Evd.cs

@ -62,11 +62,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
get get
{ {
var det = Complex.One; var det = Complex.One;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
det *= VectorEv[i]; det *= EigenValues[i];
if (((Complex32)VectorEv[i]).AlmostEqual(Complex32.Zero)) if (((Complex32)EigenValues[i]).AlmostEqual(Complex32.Zero))
{ {
return 0; return 0;
} }
@ -85,9 +85,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
get get
{ {
var rank = 0; var rank = 0;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (((Complex32)VectorEv[i]).AlmostEqual(Complex32.Zero)) if (((Complex32)EigenValues[i]).AlmostEqual(Complex32.Zero))
{ {
continue; continue;
} }
@ -107,9 +107,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
get get
{ {
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
return false; return false;
} }

12
src/Numerics/LinearAlgebra/Complex32/Factorization/Svd.cs

@ -61,7 +61,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
get get
{ {
return VectorS.Count(t => !t.Magnitude.AlmostEqual(0.0f)); return S.Count(t => !t.Magnitude.AlmostEqual(0.0f));
} }
} }
@ -73,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
get get
{ {
return VectorS[0].Magnitude; return S[0].Magnitude;
} }
} }
@ -85,8 +85,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
get get
{ {
var tmp = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount) - 1; var tmp = Math.Min(U.RowCount, VT.ColumnCount) - 1;
return VectorS[0].Magnitude / VectorS[tmp].Magnitude; return S[0].Magnitude / S[tmp].Magnitude;
} }
} }
@ -97,13 +97,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
get get
{ {
if (MatrixU.RowCount != MatrixVT.ColumnCount) if (U.RowCount != VT.ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var det = Complex32.One; var det = Complex32.One;
foreach (var value in VectorS) foreach (var value in S)
{ {
det *= value; det *= value;
if (value.Magnitude.AlmostEqual(0.0f)) if (value.Magnitude.AlmostEqual(0.0f))

50
src/Numerics/LinearAlgebra/Complex32/Factorization/UserCholesky.cs

@ -68,40 +68,40 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
CholeskyFactor = matrix.Clone(); Factor = matrix.Clone();
var tmpColumn = new Complex32[CholeskyFactor.RowCount]; var tmpColumn = new Complex32[Factor.RowCount];
// Main loop - along the diagonal // Main loop - along the diagonal
for (var ij = 0; ij < CholeskyFactor.RowCount; ij++) for (var ij = 0; ij < Factor.RowCount; ij++)
{ {
// "Pivot" element // "Pivot" element
var tmpVal = CholeskyFactor.At(ij, ij); var tmpVal = Factor.At(ij, ij);
if (tmpVal.Real > 0.0) if (tmpVal.Real > 0.0)
{ {
tmpVal = tmpVal.SquareRoot(); tmpVal = tmpVal.SquareRoot();
CholeskyFactor.At(ij, ij, tmpVal); Factor.At(ij, ij, tmpVal);
tmpColumn[ij] = tmpVal; tmpColumn[ij] = tmpVal;
// Calculate multipliers and copy to local column // Calculate multipliers and copy to local column
// Current column, below the diagonal // Current column, below the diagonal
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(i, ij, CholeskyFactor.At(i, ij) / tmpVal); Factor.At(i, ij, Factor.At(i, ij) / tmpVal);
tmpColumn[i] = CholeskyFactor.At(i, ij); tmpColumn[i] = Factor.At(i, ij);
} }
// Remaining columns, below the diagonal // Remaining columns, below the diagonal
DoCholeskyStep(CholeskyFactor, CholeskyFactor.RowCount, ij + 1, CholeskyFactor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads); DoCholeskyStep(Factor, Factor.RowCount, ij + 1, Factor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads);
} }
else else
{ {
throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
} }
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(ij, i, Complex32.Zero); Factor.At(ij, i, Complex32.Zero);
} }
} }
} }
@ -169,13 +169,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
for (var c = 0; c < result.ColumnCount; c++) for (var c = 0; c < result.ColumnCount; c++)
{ {
@ -186,10 +186,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result.At(k, c); sum -= Factor.At(i, k) * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -198,10 +198,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i).Conjugate() * result.At(k, c); sum -= Factor.At(k, i).Conjugate() * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
} }
} }
@ -230,13 +230,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
// Solve L*Y = B; // Solve L*Y = B;
Complex32 sum; Complex32 sum;
@ -245,10 +245,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
sum = result[i]; sum = result[i];
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result[k]; sum -= Factor.At(i, k) * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -257,10 +257,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
sum = result[i]; sum = result[i];
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i).Conjugate() * result[k]; sum -= Factor.At(k, i).Conjugate() * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
} }
} }

86
src/Numerics/LinearAlgebra/Complex32/Factorization/UserEvd.cs

@ -78,9 +78,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matricies for eigenvalues and eigenvectors // Initialize matricies for eigenvalues and eigenvectors
MatrixEv = DenseMatrix.Identity(order); EigenVectors = DenseMatrix.Identity(order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new LinearAlgebra.Complex.DenseVector(order); EigenValues = new LinearAlgebra.Complex.DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -105,7 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
VectorEv[i] = new Complex(d[i], e[i]); EigenValues[i] = new Complex(d[i], e[i]);
} }
} }
else else
@ -115,9 +115,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
NonsymmetricReduceHessenberToRealSchur(matrixH, order); NonsymmetricReduceHessenberToRealSchur(matrixH, order);
} }
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
MatrixD.At(i, i, (Complex32)VectorEv[i]); D.At(i, i, (Complex32)EigenValues[i]);
} }
} }
@ -339,9 +339,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Accumulate transformation. // Accumulate transformation.
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
{ {
h = MatrixEv.At(k, i + 1).Real; h = EigenVectors.At(k, i + 1).Real;
MatrixEv.At(k, i + 1, (s * MatrixEv.At(k, i).Real) + (c * h)); EigenVectors.At(k, i + 1, (s * EigenVectors.At(k, i).Real) + (c * h));
MatrixEv.At(k, i, (c * MatrixEv.At(k, i).Real) - (s * h)); EigenVectors.At(k, i, (c * EigenVectors.At(k, i).Real) - (s * h));
} }
} }
@ -383,9 +383,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
d[i] = p; d[i] = p;
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
p = MatrixEv.At(j, i).Real; p = EigenVectors.At(j, i).Real;
MatrixEv.At(j, i, MatrixEv.At(j, k)); EigenVectors.At(j, i, EigenVectors.At(j, k));
MatrixEv.At(j, k, p); EigenVectors.At(j, k, p);
} }
} }
} }
@ -407,7 +407,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(i, j, MatrixEv.At(i, j).Real * tau[i].Conjugate()); EigenVectors.At(i, j, EigenVectors.At(i, j).Real * tau[i].Conjugate());
} }
} }
@ -422,14 +422,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var s = Complex32.Zero; var s = Complex32.Zero;
for (var k = 0; k < i; k++) for (var k = 0; k < i; k++)
{ {
s += MatrixEv.At(k, j) * matrixA[i, k]; s += EigenVectors.At(k, j) * matrixA[i, k];
} }
s = (s / h) / h; s = (s / h) / h;
for (var k = 0; k < i; k++) for (var k = 0; k < i; k++)
{ {
MatrixEv.At(k, j, MatrixEv.At(k, j) - s * matrixA[i, k].Conjugate()); EigenVectors.At(k, j, EigenVectors.At(k, j) - s * matrixA[i, k].Conjugate());
} }
} }
} }
@ -523,7 +523,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(i, j, i == j ? Complex32.One : Complex32.Zero); EigenVectors.At(i, j, i == j ? Complex32.One : Complex32.Zero);
} }
} }
@ -543,14 +543,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var g = Complex32.Zero; var g = Complex32.Zero;
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
g += ort[i].Conjugate() * MatrixEv.At(i, j); g += ort[i].Conjugate() * EigenVectors.At(i, j);
} }
// Double division avoids possible underflow // Double division avoids possible underflow
g /= norm; g /= norm;
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
MatrixEv.At(i, j, MatrixEv.At(i, j) + g * ort[i]); EigenVectors.At(i, j, EigenVectors.At(i, j) + g * ort[i]);
} }
} }
} }
@ -575,7 +575,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(j, i, MatrixEv.At(j, i) * y); EigenVectors.At(j, i, EigenVectors.At(j, i) * y);
} }
} }
} }
@ -621,7 +621,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (l == n) if (l == n)
{ {
matrixH[n, n] += exshift; matrixH[n, n] += exshift;
VectorEv[n] = matrixH[n, n].ToComplex(); EigenValues[n] = matrixH[n, n].ToComplex();
n--; n--;
iter = 0; iter = 0;
} }
@ -667,7 +667,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
s = matrixH[i, i - 1].Real; s = matrixH[i, i - 1].Real;
norm = SpecialFunctions.Hypotenuse(matrixH[i - 1, i - 1].Magnitude, s.Real); norm = SpecialFunctions.Hypotenuse(matrixH[i - 1, i - 1].Magnitude, s.Real);
x = matrixH[i - 1, i - 1] / norm; x = matrixH[i - 1, i - 1] / norm;
VectorEv[i - 1] = x.ToComplex(); EigenValues[i - 1] = x.ToComplex();
matrixH[i - 1, i - 1] = norm; matrixH[i - 1, i - 1] = norm;
matrixH[i, i - 1] = new Complex32(0.0f, s.Real / norm); matrixH[i, i - 1] = new Complex32(0.0f, s.Real / norm);
@ -695,7 +695,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Inverse operation (columns). // Inverse operation (columns).
for (var j = l + 1; j <= n; j++) for (var j = l + 1; j <= n; j++)
{ {
x = (Complex32)VectorEv[j - 1]; x = (Complex32)EigenValues[j - 1];
for (var i = 0; i <= j; i++) for (var i = 0; i <= j; i++)
{ {
z = matrixH[i, j]; z = matrixH[i, j];
@ -715,10 +715,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
y = MatrixEv.At(i, j - 1); y = EigenVectors.At(i, j - 1);
z = MatrixEv.At(i, j); z = EigenVectors.At(i, j);
MatrixEv.At(i, j - 1, (x * y) + (matrixH[j, j - 1].Imaginary * z)); EigenVectors.At(i, j - 1, (x * y) + (matrixH[j, j - 1].Imaginary * z));
MatrixEv.At(i, j, (x.Conjugate() * z) - (matrixH[j, j - 1].Imaginary * y)); EigenVectors.At(i, j, (x.Conjugate() * z) - (matrixH[j, j - 1].Imaginary * y));
} }
} }
@ -731,7 +731,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
MatrixEv.At(i, n, MatrixEv.At(i, n) * s); EigenVectors.At(i, n, EigenVectors.At(i, n) * s);
} }
} }
} }
@ -760,7 +760,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (n = order - 1; n > 0; n--) for (n = order - 1; n > 0; n--)
{ {
x = (Complex32)VectorEv[n]; x = (Complex32)EigenValues[n];
matrixH[n, n] = 1.0f; matrixH[n, n] = 1.0f;
for (var i = n - 1; i >= 0; i--) for (var i = n - 1; i >= 0; i--)
@ -771,7 +771,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
z += matrixH[i, j] * matrixH[j, n]; z += matrixH[i, j] * matrixH[j, n];
} }
y = x - (Complex32)VectorEv[i]; y = x - (Complex32)EigenValues[i];
if (y.Real == 0.0f && y.Imaginary == 0.0f) if (y.Real == 0.0f && y.Imaginary == 0.0f)
{ {
y = eps * norm; y = eps * norm;
@ -799,10 +799,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
z = Complex32.Zero; z = Complex32.Zero;
for (var k = 0; k <= j; k++) for (var k = 0; k <= j; k++)
{ {
z += MatrixEv.At(i, k) * matrixH[k, j]; z += EigenVectors.At(i, k) * matrixH[k, j];
} }
MatrixEv.At(i, j, z); EigenVectors.At(i, j, z);
} }
} }
} }
@ -832,20 +832,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Complex32[order]; var tmp = new Complex32[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -857,10 +857,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j).Conjugate() * input.At(i, k); value += EigenVectors.At(i, j).Conjugate() * input.At(i, k);
} }
value /= (float)VectorEv[j].Real; value /= (float)EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -871,7 +871,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
Complex32 value = 0.0f; Complex32 value = 0.0f;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -903,13 +903,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -917,7 +917,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VH * b; // Symmetric case -> x = V * inv(λ) * VH * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new Complex32[order]; var tmp = new Complex32[order];
Complex32 value; Complex32 value;
@ -928,10 +928,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j).Conjugate() * input[i]; value += EigenVectors.At(i, j).Conjugate() * input[i];
} }
value /= (float)VectorEv[j].Real; value /= (float)EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -942,7 +942,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
value = 0; value = 0;
for (int i = 0; i < order; i++) for (int i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result[j] = value; result[j] = value;

56
src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs

@ -64,36 +64,36 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
for (var k = 0; k < MatrixQ.ColumnCount; k++) for (var k = 0; k < Q.ColumnCount; k++)
{ {
var norm = MatrixQ.Column(k).L2Norm().Real; var norm = Q.Column(k).L2Norm().Real;
if (norm == 0.0f) if (norm == 0.0f)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);
} }
MatrixR.At(k, k, norm); MatrixR.At(k, k, norm);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
MatrixQ.At(i, k, MatrixQ.At(i, k) / norm); Q.At(i, k, Q.At(i, k) / norm);
} }
for (var j = k + 1; j < MatrixQ.ColumnCount; j++) for (var j = k + 1; j < Q.ColumnCount; j++)
{ {
var dot = Complex32.Zero; var dot = Complex32.Zero;
for (int i = 0; i < MatrixQ.RowCount; i++) for (int i = 0; i < Q.RowCount; i++)
{ {
dot += MatrixQ.Column(k)[i].Conjugate() * MatrixQ.Column(j)[i]; dot += Q.Column(k)[i].Conjugate() * Q.Column(j)[i];
} }
MatrixR.At(k, j, dot); MatrixR.At(k, j, dot);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
var value = MatrixQ.At(i, j) - (MatrixQ.At(i, k) * dot); var value = Q.At(i, j) - (Q.At(i, k) * dot);
MatrixQ.At(i, j, value); Q.At(i, j, value);
} }
} }
} }
@ -124,13 +124,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -138,20 +138,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new Complex32[MatrixQ.RowCount]; var column = new Complex32[Q.RowCount];
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy.At(k, j); column[k] = inputCopy.At(k, j);
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
var s = Complex32.Zero; var s = Complex32.Zero;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -159,7 +159,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
@ -203,39 +203,39 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new Complex32[MatrixQ.RowCount]; var column = new Complex32[Q.RowCount];
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy[k]; column[k] = inputCopy[k];
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
var s = Complex32.Zero; var s = Complex32.Zero;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
inputCopy[k] /= MatrixR.At(k, k); inputCopy[k] /= MatrixR.At(k, k);
for (var i = 0; i < k; i++) for (var i = 0; i < k; i++)

24
src/Numerics/LinearAlgebra/Complex32/Factorization/UserQR.cs

@ -75,11 +75,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); Q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount);
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
MatrixQ.At(i, i, 1.0f); Q.At(i, i, 1.0f);
} }
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
@ -91,33 +91,33 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.RowCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.RowCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
else else
{ {
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
MatrixQ = matrix.Clone(); Q = matrix.Clone();
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
{ {
u[i] = GenerateColumn(MatrixQ, i, i); u[i] = GenerateColumn(Q, i, i);
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i + 1, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i + 1, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
MatrixR = MatrixQ.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount); MatrixR = Q.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount);
MatrixQ.Clear(); Q.Clear();
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
MatrixQ.At(i, i, 1.0f); Q.At(i, i, 1.0f);
} }
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
@ -272,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var s = Complex32.Zero; var s = Complex32.Zero;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -349,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var s = Complex32.Zero; var s = Complex32.Zero;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i).Conjugate() * column[k]; s += Q.At(k, i).Conjugate() * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;

186
src/Numerics/LinearAlgebra/Complex32/Factorization/UserSvd.cs

@ -70,9 +70,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount);
var matrixCopy = matrix.Clone(); var matrixCopy = matrix.Clone();
VectorS = matrixCopy.CreateVector(nm); S = matrixCopy.CreateVector(nm);
MatrixU = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); U = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount);
MatrixVT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); VT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount);
const int maxiter = 1000; const int maxiter = 1000;
var e = new Complex32[matrixCopy.ColumnCount]; var e = new Complex32[matrixCopy.ColumnCount];
@ -95,26 +95,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (l < nct) if (l < nct)
{ {
// Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l]. // Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l].
VectorS[l] = Cnrm2Column(matrixCopy, matrixCopy.RowCount, l, l); S[l] = Cnrm2Column(matrixCopy, matrixCopy.RowCount, l, l);
if (VectorS[l].Magnitude != 0.0f) if (S[l].Magnitude != 0.0f)
{ {
if (matrixCopy.At(l, l).Magnitude != 0.0f) if (matrixCopy.At(l, l).Magnitude != 0.0f)
{ {
VectorS[l] = Csign(VectorS[l], matrixCopy.At(l, l)); S[l] = Csign(S[l], matrixCopy.At(l, l));
} }
CscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0f / VectorS[l]); CscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0f / S[l]);
matrixCopy.At(l, l, (Complex32.One + matrixCopy.At(l, l))); matrixCopy.At(l, l, (Complex32.One + matrixCopy.At(l, l)));
} }
VectorS[l] = -VectorS[l]; S[l] = -S[l];
} }
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
if (l < nct) if (l < nct)
{ {
if (VectorS[l].Magnitude != 0.0f) if (S[l].Magnitude != 0.0f)
{ {
// Apply the transformation. // Apply the transformation.
t = -Cdotc(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l); t = -Cdotc(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l);
@ -138,7 +138,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Place the transformation in u for subsequent back multiplication. // Place the transformation in u for subsequent back multiplication.
for (i = l; i < matrixCopy.RowCount; i++) for (i = l; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, matrixCopy.At(i, l)); U.At(i, l, matrixCopy.At(i, l));
} }
} }
@ -199,7 +199,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Place the transformation in v for subsequent back multiplication. // Place the transformation in v for subsequent back multiplication.
for (i = lp1; i < matrixCopy.ColumnCount; i++) for (i = lp1; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, e[i]); VT.At(i, l, e[i]);
} }
} }
} }
@ -210,12 +210,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var nrtp1 = nrt + 1; var nrtp1 = nrt + 1;
if (nct < matrixCopy.ColumnCount) if (nct < matrixCopy.ColumnCount)
{ {
VectorS[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1)); S[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1));
} }
if (matrixCopy.RowCount < m) if (matrixCopy.RowCount < m)
{ {
VectorS[m - 1] = Complex32.Zero; S[m - 1] = Complex32.Zero;
} }
if (nrtp1 < m) if (nrtp1 < m)
@ -232,43 +232,43 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, j, Complex32.Zero); U.At(i, j, Complex32.Zero);
} }
MatrixU.At(j, j, Complex32.One); U.At(j, j, Complex32.One);
} }
for (l = nct - 1; l >= 0; l--) for (l = nct - 1; l >= 0; l--)
{ {
if (VectorS[l].Magnitude != 0.0f) if (S[l].Magnitude != 0.0f)
{ {
for (j = l + 1; j < ncu; j++) for (j = l + 1; j < ncu; j++)
{ {
t = -Cdotc(MatrixU, matrixCopy.RowCount, l, j, l) / MatrixU.At(l, l); t = -Cdotc(U, matrixCopy.RowCount, l, j, l) / U.At(l, l);
if (t != Complex32.Zero) if (t != Complex32.Zero)
{ {
for (var ii = l; ii < matrixCopy.RowCount; ii++) for (var ii = l; ii < matrixCopy.RowCount; ii++)
{ {
MatrixU.At(ii, j, MatrixU.At(ii, j) + (t * MatrixU.At(ii, l))); U.At(ii, j, U.At(ii, j) + (t * U.At(ii, l)));
} }
} }
} }
CscalColumn(MatrixU, matrixCopy.RowCount, l, l, -1.0f); CscalColumn(U, matrixCopy.RowCount, l, l, -1.0f);
MatrixU.At(l, l, Complex32.One + MatrixU.At(l, l)); U.At(l, l, Complex32.One + U.At(l, l));
for (i = 0; i < l; i++) for (i = 0; i < l; i++)
{ {
MatrixU.At(i, l, Complex32.Zero); U.At(i, l, Complex32.Zero);
} }
} }
else else
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, Complex32.Zero); U.At(i, l, Complex32.Zero);
} }
MatrixU.At(l, l, Complex32.One); U.At(l, l, Complex32.One);
} }
} }
} }
@ -285,12 +285,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
t = -Cdotc(MatrixVT, matrixCopy.ColumnCount, l, j, lp1) / MatrixVT.At(lp1, l); t = -Cdotc(VT, matrixCopy.ColumnCount, l, j, lp1) / VT.At(lp1, l);
if (t != Complex32.Zero) if (t != Complex32.Zero)
{ {
for (var ii = l; ii < matrixCopy.ColumnCount; ii++) for (var ii = l; ii < matrixCopy.ColumnCount; ii++)
{ {
MatrixVT.At(ii, j, MatrixVT.At(ii, j) + (t * MatrixVT.At(ii, l))); VT.At(ii, j, VT.At(ii, j) + (t * VT.At(ii, l)));
} }
} }
} }
@ -299,10 +299,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (i = 0; i < matrixCopy.ColumnCount; i++) for (i = 0; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, Complex32.Zero); VT.At(i, l, Complex32.Zero);
} }
MatrixVT.At(l, l, Complex32.One); VT.At(l, l, Complex32.One);
} }
} }
@ -310,11 +310,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (i = 0; i < m; i++) for (i = 0; i < m; i++)
{ {
Complex32 r; Complex32 r;
if (VectorS[i].Magnitude != 0.0f) if (S[i].Magnitude != 0.0f)
{ {
t = VectorS[i].Magnitude; t = S[i].Magnitude;
r = VectorS[i] / t; r = S[i] / t;
VectorS[i] = t; S[i] = t;
if (i < m - 1) if (i < m - 1)
{ {
e[i] = e[i] / r; e[i] = e[i] / r;
@ -322,7 +322,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
CscalColumn(MatrixU, matrixCopy.RowCount, i, 0, r); CscalColumn(U, matrixCopy.RowCount, i, 0, r);
} }
} }
@ -337,10 +337,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
t = e[i].Magnitude; t = e[i].Magnitude;
r = t / e[i]; r = t / e[i];
e[i] = t; e[i] = t;
VectorS[i + 1] = VectorS[i + 1] * r; S[i + 1] = S[i + 1] * r;
if (ComputeVectors) if (ComputeVectors)
{ {
CscalColumn(MatrixVT, matrixCopy.ColumnCount, i + 1, 0, r); CscalColumn(VT, matrixCopy.ColumnCount, i + 1, 0, r);
} }
} }
} }
@ -368,7 +368,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
float test; float test;
for (l = m - 2; l >= 0; l--) for (l = m - 2; l >= 0; l--)
{ {
test = VectorS[l].Magnitude + VectorS[l + 1].Magnitude; test = S[l].Magnitude + S[l + 1].Magnitude;
ztest = test + e[l].Magnitude; ztest = test + e[l].Magnitude;
if (ztest.AlmostEqualInDecimalPlaces(test, 7)) if (ztest.AlmostEqualInDecimalPlaces(test, 7))
{ {
@ -398,10 +398,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
test = test + e[ls - 1].Magnitude; test = test + e[ls - 1].Magnitude;
} }
ztest = test + VectorS[ls].Magnitude; ztest = test + S[ls].Magnitude;
if (ztest.AlmostEqualInDecimalPlaces(test, 7)) if (ztest.AlmostEqualInDecimalPlaces(test, 7))
{ {
VectorS[ls] = Complex32.Zero; S[ls] = Complex32.Zero;
break; break;
} }
} }
@ -438,9 +438,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
for (var kk = l; kk < m - 1; kk++) for (var kk = l; kk < m - 1; kk++)
{ {
k = m - 2 - kk + l; k = m - 2 - kk + l;
t1 = VectorS[k].Real; t1 = S[k].Real;
Srotg(ref t1, ref f, out cs, out sn); Srotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
if (k != l) if (k != l)
{ {
f = -sn * e[k - 1].Real; f = -sn * e[k - 1].Real;
@ -449,7 +449,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
Csrot(MatrixVT, matrixCopy.ColumnCount, k, m - 1, cs, sn); Csrot(VT, matrixCopy.ColumnCount, k, m - 1, cs, sn);
} }
} }
@ -461,14 +461,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
e[l - 1] = Complex32.Zero; e[l - 1] = Complex32.Zero;
for (k = l; k < m; k++) for (k = l; k < m; k++)
{ {
t1 = VectorS[k].Real; t1 = S[k].Real;
Srotg(ref t1, ref f, out cs, out sn); Srotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
f = -sn * e[k].Real; f = -sn * e[k].Real;
e[k] = cs * e[k]; e[k] = cs * e[k];
if (ComputeVectors) if (ComputeVectors)
{ {
Csrot(MatrixU, matrixCopy.RowCount, k, l - 1, cs, sn); Csrot(U, matrixCopy.RowCount, k, l - 1, cs, sn);
} }
} }
@ -478,15 +478,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
case 3: case 3:
// Calculate the shift. // Calculate the shift.
var scale = 0.0f; var scale = 0.0f;
scale = Math.Max(scale, VectorS[m - 1].Magnitude); scale = Math.Max(scale, S[m - 1].Magnitude);
scale = Math.Max(scale, VectorS[m - 2].Magnitude); scale = Math.Max(scale, S[m - 2].Magnitude);
scale = Math.Max(scale, e[m - 2].Magnitude); scale = Math.Max(scale, e[m - 2].Magnitude);
scale = Math.Max(scale, VectorS[l].Magnitude); scale = Math.Max(scale, S[l].Magnitude);
scale = Math.Max(scale, e[l].Magnitude); scale = Math.Max(scale, e[l].Magnitude);
var sm = VectorS[m - 1].Real / scale; var sm = S[m - 1].Real / scale;
var smm1 = VectorS[m - 2].Real / scale; var smm1 = S[m - 2].Real / scale;
var emm1 = e[m - 2].Real / scale; var emm1 = e[m - 2].Real / scale;
var sl = VectorS[l].Real / scale; var sl = S[l].Real / scale;
var el = e[l].Real / scale; var el = e[l].Real / scale;
var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0f; var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0f;
var c = (sm * emm1) * (sm * emm1); var c = (sm * emm1) * (sm * emm1);
@ -515,24 +515,24 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
e[k - 1] = f; e[k - 1] = f;
} }
f = (cs * VectorS[k].Real) + (sn * e[k].Real); f = (cs * S[k].Real) + (sn * e[k].Real);
e[k] = (cs * e[k]) - (sn * VectorS[k]); e[k] = (cs * e[k]) - (sn * S[k]);
g = sn * VectorS[k + 1].Real; g = sn * S[k + 1].Real;
VectorS[k + 1] = cs * VectorS[k + 1]; S[k + 1] = cs * S[k + 1];
if (ComputeVectors) if (ComputeVectors)
{ {
Csrot(MatrixVT, matrixCopy.ColumnCount, k, k + 1, cs, sn); Csrot(VT, matrixCopy.ColumnCount, k, k + 1, cs, sn);
} }
Srotg(ref f, ref g, out cs, out sn); Srotg(ref f, ref g, out cs, out sn);
VectorS[k] = f; S[k] = f;
f = (cs * e[k].Real) + (sn * VectorS[k + 1].Real); f = (cs * e[k].Real) + (sn * S[k + 1].Real);
VectorS[k + 1] = (-sn * e[k]) + (cs * VectorS[k + 1]); S[k + 1] = (-sn * e[k]) + (cs * S[k + 1]);
g = sn * e[k + 1].Real; g = sn * e[k + 1].Real;
e[k + 1] = cs * e[k + 1]; e[k + 1] = cs * e[k + 1];
if (ComputeVectors && k < matrixCopy.RowCount) if (ComputeVectors && k < matrixCopy.RowCount)
{ {
Csrot(MatrixU, matrixCopy.RowCount, k, k + 1, cs, sn); Csrot(U, matrixCopy.RowCount, k, k + 1, cs, sn);
} }
} }
@ -543,34 +543,34 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Convergence. // Convergence.
case 4: case 4:
// Make the singular value positive // Make the singular value positive
if (VectorS[l].Real < 0.0f) if (S[l].Real < 0.0f)
{ {
VectorS[l] = -VectorS[l]; S[l] = -S[l];
if (ComputeVectors) if (ComputeVectors)
{ {
CscalColumn(MatrixVT, matrixCopy.ColumnCount, l, 0, -1.0f); CscalColumn(VT, matrixCopy.ColumnCount, l, 0, -1.0f);
} }
} }
// Order the singular value. // Order the singular value.
while (l != mn - 1) while (l != mn - 1)
{ {
if (VectorS[l].Real >= VectorS[l + 1].Real) if (S[l].Real >= S[l + 1].Real)
{ {
break; break;
} }
t = VectorS[l]; t = S[l];
VectorS[l] = VectorS[l + 1]; S[l] = S[l + 1];
VectorS[l + 1] = t; S[l + 1] = t;
if (ComputeVectors && l < matrixCopy.ColumnCount) if (ComputeVectors && l < matrixCopy.ColumnCount)
{ {
Swap(MatrixVT, matrixCopy.ColumnCount, l, l + 1); Swap(VT, matrixCopy.ColumnCount, l, l + 1);
} }
if (ComputeVectors && l < matrixCopy.RowCount) if (ComputeVectors && l < matrixCopy.RowCount)
{ {
Swap(MatrixU, matrixCopy.RowCount, l, l + 1); Swap(U, matrixCopy.RowCount, l, l + 1);
} }
l = l + 1; l = l + 1;
@ -584,7 +584,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
MatrixVT = MatrixVT.ConjugateTranspose(); VT = VT.ConjugateTranspose();
} }
// Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses // Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses
@ -596,10 +596,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
var tmp = matrixCopy.CreateVector(nm); var tmp = matrixCopy.CreateVector(nm);
for (i = 0; i < nm; i++) for (i = 0; i < nm; i++)
{ {
tmp[i] = VectorS[i]; tmp[i] = S[i];
} }
VectorS = tmp; S = tmp;
} }
} }
@ -825,46 +825,46 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var bn = input.ColumnCount; var bn = input.ColumnCount;
var tmp = new Complex32[MatrixVT.ColumnCount]; var tmp = new Complex32[VT.ColumnCount];
for (var k = 0; k < bn; k++) for (var k = 0; k < bn; k++)
{ {
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex32.Zero; var value = Complex32.Zero;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j).Conjugate() * input.At(i, k); value += U.At(i, j).Conjugate() * input.At(i, k);
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex32.Zero; var value = Complex32.Zero;
for (var i = 0; i < MatrixVT.ColumnCount; i++) for (var i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j).Conjugate() * tmp[i]; value += VT.At(i, j).Conjugate() * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -896,41 +896,41 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var tmp = new Complex32[MatrixVT.ColumnCount]; var tmp = new Complex32[VT.ColumnCount];
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex32.Zero; var value = Complex32.Zero;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j).Conjugate() * input[i]; value += U.At(i, j).Conjugate() * input[i];
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
var value = Complex32.Zero; var value = Complex32.Zero;
for (var i = 0; i < MatrixVT.ColumnCount; i++) for (var i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j).Conjugate() * tmp[i]; value += VT.At(i, j).Conjugate() * tmp[i];
} }
result[j] = value; result[j] = value;

8
src/Numerics/LinearAlgebra/Double/Factorization/Cholesky.cs

@ -53,9 +53,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get get
{ {
var det = 1.0; var det = 1.0;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
var d = CholeskyFactor.At(j, j); var d = Factor.At(j, j);
det *= d * d; det *= d * d;
} }
@ -71,9 +71,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get get
{ {
var det = 0.0; var det = 0.0;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
det += 2 * Math.Log(CholeskyFactor.At(j, j)); det += 2 * Math.Log(Factor.At(j, j));
} }
return det; return det;

14
src/Numerics/LinearAlgebra/Double/Factorization/DenseCholesky.cs

@ -67,7 +67,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
var factor = (DenseMatrix)matrix.Clone(); var factor = (DenseMatrix)matrix.Clone();
Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount); Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount);
CholeskyFactor = factor; Factor = factor;
} }
/// <summary> /// <summary>
@ -99,9 +99,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseMatrix; var dinput = input as DenseMatrix;
@ -120,7 +120,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfDouble); Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfDouble);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount);
} }
@ -148,9 +148,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -169,7 +169,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfDouble); Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfDouble);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1);
} }
} }

34
src/Numerics/LinearAlgebra/Double/Factorization/DenseEvd.cs

@ -79,9 +79,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matrices for eigenvalues and eigenvectors // Initialize matrices for eigenvalues and eigenvectors
MatrixEv = matrix.CreateMatrix(order, order); EigenVectors = matrix.CreateMatrix(order, order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new LinearAlgebra.Complex.DenseVector(order); EigenValues = new LinearAlgebra.Complex.DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -93,8 +93,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
} }
Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) MatrixEv).Values, Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) EigenVectors).Values,
((LinearAlgebra.Complex.DenseVector)VectorEv).Values, ((DenseMatrix)MatrixD).Values); ((LinearAlgebra.Complex.DenseVector)EigenValues).Values, ((DenseMatrix)D).Values);
} }
/// <summary> /// <summary>
@ -1132,20 +1132,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new double[order]; var tmp = new double[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -1157,10 +1157,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i]*input.At(i, k); value += ((DenseMatrix) EigenVectors).Values[(j*order) + i]*input.At(i, k);
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1171,7 +1171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
double value = 0; double value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -1203,13 +1203,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -1217,7 +1217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VT * b; // Symmetric case -> x = V * inv(λ) * VT * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new double[order]; var tmp = new double[order];
double value; double value;
@ -1228,10 +1228,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i]*input[i]; value += ((DenseMatrix) EigenVectors).Values[(j*order) + i]*input[i];
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1242,7 +1242,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
value = 0; value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result[j] = value; result[j] = value;

18
src/Numerics/LinearAlgebra/Double/Factorization/DenseGramSchmidt.cs

@ -69,9 +69,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
Factorize(((DenseMatrix)MatrixQ).Values, MatrixQ.RowCount, MatrixQ.ColumnCount, ((DenseMatrix)MatrixR).Values); Factorize(((DenseMatrix)Q).Values, Q.RowCount, Q.ColumnCount, ((DenseMatrix)MatrixR).Values);
} }
/// <summary> /// <summary>
@ -149,13 +149,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -172,7 +172,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin);
} }
/// <summary> /// <summary>
@ -194,15 +194,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -217,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin);
} }
} }
} }

16
src/Numerics/LinearAlgebra/Double/Factorization/DenseQR.cs

@ -80,15 +80,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = new DenseMatrix(matrix.RowCount); Q = new DenseMatrix(matrix.RowCount);
Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixQ).Values, Tau); ((DenseMatrix)Q).Values, Tau);
} }
else else
{ {
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = new DenseMatrix(matrix.ColumnCount); MatrixR = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix) MatrixQ).Values, matrix.RowCount, Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix) Q).Values, matrix.RowCount,
matrix.ColumnCount, matrix.ColumnCount,
((DenseMatrix) MatrixR).Values, Tau); ((DenseMatrix) MatrixR).Values, Tau);
} }
@ -119,7 +119,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
@ -142,7 +142,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod);
} }
/// <summary> /// <summary>
@ -164,7 +164,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
@ -187,7 +187,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod);
} }
} }
} }

22
src/Numerics/LinearAlgebra/Double/Factorization/DenseSvd.cs

@ -66,10 +66,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
ComputeVectors = computeVectors; ComputeVectors = computeVectors;
var nm = Math.Min(matrix.RowCount, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount, matrix.ColumnCount);
VectorS = new DenseVector(nm); S = new DenseVector(nm);
MatrixU = new DenseMatrix(matrix.RowCount); U = new DenseMatrix(matrix.RowCount);
MatrixVT = new DenseMatrix(matrix.ColumnCount); VT = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values); Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values);
} }
/// <summary> /// <summary>
@ -102,13 +102,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -125,7 +125,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, input.ColumnCount, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, input.ColumnCount, dresult.Values);
} }
/// <summary> /// <summary>
@ -152,15 +152,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -175,7 +175,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, 1, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, 1, dresult.Values);
} }
} }
} }

14
src/Numerics/LinearAlgebra/Double/Factorization/Evd.cs

@ -59,11 +59,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get get
{ {
var det = Complex.One; var det = Complex.One;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
det *= VectorEv[i]; det *= EigenValues[i];
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
return 0; return 0;
} }
@ -82,9 +82,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get get
{ {
var rank = 0; var rank = 0;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
continue; continue;
} }
@ -104,9 +104,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
get get
{ {
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
return false; return false;
} }

12
src/Numerics/LinearAlgebra/Double/Factorization/Svd.cs

@ -59,7 +59,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
get get
{ {
return VectorS.Count(t => !Math.Abs(t).AlmostEqual(0.0)); return S.Count(t => !Math.Abs(t).AlmostEqual(0.0));
} }
} }
@ -71,7 +71,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
get get
{ {
return Math.Abs(VectorS[0]); return Math.Abs(S[0]);
} }
} }
@ -83,8 +83,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
get get
{ {
var tmp = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount) - 1; var tmp = Math.Min(U.RowCount, VT.ColumnCount) - 1;
return Math.Abs(VectorS[0]) / Math.Abs(VectorS[tmp]); return Math.Abs(S[0]) / Math.Abs(S[tmp]);
} }
} }
@ -95,13 +95,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
get get
{ {
if (MatrixU.RowCount != MatrixVT.ColumnCount) if (U.RowCount != VT.ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var det = 1.0; var det = 1.0;
foreach (var value in VectorS) foreach (var value in S)
{ {
det *= value; det *= value;
if (Math.Abs(value).AlmostEqual(0.0)) if (Math.Abs(value).AlmostEqual(0.0))

50
src/Numerics/LinearAlgebra/Double/Factorization/UserCholesky.cs

@ -66,40 +66,40 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
CholeskyFactor = matrix.Clone(); Factor = matrix.Clone();
var tmpColumn = new double[CholeskyFactor.RowCount]; var tmpColumn = new double[Factor.RowCount];
// Main loop - along the diagonal // Main loop - along the diagonal
for (var ij = 0; ij < CholeskyFactor.RowCount; ij++) for (var ij = 0; ij < Factor.RowCount; ij++)
{ {
// "Pivot" element // "Pivot" element
var tmpVal = CholeskyFactor.At(ij, ij); var tmpVal = Factor.At(ij, ij);
if (tmpVal > 0.0) if (tmpVal > 0.0)
{ {
tmpVal = Math.Sqrt(tmpVal); tmpVal = Math.Sqrt(tmpVal);
CholeskyFactor.At(ij, ij, tmpVal); Factor.At(ij, ij, tmpVal);
tmpColumn[ij] = tmpVal; tmpColumn[ij] = tmpVal;
// Calculate multipliers and copy to local column // Calculate multipliers and copy to local column
// Current column, below the diagonal // Current column, below the diagonal
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(i, ij, CholeskyFactor.At(i, ij) / tmpVal); Factor.At(i, ij, Factor.At(i, ij) / tmpVal);
tmpColumn[i] = CholeskyFactor.At(i, ij); tmpColumn[i] = Factor.At(i, ij);
} }
// Remaining columns, below the diagonal // Remaining columns, below the diagonal
DoCholeskyStep(CholeskyFactor, CholeskyFactor.RowCount, ij + 1, CholeskyFactor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads); DoCholeskyStep(Factor, Factor.RowCount, ij + 1, Factor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads);
} }
else else
{ {
throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
} }
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(ij, i, 0.0); Factor.At(ij, i, 0.0);
} }
} }
} }
@ -167,13 +167,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
for (var c = 0; c < result.ColumnCount; c++) for (var c = 0; c < result.ColumnCount; c++)
{ {
@ -184,10 +184,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result.At(k, c); sum -= Factor.At(i, k) * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -196,10 +196,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i) * result.At(k, c); sum -= Factor.At(k, i) * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
} }
} }
@ -228,13 +228,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
// Solve L*Y = B; // Solve L*Y = B;
double sum; double sum;
@ -243,10 +243,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
sum = result[i]; sum = result[i];
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result[k]; sum -= Factor.At(i, k) * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -255,10 +255,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
sum = result[i]; sum = result[i];
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i) * result[k]; sum -= Factor.At(k, i) * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
} }
} }

118
src/Numerics/LinearAlgebra/Double/Factorization/UserEvd.cs

@ -79,9 +79,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matricies for eigenvalues and eigenvectors // Initialize matricies for eigenvalues and eigenvectors
MatrixEv = matrix.CreateMatrix(order, order); EigenVectors = matrix.CreateMatrix(order, order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new LinearAlgebra.Complex.DenseVector(order); EigenValues = new LinearAlgebra.Complex.DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -98,8 +98,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
matrix.CopyTo(MatrixEv); matrix.CopyTo(EigenVectors);
d = MatrixEv.Row(order - 1).ToArray(); d = EigenVectors.Row(order - 1).ToArray();
SymmetricTridiagonalize(d, e, order); SymmetricTridiagonalize(d, e, order);
SymmetricDiagonalize(d, e, order); SymmetricDiagonalize(d, e, order);
@ -114,21 +114,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
MatrixD.At(i, i, d[i]); D.At(i, i, d[i]);
if (e[i] > 0) if (e[i] > 0)
{ {
MatrixD.At(i, i + 1, e[i]); D.At(i, i + 1, e[i]);
} }
else if (e[i] < 0) else if (e[i] < 0)
{ {
MatrixD.At(i, i - 1, e[i]); D.At(i, i - 1, e[i]);
} }
} }
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
VectorEv[i] = new Complex(d[i], e[i]); EigenValues[i] = new Complex(d[i], e[i]);
} }
} }
@ -161,9 +161,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
e[i] = d[i - 1]; e[i] = d[i - 1];
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)
{ {
d[j] = MatrixEv.At(i - 1, j); d[j] = EigenVectors.At(i - 1, j);
MatrixEv.At(i, j, 0.0); EigenVectors.At(i, j, 0.0);
MatrixEv.At(j, i, 0.0); EigenVectors.At(j, i, 0.0);
} }
} }
else else
@ -195,13 +195,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)
{ {
f = d[j]; f = d[j];
MatrixEv.At(j, i, f); EigenVectors.At(j, i, f);
g = e[j] + (MatrixEv.At(j, j) * f); g = e[j] + (EigenVectors.At(j, j) * f);
for (var k = j + 1; k <= i - 1; k++) for (var k = j + 1; k <= i - 1; k++)
{ {
g += MatrixEv.At(k, j) * d[k]; g += EigenVectors.At(k, j) * d[k];
e[k] += MatrixEv.At(k, j) * f; e[k] += EigenVectors.At(k, j) * f;
} }
e[j] = g; e[j] = g;
@ -229,11 +229,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (var k = j; k <= i - 1; k++) for (var k = j; k <= i - 1; k++)
{ {
MatrixEv.At(k, j, MatrixEv.At(k, j) - (f * e[k]) - (g * d[k])); EigenVectors.At(k, j, EigenVectors.At(k, j) - (f * e[k]) - (g * d[k]));
} }
d[j] = MatrixEv.At(i - 1, j); d[j] = EigenVectors.At(i - 1, j);
MatrixEv.At(i, j, 0.0); EigenVectors.At(i, j, 0.0);
} }
} }
@ -243,14 +243,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Accumulate transformations. // Accumulate transformations.
for (var i = 0; i < order - 1; i++) for (var i = 0; i < order - 1; i++)
{ {
MatrixEv.At(order - 1, i, MatrixEv.At(i, i)); EigenVectors.At(order - 1, i, EigenVectors.At(i, i));
MatrixEv.At(i, i, 1.0); EigenVectors.At(i, i, 1.0);
var h = d[i + 1]; var h = d[i + 1];
if (h != 0.0) if (h != 0.0)
{ {
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
d[k] = MatrixEv.At(k, i + 1) / h; d[k] = EigenVectors.At(k, i + 1) / h;
} }
for (var j = 0; j <= i; j++) for (var j = 0; j <= i; j++)
@ -258,29 +258,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var g = 0.0; var g = 0.0;
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
g += MatrixEv.At(k, i + 1) * MatrixEv.At(k, j); g += EigenVectors.At(k, i + 1) * EigenVectors.At(k, j);
} }
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
MatrixEv.At(k, j, MatrixEv.At(k, j) - g * d[k]); EigenVectors.At(k, j, EigenVectors.At(k, j) - g * d[k]);
} }
} }
} }
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
MatrixEv.At(k, i + 1, 0.0); EigenVectors.At(k, i + 1, 0.0);
} }
} }
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
d[j] = MatrixEv.At(order - 1, j); d[j] = EigenVectors.At(order - 1, j);
MatrixEv.At(order - 1, j, 0.0); EigenVectors.At(order - 1, j, 0.0);
} }
MatrixEv.At(order - 1, order - 1, 1.0); EigenVectors.At(order - 1, order - 1, 1.0);
e[0] = 0.0; e[0] = 0.0;
} }
@ -379,9 +379,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Accumulate transformation. // Accumulate transformation.
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
{ {
h = MatrixEv.At(k, i + 1); h = EigenVectors.At(k, i + 1);
MatrixEv.At(k, i + 1, (s * MatrixEv.At(k, i)) + (c * h)); EigenVectors.At(k, i + 1, (s * EigenVectors.At(k, i)) + (c * h));
MatrixEv.At(k, i, (c * MatrixEv.At(k, i)) - (s * h)); EigenVectors.At(k, i, (c * EigenVectors.At(k, i)) - (s * h));
} }
} }
@ -423,9 +423,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
d[i] = p; d[i] = p;
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
p = MatrixEv.At(j, i); p = EigenVectors.At(j, i);
MatrixEv.At(j, i, MatrixEv.At(j, k)); EigenVectors.At(j, i, EigenVectors.At(j, k));
MatrixEv.At(j, k, p); EigenVectors.At(j, k, p);
} }
} }
} }
@ -514,7 +514,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(i, j, i == j ? 1.0 : 0.0); EigenVectors.At(i, j, i == j ? 1.0 : 0.0);
} }
} }
@ -532,14 +532,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var g = 0.0; var g = 0.0;
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
g += ort[i] * MatrixEv.At(i, j); g += ort[i] * EigenVectors.At(i, j);
} }
// Double division avoids possible underflow // Double division avoids possible underflow
g = (g / ort[m]) / matrixH[m, m - 1]; g = (g / ort[m]) / matrixH[m, m - 1];
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
MatrixEv.At(i, j, MatrixEv.At(i, j) + g * ort[i]); EigenVectors.At(i, j, EigenVectors.At(i, j) + g * ort[i]);
} }
} }
} }
@ -669,9 +669,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Accumulate transformations // Accumulate transformations
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
z = MatrixEv.At(i, n - 1); z = EigenVectors.At(i, n - 1);
MatrixEv.At(i, n - 1, (q * z) + (p * MatrixEv.At(i, n))); EigenVectors.At(i, n - 1, (q * z) + (p * EigenVectors.At(i, n)));
MatrixEv.At(i, n, (q * MatrixEv.At(i, n)) - (p * z)); EigenVectors.At(i, n, (q * EigenVectors.At(i, n)) - (p * z));
} }
// Complex pair // Complex pair
@ -859,16 +859,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Accumulate transformations // Accumulate transformations
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
p = (x * MatrixEv.At(i, k)) + (y * MatrixEv.At(i, k + 1)); p = (x * EigenVectors.At(i, k)) + (y * EigenVectors.At(i, k + 1));
if (notlast) if (notlast)
{ {
p = p + (z * MatrixEv.At(i, k + 2)); p = p + (z * EigenVectors.At(i, k + 2));
MatrixEv.At(i, k + 2, MatrixEv.At(i, k + 2) - (p * r)); EigenVectors.At(i, k + 2, EigenVectors.At(i, k + 2) - (p * r));
} }
MatrixEv.At(i, k, MatrixEv.At(i, k) - p); EigenVectors.At(i, k, EigenVectors.At(i, k) - p);
MatrixEv.At(i, k + 1, MatrixEv.At(i, k + 1) - (p * q)); EigenVectors.At(i, k + 1, EigenVectors.At(i, k + 1) - (p * q));
} }
} // (s != 0) } // (s != 0)
} // k loop } // k loop
@ -1052,10 +1052,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
z = 0.0; z = 0.0;
for (var k = 0; k <= j; k++) for (var k = 0; k <= j; k++)
{ {
z = z + (MatrixEv.At(i, k) * matrixH[k, j]); z = z + (EigenVectors.At(i, k) * matrixH[k, j]);
} }
MatrixEv.At(i, j, z); EigenVectors.At(i, j, z);
} }
} }
} }
@ -1103,20 +1103,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new double[order]; var tmp = new double[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -1128,10 +1128,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j) * input.At(i, k); value += EigenVectors.At(i, j) * input.At(i, k);
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1142,7 +1142,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
double value = 0; double value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -1174,13 +1174,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -1188,7 +1188,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VT * b; // Symmetric case -> x = V * inv(λ) * VT * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new double[order]; var tmp = new double[order];
double value; double value;
@ -1199,10 +1199,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j) * input[i]; value += EigenVectors.At(i, j) * input[i];
} }
value /= VectorEv[j].Real; value /= EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1213,7 +1213,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
value = 0; value = 0;
for (int i = 0; i < order; i++) for (int i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result[j] = value; result[j] = value;

54
src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs

@ -62,31 +62,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
for (var k = 0; k < MatrixQ.ColumnCount; k++) for (var k = 0; k < Q.ColumnCount; k++)
{ {
var norm = MatrixQ.Column(k).L2Norm(); var norm = Q.Column(k).L2Norm();
if (norm == 0.0) if (norm == 0.0)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);
} }
MatrixR.At(k, k, norm); MatrixR.At(k, k, norm);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
MatrixQ.At(i, k, MatrixQ.At(i, k) / norm); Q.At(i, k, Q.At(i, k) / norm);
} }
for (var j = k + 1; j < MatrixQ.ColumnCount; j++) for (var j = k + 1; j < Q.ColumnCount; j++)
{ {
var dot = MatrixQ.Column(k).DotProduct(MatrixQ.Column(j)); var dot = Q.Column(k).DotProduct(Q.Column(j));
MatrixR.At(k, j, dot); MatrixR.At(k, j, dot);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
var value = MatrixQ.At(i, j) - (MatrixQ.At(i, k) * dot); var value = Q.At(i, j) - (Q.At(i, k) * dot);
MatrixQ.At(i, j, value); Q.At(i, j, value);
} }
} }
} }
@ -117,13 +117,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -131,20 +131,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new double[MatrixQ.RowCount]; var column = new double[Q.RowCount];
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy.At(k, j); column[k] = inputCopy.At(k, j);
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
double s = 0; double s = 0;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -152,7 +152,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
@ -196,39 +196,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new double[MatrixQ.RowCount]; var column = new double[Q.RowCount];
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy[k]; column[k] = inputCopy[k];
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
double s = 0; double s = 0;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
inputCopy[k] /= MatrixR.At(k, k); inputCopy[k] /= MatrixR.At(k, k);
for (var i = 0; i < k; i++) for (var i = 0; i < k; i++)

24
src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs

@ -73,11 +73,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); Q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount);
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
MatrixQ.At(i, i, 1.0); Q.At(i, i, 1.0);
} }
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
@ -89,33 +89,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.RowCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.RowCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
else else
{ {
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
MatrixQ = matrix.Clone(); Q = matrix.Clone();
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
{ {
u[i] = GenerateColumn(MatrixQ, i, i); u[i] = GenerateColumn(Q, i, i);
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i + 1, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i + 1, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
MatrixR = MatrixQ.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount); MatrixR = Q.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount);
MatrixQ.Clear(); Q.Clear();
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
MatrixQ.At(i, i, 1.0); Q.At(i, i, 1.0);
} }
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
@ -272,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
double s = 0; double s = 0;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -349,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
double s = 0; double s = 0;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;

186
src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs

@ -68,9 +68,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount);
var matrixCopy = matrix.Clone(); var matrixCopy = matrix.Clone();
VectorS = matrixCopy.CreateVector(nm); S = matrixCopy.CreateVector(nm);
MatrixU = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); U = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount);
MatrixVT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); VT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount);
const int maxiter = 1000; const int maxiter = 1000;
var e = new double[matrixCopy.ColumnCount]; var e = new double[matrixCopy.ColumnCount];
@ -94,26 +94,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
// Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l]. // Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l].
var xnorm = Dnrm2Column(matrixCopy, matrixCopy.RowCount, l, l); var xnorm = Dnrm2Column(matrixCopy, matrixCopy.RowCount, l, l);
VectorS[l] = xnorm; S[l] = xnorm;
if (VectorS[l] != 0.0) if (S[l] != 0.0)
{ {
if (matrixCopy.At(l, l) != 0.0) if (matrixCopy.At(l, l) != 0.0)
{ {
VectorS[l] = Dsign(VectorS[l], matrixCopy.At(l, l)); S[l] = Dsign(S[l], matrixCopy.At(l, l));
} }
DscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0 / VectorS[l]); DscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0 / S[l]);
matrixCopy.At(l, l, (1.0 + matrixCopy.At(l, l))); matrixCopy.At(l, l, (1.0 + matrixCopy.At(l, l)));
} }
VectorS[l] = -VectorS[l]; S[l] = -S[l];
} }
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
if (l < nct) if (l < nct)
{ {
if (VectorS[l] != 0.0) if (S[l] != 0.0)
{ {
// Apply the transformation. // Apply the transformation.
t = -Ddot(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l); t = -Ddot(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l);
@ -134,7 +134,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Place the transformation in u for subsequent back multiplication. // Place the transformation in u for subsequent back multiplication.
for (i = l; i < matrixCopy.RowCount; i++) for (i = l; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, matrixCopy.At(i, l)); U.At(i, l, matrixCopy.At(i, l));
} }
} }
@ -189,7 +189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Place the transformation in v for subsequent back multiplication. // Place the transformation in v for subsequent back multiplication.
for (i = lp1; i < matrixCopy.ColumnCount; i++) for (i = lp1; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, e[i]); VT.At(i, l, e[i]);
} }
} }
} }
@ -200,12 +200,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var nrtp1 = nrt + 1; var nrtp1 = nrt + 1;
if (nct < matrixCopy.ColumnCount) if (nct < matrixCopy.ColumnCount)
{ {
VectorS[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1)); S[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1));
} }
if (matrixCopy.RowCount < m) if (matrixCopy.RowCount < m)
{ {
VectorS[m - 1] = 0.0; S[m - 1] = 0.0;
} }
if (nrtp1 < m) if (nrtp1 < m)
@ -222,40 +222,40 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, j, 0.0); U.At(i, j, 0.0);
} }
MatrixU.At(j, j, 1.0); U.At(j, j, 1.0);
} }
for (l = nct - 1; l >= 0; l--) for (l = nct - 1; l >= 0; l--)
{ {
if (VectorS[l] != 0.0) if (S[l] != 0.0)
{ {
for (j = l + 1; j < ncu; j++) for (j = l + 1; j < ncu; j++)
{ {
t = -Ddot(MatrixU, matrixCopy.RowCount, l, j, l) / MatrixU.At(l, l); t = -Ddot(U, matrixCopy.RowCount, l, j, l) / U.At(l, l);
for (var ii = l; ii < matrixCopy.RowCount; ii++) for (var ii = l; ii < matrixCopy.RowCount; ii++)
{ {
MatrixU.At(ii, j, MatrixU.At(ii, j) + (t * MatrixU.At(ii, l))); U.At(ii, j, U.At(ii, j) + (t * U.At(ii, l)));
} }
} }
DscalColumn(MatrixU, matrixCopy.RowCount, l, l, -1.0); DscalColumn(U, matrixCopy.RowCount, l, l, -1.0);
MatrixU.At(l, l, 1.0 + MatrixU.At(l, l)); U.At(l, l, 1.0 + U.At(l, l));
for (i = 0; i < l; i++) for (i = 0; i < l; i++)
{ {
MatrixU.At(i, l, 0.0); U.At(i, l, 0.0);
} }
} }
else else
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, 0.0); U.At(i, l, 0.0);
} }
MatrixU.At(l, l, 1.0); U.At(l, l, 1.0);
} }
} }
} }
@ -272,10 +272,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
t = -Ddot(MatrixVT, matrixCopy.ColumnCount, l, j, lp1) / MatrixVT.At(lp1, l); t = -Ddot(VT, matrixCopy.ColumnCount, l, j, lp1) / VT.At(lp1, l);
for (var ii = l; ii < matrixCopy.ColumnCount; ii++) for (var ii = l; ii < matrixCopy.ColumnCount; ii++)
{ {
MatrixVT.At(ii, j, MatrixVT.At(ii, j) + (t * MatrixVT.At(ii, l))); VT.At(ii, j, VT.At(ii, j) + (t * VT.At(ii, l)));
} }
} }
} }
@ -283,10 +283,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (i = 0; i < matrixCopy.ColumnCount; i++) for (i = 0; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, 0.0); VT.At(i, l, 0.0);
} }
MatrixVT.At(l, l, 1.0); VT.At(l, l, 1.0);
} }
} }
@ -294,11 +294,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (i = 0; i < m; i++) for (i = 0; i < m; i++)
{ {
double r; double r;
if (VectorS[i] != 0.0) if (S[i] != 0.0)
{ {
t = VectorS[i]; t = S[i];
r = VectorS[i] / t; r = S[i] / t;
VectorS[i] = t; S[i] = t;
if (i < m - 1) if (i < m - 1)
{ {
e[i] = e[i] / r; e[i] = e[i] / r;
@ -306,7 +306,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
DscalColumn(MatrixU, matrixCopy.RowCount, i, 0, r); DscalColumn(U, matrixCopy.RowCount, i, 0, r);
} }
} }
@ -321,10 +321,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
t = e[i]; t = e[i];
r = t / e[i]; r = t / e[i];
e[i] = t; e[i] = t;
VectorS[i + 1] = VectorS[i + 1] * r; S[i + 1] = S[i + 1] * r;
if (ComputeVectors) if (ComputeVectors)
{ {
DscalColumn(MatrixVT, matrixCopy.ColumnCount, i + 1, 0, r); DscalColumn(VT, matrixCopy.ColumnCount, i + 1, 0, r);
} }
} }
} }
@ -352,7 +352,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
double test; double test;
for (l = m - 2; l >= 0; l--) for (l = m - 2; l >= 0; l--)
{ {
test = Math.Abs(VectorS[l]) + Math.Abs(VectorS[l + 1]); test = Math.Abs(S[l]) + Math.Abs(S[l + 1]);
ztest = test + Math.Abs(e[l]); ztest = test + Math.Abs(e[l]);
if (ztest.AlmostEqualInDecimalPlaces(test, 15)) if (ztest.AlmostEqualInDecimalPlaces(test, 15))
{ {
@ -382,10 +382,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
test = test + Math.Abs(e[ls - 1]); test = test + Math.Abs(e[ls - 1]);
} }
ztest = test + Math.Abs(VectorS[ls]); ztest = test + Math.Abs(S[ls]);
if (ztest.AlmostEqualInDecimalPlaces(test, 15)) if (ztest.AlmostEqualInDecimalPlaces(test, 15))
{ {
VectorS[ls] = 0.0; S[ls] = 0.0;
break; break;
} }
} }
@ -422,9 +422,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
for (var kk = l; kk < m - 1; kk++) for (var kk = l; kk < m - 1; kk++)
{ {
k = m - 2 - kk + l; k = m - 2 - kk + l;
t1 = VectorS[k]; t1 = S[k];
Drotg(ref t1, ref f, out cs, out sn); Drotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
if (k != l) if (k != l)
{ {
f = -sn * e[k - 1]; f = -sn * e[k - 1];
@ -433,7 +433,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
Drot(MatrixVT, matrixCopy.ColumnCount, k, m - 1, cs, sn); Drot(VT, matrixCopy.ColumnCount, k, m - 1, cs, sn);
} }
} }
@ -445,14 +445,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
e[l - 1] = 0.0; e[l - 1] = 0.0;
for (k = l; k < m; k++) for (k = l; k < m; k++)
{ {
t1 = VectorS[k]; t1 = S[k];
Drotg(ref t1, ref f, out cs, out sn); Drotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
f = -sn * e[k]; f = -sn * e[k];
e[k] = cs * e[k]; e[k] = cs * e[k];
if (ComputeVectors) if (ComputeVectors)
{ {
Drot(MatrixU, matrixCopy.RowCount, k, l - 1, cs, sn); Drot(U, matrixCopy.RowCount, k, l - 1, cs, sn);
} }
} }
@ -462,15 +462,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
case 3: case 3:
// Calculate the shift. // Calculate the shift.
var scale = 0.0; var scale = 0.0;
scale = Math.Max(scale, Math.Abs(VectorS[m - 1])); scale = Math.Max(scale, Math.Abs(S[m - 1]));
scale = Math.Max(scale, Math.Abs(VectorS[m - 2])); scale = Math.Max(scale, Math.Abs(S[m - 2]));
scale = Math.Max(scale, Math.Abs(e[m - 2])); scale = Math.Max(scale, Math.Abs(e[m - 2]));
scale = Math.Max(scale, Math.Abs(VectorS[l])); scale = Math.Max(scale, Math.Abs(S[l]));
scale = Math.Max(scale, Math.Abs(e[l])); scale = Math.Max(scale, Math.Abs(e[l]));
var sm = VectorS[m - 1] / scale; var sm = S[m - 1] / scale;
var smm1 = VectorS[m - 2] / scale; var smm1 = S[m - 2] / scale;
var emm1 = e[m - 2] / scale; var emm1 = e[m - 2] / scale;
var sl = VectorS[l] / scale; var sl = S[l] / scale;
var el = e[l] / scale; var el = e[l] / scale;
var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0; var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0;
var c = (sm * emm1) * (sm * emm1); var c = (sm * emm1) * (sm * emm1);
@ -498,24 +498,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
e[k - 1] = f; e[k - 1] = f;
} }
f = (cs * VectorS[k]) + (sn * e[k]); f = (cs * S[k]) + (sn * e[k]);
e[k] = (cs * e[k]) - (sn * VectorS[k]); e[k] = (cs * e[k]) - (sn * S[k]);
g = sn * VectorS[k + 1]; g = sn * S[k + 1];
VectorS[k + 1] = cs * VectorS[k + 1]; S[k + 1] = cs * S[k + 1];
if (ComputeVectors) if (ComputeVectors)
{ {
Drot(MatrixVT, matrixCopy.ColumnCount, k, k + 1, cs, sn); Drot(VT, matrixCopy.ColumnCount, k, k + 1, cs, sn);
} }
Drotg(ref f, ref g, out cs, out sn); Drotg(ref f, ref g, out cs, out sn);
VectorS[k] = f; S[k] = f;
f = (cs * e[k]) + (sn * VectorS[k + 1]); f = (cs * e[k]) + (sn * S[k + 1]);
VectorS[k + 1] = (-sn * e[k]) + (cs * VectorS[k + 1]); S[k + 1] = (-sn * e[k]) + (cs * S[k + 1]);
g = sn * e[k + 1]; g = sn * e[k + 1];
e[k + 1] = cs * e[k + 1]; e[k + 1] = cs * e[k + 1];
if (ComputeVectors && k < matrixCopy.RowCount) if (ComputeVectors && k < matrixCopy.RowCount)
{ {
Drot(MatrixU, matrixCopy.RowCount, k, k + 1, cs, sn); Drot(U, matrixCopy.RowCount, k, k + 1, cs, sn);
} }
} }
@ -526,34 +526,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Convergence. // Convergence.
case 4: case 4:
// Make the singular value positive // Make the singular value positive
if (VectorS[l] < 0.0) if (S[l] < 0.0)
{ {
VectorS[l] = -VectorS[l]; S[l] = -S[l];
if (ComputeVectors) if (ComputeVectors)
{ {
DscalColumn(MatrixVT, matrixCopy.ColumnCount, l, 0, -1.0); DscalColumn(VT, matrixCopy.ColumnCount, l, 0, -1.0);
} }
} }
// Order the singular value. // Order the singular value.
while (l != mn - 1) while (l != mn - 1)
{ {
if (VectorS[l] >= VectorS[l + 1]) if (S[l] >= S[l + 1])
{ {
break; break;
} }
t = VectorS[l]; t = S[l];
VectorS[l] = VectorS[l + 1]; S[l] = S[l + 1];
VectorS[l + 1] = t; S[l + 1] = t;
if (ComputeVectors && l < matrixCopy.ColumnCount) if (ComputeVectors && l < matrixCopy.ColumnCount)
{ {
Dswap(MatrixVT, matrixCopy.ColumnCount, l, l + 1); Dswap(VT, matrixCopy.ColumnCount, l, l + 1);
} }
if (ComputeVectors && l < matrixCopy.RowCount) if (ComputeVectors && l < matrixCopy.RowCount)
{ {
Dswap(MatrixU, matrixCopy.RowCount, l, l + 1); Dswap(U, matrixCopy.RowCount, l, l + 1);
} }
l = l + 1; l = l + 1;
@ -567,7 +567,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
MatrixVT = MatrixVT.Transpose(); VT = VT.Transpose();
} }
// Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses // Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses
@ -579,10 +579,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var tmp = matrixCopy.CreateVector(nm); var tmp = matrixCopy.CreateVector(nm);
for (i = 0; i < nm; i++) for (i = 0; i < nm; i++)
{ {
tmp[i] = VectorS[i]; tmp[i] = S[i];
} }
VectorS = tmp; S = tmp;
} }
} }
@ -808,46 +808,46 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var bn = input.ColumnCount; var bn = input.ColumnCount;
var tmp = new double[MatrixVT.ColumnCount]; var tmp = new double[VT.ColumnCount];
for (var k = 0; k < bn; k++) for (var k = 0; k < bn; k++)
{ {
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
double value = 0; double value = 0;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j) * input.At(i, k); value += U.At(i, j) * input.At(i, k);
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
double value = 0; double value = 0;
for (var i = 0; i < MatrixVT.ColumnCount; i++) for (var i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j) * tmp[i]; value += VT.At(i, j) * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -879,42 +879,42 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var tmp = new double[MatrixVT.ColumnCount]; var tmp = new double[VT.ColumnCount];
double value; double value;
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
value = 0; value = 0;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j) * input[i]; value += U.At(i, j) * input[i];
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
value = 0; value = 0;
for (int i = 0; i < MatrixVT.ColumnCount; i++) for (int i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j) * tmp[i]; value += VT.At(i, j) * tmp[i];
} }
result[j] = value; result[j] = value;

13
src/Numerics/LinearAlgebra/Factorization/Cholesky.cs

@ -45,21 +45,10 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
public abstract class Cholesky<T> : ISolver<T> public abstract class Cholesky<T> : ISolver<T>
where T : struct, IEquatable<T>, IFormattable where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary>
/// Gets or sets the lower triangular form of the Cholesky matrix
/// </summary>
protected Matrix<T> CholeskyFactor { get; set; }
/// <summary> /// <summary>
/// Gets the lower triangular form of the Cholesky matrix. /// Gets the lower triangular form of the Cholesky matrix.
/// </summary> /// </summary>
public virtual Matrix<T> Factor public Matrix<T> Factor { get; protected set; }
{
get
{
return CholeskyFactor.Clone();
}
}
/// <summary> /// <summary>
/// Gets the determinant of the matrix for which the Cholesky matrix was computed. /// Gets the determinant of the matrix for which the Cholesky matrix was computed.

31
src/Numerics/LinearAlgebra/Factorization/Evd.cs

@ -82,38 +82,17 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// <summary> /// <summary>
/// Gets or sets the eigen values (λ) of matrix in ascending value. /// Gets or sets the eigen values (λ) of matrix in ascending value.
/// </summary> /// </summary>
protected Vector<Complex> VectorEv { get; set; } public Vector<Complex> EigenValues { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets eigenvectors. /// Gets or sets eigenvectors.
/// </summary> /// </summary>
protected Matrix<T> MatrixEv { get; set; } public Matrix<T> EigenVectors { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets the block diagonal eigenvalue matrix. /// Gets or sets the block diagonal eigenvalue matrix.
/// </summary> /// </summary>
protected Matrix<T> MatrixD { get; set; } public Matrix<T> D { get; protected set; }
/// <summary>Returns the eigen values as a <see cref="Vector{T}"/>.</summary>
/// <returns>The eigen values.</returns>
public Vector<Complex> EigenValues()
{
return VectorEv.Clone();
}
/// <summary>Returns the right eigen vectors as a <see cref="Matrix{T}"/>.</summary>
/// <returns>The eigen vectors. </returns>
public Matrix<T> EigenVectors()
{
return MatrixEv.Clone();
}
/// <summary>Returns the block diagonal eigenvalue matrix <see cref="Matrix{T}"/>.</summary>
/// <returns>The block diagonal eigenvalue matrix <see cref="Matrix{T}"/>.</returns>
public Matrix<T> D()
{
return MatrixD.Clone();
}
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
@ -128,7 +107,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = MatrixEv.CreateMatrix(MatrixEv.ColumnCount, input.ColumnCount); var result = EigenVectors.CreateMatrix(EigenVectors.ColumnCount, input.ColumnCount);
Solve(input, result); Solve(input, result);
return result; return result;
} }
@ -153,7 +132,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var x = MatrixEv.CreateVector(MatrixEv.ColumnCount); var x = EigenVectors.CreateVector(EigenVectors.ColumnCount);
Solve(input, x); Solve(input, x);
return x; return x;
} }

20
src/Numerics/LinearAlgebra/Factorization/QR.cs

@ -63,7 +63,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// <summary> /// <summary>
/// Gets or sets orthogonal Q matrix /// Gets or sets orthogonal Q matrix
/// </summary> /// </summary>
protected Matrix<T> MatrixQ { get; set; } public Matrix<T> Q { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets upper triangular factor R /// Gets or sets upper triangular factor R
@ -75,26 +75,12 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// </summary> /// </summary>
protected QRMethod QrMethod { get; set; } protected QRMethod QrMethod { get; set; }
/// <summary>
/// Gets orthogonal Q matrix
/// </summary>
public virtual Matrix<T> Q
{
get
{
return MatrixQ.Clone();
}
}
/// <summary> /// <summary>
/// Gets the upper triangular factor R. /// Gets the upper triangular factor R.
/// </summary> /// </summary>
public virtual Matrix<T> R public Matrix<T> R
{ {
get get { return MatrixR.UpperTriangle(); }
{
return MatrixR.UpperTriangle();
}
} }
/// <summary> /// <summary>

40
src/Numerics/LinearAlgebra/Factorization/Svd.cs

@ -59,17 +59,17 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// <summary> /// <summary>
/// Gets or sets the singular values (Σ) of matrix in ascending value. /// Gets or sets the singular values (Σ) of matrix in ascending value.
/// </summary> /// </summary>
protected Vector<T> VectorS { get; set; } public Vector<T> S { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets left singular vectors (U - m-by-m unitary matrix) /// Gets or sets left singular vectors (U - m-by-m unitary matrix)
/// </summary> /// </summary>
protected Matrix<T> MatrixU { get; set; } public Matrix<T> U { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets transpose right singular vectors (transpose of V, an n-by-n unitary matrix /// Gets or sets transpose right singular vectors (transpose of V, an n-by-n unitary matrix
/// </summary> /// </summary>
protected Matrix<T> MatrixVT { get; set; } public Matrix<T> VT { get; protected set; }
/// <summary> /// <summary>
/// Gets the effective numerical matrix rank. /// Gets the effective numerical matrix rank.
@ -94,35 +94,20 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
/// </summary> /// </summary>
public abstract T Determinant { get; } public abstract T Determinant { get; }
/// <summary>Returns the left singular vectors as a <see cref="Matrix{T}"/>.</summary>
/// <returns>The left singular vectors. The matrix will be <c>null</c>, if <b>computeVectors</b> in the constructor is set to <c>false</c>.</returns>
public Matrix<T> U()
{
return ComputeVectors ? MatrixU.Clone() : null;
}
/// <summary>Returns the right singular vectors as a <see cref="Matrix{T}"/>.</summary>
/// <returns>The right singular vectors. The matrix will be <c>null</c>, if <b>computeVectors</b> in the constructor is set to <c>false</c>.</returns>
/// <remarks>This is the transpose of the V matrix.</remarks>
public Matrix<T> VT()
{
return ComputeVectors ? MatrixVT.Clone() : null;
}
/// <summary>Returns the singular values as a diagonal <see cref="Matrix{T}"/>.</summary> /// <summary>Returns the singular values as a diagonal <see cref="Matrix{T}"/>.</summary>
/// <returns>The singular values as a diagonal <see cref="Matrix{T}"/>.</returns> /// <returns>The singular values as a diagonal <see cref="Matrix{T}"/>.</returns>
public Matrix<T> W() public Matrix<T> W()
{ {
var rows = MatrixU.RowCount; var rows = U.RowCount;
var columns = MatrixVT.ColumnCount; var columns = VT.ColumnCount;
var result = MatrixU.CreateMatrix(rows, columns); var result = U.CreateMatrix(rows, columns);
for (var i = 0; i < rows; i++) for (var i = 0; i < rows; i++)
{ {
for (var j = 0; j < columns; j++) for (var j = 0; j < columns; j++)
{ {
if (i == j) if (i == j)
{ {
result.At(i, i, VectorS[i]); result.At(i, i, S[i]);
} }
} }
} }
@ -130,13 +115,6 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
return result; return result;
} }
/// <summary>Returns the singular values as a <see cref="Vector{T}"/>.</summary>
/// <returns>the singular values as a <see cref="Vector{T}"/>.</returns>
public Vector<T> S()
{
return VectorS.Clone();
}
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary> /// </summary>
@ -155,7 +133,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
throw new InvalidOperationException(Resources.SingularVectorsNotComputed); throw new InvalidOperationException(Resources.SingularVectorsNotComputed);
} }
var result = MatrixU.CreateMatrix(MatrixVT.ColumnCount, input.ColumnCount); var result = U.CreateMatrix(VT.ColumnCount, input.ColumnCount);
Solve(input, result); Solve(input, result);
return result; return result;
} }
@ -185,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
throw new InvalidOperationException(Resources.SingularVectorsNotComputed); throw new InvalidOperationException(Resources.SingularVectorsNotComputed);
} }
var x = MatrixU.CreateVector(MatrixVT.ColumnCount); var x = U.CreateVector(VT.ColumnCount);
Solve(input, x); Solve(input, x);
return x; return x;
} }

1
src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs

@ -29,7 +29,6 @@
// </copyright> // </copyright>
using System; using System;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties; using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra namespace MathNet.Numerics.LinearAlgebra

1
src/Numerics/LinearAlgebra/Matrix.cs

@ -28,7 +28,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.LinearAlgebra.Storage; using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties; using MathNet.Numerics.Properties;
using System; using System;

8
src/Numerics/LinearAlgebra/Single/Factorization/Cholesky.cs

@ -53,9 +53,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
get get
{ {
var det = 1.0f; var det = 1.0f;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
var d = CholeskyFactor.At(j, j); var d = Factor.At(j, j);
det *= d * d; det *= d * d;
} }
@ -71,9 +71,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
get get
{ {
var det = 0.0f; var det = 0.0f;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < Factor.RowCount; j++)
{ {
det += 2.0f * Convert.ToSingle(Math.Log(CholeskyFactor.At(j, j))); det += 2.0f * Convert.ToSingle(Math.Log(Factor.At(j, j)));
} }
return det; return det;

14
src/Numerics/LinearAlgebra/Single/Factorization/DenseCholesky.cs

@ -67,7 +67,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
var factor = (DenseMatrix)matrix.Clone(); var factor = (DenseMatrix)matrix.Clone();
Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount); Control.LinearAlgebraProvider.CholeskyFactor(factor.Values, factor.RowCount);
CholeskyFactor = factor; Factor = factor;
} }
/// <summary> /// <summary>
@ -99,9 +99,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseMatrix; var dinput = input as DenseMatrix;
@ -120,7 +120,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfFloat); Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfFloat);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, dresult.ColumnCount);
} }
@ -148,9 +148,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -169,7 +169,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfFloat); Buffer.BlockCopy(dinput.Values, 0, dresult.Values, 0, dinput.Values.Length * Constants.SizeOfFloat);
// Cholesky solve by overwriting result. // Cholesky solve by overwriting result.
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)Factor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Values, dfactor.RowCount, dresult.Values, 1);
} }
} }

34
src/Numerics/LinearAlgebra/Single/Factorization/DenseEvd.cs

@ -79,9 +79,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matrices for eigenvalues and eigenvectors // Initialize matrices for eigenvalues and eigenvectors
MatrixEv = matrix.CreateMatrix(order, order); EigenVectors = matrix.CreateMatrix(order, order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new LinearAlgebra.Complex.DenseVector(order); EigenValues = new LinearAlgebra.Complex.DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -93,8 +93,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
} }
Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) MatrixEv).Values, Control.LinearAlgebraProvider.EigenDecomp(IsSymmetric, order, matrix.Values, ((DenseMatrix) EigenVectors).Values,
((LinearAlgebra.Complex.DenseVector) VectorEv).Values, ((DenseMatrix) MatrixD).Values); ((LinearAlgebra.Complex.DenseVector) EigenValues).Values, ((DenseMatrix) D).Values);
} }
/// <summary> /// <summary>
@ -1132,20 +1132,20 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new float[order]; var tmp = new float[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -1157,10 +1157,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i]*input.At(i, k); value += ((DenseMatrix) EigenVectors).Values[(j*order) + i]*input.At(i, k);
} }
value /= (float) VectorEv[j].Real; value /= (float) EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1171,7 +1171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
float value = 0; float value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -1203,13 +1203,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -1217,7 +1217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VT * b; // Symmetric case -> x = V * inv(λ) * VT * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new float[order]; var tmp = new float[order];
float value; float value;
@ -1228,10 +1228,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(j*order) + i]*input[i]; value += ((DenseMatrix) EigenVectors).Values[(j*order) + i]*input[i];
} }
value /= (float) VectorEv[j].Real; value /= (float) EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1242,7 +1242,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
value = 0; value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += ((DenseMatrix) MatrixEv).Values[(i*order) + j]*tmp[i]; value += ((DenseMatrix) EigenVectors).Values[(i*order) + j]*tmp[i];
} }
result[j] = value; result[j] = value;

18
src/Numerics/LinearAlgebra/Single/Factorization/DenseGramSchmidt.cs

@ -69,9 +69,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
Factorize(((DenseMatrix)MatrixQ).Values, MatrixQ.RowCount, MatrixQ.ColumnCount, ((DenseMatrix)MatrixR).Values); Factorize(((DenseMatrix)Q).Values, Q.RowCount, Q.ColumnCount, ((DenseMatrix)MatrixR).Values);
} }
/// <summary> /// <summary>
@ -149,13 +149,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -172,7 +172,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense matrices at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, input.ColumnCount, dresult.Values, QRMethod.Thin);
} }
/// <summary> /// <summary>
@ -194,15 +194,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -217,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do GramSchmidt factorization for dense vectors at the moment.");
} }
_provider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin); _provider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, null, dinput.Values, 1, dresult.Values, QRMethod.Thin);
} }
} }
} }

16
src/Numerics/LinearAlgebra/Single/Factorization/DenseQR.cs

@ -80,15 +80,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = new DenseMatrix(matrix.RowCount); Q = new DenseMatrix(matrix.RowCount);
Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.QRFactor(((DenseMatrix)MatrixR).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixQ).Values, Tau); ((DenseMatrix)Q).Values, Tau);
} }
else else
{ {
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = new DenseMatrix(matrix.ColumnCount); MatrixR = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix)MatrixQ).Values, matrix.RowCount, matrix.ColumnCount, Control.LinearAlgebraProvider.ThinQRFactor(((DenseMatrix)Q).Values, matrix.RowCount, matrix.ColumnCount,
((DenseMatrix)MatrixR).Values, Tau); ((DenseMatrix)MatrixR).Values, Tau);
} }
} }
@ -118,7 +118,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
@ -141,7 +141,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do QR factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, input.ColumnCount, dresult.Values, QrMethod);
} }
/// <summary> /// <summary>
@ -163,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
@ -186,7 +186,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do QR factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Values, ((DenseMatrix)MatrixR).Values, MatrixQ.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)Q).Values, ((DenseMatrix)MatrixR).Values, Q.RowCount, MatrixR.ColumnCount, Tau, dinput.Values, 1, dresult.Values, QrMethod);
} }
} }
} }

22
src/Numerics/LinearAlgebra/Single/Factorization/DenseSvd.cs

@ -66,10 +66,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
ComputeVectors = computeVectors; ComputeVectors = computeVectors;
var nm = Math.Min(matrix.RowCount, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount, matrix.ColumnCount);
VectorS = new DenseVector(nm); S = new DenseVector(nm);
MatrixU = new DenseMatrix(matrix.RowCount); U = new DenseMatrix(matrix.RowCount);
MatrixVT = new DenseMatrix(matrix.ColumnCount); VT = new DenseMatrix(matrix.ColumnCount);
Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values); Control.LinearAlgebraProvider.SingularValueDecomposition(computeVectors, ((DenseMatrix)matrix.Clone()).Values, matrix.RowCount, matrix.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values);
} }
/// <summary> /// <summary>
@ -102,13 +102,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -125,7 +125,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense matrices at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, input.ColumnCount, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, input.ColumnCount, dresult.Values);
} }
/// <summary> /// <summary>
@ -152,15 +152,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var dinput = input as DenseVector; var dinput = input as DenseVector;
@ -175,7 +175,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment."); throw new NotSupportedException("Can only do SVD factorization for dense vectors at the moment.");
} }
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Values, ((DenseMatrix)MatrixU).Values, ((DenseMatrix)MatrixVT).Values, dinput.Values, 1, dresult.Values); Control.LinearAlgebraProvider.SvdSolveFactored(U.RowCount, VT.ColumnCount, ((DenseVector)S).Values, ((DenseMatrix)U).Values, ((DenseMatrix)VT).Values, dinput.Values, 1, dresult.Values);
} }
} }
} }

14
src/Numerics/LinearAlgebra/Single/Factorization/Evd.cs

@ -60,11 +60,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
get get
{ {
var det = Complex.One; var det = Complex.One;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
det *= VectorEv[i]; det *= EigenValues[i];
if (((Numerics.Complex32)VectorEv[i]).AlmostEqual(Numerics.Complex32.Zero)) if (((Numerics.Complex32)EigenValues[i]).AlmostEqual(Numerics.Complex32.Zero))
{ {
return 0; return 0;
} }
@ -83,9 +83,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
get get
{ {
var rank = 0; var rank = 0;
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (((Numerics.Complex32)VectorEv[i]).AlmostEqual(Numerics.Complex32.Zero)) if (((Numerics.Complex32)EigenValues[i]).AlmostEqual(Numerics.Complex32.Zero))
{ {
continue; continue;
} }
@ -105,9 +105,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
get get
{ {
for (var i = 0; i < VectorEv.Count; i++) for (var i = 0; i < EigenValues.Count; i++)
{ {
if (VectorEv[i].AlmostEqual(Complex.Zero)) if (EigenValues[i].AlmostEqual(Complex.Zero))
{ {
return false; return false;
} }

12
src/Numerics/LinearAlgebra/Single/Factorization/Svd.cs

@ -59,7 +59,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
get get
{ {
return VectorS.Count(t => !Math.Abs(t).AlmostEqual(0.0f)); return S.Count(t => !Math.Abs(t).AlmostEqual(0.0f));
} }
} }
@ -71,7 +71,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
get get
{ {
return Math.Abs(VectorS[0]); return Math.Abs(S[0]);
} }
} }
@ -83,8 +83,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
get get
{ {
var tmp = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount) - 1; var tmp = Math.Min(U.RowCount, VT.ColumnCount) - 1;
return Math.Abs(VectorS[0]) / Math.Abs(VectorS[tmp]); return Math.Abs(S[0]) / Math.Abs(S[tmp]);
} }
} }
@ -95,13 +95,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
get get
{ {
if (MatrixU.RowCount != MatrixVT.ColumnCount) if (U.RowCount != VT.ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var det = 1.0; var det = 1.0;
foreach (var value in VectorS) foreach (var value in S)
{ {
det *= value; det *= value;
if (Math.Abs(value).AlmostEqual(0.0f)) if (Math.Abs(value).AlmostEqual(0.0f))

50
src/Numerics/LinearAlgebra/Single/Factorization/UserCholesky.cs

@ -66,40 +66,40 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting). // Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
CholeskyFactor = matrix.Clone(); Factor = matrix.Clone();
var tmpColumn = new float[CholeskyFactor.RowCount]; var tmpColumn = new float[Factor.RowCount];
// Main loop - along the diagonal // Main loop - along the diagonal
for (var ij = 0; ij < CholeskyFactor.RowCount; ij++) for (var ij = 0; ij < Factor.RowCount; ij++)
{ {
// "Pivot" element // "Pivot" element
var tmpVal = CholeskyFactor.At(ij, ij); var tmpVal = Factor.At(ij, ij);
if (tmpVal > 0.0) if (tmpVal > 0.0)
{ {
tmpVal = (float)Math.Sqrt(tmpVal); tmpVal = (float)Math.Sqrt(tmpVal);
CholeskyFactor.At(ij, ij, tmpVal); Factor.At(ij, ij, tmpVal);
tmpColumn[ij] = tmpVal; tmpColumn[ij] = tmpVal;
// Calculate multipliers and copy to local column // Calculate multipliers and copy to local column
// Current column, below the diagonal // Current column, below the diagonal
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(i, ij, CholeskyFactor.At(i, ij) / tmpVal); Factor.At(i, ij, Factor.At(i, ij) / tmpVal);
tmpColumn[i] = CholeskyFactor.At(i, ij); tmpColumn[i] = Factor.At(i, ij);
} }
// Remaining columns, below the diagonal // Remaining columns, below the diagonal
DoCholeskyStep(CholeskyFactor, CholeskyFactor.RowCount, ij + 1, CholeskyFactor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads); DoCholeskyStep(Factor, Factor.RowCount, ij + 1, Factor.RowCount, tmpColumn, Control.NumberOfParallelWorkerThreads);
} }
else else
{ {
throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
} }
for (var i = ij + 1; i < CholeskyFactor.RowCount; i++) for (var i = ij + 1; i < Factor.RowCount; i++)
{ {
CholeskyFactor.At(ij, i, 0.0f); Factor.At(ij, i, 0.0f);
} }
} }
} }
@ -167,13 +167,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (input.RowCount != CholeskyFactor.RowCount) if (input.RowCount != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
for (var c = 0; c < result.ColumnCount; c++) for (var c = 0; c < result.ColumnCount; c++)
{ {
@ -184,10 +184,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result.At(k, c); sum -= Factor.At(i, k) * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -196,10 +196,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
sum = result.At(i, c); sum = result.At(i, c);
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i) * result.At(k, c); sum -= Factor.At(k, i) * result.At(k, c);
} }
result.At(i, c, sum / CholeskyFactor.At(i, i)); result.At(i, c, sum / Factor.At(i, i));
} }
} }
} }
@ -228,13 +228,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
if (input.Count != CholeskyFactor.RowCount) if (input.Count != Factor.RowCount)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(input, CholeskyFactor); throw Matrix.DimensionsDontMatch<ArgumentException>(input, Factor);
} }
input.CopyTo(result); input.CopyTo(result);
var order = CholeskyFactor.RowCount; var order = Factor.RowCount;
// Solve L*Y = B; // Solve L*Y = B;
float sum; float sum;
@ -243,10 +243,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
sum = result[i]; sum = result[i];
for (var k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
sum -= CholeskyFactor.At(i, k) * result[k]; sum -= Factor.At(i, k) * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
// Solve L'*X = Y; // Solve L'*X = Y;
@ -255,10 +255,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
sum = result[i]; sum = result[i];
for (var k = i + 1; k < order; k++) for (var k = i + 1; k < order; k++)
{ {
sum -= CholeskyFactor.At(k, i) * result[k]; sum -= Factor.At(k, i) * result[k];
} }
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / Factor.At(i, i);
} }
} }
} }

118
src/Numerics/LinearAlgebra/Single/Factorization/UserEvd.cs

@ -78,9 +78,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var order = matrix.RowCount; var order = matrix.RowCount;
// Initialize matricies for eigenvalues and eigenvectors // Initialize matricies for eigenvalues and eigenvectors
MatrixEv = matrix.CreateMatrix(order, order); EigenVectors = matrix.CreateMatrix(order, order);
MatrixD = matrix.CreateMatrix(order, order); D = matrix.CreateMatrix(order, order);
VectorEv = new LinearAlgebra.Complex.DenseVector(order); EigenValues = new LinearAlgebra.Complex.DenseVector(order);
IsSymmetric = true; IsSymmetric = true;
@ -97,8 +97,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
matrix.CopyTo(MatrixEv); matrix.CopyTo(EigenVectors);
d = MatrixEv.Row(order - 1).ToArray(); d = EigenVectors.Row(order - 1).ToArray();
SymmetricTridiagonalize(d, e, order); SymmetricTridiagonalize(d, e, order);
SymmetricDiagonalize(d, e, order); SymmetricDiagonalize(d, e, order);
@ -113,21 +113,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
MatrixD.At(i, i, d[i]); D.At(i, i, d[i]);
if (e[i] > 0) if (e[i] > 0)
{ {
MatrixD.At(i, i + 1, e[i]); D.At(i, i + 1, e[i]);
} }
else if (e[i] < 0) else if (e[i] < 0)
{ {
MatrixD.At(i, i - 1, e[i]); D.At(i, i - 1, e[i]);
} }
} }
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
VectorEv[i] = new Complex(d[i], e[i]); EigenValues[i] = new Complex(d[i], e[i]);
} }
} }
@ -160,9 +160,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
e[i] = d[i - 1]; e[i] = d[i - 1];
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)
{ {
d[j] = MatrixEv.At(i - 1, j); d[j] = EigenVectors.At(i - 1, j);
MatrixEv.At(i, j, 0.0f); EigenVectors.At(i, j, 0.0f);
MatrixEv.At(j, i, 0.0f); EigenVectors.At(j, i, 0.0f);
} }
} }
else else
@ -194,13 +194,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)
{ {
f = d[j]; f = d[j];
MatrixEv.At(j, i, f); EigenVectors.At(j, i, f);
g = e[j] + (MatrixEv.At(j, j) * f); g = e[j] + (EigenVectors.At(j, j) * f);
for (var k = j + 1; k <= i - 1; k++) for (var k = j + 1; k <= i - 1; k++)
{ {
g += MatrixEv.At(k, j) * d[k]; g += EigenVectors.At(k, j) * d[k];
e[k] += MatrixEv.At(k, j) * f; e[k] += EigenVectors.At(k, j) * f;
} }
e[j] = g; e[j] = g;
@ -228,11 +228,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (var k = j; k <= i - 1; k++) for (var k = j; k <= i - 1; k++)
{ {
MatrixEv.At(k, j, MatrixEv.At(k, j) - (f * e[k]) - (g * d[k])); EigenVectors.At(k, j, EigenVectors.At(k, j) - (f * e[k]) - (g * d[k]));
} }
d[j] = MatrixEv.At(i - 1, j); d[j] = EigenVectors.At(i - 1, j);
MatrixEv.At(i, j, 0.0f); EigenVectors.At(i, j, 0.0f);
} }
} }
@ -242,14 +242,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Accumulate transformations. // Accumulate transformations.
for (var i = 0; i < order - 1; i++) for (var i = 0; i < order - 1; i++)
{ {
MatrixEv.At(order - 1, i, MatrixEv.At(i, i)); EigenVectors.At(order - 1, i, EigenVectors.At(i, i));
MatrixEv.At(i, i, 1.0f); EigenVectors.At(i, i, 1.0f);
var h = d[i + 1]; var h = d[i + 1];
if (h != 0.0f) if (h != 0.0f)
{ {
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
d[k] = MatrixEv.At(k, i + 1) / h; d[k] = EigenVectors.At(k, i + 1) / h;
} }
for (var j = 0; j <= i; j++) for (var j = 0; j <= i; j++)
@ -257,29 +257,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var g = 0.0f; var g = 0.0f;
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
g += MatrixEv.At(k, i + 1) * MatrixEv.At(k, j); g += EigenVectors.At(k, i + 1) * EigenVectors.At(k, j);
} }
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
MatrixEv.At(k, j, MatrixEv.At(k, j) - g * d[k]); EigenVectors.At(k, j, EigenVectors.At(k, j) - g * d[k]);
} }
} }
} }
for (var k = 0; k <= i; k++) for (var k = 0; k <= i; k++)
{ {
MatrixEv.At(k, i + 1, 0.0f); EigenVectors.At(k, i + 1, 0.0f);
} }
} }
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
d[j] = MatrixEv.At(order - 1, j); d[j] = EigenVectors.At(order - 1, j);
MatrixEv.At(order - 1, j, 0.0f); EigenVectors.At(order - 1, j, 0.0f);
} }
MatrixEv.At(order - 1, order - 1, 1.0f); EigenVectors.At(order - 1, order - 1, 1.0f);
e[0] = 0.0f; e[0] = 0.0f;
} }
@ -378,9 +378,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Accumulate transformation. // Accumulate transformation.
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
{ {
h = MatrixEv.At(k, i + 1); h = EigenVectors.At(k, i + 1);
MatrixEv.At(k, i + 1, (s * MatrixEv.At(k, i)) + (c * h)); EigenVectors.At(k, i + 1, (s * EigenVectors.At(k, i)) + (c * h));
MatrixEv.At(k, i, (c * MatrixEv.At(k, i)) - (s * h)); EigenVectors.At(k, i, (c * EigenVectors.At(k, i)) - (s * h));
} }
} }
@ -422,9 +422,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
d[i] = p; d[i] = p;
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
p = MatrixEv.At(j, i); p = EigenVectors.At(j, i);
MatrixEv.At(j, i, MatrixEv.At(j, k)); EigenVectors.At(j, i, EigenVectors.At(j, k));
MatrixEv.At(j, k, p); EigenVectors.At(j, k, p);
} }
} }
} }
@ -513,7 +513,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (var j = 0; j < order; j++) for (var j = 0; j < order; j++)
{ {
MatrixEv.At(i, j, i == j ? 1.0f : 0.0f); EigenVectors.At(i, j, i == j ? 1.0f : 0.0f);
} }
} }
@ -531,14 +531,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var g = 0.0f; var g = 0.0f;
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
g += ort[i] * MatrixEv.At(i, j); g += ort[i] * EigenVectors.At(i, j);
} }
// Double division avoids possible underflow // Double division avoids possible underflow
g = (g / ort[m]) / matrixH[m, m - 1]; g = (g / ort[m]) / matrixH[m, m - 1];
for (var i = m; i < order; i++) for (var i = m; i < order; i++)
{ {
MatrixEv.At(i, j, MatrixEv.At(i, j) + g * ort[i]); EigenVectors.At(i, j, EigenVectors.At(i, j) + g * ort[i]);
} }
} }
} }
@ -668,9 +668,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Accumulate transformations // Accumulate transformations
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
z = MatrixEv.At(i, n - 1); z = EigenVectors.At(i, n - 1);
MatrixEv.At(i, n - 1, (q * z) + (p * MatrixEv.At(i, n))); EigenVectors.At(i, n - 1, (q * z) + (p * EigenVectors.At(i, n)));
MatrixEv.At(i, n, (q * MatrixEv.At(i, n)) - (p * z)); EigenVectors.At(i, n, (q * EigenVectors.At(i, n)) - (p * z));
} }
// Complex pair // Complex pair
@ -858,16 +858,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Accumulate transformations // Accumulate transformations
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
p = (x * MatrixEv.At(i, k)) + (y * MatrixEv.At(i, k + 1)); p = (x * EigenVectors.At(i, k)) + (y * EigenVectors.At(i, k + 1));
if (notlast) if (notlast)
{ {
p = p + (z * MatrixEv.At(i, k + 2)); p = p + (z * EigenVectors.At(i, k + 2));
MatrixEv.At(i, k + 2, MatrixEv.At(i, k + 2) - (p * r)); EigenVectors.At(i, k + 2, EigenVectors.At(i, k + 2) - (p * r));
} }
MatrixEv.At(i, k, MatrixEv.At(i, k) - p); EigenVectors.At(i, k, EigenVectors.At(i, k) - p);
MatrixEv.At(i, k + 1, MatrixEv.At(i, k + 1) - (p * q)); EigenVectors.At(i, k + 1, EigenVectors.At(i, k + 1) - (p * q));
} }
} // (s != 0) } // (s != 0)
} // k loop } // k loop
@ -1051,10 +1051,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
z = 0.0f; z = 0.0f;
for (var k = 0; k <= j; k++) for (var k = 0; k <= j; k++)
{ {
z = z + (MatrixEv.At(i, k) * matrixH[k, j]); z = z + (EigenVectors.At(i, k) * matrixH[k, j]);
} }
MatrixEv.At(i, j, z); EigenVectors.At(i, j, z);
} }
} }
} }
@ -1102,20 +1102,20 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (VectorEv.Count != input.RowCount) if (EigenValues.Count != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (VectorEv.Count != result.RowCount) if (EigenValues.Count != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
if (IsSymmetric) if (IsSymmetric)
{ {
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new float[order]; var tmp = new float[order];
for (var k = 0; k < order; k++) for (var k = 0; k < order; k++)
@ -1127,10 +1127,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j) * input.At(i, k); value += EigenVectors.At(i, j) * input.At(i, k);
} }
value /= (float)VectorEv[j].Real; value /= (float)EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1141,7 +1141,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
float value = 0; float value = 0;
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -1173,13 +1173,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x m matrix // Ax=b where A is an m x m matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (VectorEv.Count != input.Count) if (EigenValues.Count != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (VectorEv.Count != result.Count) if (EigenValues.Count != result.Count)
{ {
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (IsSymmetric) if (IsSymmetric)
{ {
// Symmetric case -> x = V * inv(λ) * VT * b; // Symmetric case -> x = V * inv(λ) * VT * b;
var order = VectorEv.Count; var order = EigenValues.Count;
var tmp = new float[order]; var tmp = new float[order];
float value; float value;
@ -1198,10 +1198,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
value += MatrixEv.At(i, j) * input[i]; value += EigenVectors.At(i, j) * input[i];
} }
value /= (float)VectorEv[j].Real; value /= (float)EigenValues[j].Real;
} }
tmp[j] = value; tmp[j] = value;
@ -1212,7 +1212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
value = 0; value = 0;
for (int i = 0; i < order; i++) for (int i = 0; i < order; i++)
{ {
value += MatrixEv.At(j, i) * tmp[i]; value += EigenVectors.At(j, i) * tmp[i];
} }
result[j] = value; result[j] = value;

54
src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs

@ -62,31 +62,31 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix); throw Matrix.DimensionsDontMatch<ArgumentException>(matrix);
} }
MatrixQ = matrix.Clone(); Q = matrix.Clone();
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
for (var k = 0; k < MatrixQ.ColumnCount; k++) for (var k = 0; k < Q.ColumnCount; k++)
{ {
var norm = MatrixQ.Column(k).L2Norm(); var norm = Q.Column(k).L2Norm();
if (norm == 0.0) if (norm == 0.0)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);
} }
MatrixR.At(k, k, norm); MatrixR.At(k, k, norm);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
MatrixQ.At(i, k, MatrixQ.At(i, k) / norm); Q.At(i, k, Q.At(i, k) / norm);
} }
for (var j = k + 1; j < MatrixQ.ColumnCount; j++) for (var j = k + 1; j < Q.ColumnCount; j++)
{ {
var dot = MatrixQ.Column(k).DotProduct(MatrixQ.Column(j)); var dot = Q.Column(k).DotProduct(Q.Column(j));
MatrixR.At(k, j, dot); MatrixR.At(k, j, dot);
for (var i = 0; i < MatrixQ.RowCount; i++) for (var i = 0; i < Q.RowCount; i++)
{ {
var value = MatrixQ.At(i, j) - (MatrixQ.At(i, k) * dot); var value = Q.At(i, j) - (Q.At(i, k) * dot);
MatrixQ.At(i, j, value); Q.At(i, j, value);
} }
} }
} }
@ -117,13 +117,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixQ.RowCount != input.RowCount) if (Q.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixQ.ColumnCount != result.RowCount) if (Q.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
@ -131,20 +131,20 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new float[MatrixQ.RowCount]; var column = new float[Q.RowCount];
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy.At(k, j); column[k] = inputCopy.At(k, j);
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
float s = 0; float s = 0;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -152,7 +152,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
for (var j = 0; j < input.ColumnCount; j++) for (var j = 0; j < input.ColumnCount; j++)
{ {
@ -196,39 +196,39 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixQ.RowCount != input.Count) if (Q.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixQ.ColumnCount != result.Count) if (Q.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixQ, result); throw Matrix.DimensionsDontMatch<ArgumentException>(Q, result);
} }
var inputCopy = input.Clone(); var inputCopy = input.Clone();
// Compute Y = transpose(Q)*B // Compute Y = transpose(Q)*B
var column = new float[MatrixQ.RowCount]; var column = new float[Q.RowCount];
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
column[k] = inputCopy[k]; column[k] = inputCopy[k];
} }
for (var i = 0; i < MatrixQ.ColumnCount; i++) for (var i = 0; i < Q.ColumnCount; i++)
{ {
float s = 0; float s = 0;
for (var k = 0; k < MatrixQ.RowCount; k++) for (var k = 0; k < Q.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;
} }
// Solve R*X = Y; // Solve R*X = Y;
for (var k = MatrixQ.ColumnCount - 1; k >= 0; k--) for (var k = Q.ColumnCount - 1; k >= 0; k--)
{ {
inputCopy[k] /= MatrixR.At(k, k); inputCopy[k] /= MatrixR.At(k, k);
for (var i = 0; i < k; i++) for (var i = 0; i < k; i++)

24
src/Numerics/LinearAlgebra/Single/Factorization/UserQR.cs

@ -73,11 +73,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (method == QRMethod.Full) if (method == QRMethod.Full)
{ {
MatrixR = matrix.Clone(); MatrixR = matrix.Clone();
MatrixQ = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount); Q = matrix.CreateMatrix(matrix.RowCount, matrix.RowCount);
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
MatrixQ.At(i, i, 1.0f); Q.At(i, i, 1.0f);
} }
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
@ -89,33 +89,33 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.RowCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.RowCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
else else
{ {
MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount);
MatrixQ = matrix.Clone(); Q = matrix.Clone();
for (var i = 0; i < minmn; i++) for (var i = 0; i < minmn; i++)
{ {
u[i] = GenerateColumn(MatrixQ, i, i); u[i] = GenerateColumn(Q, i, i);
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i + 1, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i + 1, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
MatrixR = MatrixQ.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount); MatrixR = Q.SubMatrix(0, matrix.ColumnCount, 0, matrix.ColumnCount);
MatrixQ.Clear(); Q.Clear();
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
MatrixQ.At(i, i, 1.0f); Q.At(i, i, 1.0f);
} }
for (var i = minmn - 1; i >= 0; i--) for (var i = minmn - 1; i >= 0; i--)
{ {
ComputeQR(u[i], MatrixQ, i, matrix.RowCount, i, matrix.ColumnCount, ComputeQR(u[i], Q, i, matrix.RowCount, i, matrix.ColumnCount,
Control.NumberOfParallelWorkerThreads); Control.NumberOfParallelWorkerThreads);
} }
} }
@ -271,7 +271,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
float s = 0; float s = 0;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy.At(i, j, s); inputCopy.At(i, j, s);
@ -348,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
float s = 0; float s = 0;
for (var k = 0; k < MatrixR.RowCount; k++) for (var k = 0; k < MatrixR.RowCount; k++)
{ {
s += MatrixQ.At(k, i) * column[k]; s += Q.At(k, i) * column[k];
} }
inputCopy[i] = s; inputCopy[i] = s;

186
src/Numerics/LinearAlgebra/Single/Factorization/UserSvd.cs

@ -68,9 +68,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount); var nm = Math.Min(matrix.RowCount + 1, matrix.ColumnCount);
var matrixCopy = matrix.Clone(); var matrixCopy = matrix.Clone();
VectorS = matrixCopy.CreateVector(nm); S = matrixCopy.CreateVector(nm);
MatrixU = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount); U = matrixCopy.CreateMatrix(matrixCopy.RowCount, matrixCopy.RowCount);
MatrixVT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount); VT = matrixCopy.CreateMatrix(matrixCopy.ColumnCount, matrixCopy.ColumnCount);
const int maxiter = 1000; const int maxiter = 1000;
var e = new float[matrixCopy.ColumnCount]; var e = new float[matrixCopy.ColumnCount];
@ -94,26 +94,26 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
// Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l]. // Compute the transformation for the l-th column and place the l-th diagonal in VectorS[l].
var xnorm = Dnrm2Column(matrixCopy, matrixCopy.RowCount, l, l); var xnorm = Dnrm2Column(matrixCopy, matrixCopy.RowCount, l, l);
VectorS[l] = xnorm; S[l] = xnorm;
if (VectorS[l] != 0.0) if (S[l] != 0.0)
{ {
if (matrixCopy.At(l, l) != 0.0) if (matrixCopy.At(l, l) != 0.0)
{ {
VectorS[l] = Dsign(VectorS[l], matrixCopy.At(l, l)); S[l] = Dsign(S[l], matrixCopy.At(l, l));
} }
DscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0f / VectorS[l]); DscalColumn(matrixCopy, matrixCopy.RowCount, l, l, 1.0f / S[l]);
matrixCopy.At(l, l, (1.0f + matrixCopy.At(l, l))); matrixCopy.At(l, l, (1.0f + matrixCopy.At(l, l)));
} }
VectorS[l] = -VectorS[l]; S[l] = -S[l];
} }
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
if (l < nct) if (l < nct)
{ {
if (VectorS[l] != 0.0) if (S[l] != 0.0)
{ {
// Apply the transformation. // Apply the transformation.
t = -Ddot(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l); t = -Ddot(matrixCopy, matrixCopy.RowCount, l, j, l) / matrixCopy.At(l, l);
@ -134,7 +134,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Place the transformation in u for subsequent back multiplication. // Place the transformation in u for subsequent back multiplication.
for (i = l; i < matrixCopy.RowCount; i++) for (i = l; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, matrixCopy.At(i, l)); U.At(i, l, matrixCopy.At(i, l));
} }
} }
@ -189,7 +189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Place the transformation in v for subsequent back multiplication. // Place the transformation in v for subsequent back multiplication.
for (i = lp1; i < matrixCopy.ColumnCount; i++) for (i = lp1; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, e[i]); VT.At(i, l, e[i]);
} }
} }
} }
@ -200,12 +200,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var nrtp1 = nrt + 1; var nrtp1 = nrt + 1;
if (nct < matrixCopy.ColumnCount) if (nct < matrixCopy.ColumnCount)
{ {
VectorS[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1)); S[nctp1 - 1] = matrixCopy.At((nctp1 - 1), (nctp1 - 1));
} }
if (matrixCopy.RowCount < m) if (matrixCopy.RowCount < m)
{ {
VectorS[m - 1] = 0.0f; S[m - 1] = 0.0f;
} }
if (nrtp1 < m) if (nrtp1 < m)
@ -222,40 +222,40 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, j, 0.0f); U.At(i, j, 0.0f);
} }
MatrixU.At(j, j, 1.0f); U.At(j, j, 1.0f);
} }
for (l = nct - 1; l >= 0; l--) for (l = nct - 1; l >= 0; l--)
{ {
if (VectorS[l] != 0.0) if (S[l] != 0.0)
{ {
for (j = l + 1; j < ncu; j++) for (j = l + 1; j < ncu; j++)
{ {
t = -Ddot(MatrixU, matrixCopy.RowCount, l, j, l) / MatrixU.At(l, l); t = -Ddot(U, matrixCopy.RowCount, l, j, l) / U.At(l, l);
for (var ii = l; ii < matrixCopy.RowCount; ii++) for (var ii = l; ii < matrixCopy.RowCount; ii++)
{ {
MatrixU.At(ii, j, MatrixU.At(ii, j) + (t * MatrixU.At(ii, l))); U.At(ii, j, U.At(ii, j) + (t * U.At(ii, l)));
} }
} }
DscalColumn(MatrixU, matrixCopy.RowCount, l, l, -1.0f); DscalColumn(U, matrixCopy.RowCount, l, l, -1.0f);
MatrixU.At(l, l, 1.0f + MatrixU.At(l, l)); U.At(l, l, 1.0f + U.At(l, l));
for (i = 0; i < l; i++) for (i = 0; i < l; i++)
{ {
MatrixU.At(i, l, 0.0f); U.At(i, l, 0.0f);
} }
} }
else else
{ {
for (i = 0; i < matrixCopy.RowCount; i++) for (i = 0; i < matrixCopy.RowCount; i++)
{ {
MatrixU.At(i, l, 0.0f); U.At(i, l, 0.0f);
} }
MatrixU.At(l, l, 1.0f); U.At(l, l, 1.0f);
} }
} }
} }
@ -272,10 +272,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
for (j = lp1; j < matrixCopy.ColumnCount; j++) for (j = lp1; j < matrixCopy.ColumnCount; j++)
{ {
t = -Ddot(MatrixVT, matrixCopy.ColumnCount, l, j, lp1) / MatrixVT.At(lp1, l); t = -Ddot(VT, matrixCopy.ColumnCount, l, j, lp1) / VT.At(lp1, l);
for (var ii = l; ii < matrixCopy.ColumnCount; ii++) for (var ii = l; ii < matrixCopy.ColumnCount; ii++)
{ {
MatrixVT.At(ii, j, MatrixVT.At(ii, j) + (t * MatrixVT.At(ii, l))); VT.At(ii, j, VT.At(ii, j) + (t * VT.At(ii, l)));
} }
} }
} }
@ -283,10 +283,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (i = 0; i < matrixCopy.ColumnCount; i++) for (i = 0; i < matrixCopy.ColumnCount; i++)
{ {
MatrixVT.At(i, l, 0.0f); VT.At(i, l, 0.0f);
} }
MatrixVT.At(l, l, 1.0f); VT.At(l, l, 1.0f);
} }
} }
@ -294,11 +294,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (i = 0; i < m; i++) for (i = 0; i < m; i++)
{ {
float r; float r;
if (VectorS[i] != 0.0) if (S[i] != 0.0)
{ {
t = VectorS[i]; t = S[i];
r = VectorS[i] / t; r = S[i] / t;
VectorS[i] = t; S[i] = t;
if (i < m - 1) if (i < m - 1)
{ {
e[i] = e[i] / r; e[i] = e[i] / r;
@ -306,7 +306,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
DscalColumn(MatrixU, matrixCopy.RowCount, i, 0, r); DscalColumn(U, matrixCopy.RowCount, i, 0, r);
} }
} }
@ -321,10 +321,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
t = e[i]; t = e[i];
r = t / e[i]; r = t / e[i];
e[i] = t; e[i] = t;
VectorS[i + 1] = VectorS[i + 1] * r; S[i + 1] = S[i + 1] * r;
if (ComputeVectors) if (ComputeVectors)
{ {
DscalColumn(MatrixVT, matrixCopy.ColumnCount, i + 1, 0, r); DscalColumn(VT, matrixCopy.ColumnCount, i + 1, 0, r);
} }
} }
} }
@ -352,7 +352,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
float test; float test;
for (l = m - 2; l >= 0; l--) for (l = m - 2; l >= 0; l--)
{ {
test = Math.Abs(VectorS[l]) + Math.Abs(VectorS[l + 1]); test = Math.Abs(S[l]) + Math.Abs(S[l + 1]);
ztest = test + Math.Abs(e[l]); ztest = test + Math.Abs(e[l]);
if (ztest.AlmostEqualInDecimalPlaces(test, 7)) if (ztest.AlmostEqualInDecimalPlaces(test, 7))
{ {
@ -382,10 +382,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
test = test + Math.Abs(e[ls - 1]); test = test + Math.Abs(e[ls - 1]);
} }
ztest = test + Math.Abs(VectorS[ls]); ztest = test + Math.Abs(S[ls]);
if (ztest.AlmostEqualInDecimalPlaces(test, 7)) if (ztest.AlmostEqualInDecimalPlaces(test, 7))
{ {
VectorS[ls] = 0.0f; S[ls] = 0.0f;
break; break;
} }
} }
@ -422,9 +422,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
for (var kk = l; kk < m - 1; kk++) for (var kk = l; kk < m - 1; kk++)
{ {
k = m - 2 - kk + l; k = m - 2 - kk + l;
t1 = VectorS[k]; t1 = S[k];
Drotg(ref t1, ref f, out cs, out sn); Drotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
if (k != l) if (k != l)
{ {
f = -sn * e[k - 1]; f = -sn * e[k - 1];
@ -433,7 +433,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
Drot(MatrixVT, matrixCopy.ColumnCount, k, m - 1, cs, sn); Drot(VT, matrixCopy.ColumnCount, k, m - 1, cs, sn);
} }
} }
@ -445,14 +445,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
e[l - 1] = 0.0f; e[l - 1] = 0.0f;
for (k = l; k < m; k++) for (k = l; k < m; k++)
{ {
t1 = VectorS[k]; t1 = S[k];
Drotg(ref t1, ref f, out cs, out sn); Drotg(ref t1, ref f, out cs, out sn);
VectorS[k] = t1; S[k] = t1;
f = -sn * e[k]; f = -sn * e[k];
e[k] = cs * e[k]; e[k] = cs * e[k];
if (ComputeVectors) if (ComputeVectors)
{ {
Drot(MatrixU, matrixCopy.RowCount, k, l - 1, cs, sn); Drot(U, matrixCopy.RowCount, k, l - 1, cs, sn);
} }
} }
@ -462,15 +462,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
case 3: case 3:
// Calculate the shift. // Calculate the shift.
var scale = 0.0f; var scale = 0.0f;
scale = Math.Max(scale, Math.Abs(VectorS[m - 1])); scale = Math.Max(scale, Math.Abs(S[m - 1]));
scale = Math.Max(scale, Math.Abs(VectorS[m - 2])); scale = Math.Max(scale, Math.Abs(S[m - 2]));
scale = Math.Max(scale, Math.Abs(e[m - 2])); scale = Math.Max(scale, Math.Abs(e[m - 2]));
scale = Math.Max(scale, Math.Abs(VectorS[l])); scale = Math.Max(scale, Math.Abs(S[l]));
scale = Math.Max(scale, Math.Abs(e[l])); scale = Math.Max(scale, Math.Abs(e[l]));
var sm = VectorS[m - 1] / scale; var sm = S[m - 1] / scale;
var smm1 = VectorS[m - 2] / scale; var smm1 = S[m - 2] / scale;
var emm1 = e[m - 2] / scale; var emm1 = e[m - 2] / scale;
var sl = VectorS[l] / scale; var sl = S[l] / scale;
var el = e[l] / scale; var el = e[l] / scale;
var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0f; var b = (((smm1 + sm) * (smm1 - sm)) + (emm1 * emm1)) / 2.0f;
var c = (sm * emm1) * (sm * emm1); var c = (sm * emm1) * (sm * emm1);
@ -498,24 +498,24 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
e[k - 1] = f; e[k - 1] = f;
} }
f = (cs * VectorS[k]) + (sn * e[k]); f = (cs * S[k]) + (sn * e[k]);
e[k] = (cs * e[k]) - (sn * VectorS[k]); e[k] = (cs * e[k]) - (sn * S[k]);
g = sn * VectorS[k + 1]; g = sn * S[k + 1];
VectorS[k + 1] = cs * VectorS[k + 1]; S[k + 1] = cs * S[k + 1];
if (ComputeVectors) if (ComputeVectors)
{ {
Drot(MatrixVT, matrixCopy.ColumnCount, k, k + 1, cs, sn); Drot(VT, matrixCopy.ColumnCount, k, k + 1, cs, sn);
} }
Drotg(ref f, ref g, out cs, out sn); Drotg(ref f, ref g, out cs, out sn);
VectorS[k] = f; S[k] = f;
f = (cs * e[k]) + (sn * VectorS[k + 1]); f = (cs * e[k]) + (sn * S[k + 1]);
VectorS[k + 1] = (-sn * e[k]) + (cs * VectorS[k + 1]); S[k + 1] = (-sn * e[k]) + (cs * S[k + 1]);
g = sn * e[k + 1]; g = sn * e[k + 1];
e[k + 1] = cs * e[k + 1]; e[k + 1] = cs * e[k + 1];
if (ComputeVectors && k < matrixCopy.RowCount) if (ComputeVectors && k < matrixCopy.RowCount)
{ {
Drot(MatrixU, matrixCopy.RowCount, k, k + 1, cs, sn); Drot(U, matrixCopy.RowCount, k, k + 1, cs, sn);
} }
} }
@ -526,34 +526,34 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Convergence. // Convergence.
case 4: case 4:
// Make the singular value positive // Make the singular value positive
if (VectorS[l] < 0.0) if (S[l] < 0.0)
{ {
VectorS[l] = -VectorS[l]; S[l] = -S[l];
if (ComputeVectors) if (ComputeVectors)
{ {
DscalColumn(MatrixVT, matrixCopy.ColumnCount, l, 0, -1.0f); DscalColumn(VT, matrixCopy.ColumnCount, l, 0, -1.0f);
} }
} }
// Order the singular value. // Order the singular value.
while (l != mn - 1) while (l != mn - 1)
{ {
if (VectorS[l] >= VectorS[l + 1]) if (S[l] >= S[l + 1])
{ {
break; break;
} }
t = VectorS[l]; t = S[l];
VectorS[l] = VectorS[l + 1]; S[l] = S[l + 1];
VectorS[l + 1] = t; S[l + 1] = t;
if (ComputeVectors && l < matrixCopy.ColumnCount) if (ComputeVectors && l < matrixCopy.ColumnCount)
{ {
Dswap(MatrixVT, matrixCopy.ColumnCount, l, l + 1); Dswap(VT, matrixCopy.ColumnCount, l, l + 1);
} }
if (ComputeVectors && l < matrixCopy.RowCount) if (ComputeVectors && l < matrixCopy.RowCount)
{ {
Dswap(MatrixU, matrixCopy.RowCount, l, l + 1); Dswap(U, matrixCopy.RowCount, l, l + 1);
} }
l = l + 1; l = l + 1;
@ -567,7 +567,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
if (ComputeVectors) if (ComputeVectors)
{ {
MatrixVT = MatrixVT.Transpose(); VT = VT.Transpose();
} }
// Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses // Adjust the size of s if rows < columns. We are using ported copy of linpack's svd code and it uses
@ -579,10 +579,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
var tmp = matrixCopy.CreateVector(nm); var tmp = matrixCopy.CreateVector(nm);
for (i = 0; i < nm; i++) for (i = 0; i < nm; i++)
{ {
tmp[i] = VectorS[i]; tmp[i] = S[i];
} }
VectorS = tmp; S = tmp;
} }
} }
@ -808,46 +808,46 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
} }
// The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows
if (MatrixU.RowCount != input.RowCount) if (U.RowCount != input.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension);
} }
// The solution X row dimension is equal to the column dimension of A // The solution X row dimension is equal to the column dimension of A
if (MatrixVT.ColumnCount != result.RowCount) if (VT.ColumnCount != result.RowCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var bn = input.ColumnCount; var bn = input.ColumnCount;
var tmp = new float[MatrixVT.ColumnCount]; var tmp = new float[VT.ColumnCount];
for (var k = 0; k < bn; k++) for (var k = 0; k < bn; k++)
{ {
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
float value = 0; float value = 0;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j) * input.At(i, k); value += U.At(i, j) * input.At(i, k);
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
float value = 0; float value = 0;
for (var i = 0; i < MatrixVT.ColumnCount; i++) for (var i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j) * tmp[i]; value += VT.At(i, j) * tmp[i];
} }
result.At(j, k, value); result.At(j, k, value);
@ -879,42 +879,42 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
// Ax=b where A is an m x n matrix // Ax=b where A is an m x n matrix
// Check that b is a column vector with m entries // Check that b is a column vector with m entries
if (MatrixU.RowCount != input.Count) if (U.RowCount != input.Count)
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength); throw new ArgumentException(Resources.ArgumentVectorsSameLength);
} }
// Check that x is a column vector with n entries // Check that x is a column vector with n entries
if (MatrixVT.ColumnCount != result.Count) if (VT.ColumnCount != result.Count)
{ {
throw Matrix.DimensionsDontMatch<ArgumentException>(MatrixVT, result); throw Matrix.DimensionsDontMatch<ArgumentException>(VT, result);
} }
var mn = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var mn = Math.Min(U.RowCount, VT.ColumnCount);
var tmp = new float[MatrixVT.ColumnCount]; var tmp = new float[VT.ColumnCount];
float value; float value;
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
value = 0; value = 0;
if (j < mn) if (j < mn)
{ {
for (var i = 0; i < MatrixU.RowCount; i++) for (var i = 0; i < U.RowCount; i++)
{ {
value += MatrixU.At(i, j) * input[i]; value += U.At(i, j) * input[i];
} }
value /= VectorS[j]; value /= S[j];
} }
tmp[j] = value; tmp[j] = value;
} }
for (var j = 0; j < MatrixVT.ColumnCount; j++) for (var j = 0; j < VT.ColumnCount; j++)
{ {
value = 0; value = 0;
for (int i = 0; i < MatrixVT.ColumnCount; i++) for (int i = 0; i < VT.ColumnCount; i++)
{ {
value += MatrixVT.At(i, j) * tmp[i]; value += VT.At(i, j) * tmp[i];
} }
result[j] = value; result[j] = value;

2
src/UnitTests/ArrayHelpers.cs

@ -27,8 +27,6 @@
namespace MathNet.Numerics.UnitTests namespace MathNet.Numerics.UnitTests
{ {
using System; using System;
using System.Collections.Generic;
using System.Linq;
/// <summary> /// <summary>
/// Array and List helper/extention for Silverlight /// Array and List helper/extention for Silverlight

18
src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs

@ -57,9 +57,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixI = DenseMatrix.Identity(order); var matrixI = DenseMatrix.Identity(order);
var factorEvd = matrixI.Evd(); var factorEvd = matrixI.Evd();
var eigenValues = factorEvd.EigenValues(); var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
@ -87,17 +87,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, factorEvd.D().RowCount); Assert.AreEqual(order, factorEvd.D.RowCount);
Assert.AreEqual(order, factorEvd.D().ColumnCount); Assert.AreEqual(order, factorEvd.D.ColumnCount);
// Make sure the A*V = λ*V // Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors; var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * factorEvd.D(); var matrixLv = eigenVectors * factorEvd.D;
for (var i = 0; i < matrixAv.RowCount; i++) for (var i = 0; i < matrixAv.RowCount; i++)
{ {
@ -123,8 +123,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order);
MatrixHelpers.ForceConjugateSymmetric(matrixA); MatrixHelpers.ForceConjugateSymmetric(matrixA);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);

2
src/UnitTests/LinearAlgebraTests/Complex/Factorization/GramSchmidtTests.cs

@ -1,4 +1,4 @@
// <copyright file="GramSchmidtTests.cs" company="Math.NET"> // <copyright file="GramSchmidtTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics

8
src/UnitTests/LinearAlgebraTests/Complex/Factorization/SvdTests.cs

@ -58,8 +58,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixI = DenseMatrix.Identity(order); var matrixI = DenseMatrix.Identity(order);
var factorSvd = matrixI.Svd(true); var factorSvd = matrixI.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
Assert.AreEqual(matrixI.RowCount, u.RowCount); Assert.AreEqual(matrixI.RowCount, u.RowCount);
@ -95,8 +95,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column);
var factorSvd = matrixA.Svd(true); var factorSvd = matrixA.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
// Make sure the U has the right dimensions. // Make sure the U has the right dimensions.

1
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserCholeskyTests.cs

@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex;
using NUnit.Framework; using NUnit.Framework;
/// <summary> /// <summary>

15
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs

@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Factorization; using LinearAlgebra.Complex.Factorization;
using NUnit.Framework; using NUnit.Framework;
@ -57,9 +56,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixI = UserDefinedMatrix.Identity(order); var matrixI = UserDefinedMatrix.Identity(order);
var factorEvd = matrixI.Evd(); var factorEvd = matrixI.Evd();
var eigenValues = factorEvd.EigenValues(); var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
@ -87,8 +86,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);
@ -123,8 +122,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);

3
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserGramSchmidtTests.cs

@ -1,4 +1,4 @@
// <copyright file="UserGramSchmidtTests.cs" company="Math.NET"> // <copyright file="UserGramSchmidtTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Factorization; using LinearAlgebra.Complex.Factorization;
using NUnit.Framework; using NUnit.Framework;

1
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserLUTests.cs

@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex;
using NUnit.Framework; using NUnit.Framework;
/// <summary> /// <summary>

1
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserQRTests.cs

@ -24,7 +24,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Factorization; using MathNet.Numerics.LinearAlgebra.Complex.Factorization;
using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization;
using NUnit.Framework; using NUnit.Framework;

9
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserSvdTests.cs

@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Factorization; using LinearAlgebra.Complex.Factorization;
using NUnit.Framework; using NUnit.Framework;
@ -57,8 +56,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixI = UserDefinedMatrix.Identity(order); var matrixI = UserDefinedMatrix.Identity(order);
var factorSvd = matrixI.Svd(true); var factorSvd = matrixI.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
Assert.AreEqual(matrixI.RowCount, u.RowCount); Assert.AreEqual(matrixI.RowCount, u.RowCount);
@ -94,8 +93,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column);
var factorSvd = matrixA.Svd(true); var factorSvd = matrixA.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
// Make sure the U has the right dimensions. // Make sure the U has the right dimensions.

1
src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs

@ -26,7 +26,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
{ {
using System.Numerics;
using NUnit.Framework; using NUnit.Framework;
/// <summary> /// <summary>

1
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs

@ -30,7 +30,6 @@
using System; using System;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers;

1
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs

@ -30,7 +30,6 @@
using System; using System;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers;

1
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs

@ -30,7 +30,6 @@
using System; using System;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers;

1
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs

@ -30,7 +30,6 @@
using System; using System;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers;

1
src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs

@ -31,7 +31,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status; using MathNet.Numerics.LinearAlgebra.Solvers.Status;

1
src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrix.cs

@ -24,7 +24,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Storage; using MathNet.Numerics.LinearAlgebra.Storage;

1
src/UnitTests/LinearAlgebraTests/Complex/UserDefinedVector.cs

@ -24,7 +24,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Complex; using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Storage; using MathNet.Numerics.LinearAlgebra.Storage;

18
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs

@ -58,9 +58,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixI = DenseMatrix.Identity(order); var matrixI = DenseMatrix.Identity(order);
var factorEvd = matrixI.Evd(); var factorEvd = matrixI.Evd();
var eigenValues = factorEvd.EigenValues(); var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
@ -68,7 +68,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
Assert.AreEqual(matrixI.ColumnCount, d.RowCount); Assert.AreEqual(matrixI.ColumnCount, d.RowCount);
Assert.AreEqual(matrixI.ColumnCount, d.ColumnCount); Assert.AreEqual(matrixI.ColumnCount, d.ColumnCount);
for (var i = 0; i < factorEvd.EigenValues().Count; i++) for (var i = 0; i < factorEvd.EigenValues.Count; i++)
{ {
Assert.AreEqual(Complex.One, eigenValues[i]); Assert.AreEqual(Complex.One, eigenValues[i]);
} }
@ -88,8 +88,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);
@ -99,7 +99,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
// Make sure the A*V = λ*V // Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors; var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * factorEvd.D(); var matrixLv = eigenVectors * factorEvd.D;
for (var i = 0; i < matrixAv.RowCount; i++) for (var i = 0; i < matrixAv.RowCount; i++)
{ {
@ -120,8 +120,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order);
MatrixHelpers.ForceConjugateSymmetric(matrixA); MatrixHelpers.ForceConjugateSymmetric(matrixA);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);

2
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/GramSchmidtTests.cs

@ -1,4 +1,4 @@
// <copyright file="GramSchmidtTests.cs" company="Math.NET"> // <copyright file="GramSchmidtTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics

2
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/QRTests.cs

@ -1,4 +1,4 @@
// <copyright file="QRTests.cs" company="Math.NET"> // <copyright file="QRTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics

8
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/SvdTests.cs

@ -58,8 +58,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixI = DenseMatrix.Identity(order); var matrixI = DenseMatrix.Identity(order);
var factorSvd = matrixI.Svd(true); var factorSvd = matrixI.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
Assert.AreEqual(matrixI.RowCount, u.RowCount); Assert.AreEqual(matrixI.RowCount, u.RowCount);
@ -95,8 +95,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column);
var factorSvd = matrixA.Svd(true); var factorSvd = matrixA.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
// Make sure the U has the right dimensions. // Make sure the U has the right dimensions.

1
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserCholeskyTests.cs

@ -27,7 +27,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
using System; using System;
using LinearAlgebra.Complex32;
using NUnit.Framework; using NUnit.Framework;
using Complex32 = Numerics.Complex32; using Complex32 = Numerics.Complex32;

15
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs

@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex32;
using LinearAlgebra.Complex32.Factorization; using LinearAlgebra.Complex32.Factorization;
using NUnit.Framework; using NUnit.Framework;
using Complex32 = Numerics.Complex32; using Complex32 = Numerics.Complex32;
@ -58,9 +57,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixI = UserDefinedMatrix.Identity(order); var matrixI = UserDefinedMatrix.Identity(order);
var factorEvd = matrixI.Evd(); var factorEvd = matrixI.Evd();
var eigenValues = factorEvd.EigenValues(); var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
@ -88,8 +87,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);
@ -120,8 +119,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order); var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianUserDefinedMatrix(order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);

3
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserGramSchmidtTests.cs

@ -1,4 +1,4 @@
// <copyright file="UserGramSchmidtTests.cs" company="Math.NET"> // <copyright file="UserGramSchmidtTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
@ -27,7 +27,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
using System; using System;
using LinearAlgebra.Complex32;
using LinearAlgebra.Complex32.Factorization; using LinearAlgebra.Complex32.Factorization;
using NUnit.Framework; using NUnit.Framework;
using Complex32 = Numerics.Complex32; using Complex32 = Numerics.Complex32;

1
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserLUTests.cs

@ -27,7 +27,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
using System; using System;
using LinearAlgebra.Complex32;
using NUnit.Framework; using NUnit.Framework;
using Complex32 = Numerics.Complex32; using Complex32 = Numerics.Complex32;

3
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserQRTests.cs

@ -1,4 +1,4 @@
// <copyright file="UserQRTests.cs" company="Math.NET"> // <copyright file="UserQRTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
@ -24,7 +24,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Complex32.Factorization; using MathNet.Numerics.LinearAlgebra.Complex32.Factorization;
using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization;
using NUnit.Framework; using NUnit.Framework;

9
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserSvdTests.cs

@ -27,7 +27,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
using System; using System;
using LinearAlgebra.Complex32;
using LinearAlgebra.Complex32.Factorization; using LinearAlgebra.Complex32.Factorization;
using NUnit.Framework; using NUnit.Framework;
using Complex32 = Numerics.Complex32; using Complex32 = Numerics.Complex32;
@ -57,8 +56,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixI = UserDefinedMatrix.Identity(order); var matrixI = UserDefinedMatrix.Identity(order);
var factorSvd = matrixI.Svd(true); var factorSvd = matrixI.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
Assert.AreEqual(matrixI.RowCount, u.RowCount); Assert.AreEqual(matrixI.RowCount, u.RowCount);
@ -94,8 +93,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column); var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(row, column);
var factorSvd = matrixA.Svd(true); var factorSvd = matrixA.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
// Make sure the U has the right dimensions. // Make sure the U has the right dimensions.

1
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs

@ -31,7 +31,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Complex32.Solvers;
using MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers; using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status; using MathNet.Numerics.LinearAlgebra.Solvers.Status;

1
src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs

@ -24,7 +24,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Storage; using MathNet.Numerics.LinearAlgebra.Storage;

1
src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedVector.cs

@ -24,7 +24,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Complex32; using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Storage; using MathNet.Numerics.LinearAlgebra.Storage;

16
src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs

@ -57,9 +57,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixI = DenseMatrix.Identity(order); var matrixI = DenseMatrix.Identity(order);
var factorEvd = matrixI.Evd(); var factorEvd = matrixI.Evd();
var eigenValues = factorEvd.EigenValues(); var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
@ -87,8 +87,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);
@ -98,7 +98,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
// Make sure the A*V = λ*V // Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors; var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * factorEvd.D(); var matrixLv = eigenVectors * factorEvd.D;
for (var i = 0; i < matrixAv.RowCount; i++) for (var i = 0; i < matrixAv.RowCount; i++)
{ {
@ -124,8 +124,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order); var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteDenseMatrix(order);
MatrixHelpers.ForceSymmetric(matrixA); MatrixHelpers.ForceSymmetric(matrixA);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);

8
src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs

@ -56,8 +56,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixI = DenseMatrix.Identity(order); var matrixI = DenseMatrix.Identity(order);
var factorSvd = matrixI.Svd(true); var factorSvd = matrixI.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
Assert.AreEqual(matrixI.RowCount, u.RowCount); Assert.AreEqual(matrixI.RowCount, u.RowCount);
@ -93,8 +93,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(row, column);
var factorSvd = matrixA.Svd(true); var factorSvd = matrixA.Svd(true);
var u = factorSvd.U(); var u = factorSvd.U;
var vt = factorSvd.VT(); var vt = factorSvd.VT;
var w = factorSvd.W(); var w = factorSvd.W();
// Make sure the U has the right dimensions. // Make sure the U has the right dimensions.

1
src/UnitTests/LinearAlgebraTests/Double/Factorization/UserCholeskyTests.cs

@ -27,7 +27,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
using System; using System;
using LinearAlgebra.Double;
using NUnit.Framework; using NUnit.Framework;
/// <summary> /// <summary>

15
src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs

@ -28,7 +28,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using LinearAlgebra.Double;
using LinearAlgebra.Double.Factorization; using LinearAlgebra.Double.Factorization;
using NUnit.Framework; using NUnit.Framework;
@ -57,9 +56,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixI = UserDefinedMatrix.Identity(order); var matrixI = UserDefinedMatrix.Identity(order);
var factorEvd = matrixI.Evd(); var factorEvd = matrixI.Evd();
var eigenValues = factorEvd.EigenValues(); var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount); Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
@ -87,8 +86,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomUserDefinedMatrix(order, order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);
@ -123,8 +122,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order); var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteUserDefinedMatrix(order);
var factorEvd = matrixA.Evd(); var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors(); var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D(); var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount); Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount); Assert.AreEqual(order, eigenVectors.ColumnCount);

1
src/UnitTests/LinearAlgebraTests/Double/Factorization/UserGramSchmidtTests.cs

@ -27,7 +27,6 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
{ {
using System; using System;
using LinearAlgebra.Double;
using LinearAlgebra.Double.Factorization; using LinearAlgebra.Double.Factorization;
using NUnit.Framework; using NUnit.Framework;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save