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); }
// FUNCTIONAL COMBINATORS: MAP internal override TState Fold2Unchecked <TOther, TState>(VectorStorage <TOther> other, Func <TState, T, TOther, TState> f, TState state, Zeros zeros) { var sparseOther = other as SparseVectorStorage <TOther>; if (sparseOther != null) { int[] otherIndices = sparseOther.Indices; TOther[] otherValues = sparseOther.Values; int otherValueCount = sparseOther.ValueCount; TOther otherZero = BuilderInstance <TOther> .Vector.Zero; if (zeros == Zeros.Include) { int p = 0, q = 0; for (int i = 0; i < Length; i++) { var left = p < ValueCount && Indices[p] == i ? Values[p++] : Zero; var right = q < otherValueCount && otherIndices[q] == i ? otherValues[q++] : otherZero; state = f(state, left, right); } } else { int p = 0, q = 0; while (p < ValueCount || q < otherValueCount) { if (q >= otherValueCount || p < ValueCount && Indices[p] < otherIndices[q]) { state = f(state, Values[p], otherZero); p++; } else if (p >= ValueCount || q < otherValueCount && Indices[p] > otherIndices[q]) { state = f(state, Zero, otherValues[q]); q++; } else { Debug.Assert(Indices[p] == otherIndices[q]); state = f(state, Values[p], otherValues[q]); p++; q++; } } } return(state); } var denseOther = other as DenseVectorStorage <TOther>; if (denseOther != null) { TOther[] otherData = denseOther.Data; int k = 0; for (int i = 0; i < otherData.Length; i++) { if (k < ValueCount && Indices[k] == i) { state = f(state, Values[k], otherData[i]); k++; } else { state = f(state, Zero, otherData[i]); } } return(state); } return(base.Fold2Unchecked(other, f, state, zeros)); }
internal override Tuple <int, T, TOther> Find2Unchecked <TOther>(VectorStorage <TOther> other, Func <T, TOther, bool> predicate, Zeros zeros) { var denseOther = other as DenseVectorStorage <TOther>; if (denseOther != null) { TOther[] otherData = denseOther.Data; int k = 0; for (int i = 0; i < otherData.Length; i++) { if (k < ValueCount && Indices[k] == i) { if (predicate(Values[k], otherData[i])) { return(new Tuple <int, T, TOther>(i, Values[k], otherData[i])); } k++; } else { if (predicate(Zero, otherData[i])) { return(new Tuple <int, T, TOther>(i, Zero, otherData[i])); } } } return(null); } var sparseOther = other as SparseVectorStorage <TOther>; if (sparseOther != null) { int[] otherIndices = sparseOther.Indices; TOther[] otherValues = sparseOther.Values; int otherValueCount = sparseOther.ValueCount; TOther otherZero = BuilderInstance <TOther> .Matrix.Zero; // Full Scan int k = 0, otherk = 0; if (zeros == Zeros.Include && ValueCount < Length && sparseOther.ValueCount < Length && predicate(Zero, otherZero)) { for (int i = 0; i < Length; i++) { var left = k < ValueCount && Indices[k] == i ? Values[k++] : Zero; var right = otherk < otherValueCount && otherIndices[otherk] == i ? otherValues[otherk++] : otherZero; if (predicate(left, right)) { return(new Tuple <int, T, TOther>(i, left, right)); } } return(null); } // Sparse Scan k = 0; otherk = 0; while (k < ValueCount || otherk < otherValueCount) { if (k == ValueCount || otherk < otherValueCount && Indices[k] > otherIndices[otherk]) { if (predicate(Zero, otherValues[otherk++])) { return(new Tuple <int, T, TOther>(otherIndices[otherk - 1], Zero, otherValues[otherk - 1])); } } else if (otherk == otherValueCount || Indices[k] < otherIndices[otherk]) { if (predicate(Values[k++], otherZero)) { return(new Tuple <int, T, TOther>(Indices[k - 1], Values[k - 1], otherZero)); } } else { if (predicate(Values[k++], otherValues[otherk++])) { return(new Tuple <int, T, TOther>(Indices[k - 1], Values[k - 1], otherValues[otherk - 1])); } } } return(null); } // FALL BACK return(base.Find2Unchecked(other, predicate, zeros)); }
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) { T[] targetData = denseTarget.Data; T[] otherData = denseOther.Data; int k = 0; for (int 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) { T[] targetData = denseTarget.Data; int[] otherIndices = sparseOther.Indices; T[] otherValues = sparseOther.Values; int otherValueCount = sparseOther.ValueCount; if (processZeros) { int p = 0, q = 0; for (int 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>(); int[] otherIndices = sparseOther.Indices; T[] otherValues = sparseOther.Values; int 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); }