You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel.HNSW/Utils/VectorUtils.cs

92 lines
2.6 KiB

using System;
using System.Collections.Generic;
using System.Numerics;
namespace ZeroLevel.HNSW
{
public static class VectorUtils
{
public static List<float[]> RandomVectors(int vectorSize, int vectorsCount)
{
var vectors = new List<float[]>();
for (int i = 0; i < vectorsCount; i++)
{
var vector = new float[vectorSize];
DefaultRandomGenerator.Instance.NextFloats(vector);
VectorUtils.NormalizeSIMD(vector);
vectors.Add(vector);
}
return vectors;
}
public static float Magnitude(IList<float> vector)
{
float magnitude = 0.0f;
for (int i = 0; i < vector.Count; ++i)
{
magnitude += vector[i] * vector[i];
}
return (float)Math.Sqrt(magnitude);
}
public static void Normalize(IList<float> vector)
{
float normFactor = 1f / Magnitude(vector);
for (int i = 0; i < vector.Count; ++i)
{
vector[i] *= normFactor;
}
}
public static float MagnitudeSIMD(float[] vector)
{
if (!Vector.IsHardwareAccelerated)
{
throw new NotSupportedException($"{nameof(VectorUtils.NormalizeSIMD)} is not supported");
}
float magnitude = 0.0f;
int step = Vector<float>.Count;
int i, to = vector.Length - step;
for (i = 0; i <= to; i += Vector<float>.Count)
{
var vi = new Vector<float>(vector, i);
magnitude += Vector.Dot(vi, vi);
}
for (; i < vector.Length; ++i)
{
magnitude += vector[i] * vector[i];
}
return (float)Math.Sqrt(magnitude);
}
public static void NormalizeSIMD(float[] vector)
{
if (!Vector.IsHardwareAccelerated)
{
throw new NotSupportedException($"{nameof(VectorUtils.NormalizeSIMD)} is not supported");
}
float normFactor = 1f / MagnitudeSIMD(vector);
int step = Vector<float>.Count;
int i, to = vector.Length - step;
for (i = 0; i <= to; i += step)
{
var vi = new Vector<float>(vector, i);
vi = Vector.Multiply(normFactor, vi);
vi.CopyTo(vector, i);
}
for (; i < vector.Length; ++i)
{
vector[i] *= normFactor;
}
}
}
}

Powered by TurnKey Linux.