Ruby 2.6 の新機能の endless range と Range#% を Numo::NArray と Cumo で対応しました。

自分が参加している Red Data Toolsred-data-tools/ja - Gitter@mrkn さんから、

ArithmeticSequence と Range から begin, end, step, exclude_end を取り出す C API を trunk に追加しました。 ruby/ruby@914a290 だれか、これを使って NArray などの slicing に対応するプルリクエストを作ってみませんか?

という提案を頂いたので、 Numo::NArrayCumo (※ Numo::NArray のGPU 版)で 上記 C API を使用して Ruby 2.6 の新機能の endless rangeRange#% に対応を実施しました。

endless range とは、下記のように 末端の "-1" 指摘を省略できる書き方です。
また、step の alias として % を使用できると、より直感的に書く事ができます。

> a = [0, 1, 2, 3, 4]
 => [0, 1, 2, 3, 4] 
> a[1..-1]
 => [1, 2, 3, 4] 
> a[1...-1]
 => [1, 2, 3] 
> (1..4).to_a
 => [1, 2, 3, 4] 
> (1..4).step(2).to_a
 => [1, 3] 
  • Ruby 2.6 (endless range, Range#%)
> a = [0, 1, 2, 3, 4]
 => [0, 1, 2, 3, 4] 
> a[1..]
 => [1, 2, 3, 4] 
> a[1...]
 => [1, 2, 3, 4] 
> (1..4).to_a
 => [1, 2, 3, 4] 
> ((1..4) % 2).to_a
 => [1, 3] 

このように便利な記法が Numo::NArray や Cumo でも使えると嬉しいので、Ruby 2.6 の環境で同様に書けるように対応しました。

  • Numo::NArray
> require 'numo/narray'
> a = Numo::Int32.new(5).seq
 => Numo::Int32#shape=[5]
[0, 1, 2, 3, 4]
> a[1..]
 => Numo::Int32(view)#shape=[4]
[1, 2, 3, 4] 
> a[1...]
 => Numo::Int32(view)#shape=[4]
[1, 2, 3, 4] 
> a[(1..) % 2]
 => Numo::Int32(view)#shape=[2]
[1, 3] 
  • Cumo
> require 'cumo'
> a = Cumo::Int32.new(5).seq
=> Cumo::Int32#shape=[5]
[0, 1, 2, 3, 4]
> a[1..]
=> Cumo::Int32(view)#shape=[4]
[1, 2, 3, 4]
> a[1...]
=> Cumo::Int32(view)#shape=[4]
[1, 2, 3, 4]
> a[(1..) % 2]
=> Cumo::Int32(view)#shape=[2]
[1, 3]

numo-narray の endless range、Range#%の PR は master に 取り込まれている ので次のリリース(0.9.1.5以降?)で使用可能になると思われます。
cumo は リリース版ですでに 取り込まれている ので 0.2.5 以降で使用可能です。

Ruby 本体側でデータサイエンス向けの機能が取り込まれていくと、データサイエンス用ライブラリ側も便利になっていきますので嬉しいですよね。