lib/ollama/utils/math.rb
module Ollama::Utils::Math # Returns the cosine similarity between two vectors +a+ and +b+, 1.0 is # exactly the same, 0.0 means decorrelated. # # @param [Vector] a The first vector # @param [Vector] b The second vector # @option a_norm [Float] a The Euclidean norm of vector a (default: calculated from a) # @option b_norm [Float] b The Euclidean norm of vector b (default: calculated from b) # # @return [Float] The cosine similarity between the two vectors # # @example Calculate the cosine similarity between two vectors # cosine_similarity(a: [1, 2], b: [3, 4]) # # @see #convert_to_vector # @see #norm def cosine_similarity(a:, b:, a_norm: norm(a), b_norm: norm(b)) a, b = convert_to_vector(a), convert_to_vector(b) a.dot(b) / (a_norm * b_norm) end # Returns the Euclidean norm (magnitude) of a vector. # # @param vector [Array] The input vector. # # @return [Float] The magnitude of the vector. # # @example # norm([3, 4]) # => 5.0 def norm(vector) s = 0.0 vector.each { s += _1.abs2 } Math.sqrt(s) end # Converts an array to a Numo NArray. # # @param [Array] vector The input array to be converted. # # @return [Numo::NArray] The converted NArray, or the original if it's already a Numo NArray. # # @example Convert an array to a Numo NArray # convert_to_vector([1, 2, 3]) # => Numo::NArray[1, 2, 3] def convert_to_vector(vector) vector.is_a?(Numo::NArray) and return vector Numo::NArray[*vector] end end