今日のRuby
実数直積集合の距離関数(see: wikipedia:距離空間)をナイーブに実装。
module Matric class << self def chebyshev(array1, array2, k) raise "All elements in 'array1' shall be real numbers" unless array1.all?{|i| i.is_a?(Fixnum) || i.is_a?(Float)} raise "All elements in 'array2' shall be real numbers" unless array2.all?{|i| i.is_a?(Fixnum) || i.is_a?(Float)} raise "The argument 'k' shall be a natural number" unless k.is_a?(Fixnum) && k > 0 pairs = pair(array1, array2) pairs.map{|p| (p[0] - p[1]).abs ** k }.reduce{|i, j| i + j } ** (1.0 / k) end def city_block(array1, array2) return chebyshev(array1, array2, 1) end def euclidean(array1, array2) return chebyshev(array1, array2, 2) end private def pair(array1, array2) raise if array1.size != array2.size return Array.new(array1.size) do |i| [array1[i], array2[i]] end end end end
チェビシェフ距離を定義して、そのアプリケーションとしてユークリッド距離とマンハッタン距離を実装してます。
テストケース。このテストは同じものを与えて距離が0になるかどうかしかテストしていない。不十分。
require 'test/unit' require File.join(File.dirname(__FILE__), "matric") class TestMatric < Test::Unit::TestCase def setup @data1 = [0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1] @data2 = [1, 0, 0, 1, 1, 1, 1, 1, 1, 0] @trash_data = [1, 2, 3, 4, 5, 6, "a", 1] end def test_chebyshev begin Matric.chebyshev(@data1, @data1, false) assert(false) rescue assert(true) end begin Matric.chebyshev(@data1, @data2, 1) assert(false) rescue assert(true) end begin Matric.chebyshev(@data1, @trash_data, 1) assert(false) rescue assert(true) end end def test_city_block assert(Matric.city_block(@data1, @data1) == 0) end def test_euclidean assert(Matric.city_block(@data1, @data1) == 0) end end