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);
            }
            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();
            }
        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++)
                {
                    a[i]  = DotProduct(model, offs, values, indices, count);
                    offs += length;
                }
            }
            dst = new VBuffer <Float>(cdst, a, dst.Indices);
        }