Functions/GenXdev.AI/Get-VectorSimilarity.ps1
################################################################################ <# .SYNOPSIS Calculates the cosine similarity between two vectors, returning a value between 0 and 1. .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. .PARAMETER Vector1 The first vector as an array of numbers (e.g., [0.12, -0.45, 0.89]). Must be the same length as Vector2. .PARAMETER Vector2 The second vector as an array of numbers (e.g., [0.15, -0.40, 0.92]). Must be the same length as Vector1. .EXAMPLE $v1 = @(0.12, -0.45, 0.89) $v2 = @(0.15, -0.40, 0.92) Get-VectorSimilarity -Vector1 $v1 -Vector2 $v2 # Returns approximately 0.998, indicating high similarity #> function Get-VectorSimilarity { [CmdletBinding()] [OutputType([double])] param ( ######################################################################## [Parameter( Mandatory = $true, Position = 0, HelpMessage = "First vector array of numbers" )] [double[]]$Vector1, ######################################################################## [Parameter( Mandatory = $true, Position = 1, HelpMessage = "Second vector array of numbers" )] [double[]]$Vector2 ######################################################################## ) begin { Write-Verbose "Validating input vectors..." # check for null vectors if (-not $Vector1 -or -not $Vector2) { Write-Error "Both Vector1 and Vector2 must contain values." return $null } # verify vectors have matching lengths if ($Vector1.Length -ne $Vector2.Length) { Write-Error "Vector1 and Vector2 must have the same length." return $null } # ensure vectors are not empty if ($Vector1.Length -eq 0) { Write-Error "Vectors cannot be empty." return $null } } process { try { Write-Verbose "Calculating vector similarity..." # compute the dot product of the two vectors $dotProduct = 0.0 for ($i = 0; $i -lt $Vector1.Length; $i++) { $dotProduct += $Vector1[$i] * $Vector2[$i] } # calculate the magnitude (euclidean norm) of each vector $magnitude1 = 0.0 $magnitude2 = 0.0 for ($i = 0; $i -lt $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 -eq 0 -or $magnitude2 -eq 0) { Write-Warning ("One or both vectors have zero magnitude. " + "Similarity is undefined.") return 0.0 } # calculate final cosine similarity $similarity = $dotProduct / ($magnitude1 * $magnitude2) # normalize result to 0-1 range $normalizedSimilarity = [Math]::Min([Math]::Max($similarity, -1), 1) $normalizedSimilarity = ($normalizedSimilarity + 1) / 2 Write-Verbose "Similarity calculation complete" return [math]::Round($normalizedSimilarity, 6) } catch { Write-Error "Error calculating similarity: $_" return $null } } end { } } ################################################################################ |