void ValidateSubRowRange(MatrixStorage <T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount) { if (columnCount < 1) { throw new ArgumentOutOfRangeException(nameof(columnCount), "Value must be positive."); } // Verify Source if ((uint)sourceColumnIndex >= (uint)Length) { throw new ArgumentOutOfRangeException(nameof(sourceColumnIndex)); } if (sourceColumnIndex + columnCount > Length) { throw new ArgumentOutOfRangeException(nameof(columnCount)); } // Verify Target if ((uint)rowIndex >= (uint)target.RowCount) { throw new ArgumentOutOfRangeException(nameof(rowIndex)); } if ((uint)targetColumnIndex >= (uint)target.ColumnCount) { throw new ArgumentOutOfRangeException(nameof(targetColumnIndex)); } if (targetColumnIndex + columnCount > target.ColumnCount) { throw new ArgumentOutOfRangeException(nameof(columnCount)); } }
// TRANSPOSE internal override void TransposeToUnchecked(MatrixStorage <T> target, ExistingData existingData) { if (target is DenseColumnMajorMatrixStorage <T> denseTarget) { TransposeToUnchecked(denseTarget); return; } if (target is SparseCompressedRowMatrixStorage <T> sparseTarget) { TransposeToUnchecked(sparseTarget); return; } // FALL BACK for (int j = 0, offset = 0; j < ColumnCount; j++, offset += RowCount) { for (int i = 0; i < RowCount; i++) { target.At(j, i, Data[i + offset]); } } }
internal override void CopySubMatrixToUnchecked(MatrixStorage <T> target, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount, ExistingData existingData) { if (target is DenseColumnMajorMatrixStorage <T> denseTarget) { CopySubMatrixToUnchecked(denseTarget, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount); return; } // TODO: Proper Sparse Implementation // FALL BACK for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) { int index = sourceRowIndex + j * RowCount; for (int ii = targetRowIndex; ii < targetRowIndex + rowCount; ii++) { target.At(ii, jj, Data[index++]); } } }
internal override Tuple <int, int, T, TOther> Find2Unchecked <TOther>(MatrixStorage <TOther> other, Func <T, TOther, bool> predicate, Zeros zeros) { if (other is DenseColumnMajorMatrixStorage <TOther> denseOther) { TOther[] otherData = denseOther.Data; for (int i = 0; i < Data.Length; i++) { if (predicate(Data[i], otherData[i])) { int row, column; RowColumnAtIndex(i, out row, out column); return(new Tuple <int, int, T, TOther>(row, column, Data[i], otherData[i])); } } return(null); } if (other is DiagonalMatrixStorage <TOther> diagonalOther) { TOther[] otherData = diagonalOther.Data; TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; int k = 0; for (int j = 0; j < ColumnCount; j++) { for (int i = 0; i < RowCount; i++) { if (predicate(Data[k], i == j ? otherData[i] : otherZero)) { return(new Tuple <int, int, T, TOther>(i, j, Data[k], i == j ? otherData[i] : otherZero)); } k++; } } return(null); } if (other is SparseCompressedRowMatrixStorage <TOther> sparseOther) { int[] otherRowPointers = sparseOther.RowPointers; int[] otherColumnIndices = sparseOther.ColumnIndices; TOther[] otherValues = sparseOther.Values; TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; int k = 0; for (int row = 0; row < RowCount; row++) { for (int col = 0; col < ColumnCount; col++) { if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col) { if (predicate(Data[col * RowCount + row], otherValues[k])) { return(new Tuple <int, int, T, TOther>(row, col, Data[col * RowCount + row], otherValues[k])); } k++; } else { if (predicate(Data[col * RowCount + row], otherZero)) { return(new Tuple <int, int, T, TOther>(row, col, Data[col * RowCount + row], otherValues[k])); } } } } return(null); } // FALL BACK return(base.Find2Unchecked(other, predicate, zeros)); }
internal override void MapSubMatrixIndexedToUnchecked <TU>(MatrixStorage <TU> target, Func <int, int, T, TU> f, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount, Zeros zeros, ExistingData existingData) { if (target is DiagonalMatrixStorage <TU> diagonalTarget) { MapSubMatrixIndexedToUnchecked(diagonalTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros); return; } if (target is DenseColumnMajorMatrixStorage <TU> denseTarget) { MapSubMatrixIndexedToUnchecked(denseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros, existingData); return; } // TODO: Proper Sparse Implementation // FALL BACK if (existingData == ExistingData.Clear) { target.ClearUnchecked(targetRowIndex, rowCount, targetColumnIndex, columnCount); } if (sourceRowIndex == sourceColumnIndex) { int targetRow = targetRowIndex; int targetColumn = targetColumnIndex; for (var i = 0; i < Math.Min(columnCount, rowCount); i++) { target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceRowIndex + i])); targetRow++; targetColumn++; } } else if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex) { // column by column, but skip resulting zero columns at the beginning int columnInit = sourceRowIndex - sourceColumnIndex; int targetRow = targetRowIndex; int targetColumn = targetColumnIndex + columnInit; for (var i = 0; i < Math.Min(columnCount - columnInit, rowCount); i++) { target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceRowIndex + i])); targetRow++; targetColumn++; } } else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex) { // row by row, but skip resulting zero rows at the beginning int rowInit = sourceColumnIndex - sourceRowIndex; int targetRow = targetRowIndex + rowInit; int targetColumn = targetColumnIndex; for (var i = 0; i < Math.Min(columnCount, rowCount - rowInit); i++) { target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceColumnIndex + i])); targetRow++; targetColumn++; } } }
internal override Tuple <int, int, T, TOther> Find2Unchecked <TOther>(MatrixStorage <TOther> other, Func <T, TOther, bool> predicate, Zeros zeros) { if (other is DenseColumnMajorMatrixStorage <TOther> denseOther) { TOther[] otherData = denseOther.Data; int k = 0; for (int j = 0; j < ColumnCount; j++) { for (int i = 0; i < RowCount; i++) { if (predicate(i == j ? Data[i] : Zero, otherData[k])) { return(new Tuple <int, int, T, TOther>(i, j, i == j ? Data[i] : Zero, otherData[k])); } k++; } } return(null); } if (other is DiagonalMatrixStorage <TOther> diagonalOther) { TOther[] otherData = diagonalOther.Data; for (int i = 0; i < Data.Length; i++) { if (predicate(Data[i], otherData[i])) { return(new Tuple <int, int, T, TOther>(i, i, Data[i], otherData[i])); } } if (zeros == Zeros.Include && (RowCount > 1 || ColumnCount > 1)) { TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; if (predicate(Zero, otherZero)) { return(new Tuple <int, int, T, TOther>(RowCount > 1 ? 1 : 0, RowCount > 1 ? 0 : 1, Zero, otherZero)); } } return(null); } if (other is SparseCompressedRowMatrixStorage <TOther> sparseOther) { int[] otherRowPointers = sparseOther.RowPointers; int[] otherColumnIndices = sparseOther.ColumnIndices; TOther[] otherValues = sparseOther.Values; TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; for (int row = 0; row < RowCount; row++) { bool diagonal = false; var startIndex = otherRowPointers[row]; var endIndex = otherRowPointers[row + 1]; for (var j = startIndex; j < endIndex; j++) { if (otherColumnIndices[j] == row) { diagonal = true; if (predicate(Data[row], otherValues[j])) { return(new Tuple <int, int, T, TOther>(row, row, Data[row], otherValues[j])); } } else { if (predicate(Zero, otherValues[j])) { return(new Tuple <int, int, T, TOther>(row, otherColumnIndices[j], Zero, otherValues[j])); } } } if (!diagonal && row < ColumnCount) { if (predicate(Data[row], otherZero)) { return(new Tuple <int, int, T, TOther>(row, row, Data[row], otherZero)); } } } if (zeros == Zeros.Include && sparseOther.ValueCount < (RowCount * ColumnCount)) { if (predicate(Zero, otherZero)) { int k = 0; for (int row = 0; row < RowCount; row++) { for (int col = 0; col < ColumnCount; col++) { if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col) { k++; } else if (row != col) { return(new Tuple <int, int, T, TOther>(row, col, Zero, otherZero)); } } } } } return(null); } // FALL BACK return(base.Find2Unchecked(other, predicate, zeros)); }
// TRANSPOSE internal override void TransposeToUnchecked(MatrixStorage <T> target, ExistingData existingData) { CopyToUnchecked(target, existingData); }
internal override TState Fold2Unchecked <TOther, TState>(MatrixStorage <TOther> other, Func <TState, T, TOther, TState> f, TState state, Zeros zeros) { if (other is DenseColumnMajorMatrixStorage <TOther> denseOther) { TOther[] otherData = denseOther.Data; int k = 0; for (int j = 0; j < ColumnCount; j++) { for (int i = 0; i < RowCount; i++) { state = f(state, i == j ? Data[i] : Zero, otherData[k]); k++; } } return(state); } if (other is DiagonalMatrixStorage <TOther> diagonalOther) { TOther[] otherData = diagonalOther.Data; for (int i = 0; i < Data.Length; i++) { state = f(state, Data[i], otherData[i]); } // Do we really need to do this? if (zeros == Zeros.Include) { TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; int count = RowCount * ColumnCount - Data.Length; for (int i = 0; i < count; i++) { state = f(state, Zero, otherZero); } } return(state); } if (other is SparseCompressedRowMatrixStorage <TOther> sparseOther) { int[] otherRowPointers = sparseOther.RowPointers; int[] otherColumnIndices = sparseOther.ColumnIndices; TOther[] otherValues = sparseOther.Values; TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; if (zeros == Zeros.Include) { int k = 0; for (int row = 0; row < RowCount; row++) { for (int col = 0; col < ColumnCount; col++) { if (k < otherRowPointers[row + 1] && otherColumnIndices[k] == col) { state = f(state, row == col ? Data[row] : Zero, otherValues[k++]); } else { state = f(state, row == col ? Data[row] : Zero, otherZero); } } } return(state); } for (int row = 0; row < RowCount; row++) { bool diagonal = false; var startIndex = otherRowPointers[row]; var endIndex = otherRowPointers[row + 1]; for (var j = startIndex; j < endIndex; j++) { if (otherColumnIndices[j] == row) { diagonal = true; state = f(state, Data[row], otherValues[j]); } else { state = f(state, Zero, otherValues[j]); } } if (!diagonal && row < ColumnCount) { state = f(state, Data[row], otherZero); } } return(state); } // FALL BACK return(base.Fold2Unchecked(other, f, state, zeros)); }
void ValidateSubMatrixRange <TU>(MatrixStorage <TU> target, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount) where TU : struct, IEquatable <TU>, IFormattable { if (rowCount < 1) { throw new ArgumentOutOfRangeException(nameof(rowCount), "Value must be positive."); } if (columnCount < 1) { throw new ArgumentOutOfRangeException(nameof(columnCount), "Value must be positive."); } // Verify Source if ((uint)sourceRowIndex >= (uint)RowCount) { throw new ArgumentOutOfRangeException(nameof(sourceRowIndex)); } if ((uint)sourceColumnIndex >= (uint)ColumnCount) { throw new ArgumentOutOfRangeException(nameof(sourceColumnIndex)); } var sourceRowMax = sourceRowIndex + rowCount; var sourceColumnMax = sourceColumnIndex + columnCount; if (sourceRowMax > RowCount) { throw new ArgumentOutOfRangeException(nameof(rowCount)); } if (sourceColumnMax > ColumnCount) { throw new ArgumentOutOfRangeException(nameof(columnCount)); } // Verify Target if ((uint)targetRowIndex >= (uint)target.RowCount) { throw new ArgumentOutOfRangeException(nameof(targetRowIndex)); } if ((uint)targetColumnIndex >= (uint)target.ColumnCount) { throw new ArgumentOutOfRangeException(nameof(targetColumnIndex)); } var targetRowMax = targetRowIndex + rowCount; var targetColumnMax = targetColumnIndex + columnCount; if (targetRowMax > target.RowCount) { throw new ArgumentOutOfRangeException(nameof(rowCount)); } if (targetColumnMax > target.ColumnCount) { throw new ArgumentOutOfRangeException(nameof(columnCount)); } }