internal virtual void CopySubVectorToUnchecked(VectorStorage <T> target, int sourceIndex, int targetIndex, int count, ExistingData existingData) { if (ReferenceEquals(this, target)) { var tmp = new T[count]; for (int i = 0; i < tmp.Length; i++) { tmp[i] = At(i + sourceIndex); } for (int i = 0; i < tmp.Length; i++) { At(i + targetIndex, tmp[i]); } return; } for (int i = sourceIndex, ii = targetIndex; i < sourceIndex + count; i++, ii++) { target.At(ii, At(i)); } }
// COLUMN COPY internal override void CopyToColumnUnchecked(MatrixStorage <T> target, int columnIndex, ExistingData existingData) { if (existingData == ExistingData.Clear) { target.ClearUnchecked(0, Length, columnIndex, 1); } if (ValueCount == 0) { return; } for (int i = 0; i < ValueCount; i++) { target.At(Indices[i], columnIndex, Values[i]); } }
void CopySubVectorToUnchecked(SparseVectorStorage <T> target, int sourceIndex, int targetIndex, int count, ExistingData existingData) { var offset = targetIndex - sourceIndex; var sourceFirst = Array.BinarySearch(Indices, 0, ValueCount, sourceIndex); var sourceLast = Array.BinarySearch(Indices, 0, ValueCount, sourceIndex + count - 1); if (sourceFirst < 0) { sourceFirst = ~sourceFirst; } if (sourceLast < 0) { sourceLast = ~sourceLast - 1; } int sourceCount = sourceLast - sourceFirst + 1; // special case when copying to itself if (ReferenceEquals(this, target)) { var values = new T[sourceCount]; var indices = new int[sourceCount]; Array.Copy(Values, sourceFirst, values, 0, sourceCount); for (int i = 0; i < indices.Length; i++) { indices[i] = Indices[i + sourceFirst]; } if (existingData == ExistingData.Clear) { Clear(targetIndex, count); } for (int i = sourceFirst; i <= sourceLast; i++) { At(indices[i] + offset, values[i]); } return; } // special case for empty target - much faster if (target.ValueCount == 0) { var values = new T[sourceCount]; var indices = new int[sourceCount]; Array.Copy(Values, sourceFirst, values, 0, sourceCount); for (int i = 0; i < indices.Length; i++) { indices[i] = Indices[i + sourceFirst] + offset; } target.ValueCount = sourceCount; target.Values = values; target.Indices = indices; return; } if (existingData == ExistingData.Clear) { target.Clear(targetIndex, count); } for (int i = sourceFirst; i <= sourceLast; i++) { target.At(Indices[i] + offset, Values[i]); } }
internal override void MapIndexedToUnchecked <TU>(VectorStorage <TU> target, Func <int, T, TU> f, Zeros zeros, ExistingData existingData) { var denseTarget = target as DenseVectorStorage <TU>; if (denseTarget != null) { CommonParallel.For(0, Data.Length, 4096, (a, b) => { for (int i = a; i < b; i++) { denseTarget.Data[i] = f(i, Data[i]); } }); return; } // FALL BACK for (int i = 0; i < Length; i++) { target.At(i, f(i, Data[i])); } }
internal override void Map2ToUnchecked(VectorStorage <T> target, VectorStorage <T> other, Func <T, T, T> f, Zeros zeros, ExistingData existingData) { var processZeros = zeros == Zeros.Include || !Zero.Equals(f(Zero, Zero)); var denseTarget = target as DenseVectorStorage <T>; var denseOther = other as DenseVectorStorage <T>; if (denseTarget == null && (denseOther != null || processZeros)) { // The handling is effectively dense but we're supposed to push // to a sparse target. Let's use a dense target instead, // then copy it normalized back to the sparse target. var intermediate = new DenseVectorStorage <T>(target.Length); Map2ToUnchecked(intermediate, other, f, zeros, ExistingData.AssumeZeros); intermediate.CopyTo(target, existingData); return; } if (denseOther != null) { var targetData = denseTarget.Data; var otherData = denseOther.Data; var k = 0; for (var i = 0; i < otherData.Length; i++) { if (k < ValueCount && Indices[k] == i) { targetData[i] = f(Values[k], otherData[i]); k++; } else { targetData[i] = f(Zero, otherData[i]); } } return; } var sparseOther = other as SparseVectorStorage <T>; if (sparseOther != null && denseTarget != null) { var targetData = denseTarget.Data; var otherIndices = sparseOther.Indices; var otherValues = sparseOther.Values; var otherValueCount = sparseOther.ValueCount; if (processZeros) { int p = 0, q = 0; for (var i = 0; i < targetData.Length; i++) { var left = p < ValueCount && Indices[p] == i ? Values[p++] : Zero; var right = q < otherValueCount && otherIndices[q] == i ? otherValues[q++] : Zero; targetData[i] = f(left, right); } } else { if (existingData == ExistingData.Clear) { denseTarget.Clear(); } int p = 0, q = 0; while (p < ValueCount || q < otherValueCount) { if (q >= otherValueCount || p < ValueCount && Indices[p] < otherIndices[q]) { targetData[Indices[p]] = f(Values[p], Zero); p++; } else if (p >= ValueCount || q < otherValueCount && Indices[p] > otherIndices[q]) { targetData[otherIndices[q]] = f(Zero, otherValues[q]); q++; } else { Debug.Assert(Indices[p] == otherIndices[q]); targetData[Indices[p]] = f(Values[p], otherValues[q]); p++; q++; } } } return; } var sparseTarget = target as SparseVectorStorage <T>; if (sparseOther != null && sparseTarget != null) { var indices = new List <int>(); var values = new List <T>(); var otherIndices = sparseOther.Indices; var otherValues = sparseOther.Values; var otherValueCount = sparseOther.ValueCount; int p = 0, q = 0; while (p < ValueCount || q < otherValueCount) { if (q >= otherValueCount || p < ValueCount && Indices[p] < otherIndices[q]) { var value = f(Values[p], Zero); if (!Zero.Equals(value)) { indices.Add(Indices[p]); values.Add(value); } p++; } else if (p >= ValueCount || q < otherValueCount && Indices[p] > otherIndices[q]) { var value = f(Zero, otherValues[q]); if (!Zero.Equals(value)) { indices.Add(otherIndices[q]); values.Add(value); } q++; } else { var value = f(Values[p], otherValues[q]); if (!Zero.Equals(value)) { indices.Add(Indices[p]); values.Add(value); } p++; q++; } } sparseTarget.Indices = indices.ToArray(); sparseTarget.Values = values.ToArray(); sparseTarget.ValueCount = values.Count; return; } // FALL BACK base.Map2ToUnchecked(target, other, f, zeros, existingData); }
// COLUMN COPY internal override void CopyToColumnUnchecked(MatrixStorage <T> target, int columnIndex, ExistingData existingData) { var denseTarget = target as DenseColumnMajorMatrixStorage <T>; if (denseTarget != null) { Array.Copy(Data, 0, denseTarget.Data, columnIndex * denseTarget.RowCount, Data.Length); return; } // FALL BACK for (int i = 0; i < Length; i++) { target.At(i, columnIndex, Data[i]); } }
// SUB-ROW COPY internal override void CopyToSubRowUnchecked(MatrixStorage <T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, ExistingData existingData) { var denseTarget = target as DenseColumnMajorMatrixStorage <T>; if (denseTarget != null) { for (int j = 0; j < Data.Length; j++) { denseTarget.Data[(j + targetColumnIndex) * target.RowCount + rowIndex] = Data[j + sourceColumnIndex]; } return; } // FALL BACK for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) { target.At(rowIndex, jj, Data[j]); } }
internal virtual void MapIndexedToUnchecked <TU>(MatrixStorage <TU> target, Func <int, int, T, TU> f, Zeros zeros, ExistingData existingData) where TU : struct, IEquatable <TU>, IFormattable { for (int j = 0; j < ColumnCount; j++) { for (int i = 0; i < RowCount; i++) { target.At(i, j, f(i, j, At(i, j))); } } }
public void Map2To(MatrixStorage <T> target, MatrixStorage <T> other, Func <T, T, T> f, Zeros zeros, ExistingData existingData) { if (target == null) { throw new ArgumentNullException("target"); } if (other == null) { throw new ArgumentNullException("other"); } if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) { var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount); throw new ArgumentException(message, "target"); } if (RowCount != other.RowCount || ColumnCount != other.ColumnCount) { var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, other.RowCount + "x" + other.ColumnCount); throw new ArgumentException(message, "other"); } Map2ToUnchecked(target, other, f, zeros, existingData); }
internal virtual void CopySubRowToUnchecked(VectorStorage <T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, ExistingData existingData) { for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) { target.At(jj, At(rowIndex, j)); } }
internal virtual void CopySubColumnToUnchecked(VectorStorage <T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, ExistingData existingData) { for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++) { target.At(ii, At(i, columnIndex)); } }
internal override void MapToUnchecked <TU>(VectorStorage <TU> target, Func <T, TU> f, Zeros zeros, ExistingData existingData) { var denseTarget = target as DenseVectorStorage <TU>; if (denseTarget != null) { for (int i = 0; i < Data.Length; i++) { denseTarget.Data[i] = f(Data[i]); } return; } // FALL BACK for (int i = 0; i < Length; i++) { target.At(i, f(Data[i])); } }
internal virtual void Map2ToUnchecked(VectorStorage <T> target, VectorStorage <T> other, Func <T, T, T> f, Zeros zeros, ExistingData existingData) { for (int i = 0; i < Length; i++) { target.At(i, f(At(i), other.At(i))); } }
internal virtual void MapToUnchecked <TU>(VectorStorage <TU> target, Func <T, TU> f, Zeros zeros, ExistingData existingData) where TU : struct, IEquatable <TU>, IFormattable { for (int i = 0; i < Length; i++) { target.At(i, f(At(i))); } }
internal virtual void MapIndexedToUnchecked <TU>(VectorStorage <TU> target, Func <int, T, TU> f, Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear) where TU : struct, IEquatable <TU>, IFormattable { for (int i = 0; i < Length; i++) { target.At(i, f(i, At(i))); } }
internal virtual void Map2ToUnchecked(MatrixStorage <T> target, MatrixStorage <T> other, Func <T, T, T> f, Zeros zeros, ExistingData existingData) { for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColumnCount; j++) { target.At(i, j, f(At(i, j), other.At(i, j))); } } }
// ROW COPY internal override void CopyToRowUnchecked(MatrixStorage <T> target, int rowIndex, ExistingData existingData) { var denseTarget = target as DenseColumnMajorMatrixStorage <T>; if (denseTarget != null) { for (int j = 0; j < Data.Length; j++) { denseTarget.Data[j * target.RowCount + rowIndex] = Data[j]; } return; } // FALL BACK for (int j = 0; j < Length; j++) { target.At(rowIndex, j, Data[j]); } }
// COLUMN COPY internal override void CopySubColumnToUnchecked(VectorStorage <T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, ExistingData existingData) { if (existingData == ExistingData.Clear) { target.Clear(targetRowIndex, rowCount); } if (columnIndex >= sourceRowIndex && columnIndex < sourceRowIndex + rowCount && columnIndex < Data.Length) { target.At(columnIndex - sourceRowIndex + targetRowIndex, Data[columnIndex]); } }
// SUB-VECTOR COPY internal override void CopySubVectorToUnchecked(VectorStorage <T> target, int sourceIndex, int targetIndex, int count, ExistingData existingData) { var denseTarget = target as DenseVectorStorage <T>; if (denseTarget != null) { Array.Copy(Data, sourceIndex, denseTarget.Data, targetIndex, count); return; } // FALL BACK base.CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, existingData); }
// TRANSPOSE internal override void TransposeToUnchecked(MatrixStorage <T> target, ExistingData existingData) { CopyToUnchecked(target, existingData); }
// SUB-COLUMN COPY internal override void CopyToSubColumnUnchecked(MatrixStorage <T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, ExistingData existingData) { var denseTarget = target as DenseColumnMajorMatrixStorage <T>; if (denseTarget != null) { Array.Copy(Data, sourceRowIndex, denseTarget.Data, columnIndex * denseTarget.RowCount + targetRowIndex, rowCount); return; } // FALL BACK for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++) { target.At(ii, columnIndex, Data[i]); } }
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) { var diagonalTarget = target as DiagonalMatrixStorage <TU>; if (diagonalTarget != null) { MapSubMatrixIndexedToUnchecked(diagonalTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros); return; } var denseTarget = target as DenseColumnMajorMatrixStorage <TU>; if (denseTarget != null) { 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 void Map2ToUnchecked(VectorStorage <T> target, VectorStorage <T> other, Func <T, T, T> f, Zeros zeros, ExistingData existingData) { if (target is SparseVectorStorage <T> ) { // Recursive to dense target at first, since the operation is // effectively dense anyway because at least one operand is dense var intermediate = new DenseVectorStorage <T>(target.Length); Map2ToUnchecked(intermediate, other, f, zeros, ExistingData.AssumeZeros); intermediate.CopyTo(target, existingData); return; } var denseTarget = target as DenseVectorStorage <T>; var denseOther = other as DenseVectorStorage <T>; if (denseTarget != null && denseOther != null) { CommonParallel.For(0, Data.Length, 4096, (a, b) => { for (int i = a; i < b; i++) { denseTarget.Data[i] = f(Data[i], denseOther.Data[i]); } }); return; } var sparseOther = other as SparseVectorStorage <T>; if (denseTarget != null && sparseOther != null) { T[] targetData = denseTarget.Data; int[] otherIndices = sparseOther.Indices; T[] otherValues = sparseOther.Values; int otherValueCount = sparseOther.ValueCount; int k = 0; for (int i = 0; i < Data.Length; i++) { if (k < otherValueCount && otherIndices[k] == i) { targetData[i] = f(Data[i], otherValues[k]); k++; } else { targetData[i] = f(Data[i], Zero); } } return; } base.Map2ToUnchecked(target, other, f, zeros, existingData); }
void MapSubMatrixIndexedToUnchecked <TU>(DenseColumnMajorMatrixStorage <TU> target, Func <int, int, T, TU> f, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount, Zeros zeros, ExistingData existingData) where TU : struct, IEquatable <TU>, IFormattable { var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero)); if (existingData == ExistingData.Clear && !processZeros) { target.ClearUnchecked(targetRowIndex, rowCount, targetColumnIndex, columnCount); } if (processZeros) { CommonParallel.For(0, columnCount, Math.Max(4096 / rowCount, 32), (a, b) => { int sourceColumn = sourceColumnIndex + a; int targetColumn = targetColumnIndex + a; for (int j = a; j < b; j++) { int targetIndex = targetRowIndex + (j + targetColumnIndex) * target.RowCount; int sourceRow = sourceRowIndex; int targetRow = targetRowIndex; for (int i = 0; i < rowCount; i++) { target.Data[targetIndex++] = f(targetRow++, targetColumn, sourceRow++ == sourceColumn ? Data[sourceColumn] : Zero); } sourceColumn++; targetColumn++; } }); } else { if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex) { // column by column, but skip resulting zero columns at the beginning int columnInit = sourceRowIndex - sourceColumnIndex; int offset = (columnInit + targetColumnIndex) * target.RowCount + targetRowIndex; int step = target.RowCount + 1; int count = Math.Min(columnCount - columnInit, rowCount); for (int k = 0, j = offset; k < count; j += step, k++) { target.Data[j] = f(targetRowIndex + k, targetColumnIndex + columnInit + k, Data[sourceRowIndex + k]); } } else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex) { // row by row, but skip resulting zero rows at the beginning int rowInit = sourceColumnIndex - sourceRowIndex; int offset = targetColumnIndex * target.RowCount + rowInit + targetRowIndex; int step = target.RowCount + 1; int count = Math.Min(columnCount, rowCount - rowInit); for (int k = 0, j = offset; k < count; j += step, k++) { target.Data[j] = f(targetRowIndex + rowInit + k, targetColumnIndex + k, Data[sourceColumnIndex + k]); } } else { int offset = targetColumnIndex * target.RowCount + targetRowIndex; int step = target.RowCount + 1; var count = Math.Min(columnCount, rowCount); for (int k = 0, j = offset; k < count; j += step, k++) { target.Data[j] = f(targetRowIndex + k, targetColumnIndex + k, Data[sourceRowIndex + k]); } } } }
// Row COPY internal override void CopyToRowUnchecked(MatrixStorage <T> target, int rowIndex, ExistingData existingData) { if (existingData == ExistingData.Clear) { target.ClearUnchecked(rowIndex, 1, 0, Length); } if (ValueCount == 0) { return; } for (int i = 0; i < ValueCount; i++) { target.At(rowIndex, Indices[i], Values[i]); } }
internal virtual void CopyToRowUnchecked(MatrixStorage <T> target, int rowIndex, ExistingData existingData = ExistingData.Clear) { for (int j = 0; j < Length; j++) { target.At(rowIndex, j, At(j)); } }
// SUB-VECTOR COPY internal override void CopySubVectorToUnchecked(VectorStorage <T> target, int sourceIndex, int targetIndex, int count, ExistingData existingData) { var sparseTarget = target as SparseVectorStorage <T>; if (sparseTarget != null) { CopySubVectorToUnchecked(sparseTarget, sourceIndex, targetIndex, count, existingData); return; } // FALL BACK var offset = targetIndex - sourceIndex; var sourceFirst = Array.BinarySearch(Indices, 0, ValueCount, sourceIndex); var sourceLast = Array.BinarySearch(Indices, 0, ValueCount, sourceIndex + count - 1); if (sourceFirst < 0) { sourceFirst = ~sourceFirst; } if (sourceLast < 0) { sourceLast = ~sourceLast - 1; } if (existingData == ExistingData.Clear) { target.Clear(targetIndex, count); } for (int i = sourceFirst; i <= sourceLast; i++) { target.At(Indices[i] + offset, Values[i]); } }
internal virtual void CopyToColumnUnchecked(MatrixStorage <T> target, int columnIndex, ExistingData existingData = ExistingData.Clear) { for (int i = 0; i < Length; i++) { target.At(i, columnIndex, At(i)); } }
internal override void MapIndexedToUnchecked <TU>(VectorStorage <TU> target, Func <int, T, TU> f, Zeros zeros, ExistingData existingData) { var sparseTarget = target as SparseVectorStorage <TU>; if (sparseTarget != null) { var indices = new List <int>(); var values = new List <TU>(); if (zeros == Zeros.Include || !Zero.Equals(f(0, Zero))) { int k = 0; for (int i = 0; i < Length; i++) { var item = k < ValueCount && (Indices[k]) == i?f(i, Values[k++]) : f(i, Zero); if (!Zero.Equals(item)) { values.Add(item); indices.Add(i); } } } else { for (int i = 0; i < ValueCount; i++) { var item = f(Indices[i], Values[i]); if (!Zero.Equals(item)) { values.Add(item); indices.Add(Indices[i]); } } } sparseTarget.Indices = indices.ToArray(); sparseTarget.Values = values.ToArray(); sparseTarget.ValueCount = values.Count; return; } var denseTarget = target as DenseVectorStorage <TU>; if (denseTarget != null) { if (existingData == ExistingData.Clear) { denseTarget.Clear(); } if (zeros == Zeros.Include || !Zero.Equals(f(0, Zero))) { int k = 0; for (int i = 0; i < Length; i++) { denseTarget.Data[i] = k < ValueCount && (Indices[k]) == i ? f(i, Values[k++]) : f(i, Zero); } } else { CommonParallel.For(0, ValueCount, 4096, (a, b) => { for (int i = a; i < b; i++) { denseTarget.Data[Indices[i]] = f(Indices[i], Values[i]); } }); } return; } // FALL BACK base.MapIndexedToUnchecked(target, f, zeros, existingData); }
public void Map2To(MatrixStorage <T> target, MatrixStorage <T> other, Func <T, T, T> f, Zeros zeros, ExistingData existingData) { if (target == null) { throw new ArgumentNullException(nameof(target)); } if (other == null) { throw new ArgumentNullException(nameof(other)); } if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) { var message = $"Matrix dimensions must agree: op1 is {RowCount}x{ColumnCount}, op2 is {target.RowCount}x{target.ColumnCount}."; throw new ArgumentException(message, nameof(target)); } if (RowCount != other.RowCount || ColumnCount != other.ColumnCount) { var message = $"Matrix dimensions must agree: op1 is {RowCount}x{ColumnCount}, op2 is {other.RowCount}x{other.ColumnCount}."; throw new ArgumentException(message, nameof(other)); } Map2ToUnchecked(target, other, f, zeros, existingData); }