< Summary

Information
Class: Intentum.AI.Similarity.CosineSimilarityEngine
Assembly: Intentum.AI
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.AI/Similarity/CosineSimilarityEngine.cs
Line coverage
96%
Covered lines: 27
Uncovered lines: 1
Coverable lines: 28
Total lines: 61
Line coverage: 96.4%
Branch coverage
92%
Covered branches: 13
Total branches: 14
Branch coverage: 92.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
CalculateIntentScore(...)100%1212100%
CalculateCosineSimilarity(...)50%2280%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.AI/Similarity/CosineSimilarityEngine.cs

#LineLine coverage
 1using Intentum.AI.Embeddings;
 2
 3namespace Intentum.AI.Similarity;
 4
 5/// <summary>
 6/// Similarity engine that uses cosine similarity between embedding vectors.
 7/// Falls back to simple average if vectors are not available.
 8/// </summary>
 9public sealed class CosineSimilarityEngine : IIntentSimilarityEngine
 10{
 11    public double CalculateIntentScore(IReadOnlyCollection<IntentEmbedding> embeddings)
 712    {
 713        if (embeddings.Count == 0)
 114            return 0;
 15
 16        // Check if all embeddings have vectors
 1617        var allHaveVectors = embeddings.All(e => e.Vector is { Count: > 0 });
 18
 619        if (!allHaveVectors)
 220        {
 21            // Fallback to simple average if vectors are not available
 622            return embeddings.Average(e => e.Score);
 23        }
 24
 25        // Calculate cosine similarity between all pairs and average
 426        var embeddingList = embeddings.ToList();
 427        var similarities = new List<double>();
 28
 2429        for (int i = 0; i < embeddingList.Count; i++)
 830        {
 2631            for (int j = i + 1; j < embeddingList.Count; j++)
 532            {
 533                var similarity = CalculateCosineSimilarity(
 534                    embeddingList[i].Vector!,
 535                    embeddingList[j].Vector!);
 536                similarities.Add(similarity);
 537            }
 838        }
 39
 40        // If only one embedding, return its score
 441        if (similarities.Count == 0)
 142            return embeddings.First().Score;
 43
 44        // Average of all pairwise cosine similarities
 345        return similarities.Average();
 746    }
 47
 48    /// <summary>
 49    /// Calculates cosine similarity between two vectors.
 50    /// Returns a value between 0 and 1, where 1 means identical, 0.5 means orthogonal, 0 means opposite.
 51    /// </summary>
 52    private static double CalculateCosineSimilarity(
 53        IReadOnlyList<double> vector1,
 54        IReadOnlyList<double> vector2)
 555    {
 556        if (vector1.Count != vector2.Count)
 057            throw new ArgumentException("Vectors must have the same length");
 58
 559        return CosineSimilarityHelper.CosineSimilarityNormalized(vector1.ToArray(), vector2.ToArray());
 560    }
 61}