private static void FillValues(float[] model, ref VBuffer <float> src, ref VBuffer <float> dst, int cdst) { var values = src.GetValues(); int count = values.Length; int length = src.Length; // Since the whitening process produces dense vector, always use dense representation of dst. var editor = VBufferEditor.Create(ref dst, cdst); if (src.IsDense) { Mkl.Gemv(Mkl.Layout.RowMajor, Mkl.Transpose.NoTrans, cdst, length, 1, model, length, values, 1, 0, editor.Values, 1); } else { var indices = src.GetIndices(); int offs = 0; for (int i = 0; i < cdst; i++) { // Returns a dot product of dense vector 'model' starting from offset 'offs' and sparse vector 'values' // with first 'count' valid elements and their corresponding 'indices'. editor.Values[i] = CpuMathUtils.DotProductSparse(model.AsSpan(offs), values, indices, count); offs += length; } } dst = editor.Commit(); }
public void DotSUTest(string mode, string test, Dictionary <string, string> environmentVariables) { RemoteExecutor.RemoteInvoke((arg0, arg1) => { CheckProperFlag(arg0); float[] src = (float[])_testArrays[int.Parse(arg1)].Clone(); float[] dst = (float[])src.Clone(); int[] idx = _testIndexArray; // Ensures src and dst are different arrays for (int i = 0; i < dst.Length; i++) { dst[i] += 1; } float expected = 0; for (int i = 0; i < idx.Length; i++) { int index = idx[i]; expected += src[index] * dst[i]; } var actual = CpuMathUtils.DotProductSparse(src, dst, idx, idx.Length); Assert.Equal(expected, actual, 2); return(RemoteExecutor.SuccessExitCode); }, mode, test, new RemoteInvokeOptions(environmentVariables)); }
private static void FillValues(float[] model, ref VBuffer <float> src, ref VBuffer <float> dst, int cdst) { int count = src.Count; int length = src.Length; var values = src.Values; var indices = src.Indices; Contracts.Assert(Utils.Size(values) >= count); // Since the whitening process produces dense vector, always use dense representation of dst. var a = Utils.Size(dst.Values) >= cdst ? dst.Values : new float[cdst]; if (src.IsDense) { Mkl.Gemv(Mkl.Layout.RowMajor, Mkl.Transpose.NoTrans, cdst, length, 1, model, length, values, 1, 0, a, 1); } else { Contracts.Assert(Utils.Size(indices) >= count); int offs = 0; for (int i = 0; i < cdst; i++) { // Returns a dot product of dense vector 'model' starting from offset 'offs' and sparse vector 'values' // with first 'count' valid elements and their corresponding 'indices'. a[i] = CpuMathUtils.DotProductSparse(model.AsSpan(offs), values, indices, count); offs += length; } } dst = new VBuffer <float>(cdst, a, dst.Indices); }
public static Float DotProduct(Float[] a, ref VBuffer <Float> b) { Contracts.Check(Utils.Size(a) == b.Length, "Vectors must have the same dimensionality."); if (b.Count == 0) { return(0); } if (b.IsDense) { return(CpuMathUtils.DotProductDense(a, b.Values, b.Length)); } return(CpuMathUtils.DotProductSparse(a, b.Values, b.Indices, b.Count)); }
/// <summary> /// Computes the dot product of two arrays /// Where "offset" is considered to be a's zero index /// </summary> /// <param name="a">one array</param> /// <param name="b">the second array (given as a VBuffer)</param> /// <param name="offset">offset in 'a'</param> /// <returns>the dot product</returns> public static Float DotProductWithOffset(ref VBuffer <Float> a, int offset, ref VBuffer <Float> b) { Contracts.Check(0 <= offset && offset <= a.Length); Contracts.Check(b.Length <= a.Length - offset, "VBuffer b must be no longer than a.Length - offset."); if (a.Count == 0 || b.Count == 0) { return(0); } if (a.IsDense) { if (b.IsDense) { return(CpuMathUtils.DotProductDense(a.Values.AsSpan(offset), b.Values, b.Length)); } return(CpuMathUtils.DotProductSparse(a.Values.AsSpan(offset), b.Values, b.Indices, b.Count)); } else { Float result = 0; int aMin = Utils.FindIndexSorted(a.Indices, 0, a.Count, offset); int aLim = Utils.FindIndexSorted(a.Indices, 0, a.Count, offset + b.Length); if (b.IsDense) { for (int iA = aMin; iA < aLim; ++iA) { result += a.Values[iA] * b.Values[a.Indices[iA] - offset]; } return(result); } for (int iA = aMin, iB = 0; iA < aLim && iB < b.Count;) { int aIndex = a.Indices[iA]; int bIndex = b.Indices[iB]; int comp = (aIndex - offset) - bIndex; if (comp == 0) { result += a.Values[iA++] * b.Values[iB++]; } else if (comp < 0) { iA++; } else { iB++; } } return(result); } }
/// <summary> /// Computes the dot product of two arrays /// Where "offset" is considered to be a's zero index /// </summary> /// <param name="a">one array</param> /// <param name="b">the second array (given as a VBuffer)</param> /// <param name="offset">offset in 'a'</param> /// <returns>the dot product</returns> public static Float DotProductWithOffset(Float[] a, int offset, ref VBuffer <Float> b) { Contracts.Check(0 <= offset && offset <= a.Length); Contracts.Check(b.Length <= a.Length - offset, "VBuffer b must be no longer than a.Length - offset."); if (b.Count == 0) { return(0); } if (b.IsDense) { return(CpuMathUtils.DotProductDense(a.AsSpan(offset), b.Values, b.Length)); } return(CpuMathUtils.DotProductSparse(a.AsSpan(offset), b.Values, b.Indices, b.Count)); }
public void DotSUTest(int test, float expected) { float[] src = (float[])testArrays[test].Clone(); float[] dst = (float[])src.Clone(); int[] idx = testIndexArray; // Ensures src and dst are different arrays for (int i = 0; i < dst.Length; i++) { dst[i] += 1; } var actual = CpuMathUtils.DotProductSparse(src, dst, idx, idx.Length); Assert.Equal(expected, actual, 4); }
private static Float L2DistSquaredHalfSparse(Float[] valuesA, int lengthA, Float[] valuesB, int[] indicesB, int countB) { Contracts.AssertValueOrNull(valuesA); Contracts.AssertValueOrNull(valuesB); Contracts.AssertValueOrNull(indicesB); Contracts.Assert(0 <= lengthA && lengthA <= Utils.Size(valuesA)); Contracts.Assert(0 <= countB && countB <= Utils.Size(indicesB)); Contracts.Assert(countB <= Utils.Size(valuesB)); var normA = CpuMathUtils.SumSq(valuesA.AsSpan(0, lengthA)); if (countB == 0) { return(normA); } var normB = CpuMathUtils.SumSq(valuesB.AsSpan(0, countB)); var dotP = CpuMathUtils.DotProductSparse(valuesA, valuesB, indicesB, countB); var res = normA + normB - 2 * dotP; return(res < 0 ? 0 : res); }
public static Float DotProduct(ref VBuffer <Float> a, ref VBuffer <Float> b) { Contracts.Check(a.Length == b.Length, "Vectors must have the same dimensionality."); if (a.Count == 0 || b.Count == 0) { return(0); } if (a.IsDense) { if (b.IsDense) { return(CpuMathUtils.DotProductDense(a.Values, b.Values, a.Length)); } return(CpuMathUtils.DotProductSparse(a.Values, b.Values, b.Indices, b.Count)); } if (b.IsDense) { return(CpuMathUtils.DotProductSparse(b.Values, a.Values, a.Indices, a.Count)); } return(DotProductSparse(a.Values, a.Indices, 0, a.Count, b.Values, b.Indices, 0, b.Count, 0)); }
private static float DotProduct(float[] a, int aOffset, ReadOnlySpan <float> b, ReadOnlySpan <int> indices, int count) { Contracts.Assert(count <= indices.Length); return(CpuMathUtils.DotProductSparse(a.AsSpan(aOffset), b, indices, count)); }
/// <summary> /// Returns a dot product of dense vector 'a' starting from offset 'aOffset' and sparse vector 'b' /// with first 'count' valid elements and their corresponding 'indices'. /// </summary> private static Float DotProduct(Float[] a, int aOffset, Float[] b, int[] indices, int count) { Contracts.Assert(count <= indices.Length); return(CpuMathUtils.DotProductSparse(a, aOffset, b, indices, count)); }
public float DotSU() => CpuMathUtils.DotProductSparse(src, dst, idx, _smallInputLength);
public float ManagedDotSUPerf() => CpuMathUtils.DotProductSparse(src, dst, idx, IDXLEN);