diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 0387fd71..51f801fc 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -464,6 +464,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return ret; } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ConjugateArray(_values, denseResult._values); + return; + } + + base.DoConjugate(result); + } + /// /// Add a scalar to each element of the matrix and stores the result in the result vector. /// @@ -943,24 +975,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex base.DoConjugateTransposeThisAndMultiply(other, result); } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - var denseResult = result as DenseMatrix; - - if (denseResult == null) - { - base.DoNegate(result); - } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); - } - } - /// /// Divides each element of the matrix by a scalar and places results into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs index 616f3377..30908336 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs @@ -357,11 +357,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (denseResult == null) { base.DoNegate(result); + return; } - else + + Control.LinearAlgebraProvider.ScaleArray(-Complex.One, _values, denseResult.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var resultDense = result as DenseVector; + if (resultDense == null) { - Control.LinearAlgebraProvider.ScaleArray(-Complex.One, _values, denseResult.Values); + base.DoConjugate(result); + return; } + + Control.LinearAlgebraProvider.ConjugateArray(_values, resultDense._values); } /// @@ -376,11 +391,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// @@ -842,27 +856,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } #endregion - - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - var resultDense = result as DenseVector; - if (resultDense == null) - { - base.DoConjugate(result); - return; - } - - CommonParallel.For(0, _length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - resultDense._values[i] = _values[i].Conjugate(); - } - }); - } } } diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 094d8986..355c6c05 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -194,6 +194,46 @@ namespace MathNet.Numerics.LinearAlgebra.Complex i => new Complex(distribution.Sample(), distribution.Sample()))); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; + } + + result.Clear(); + for (var i = 0; i < _data.Length; i++) + { + result.At(i, i, -_data[i]); + } + } + + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) + { + Control.LinearAlgebraProvider.ConjugateArray(_data, diagResult._data); + return; + } + + result.Clear(); + for (var i = 0; i < _data.Length; i++) + { + result.At(i, i, _data[i].Conjugate()); + } + } + /// /// Adds another matrix to this matrix. /// @@ -442,6 +482,52 @@ namespace MathNet.Numerics.LinearAlgebra.Complex base.DoTransposeAndMultiply(other, result); } + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(otherDataCopy, otherDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; + } + + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) + { + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index].Conjugate()*diagonal[j]); + index++; + } + } + return; + } + + base.DoConjugateTransposeAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// @@ -487,6 +573,58 @@ namespace MathNet.Numerics.LinearAlgebra.Complex base.DoTransposeThisAndMultiply(other, result); } + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex[diagonalResult._data.Length]; + var otherDataCopy = new Complex[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(thisDataCopy, thisDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; + } + + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) + { + var dense = denseOther.Data; + var conjugateDiagonal = new Complex[_data.Length]; + for (int i = 0; i < _data.Length; i++) + { + conjugateDiagonal[i] = _data[i].Conjugate(); + } + + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) + { + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*conjugateDiagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; + } + + base.DoConjugateTransposeThisAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// @@ -517,6 +655,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) + { + result.ClearSubVector(RowCount, ColumnCount - RowCount); + } + + if (d == RowCount) + { + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(_data, denseResult.Data); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(denseResult.Data, denseOther.Data, denseResult.Data); + return; + } + } + + for (var i = 0; i < d; i++) + { + result.At(i, _data[i].Conjugate()*rightSide.At(i)); + } + } + /// /// Computes the determinant of this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 1891fbb9..453b6eb4 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -638,6 +638,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1037,16 +1047,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs index b75cdbda..89882200 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs @@ -133,44 +133,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new SparseVector(SparseVectorStorage.OfInit(length, init)); } - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - if (ReferenceEquals(this, result)) - { - var tmp = Build.SameAs(this); - DoConjugate(tmp); - tmp.CopyTo(result); - } - - var targetSparse = result as SparseVector; - if (targetSparse == null) - { - base.DoConjugate(result); - return; - } - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetSparse._storage.Values = new Complex[_storage.ValueCount]; - targetSparse._storage.Indices = new int[_storage.ValueCount]; - targetSparse._storage.ValueCount = _storage.ValueCount; - - if (_storage.ValueCount != 0) - { - CommonParallel.For(0, _storage.ValueCount, (a, b) => - { - for (int i = a; i < b; i++) - { - targetSparse._storage.Values[i] = _storage.Values[i].Conjugate(); - } - }); - Buffer.BlockCopy(_storage.Indices, 0, targetSparse._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); - } - } - /// /// Adds a scalar to each element of the vector and stores the result in the result vector. /// Warning, the new 'sparse vector' with a non-zero scalar added to it will be a 100% filled @@ -196,7 +158,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new Complex[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -213,7 +175,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex vnonZeroValues[indices[j]] = values[j] + scalar; } - //assign this vectors arrary to the new arrays. + //assign this vectors arrary to the new arrays. _storage.Values = vnonZeroValues; _storage.Indices = vnonZeroIndices; _storage.ValueCount = Count; @@ -427,19 +389,47 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else + + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); + sparseResult._storage.Values = new Complex[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); + } + + Control.LinearAlgebraProvider.ScaleArray(-Complex.One, sparseResult._storage.Values, sparseResult._storage.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var sparseResult = result as SparseVector; + if (sparseResult != null) { if (!ReferenceEquals(this, result)) { sparseResult._storage.ValueCount = _storage.ValueCount; sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); sparseResult._storage.Values = new Complex[_storage.ValueCount]; Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } - Control.LinearAlgebraProvider.ScaleArray(-Complex.One, sparseResult._storage.Values, sparseResult._storage.Values); + Control.LinearAlgebraProvider.ConjugateArray(sparseResult._storage.Values, sparseResult._storage.Values); + return; + } + + result.Clear(); + for (var index = 0; index < _storage.ValueCount; index++) + { + result.At(_storage.Indices[index], _storage.Values[index].Conjugate()); } } @@ -547,7 +537,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -669,7 +659,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -810,8 +800,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index 443c0883..6819fc0b 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -423,6 +423,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ConjugateArray(_values, denseResult._values); + return; + } + + base.DoConjugate(result); + } + /// /// Returns the transpose of this matrix. /// @@ -940,24 +972,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 base.DoConjugateTransposeThisAndMultiply(other, result); } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - var denseResult = result as DenseMatrix; - - if (denseResult == null) - { - base.DoNegate(result); - } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); - } - } - /// /// Divides each element of the matrix by a scalar and places results into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs index 2dc09c29..031f2bda 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs @@ -352,11 +352,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (denseResult == null) { base.DoNegate(result); + return; } - else + + Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, _values, denseResult.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var resultDense = result as DenseVector; + if (resultDense == null) { - Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, _values, denseResult.Values); + base.DoConjugate(result); + return; } + + Control.LinearAlgebraProvider.ConjugateArray(_values, resultDense._values); } /// @@ -371,11 +386,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// @@ -837,27 +851,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } #endregion - - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - var resultDense = result as DenseVector; - if (resultDense == null) - { - base.DoConjugate(result); - return; - } - - CommonParallel.For(0, _length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - resultDense._values[i] = _values[i].Conjugate(); - } - }); - } } } diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index 4c55048f..4db5dd61 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -189,6 +189,46 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 i => new Complex32((float) distribution.Sample(), (float) distribution.Sample()))); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; + } + + result.Clear(); + for (var i = 0; i < _data.Length; i++) + { + result.At(i, i, -_data[i]); + } + } + + /// + /// Complex conjugates each element of this matrix and place the results into the result matrix. + /// + /// The result of the conjugation. + protected override void DoConjugate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) + { + Control.LinearAlgebraProvider.ConjugateArray(_data, diagResult._data); + return; + } + + result.Clear(); + for (var i = 0; i < _data.Length; i++) + { + result.At(i, i, _data[i].Conjugate()); + } + } + /// /// Adds another matrix to this matrix. /// @@ -436,6 +476,52 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 base.DoTransposeAndMultiply(other, result); } + /// + /// Multiplies this matrix with the conjugate transpose of another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(otherDataCopy, otherDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; + } + + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) + { + var dense = denseOther.Data; + var diagonal = _data; + var d = Math.Min(denseOther.ColumnCount, RowCount); + if (d < RowCount) + { + result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount); + } + int index = 0; + for (int j = 0; j < d; j++) + { + for (int i = 0; i < denseOther.RowCount; i++) + { + result.At(j, i, dense[index].Conjugate()*diagonal[j]); + index++; + } + } + return; + } + + base.DoConjugateTransposeAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. /// @@ -481,6 +567,58 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 base.DoTransposeThisAndMultiply(other, result); } + /// + /// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Matrix other, Matrix result) + { + var diagonalOther = other as DiagonalMatrix; + var diagonalResult = result as DiagonalMatrix; + if (diagonalOther != null && diagonalResult != null) + { + var thisDataCopy = new Complex32[diagonalResult._data.Length]; + var otherDataCopy = new Complex32[diagonalResult._data.Length]; + Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length); + Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length); + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(thisDataCopy, thisDataCopy); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data); + return; + } + + var denseOther = other.Storage as DenseColumnMajorMatrixStorage; + if (denseOther != null) + { + var dense = denseOther.Data; + var conjugateDiagonal = new Complex32[_data.Length]; + for (int i = 0; i < _data.Length; i++) + { + conjugateDiagonal[i] = _data[i].Conjugate(); + } + + var d = Math.Min(denseOther.RowCount, ColumnCount); + if (d < ColumnCount) + { + result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount); + } + int index = 0; + for (int i = 0; i < denseOther.ColumnCount; i++) + { + for (int j = 0; j < d; j++) + { + result.At(j, i, dense[index]*conjugateDiagonal[j]); + index++; + } + index += (denseOther.RowCount - d); + } + return; + } + + base.DoConjugateTransposeThisAndMultiply(other, result); + } + /// /// Multiplies the transpose of this matrix with a vector and places the results into the result vector. /// @@ -511,6 +649,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } + /// + /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector. + /// + /// The vector to multiply with. + /// The result of the multiplication. + protected override void DoConjugateTransposeThisAndMultiply(Vector rightSide, Vector result) + { + var d = Math.Min(ColumnCount, RowCount); + if (d < ColumnCount) + { + result.ClearSubVector(RowCount, ColumnCount - RowCount); + } + + if (d == RowCount) + { + var denseOther = rightSide.Storage as DenseVectorStorage; + var denseResult = result.Storage as DenseVectorStorage; + if (denseOther != null && denseResult != null) + { + // TODO: merge/MulByConj + Control.LinearAlgebraProvider.ConjugateArray(_data, denseResult.Data); + Control.LinearAlgebraProvider.PointWiseMultiplyArrays(denseResult.Data, denseOther.Data, denseResult.Data); + return; + } + } + + for (var i = 0; i < d; i++) + { + result.At(i, _data[i].Conjugate()*rightSide.At(i)); + } + } + /// /// Computes the determinant of this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 311aec5a..6d2eb1a1 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -633,6 +633,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1031,16 +1041,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs index 2f912994..b0abb41e 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs @@ -128,44 +128,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new SparseVector(SparseVectorStorage.OfInit(length, init)); } - /// - /// Conjugates vector and save result to - /// - /// Target vector - protected override void DoConjugate(Vector result) - { - if (ReferenceEquals(this, result)) - { - var tmp = Build.SameAs(this); - DoConjugate(tmp); - tmp.CopyTo(result); - } - - var targetSparse = result as SparseVector; - if (targetSparse == null) - { - base.DoConjugate(result); - return; - } - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetSparse._storage.Values = new Complex32[_storage.ValueCount]; - targetSparse._storage.Indices = new int[_storage.ValueCount]; - targetSparse._storage.ValueCount = _storage.ValueCount; - - if (_storage.ValueCount != 0) - { - CommonParallel.For(0, _storage.ValueCount, (a, b) => - { - for (int i = a; i < b; i++) - { - targetSparse._storage.Values[i] = _storage.Values[i].Conjugate(); - } - }); - Buffer.BlockCopy(_storage.Indices, 0, targetSparse._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); - } - } - /// /// Adds a scalar to each element of the vector and stores the result in the result vector. /// Warning, the new 'sparse vector' with a non-zero scalar added to it will be a 100% filled @@ -191,7 +153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new Complex32[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -208,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 vnonZeroValues[indices[j]] = values[j] + scalar; } - //assign this vectors arrary to the new arrays. + //assign this vectors arrary to the new arrays. _storage.Values = vnonZeroValues; _storage.Indices = vnonZeroIndices; _storage.ValueCount = Count; @@ -422,19 +384,47 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else + + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); + sparseResult._storage.Values = new Complex32[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); + } + + Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, sparseResult._storage.Values, sparseResult._storage.Values); + } + + /// + /// Conjugates vector and save result to + /// + /// Target vector + protected override void DoConjugate(Vector result) + { + var sparseResult = result as SparseVector; + if (sparseResult != null) { if (!ReferenceEquals(this, result)) { sparseResult._storage.ValueCount = _storage.ValueCount; sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount*Constants.SizeOfInt); sparseResult._storage.Values = new Complex32[_storage.ValueCount]; Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } - Control.LinearAlgebraProvider.ScaleArray(-Complex32.One, sparseResult._storage.Values, sparseResult._storage.Values); + Control.LinearAlgebraProvider.ConjugateArray(sparseResult._storage.Values, sparseResult._storage.Values); + return; + } + + result.Clear(); + for (var index = 0; index < _storage.ValueCount; index++) + { + result.At(_storage.Indices[index], _storage.Values[index].Conjugate()); } } @@ -542,7 +532,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -664,7 +654,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -805,8 +795,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix /*SparseMatrix*/ OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index abb831bc..bfcefb99 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -420,6 +420,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + /// /// Returns the transpose of this matrix. /// @@ -784,24 +800,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double base.DoTransposeThisAndMultiply(other, result); } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - var denseResult = result as DenseMatrix; - - if (denseResult == null) - { - base.DoNegate(result); - } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); - } - } - /// /// Divides each element of the matrix by a scalar and places results into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index ae78f98d..53d1465a 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -362,11 +362,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (denseResult == null) { base.DoNegate(result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1.0d, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(-1.0d, _values, denseResult.Values); } /// @@ -381,11 +380,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index 2daca108..3f6702dd 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -188,6 +188,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double i => distribution.Sample())); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; + } + + result.Clear(); + for (var i = 0; i < _data.Length; i++) + { + result.At(i, i, -_data[i]); + } + } + /// /// Adds another matrix to this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index a2ff1428..153d3583 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -365,7 +365,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Complex conjugates each element of this matrix and place the results into the result matrix. /// /// The result of the conjugation. - protected override void DoConjugate(Matrix result) + protected override sealed void DoConjugate(Matrix result) { if (ReferenceEquals(this, result)) { diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 8ccb916a..e3a9c384 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -631,6 +631,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1031,16 +1041,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index b1337963..c02aea3f 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -145,7 +145,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { if (!ReferenceEquals(this, result)) { - CopyTo(result); + CopyTo(result); } return; @@ -153,7 +153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new double[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -384,20 +384,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else - { - if (!ReferenceEquals(this, result)) - { - sparseResult._storage.ValueCount = _storage.ValueCount; - sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); - sparseResult._storage.Values = new double[_storage.ValueCount]; - Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); - } - Control.LinearAlgebraProvider.ScaleArray(-1.0d, sparseResult._storage.Values, sparseResult._storage.Values); + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + sparseResult._storage.Values = new double[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } + + Control.LinearAlgebraProvider.ScaleArray(-1.0d, sparseResult._storage.Values, sparseResult._storage.Values); } /// @@ -503,7 +502,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -625,7 +624,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -652,7 +651,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Returns the index of the absolute maximum element. /// - /// The index of absolute maximum element. + /// The index of absolute maximum element. public override int MaximumIndex() { if (_storage.ValueCount == 0) @@ -677,7 +676,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Returns the index of the minimum element. /// - /// The index of minimum element. + /// The index of minimum element. public override int MinimumIndex() { if (_storage.ValueCount == 0) @@ -773,7 +772,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { for (var i = 0; i < _storage.ValueCount; i++) { - _storage.Values[i] *= _storage.Values[i]; + _storage.Values[i] *= _storage.Values[i]; } } else @@ -816,8 +815,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 4691979b..10b65a1c 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -420,6 +420,22 @@ namespace MathNet.Numerics.LinearAlgebra.Single return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var denseResult = result as DenseMatrix; + if (denseResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); + return; + } + + base.DoNegate(result); + } + /// /// Returns the transpose of this matrix. /// @@ -784,24 +800,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single base.DoTransposeThisAndMultiply(other, result); } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - var denseResult = result as DenseMatrix; - - if (denseResult == null) - { - base.DoNegate(result); - } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1, _values, denseResult._values); - } - } - /// /// Divides each element of the matrix by a scalar and places results into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs index f36fd081..19762f2d 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs @@ -351,11 +351,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (denseResult == null) { base.DoNegate(result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(-1.0f, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(-1.0f, _values, denseResult.Values); } /// @@ -370,11 +369,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (denseResult == null) { base.DoMultiply(scalar, result); + return; } - else - { - Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); - } + + Control.LinearAlgebraProvider.ScaleArray(scalar, _values, denseResult.Values); } /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 5b84ee75..0c365220 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -188,6 +188,26 @@ namespace MathNet.Numerics.LinearAlgebra.Single i => (float) distribution.Sample())); } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + var diagResult = result as DiagonalMatrix; + if (diagResult != null) + { + Control.LinearAlgebraProvider.ScaleArray(-1, _data, diagResult._data); + return; + } + + result.Clear(); + for (var i = 0; i < _data.Length; i++) + { + result.At(i, i, -_data[i]); + } + } + /// /// Adds another matrix to this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Single/Matrix.cs b/src/Numerics/LinearAlgebra/Single/Matrix.cs index a13fda54..de324d48 100644 --- a/src/Numerics/LinearAlgebra/Single/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Single/Matrix.cs @@ -397,7 +397,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Complex conjugates each element of this matrix and place the results into the result matrix. /// /// The result of the conjugation. - protected override void DoConjugate(Matrix result) + protected override sealed void DoConjugate(Matrix result) { if (ReferenceEquals(this, result)) { diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index 9d3adb85..403fd6f7 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -631,6 +631,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } + /// + /// Negate each element of this matrix and place the results into the result matrix. + /// + /// The result of the negation. + protected override void DoNegate(Matrix result) + { + CopyTo(result); + DoMultiply(-1, result); + } + /// /// Returns the transpose of this matrix. /// @@ -1038,16 +1048,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - /// - /// Negate each element of this matrix and place the results into the result matrix. - /// - /// The result of the negation. - protected override void DoNegate(Matrix result) - { - CopyTo(result); - DoMultiply(-1, result); - } - /// /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs index e367bc55..5fcc98cc 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -153,7 +153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single if (ReferenceEquals(this, result)) { - //populate a new vector with the scalar + //populate a new vector with the scalar var vnonZeroValues = new float[Count]; var vnonZeroIndices = new int[Count]; for (int index = 0; index < Count; index++) @@ -170,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single vnonZeroValues[indices[j]] = values[j] + scalar; } - //assign this vectors arrary to the new arrays. + //assign this vectors arrary to the new arrays. _storage.Values = vnonZeroValues; _storage.Indices = vnonZeroIndices; _storage.ValueCount = Count; @@ -385,20 +385,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single { result.At(_storage.Indices[index], -_storage.Values[index]); } + return; } - else - { - if (!ReferenceEquals(this, result)) - { - sparseResult._storage.ValueCount = _storage.ValueCount; - sparseResult._storage.Indices = new int[_storage.ValueCount]; - Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); - sparseResult._storage.Values = new float[_storage.ValueCount]; - Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); - } - Control.LinearAlgebraProvider.ScaleArray(-1.0f, sparseResult._storage.Values, sparseResult._storage.Values); + if (!ReferenceEquals(this, result)) + { + sparseResult._storage.ValueCount = _storage.ValueCount; + sparseResult._storage.Indices = new int[_storage.ValueCount]; + Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt); + sparseResult._storage.Values = new float[_storage.ValueCount]; + Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount); } + + Control.LinearAlgebraProvider.ScaleArray(-1.0f, sparseResult._storage.Values, sparseResult._storage.Values); } /// @@ -504,7 +503,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single } /// - /// Returns a Vector containing the negated values of . + /// Returns a Vector containing the negated values of . /// /// The vector to get the values from. /// A vector containing the negated values as . @@ -626,7 +625,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Returns the index of the absolute minimum element. /// - /// The index of absolute minimum element. + /// The index of absolute minimum element. public override int AbsoluteMinimumIndex() { if (_storage.ValueCount == 0) @@ -653,7 +652,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Returns the index of the absolute maximum element. /// - /// The index of absolute maximum element. + /// The index of absolute maximum element. public override int MaximumIndex() { if (_storage.ValueCount == 0) @@ -678,7 +677,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Returns the index of the minimum element. /// - /// The index of minimum element. + /// The index of minimum element. public override int MinimumIndex() { if (_storage.ValueCount == 0) @@ -817,8 +816,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// First vector /// Second vector /// Matrix M[i,j] = u[i]*v[j] - /// If the u vector is . - /// If the v vector is . + /// If the u vector is . + /// If the v vector is . public static Matrix OuterProduct(SparseVector u, SparseVector v) { if (u == null) diff --git a/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs index cda85ac6..4c8e89e1 100644 --- a/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs @@ -131,6 +131,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra /// This is similar to the SCAL BLAS routine. void ScaleArray(T alpha, T[] x, T[] result); + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + void ConjugateArray(T[] x, T[] result); + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs index db336da7..d366b9ab 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs @@ -166,6 +166,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(Complex[] x, Complex[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (Control.ParallelizeOperation(x.Length)) + { + CommonParallel.For(0, x.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = x[i].Conjugate(); + } + }); + } + else + { + for (var index = 0; index < x.Length; index++) + { + result[index] = x[index].Conjugate(); + } + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs index cb098939..0298a3ac 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs @@ -163,6 +163,37 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(Complex32[] x, Complex32[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (Control.ParallelizeOperation(x.Length)) + { + CommonParallel.For(0, x.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = x[i].Conjugate(); + } + }); + } + else + { + for (var index = 0; index < x.Length; index++) + { + result[index] = x[index].Conjugate(); + } + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs index 3194284a..9365eec9 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs @@ -160,6 +160,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(double[] x, double[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (!ReferenceEquals(x, result)) + { + x.CopyTo(result, 0); + } + } + /// /// Computes the dot product of x and y. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs index d472a120..6094cb83 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs @@ -160,6 +160,24 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } } + /// + /// Conjugates an array. Can be used to conjugate a vector and a matrix. + /// + /// The values to conjugate. + /// This result of the conjugation. + public virtual void ConjugateArray(float[] x, float[] result) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (!ReferenceEquals(x, result)) + { + x.CopyTo(result, 0); + } + } + /// /// Computes the dot product of x and y. ///