diff --git a/src/Numerics/LinearAlgebra/Complex/Matrix.cs b/src/Numerics/LinearAlgebra/Complex/Matrix.cs
index fa72859b..46a1daad 100644
--- a/src/Numerics/LinearAlgebra/Complex/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/Matrix.cs
@@ -106,6 +106,104 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return Math.Sqrt(norm);
}
+ ///
+ /// Calculates the p-norms of all row vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector RowNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(RowCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + x.MagnitudeSquared(), (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + x.Magnitude, (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => Math.Max(s, x.Magnitude), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + Math.Pow(x.Magnitude, norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Calculates the p-norms of all column vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector ColumnNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(ColumnCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + x.MagnitudeSquared(), (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + x.Magnitude, (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => Math.Max(s, x.Magnitude), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + Math.Pow(x.Magnitude, norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Normalizes all row vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeRows(double norm)
+ {
+ var norminv = ((DenseVectorStorage)RowNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => norminv[i]*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
+ ///
+ /// Normalizes all column vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeColumns(double norm)
+ {
+ var norminv = ((DenseVectorStorage)ColumnNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => norminv[j]*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
///
/// Returns the conjugate transpose of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
index 859dbddd..7bd2179d 100644
--- a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
@@ -100,6 +100,104 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return Math.Sqrt(norm);
}
+ ///
+ /// Calculates the p-norms of all row vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector RowNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(RowCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + x.MagnitudeSquared, (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + x.Magnitude, (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => Math.Max(s, x.Magnitude), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + Math.Pow(x.Magnitude, norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Calculates the p-norms of all column vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector ColumnNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(ColumnCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + x.MagnitudeSquared, (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + x.Magnitude, (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => Math.Max(s, x.Magnitude), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + Math.Pow(x.Magnitude, norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Normalizes all row vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeRows(double norm)
+ {
+ var norminv = ((DenseVectorStorage)RowNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => ((float)norminv[i])*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
+ ///
+ /// Normalizes all column vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeColumns(double norm)
+ {
+ var norminv = ((DenseVectorStorage)ColumnNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => ((float)norminv[j])*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
///
/// Returns the conjugate transpose of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs
index 669197cf..2285e5bc 100644
--- a/src/Numerics/LinearAlgebra/Double/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs
@@ -98,6 +98,104 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return Math.Sqrt(norm);
}
+ ///
+ /// Calculates the p-norms of all row vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector RowNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(RowCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + x*x, (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + Math.Abs(x), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => Math.Max(s, Math.Abs(x)), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + Math.Pow(Math.Abs(x), norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Calculates the p-norms of all column vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector ColumnNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(ColumnCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + x*x, (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + Math.Abs(x), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => Math.Max(s, Math.Abs(x)), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + Math.Pow(Math.Abs(x), norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Normalizes all row vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeRows(double norm)
+ {
+ var norminv = ((DenseVectorStorage)RowNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => norminv[i]*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
+ ///
+ /// Normalizes all column vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeColumns(double norm)
+ {
+ var norminv = ((DenseVectorStorage)ColumnNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => norminv[j]*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
///
/// Returns the conjugate transpose of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
index afe767a8..11fe471f 100644
--- a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
+++ b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
@@ -1627,50 +1627,6 @@ namespace MathNet.Numerics.LinearAlgebra
}
}
- ///
- /// Normalizes the columns of a matrix.
- ///
- /// The norm under which to normalize the columns under.
- /// A normalized version of the matrix.
- /// If the parameter p is not positive.
- public Matrix NormalizeColumns(int p)
- {
- if (p < 1)
- {
- throw new ArgumentOutOfRangeException("p", Resources.ArgumentMustBePositive);
- }
-
- var result = Build.SameAs(this);
- for (var index = 0; index < ColumnCount; index++)
- {
- result.SetColumn(index, Column(index).Normalize(p));
- }
-
- return result;
- }
-
- ///
- /// Normalizes the rows of a matrix.
- ///
- /// The norm under which to normalize the rows under.
- /// A normalized version of the matrix.
- /// If the parameter p is not positive.
- public Matrix NormalizeRows(int p)
- {
- if (p < 1)
- {
- throw new ArgumentOutOfRangeException("p", Resources.ArgumentMustBePositive);
- }
-
- var ret = Build.SameAs(this);
- for (var index = 0; index < RowCount; index++)
- {
- ret.SetRow(index, Row(index).Normalize(p));
- }
-
- return ret;
- }
-
/// Calculates the induced L1 norm of this matrix.
/// The maximum absolute column sum of the matrix.
public abstract double L1Norm();
@@ -1694,7 +1650,29 @@ namespace MathNet.Numerics.LinearAlgebra
/// The square root of the sum of the squared values.
public abstract double FrobeniusNorm();
+ ///
+ /// Calculates the p-norms of all row vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public abstract Vector RowNorms(double norm);
+ ///
+ /// Calculates the p-norms of all column vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public abstract Vector ColumnNorms(double norm);
+
+ ///
+ /// Normalizes all row vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public abstract Matrix NormalizeRows(double norm);
+
+ ///
+ /// Normalizes all column vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public abstract Matrix NormalizeColumns(double norm);
#region Exceptions - possibly move elsewhere?
diff --git a/src/Numerics/LinearAlgebra/Single/Matrix.cs b/src/Numerics/LinearAlgebra/Single/Matrix.cs
index bbd4fe5c..ee0f66ea 100644
--- a/src/Numerics/LinearAlgebra/Single/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Single/Matrix.cs
@@ -98,6 +98,104 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return Math.Sqrt(norm);
}
+ ///
+ /// Calculates the p-norms of all row vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector RowNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(RowCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + x*x, (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + Math.Abs(x), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => Math.Max(s, Math.Abs(x)), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldRowsUnchecked(ret.Storage, (s, x) => s + Math.Pow(Math.Abs(x), norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Calculates the p-norms of all column vectors.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override Vector ColumnNorms(double norm)
+ {
+ if (norm <= 0.0)
+ {
+ throw new ArgumentOutOfRangeException("norm", Resources.ArgumentMustBePositive);
+ }
+
+ var ret = Vector.Build.Dense(ColumnCount);
+ if (norm == 2.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + x*x, (x, c) => Math.Sqrt(x), ret.Storage, Zeros.AllowSkip);
+ }
+ else if (norm == 1.0)
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + Math.Abs(x), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else if (double.IsPositiveInfinity(norm))
+ {
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => Math.Max(s, Math.Abs(x)), (x, c) => x, ret.Storage, Zeros.AllowSkip);
+ }
+ else
+ {
+ double invnorm = 1.0/norm;
+ Storage.FoldColumnsUnchecked(ret.Storage, (s, x) => s + Math.Pow(Math.Abs(x), norm), (x, c) => Math.Pow(x, invnorm), ret.Storage, Zeros.AllowSkip);
+ }
+ return ret;
+ }
+
+ ///
+ /// Normalizes all row vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeRows(double norm)
+ {
+ var norminv = ((DenseVectorStorage)RowNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => (float)norminv[i]*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
+ ///
+ /// Normalizes all column vectors to a unit p-norm.
+ /// Typical values for p are 1.0 (L1, Manhattan norm), 2.0 (L2, Euclidean norm) and positive infinity (infinity norm)
+ ///
+ public override sealed Matrix NormalizeColumns(double norm)
+ {
+ var norminv = ((DenseVectorStorage)ColumnNorms(norm).Storage).Data;
+ for (int i = 0; i < norminv.Length; i++)
+ {
+ norminv[i] = norminv[i] == 0d ? 1d : 1d/norminv[i];
+ }
+
+ var result = Build.SameAs(this, RowCount, ColumnCount);
+ Storage.MapIndexedTo(result.Storage, (i, j, x) => (float)norminv[j]*x, Zeros.AllowSkip, ExistingData.AssumeZeros);
+ return result;
+ }
+
///
/// Returns the conjugate transpose of this matrix.
///