|
|
|
@ -61,35 +61,35 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
|
|
|
|
if (alpha == 0.0) |
|
|
|
{ |
|
|
|
Buffer.BlockCopy(y, 0, result, 0, y.Length * Constants.SizeOfDouble); |
|
|
|
y.Copy(result); |
|
|
|
} |
|
|
|
else if (alpha == 1.0) |
|
|
|
{ |
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => result[index] = y[index] + x[index]); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = y[index] + x[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => result[index] = y[index] + x[index]); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => result[index] = y[index] + (alpha * x[index])); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = y[index] + (alpha * x[index]); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => result[index] = y[index] + (alpha * x[index])); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -113,21 +113,21 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
} |
|
|
|
else if (alpha == 1.0) |
|
|
|
{ |
|
|
|
Buffer.BlockCopy(x, 0, result, 0, x.Length * Constants.SizeOfDouble); |
|
|
|
x.Copy(result); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, x.Length, index => { result[index] = alpha * x[index]; }); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = alpha * x[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, x.Length, index => { result[index] = alpha * x[index]; }); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -197,16 +197,16 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
throw new ArgumentException(Resources.ArgumentVectorsSameLength); |
|
|
|
} |
|
|
|
|
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = x[index] + y[index]; |
|
|
|
} |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] + y[index]; }); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] + y[index]; }); |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = x[index] + y[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -242,17 +242,17 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
throw new ArgumentException(Resources.ArgumentVectorsSameLength); |
|
|
|
} |
|
|
|
|
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] - y[index]; }); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = x[index] - y[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] - y[index]; }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -287,17 +287,17 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
throw new ArgumentException(Resources.ArgumentVectorsSameLength); |
|
|
|
} |
|
|
|
|
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] * y[index]; }); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = x[index] * y[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] * y[index]; }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -332,17 +332,17 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
throw new ArgumentException(Resources.ArgumentVectorsSameLength); |
|
|
|
} |
|
|
|
|
|
|
|
if (x.Length < Control.ParallelizeElements || Control.DisableParallelization) |
|
|
|
if (Control.ParallelizeOperation(x.Length)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] / y[index]; }); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < x.Length; index++) |
|
|
|
{ |
|
|
|
result[index] = x[index] / y[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
CommonParallel.For(0, y.Length, index => { result[index] = x[index] / y[index]; }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -950,7 +950,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
} |
|
|
|
|
|
|
|
LUSolveFactored(order, a, order, ipiv, inverse); |
|
|
|
Buffer.BlockCopy(inverse, 0, a, 0, a.Length * Constants.SizeOfDouble); |
|
|
|
inverse.Copy(a); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -1019,7 +1019,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
|
|
|
|
var ipiv = new int[order]; |
|
|
|
var clone = new double[a.Length]; |
|
|
|
Buffer.BlockCopy(a, 0, clone, 0, a.Length * Constants.SizeOfDouble); |
|
|
|
a.Copy(clone); |
|
|
|
LUFactor(clone, order, ipiv); |
|
|
|
LUSolveFactored(columnsOfB, clone, order, ipiv, b); |
|
|
|
} |
|
|
|
@ -1242,7 +1242,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
} |
|
|
|
|
|
|
|
var clone = new double[a.Length]; |
|
|
|
Buffer.BlockCopy(a, 0, clone, 0, a.Length * Constants.SizeOfDouble); |
|
|
|
a.Copy(clone); |
|
|
|
CholeskyFactor(clone, orderA); |
|
|
|
CholeskySolveFactored(clone, orderA, b, columnsB); |
|
|
|
} |
|
|
|
@ -1277,40 +1277,55 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
throw new ArgumentException(Resources.ArgumentReferenceDifferent); |
|
|
|
} |
|
|
|
|
|
|
|
if( ) |
|
|
|
CommonParallel.For( |
|
|
|
0, |
|
|
|
columnsB, |
|
|
|
c => |
|
|
|
if (Control.ParallelizeOperation(columnsB * 10)) |
|
|
|
{ |
|
|
|
CommonParallel.For(0, columnsB, c => DoCholeskySolve(a, orderA, b, c)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (var index = 0; index < columnsB; index++) |
|
|
|
{ |
|
|
|
var cindex = c * orderA; |
|
|
|
DoCholeskySolve(a, orderA, b, index); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Solve L*Y = B;
|
|
|
|
double sum; |
|
|
|
for (var i = 0; i < orderA; i++) |
|
|
|
{ |
|
|
|
sum = b[cindex + i]; |
|
|
|
for (var k = i - 1; k >= 0; k--) |
|
|
|
{ |
|
|
|
sum -= a[(k * orderA) + i] * b[cindex + k]; |
|
|
|
} |
|
|
|
/// <summary>
|
|
|
|
/// Solves A*X=B for X using a previously factored A matrix.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="a">The square, positive definite matrix A. Has to be different than <paramref name="b"/>.</param>
|
|
|
|
/// <param name="orderA">The number of rows and columns in A.</param>
|
|
|
|
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
|
|
|
|
/// <param name="index">The column to solve for.</param>
|
|
|
|
private static void DoCholeskySolve(double[] a, int orderA, double[] b, int index) |
|
|
|
{ |
|
|
|
var cindex = index * orderA; |
|
|
|
|
|
|
|
b[cindex + i] = sum / a[(i * orderA) + i]; |
|
|
|
} |
|
|
|
// Solve L*Y = B;
|
|
|
|
double sum; |
|
|
|
for (var i = 0; i < orderA; i++) |
|
|
|
{ |
|
|
|
sum = b[cindex + i]; |
|
|
|
for (var k = i - 1; k >= 0; k--) |
|
|
|
{ |
|
|
|
sum -= a[(k * orderA) + i] * b[cindex + k]; |
|
|
|
} |
|
|
|
|
|
|
|
// Solve L'*X = Y;
|
|
|
|
for (var i = orderA - 1; i >= 0; i--) |
|
|
|
{ |
|
|
|
sum = b[cindex + i]; |
|
|
|
var iindex = i * orderA; |
|
|
|
for (var k = i + 1; k < orderA; k++) |
|
|
|
{ |
|
|
|
sum -= a[iindex + k] * b[cindex + k]; |
|
|
|
} |
|
|
|
b[cindex + i] = sum / a[(i * orderA) + i]; |
|
|
|
} |
|
|
|
|
|
|
|
b[cindex + i] = sum / a[iindex + i]; |
|
|
|
} |
|
|
|
}); |
|
|
|
// Solve L'*X = Y;
|
|
|
|
for (var i = orderA - 1; i >= 0; i--) |
|
|
|
{ |
|
|
|
sum = b[cindex + i]; |
|
|
|
var iindex = i * orderA; |
|
|
|
for (var k = i + 1; k < orderA; k++) |
|
|
|
{ |
|
|
|
sum -= a[iindex + k] * b[cindex + k]; |
|
|
|
} |
|
|
|
|
|
|
|
b[cindex + i] = sum / a[iindex + i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -1642,7 +1657,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra |
|
|
|
} |
|
|
|
|
|
|
|
var clone = new double[a.Length]; |
|
|
|
Buffer.BlockCopy(a, 0, clone, 0, a.Length * Constants.SizeOfDouble); |
|
|
|
a.Copy(clone); |
|
|
|
var q = new double[rows * rows]; |
|
|
|
QRFactor(clone, rows, columns, q, work); |
|
|
|
QRSolveFactored(q, clone, rows, columns, null, b, columnsB, x); |
|
|
|
|