MEP 6: find_first_index
- Created: 2022-12-03 12:20:00
メディアンフィルタの以下のコードは、
# hist(255, rgb)は総登場回数(weightはその分重複して登場したと解釈)。その半分で
def _med by reduce<_hist>.accumulate(dim=0, init=-1) |i, col, val, accm| {
ifel(accm != -1, accm, ...)
elif(val < _hist(255, col)/2, -1, i)
}
本質的には最初に val < _hist(255, col) になった場所を探している。 もっと直接的に書けるようなシンタックスシュガーを考える。
メディアンフィルタのsortバージョンに出てくる以下の式は、
let i3 = wcumsum.find_first_index |_, val| { i < val }
本質的には0次元になるreduceとして以下のようにも解釈できるよな。
def i3 by reduce<wcumsum>.accumulate(dim=0, init=-1) |ind, val, accm | {
ifel(accm != -1, accm, ...)
elif(i < val, -1, ind)
}
これならsortじゃないメディアンフィルタの時とほとんど同じコードになる。 これがサポートされる方がより根本の表現力は増しているな(最初に見つけた所で終われないので遅いが)。
ts.sumの方と同じ問題として真面目に考えるなら、例えば単に0次元の時はletにもできれば十分では無かろうか?
let i3 = reduce<wcumsum>.accumulate(dim=0, init=-1) |ind, val, accm | {
ifel(accm != -1, accm, ...)
elif(i < val, -1, ind)
}
これなら以下のts.sumも
let wsum = weight.sum |x, y, val| { val }
以下のように書けば一貫性は出てくる。
let wsum = reduce<weight>.sum |_, _, val| { val }
これは一貫性という点で許容範囲のような気がするし、sumの名前をもう少しうまいものにできればブロックの結果を足すものと、単に値を足すものの2つを用意出来そうだよな。
でもこれだと単なるexpressionに見えるよな。それならdefで0次元のテンソルが定義できるが結果として変数になっている、と解釈される方がいい気もする。 これはfind_first_indexとは別件で考えるべき事な気がする。 別issueを建てるべきか。
> MEP 7: 0次元へのreduce に建てた。
MEP 7: 0次元へのreduce で0次元のreduceを対応したので、そのシンタックスシュガーとして以下のように書く事にする。
def i3 by reduce<_hist>.find_first_index(dim=0) |i, col, val| { val >= _hist(255,col)/2 }
def byなのはかっこ悪いが、reduceの一種なのは明らかなので。 厳密には以下の式は、
def i3 by reduce<_hist>.find_first_index(dim=0) |i, col, val| {
STMT1
STMT2
STMT3
REXPR
}
以下のシンタックスシュガーという事にする(本当はbreakできるはずだがまずはしない)
def i3 by reduce<_hist>.accumulate(dim=0, init=-1) |i, col, val, accm| {
STMT1
STMT2
STMT3
ifel(accm != -1, accm, ...)
elif(REXPR, i, -1)
}