くだいて言うと周期拡張は2次元の配列をタイル状に、周期対称拡張は交互に反転して並べたもののことで、画像にフィルタをかける場合などの周囲画素の扱い方です。Rubyでこれを実現しようと長らく悩んでいましたが、やっとテスト通りました。とても単純なはずなのに、かなり時間を食ってしまいました。
とりあえずテストケース
test_lipe.rb
require 'test/unit' require 'lipe' class TC_Lipe < Test::Unit::TestCase def setup @rary = LIPE::RingArray.new(5) @sary = LIPE::SymmetryArray.new(5) for i in 0..4 @rary[i] = i @sary[i] = i end end def test_idx # Test RingArray tmp1 = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0] tmp1.each_with_index do |i, j| assert_equal(i, @rary[j - 10]) end # Test SymmetryArray tmp2 = [0, 1, 2, 3, 4, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 4, 3, 2, 1, 0, 0] tmp2.each_with_index do |i, j| assert_equal(i, @sary[j - 10]) end end end
Arrayクラスを継承してそれぞれを実現したもの
lipe.rb
module LIPE class RingArray < Array def [](idx) super(idx % length) end end class SymmetryArray < Array def [](idx) idx += 1 if idx < 0 flg, idx = idx.abs.divmod length idx = length - idx - 1 unless flg % 2 == 0 super idx end end class Image end end
結果
% ruby test_lipe.rb
Loaded suite test_lipe
Started
.
Finished in 0.002 seconds.1 tests, 42 assertions, 0 failures, 0 errors
やっと本体にかかれるのでとても良かったですね。