Functions/GenXdev.AI/Get-VectorSimilarity.cs
// ################################################################################
// Part of PowerShell module : GenXdev.AI // Original cmdlet filename : Get-VectorSimilarity.cs // Original author : René Vaessen / GenXdev // Version : 1.302.2025 // ################################################################################ // Copyright (c) René Vaessen / GenXdev // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ################################################################################ using System; using System.Management.Automation; namespace GenXdev.AI { /// <summary> /// <para type="synopsis"> /// Calculates the cosine similarity between two vectors, returning a value between 0 and 1. /// </para> /// /// <para type="description"> /// This function takes two numerical vectors (arrays) as input and computes their cosine similarity. /// The result indicates how closely related the vectors are, with 0 meaning completely dissimilar and 1 meaning identical. /// </para> /// /// <para type="description"> /// PARAMETERS /// </para> /// /// <para type="description"> /// -Vector1 <double[]><br/> /// The first vector as an array of numbers (e.g., [0.12, -0.45, 0.89]). Must be the same length as Vector2.<br/> /// - <b>Position</b>: 0<br/> /// - <b>Mandatory</b>: true<br/> /// </para> /// /// <para type="description"> /// -Vector2 <double[]><br/> /// The second vector as an array of numbers (e.g., [0.15, -0.40, 0.92]). Must be the same length as Vector1.<br/> /// - <b>Position</b>: 1<br/> /// - <b>Mandatory</b>: true<br/> /// </para> /// /// <example> /// <para>Calculate similarity between two example vectors</para> /// <para>This example demonstrates calculating the cosine similarity between two 3-dimensional vectors.</para> /// <code> /// $v1 = @(0.12, -0.45, 0.89) /// $v2 = @(0.15, -0.40, 0.92) /// Get-VectorSimilarity -Vector1 $v1 -Vector2 $v2 /// </code> /// <para>Returns approximately 0.998, indicating high similarity</para> /// </example> /// </summary> [Cmdlet(VerbsCommon.Get, "VectorSimilarity")] [OutputType(typeof(double))] public class GetVectorSimilarityCommand : PSGenXdevCmdlet { /// <summary> /// The first vector as an array of numbers (e.g., [0.12, -0.45, 0.89]). Must be the same length as Vector2. /// </summary> [Parameter( Mandatory = true, Position = 0, HelpMessage = "First vector array of numbers")] public double[] Vector1 { get; set; } /// <summary> /// The second vector as an array of numbers (e.g., [0.15, -0.40, 0.92]). Must be the same length as Vector1. /// </summary> [Parameter( Mandatory = true, Position = 1, HelpMessage = "Second vector array of numbers")] public double[] Vector2 { get; set; } /// <summary> /// Begin processing - validate input vectors /// </summary> protected override void BeginProcessing() { WriteVerbose("Validating input vectors..."); // Check for null vectors if (Vector1 == null || Vector2 == null) { WriteError(new ErrorRecord( new ArgumentException("Both Vector1 and Vector2 must contain values."), "NullVector", ErrorCategory.InvalidArgument, null)); return; } // Verify vectors have matching lengths if (Vector1.Length != Vector2.Length) { WriteError(new ErrorRecord( new ArgumentException("Vector1 and Vector2 must have the same length."), "LengthMismatch", ErrorCategory.InvalidArgument, null)); return; } // Ensure vectors are not empty if (Vector1.Length == 0) { WriteError(new ErrorRecord( new ArgumentException("Vectors cannot be empty."), "EmptyVector", ErrorCategory.InvalidArgument, null)); return; } } /// <summary> /// Process record - calculate vector similarity /// </summary> protected override void ProcessRecord() { try { WriteVerbose("Calculating vector similarity..."); // Compute the dot product of the two vectors double dotProduct = 0.0; for (int i = 0; i < Vector1.Length; i++) { dotProduct += Vector1[i] * Vector2[i]; } // Calculate the magnitude (euclidean norm) of each vector double magnitude1 = 0.0; double magnitude2 = 0.0; for (int i = 0; i < Vector1.Length; i++) { magnitude1 += Math.Pow(Vector1[i], 2); magnitude2 += Math.Pow(Vector2[i], 2); } magnitude1 = Math.Sqrt(magnitude1); magnitude2 = Math.Sqrt(magnitude2); // Prevent division by zero for zero-magnitude vectors if (magnitude1 == 0 || magnitude2 == 0) { WriteVerbose("One or both vectors have zero magnitude. Similarity is undefined."); WriteObject(0.0); return; } // Calculate final cosine similarity double similarity = dotProduct / (magnitude1 * magnitude2); // Normalize result to 0-1 range double normalizedSimilarity = Math.Min(Math.Max(similarity, -1), 1); normalizedSimilarity = (normalizedSimilarity + 1) / 2; WriteVerbose("Similarity calculation complete"); WriteObject(Math.Round(normalizedSimilarity, 6)); } catch (Exception ex) { WriteError(new ErrorRecord( ex, "SimilarityCalculationError", ErrorCategory.InvalidOperation, null)); } } /// <summary> /// End processing - no cleanup needed /// </summary> protected override void EndProcessing() { } } } |