C++のnumericで扱える関数一覧

前回、[cmathのC++日本語リファレンスを読んでまとめた記事](https://qiita.com/fockl/items/2358a4ec769874780a6a)を書いたので、ついでに[numericのC++日本語リファレンス](https://cpprefjp.github.io/reference/numeric.html)も読んで自分用にバージョン別でまとめました

- [C++11以前から使える](#c11以前から使える)
- [C++11で追加](#c11で追加)
- [C++17で追加](#c17で追加)
- [C++20で追加](#c20で追加)

前回同様、全ての関数にC++日本語リファレンスへのリンクを埋め込んであります

最大公約数や最小公倍数を求める関数はalgorithmではなくここにあります

# C++11以前から使える

[std::accumulate](https://cpprefjp.github.io/reference/numeric/accumulate.html)

std::accumulate(first, last, init)
std::accumulate(first, last, init, op)

[first, last)間の要素rの値を集計する
前から順番にinit = op(init, r[0]), init = op(init, r[1]), ...と適用し、最終結果を返す
デフォルトではop(a, b) = a+b


[std::partial_sum](https://cpprefjp.github.io/reference/numeric/partial_sum.html)

std::partial_sum(first, last, result)
std::partial_sum(first, last, result, op)

[first, last)間の要素rの値を集計しする
result[0]=r[0], result[1]=op(result[0], r[1]), ...のようにresultへ書き込む(result.size()==last-first)
デフォルトではop(a, b) = a+b

[std::adjacent_difference](https://cpprefjp.github.io/reference/numeric/adjacent_difference.html)

std::adjacent_difference(first, last, result)
std::adjacent_difference(first, last, result, op)
[first, last)間の要素rに対し、隣接要素同士の演算結果(r[0], op(r[1], r[0]), op(r[2], r[1]), ...)をresultに書き込む(result.size() == last-first)
デフォルトではop(a, b) = a-b

[std::inner_product](https://cpprefjp.github.io/reference/numeric/inner_product.html)

std::inner_product(first1, last1, first2, init)
std::inner_product(first1, last1, first2, init, op1, op2)

[first1, last1)間の要素r1と、[first2, first2+(last1-first1))間の要素r2の"内積"を計算する
init = op1(init, op2(r1[0], r2[0])), init = op1(init, op2(r1[1], r2[1])), ... とした時の結果を返す
デフォルトではop1(a, b) = a+b, op2(a, b) = a*b (なので内積)


# C++11で追加

[std::iota](https://cpprefjp.github.io/reference/numeric/iota.html)

iota(first, last, value)

[first, last)間の要素rに[value, value+(last-first))の値を前から順番に代入する
つまり、r[0]=value, r[1]=value+1, ...となる

# C++17で追加

[std::gcd](https://cpprefjp.github.io/reference/numeric/gcd.html)

std::gcd(m, n)

|m|と|n|の最大公約数を返す

[std::lcm](https://cpprefjp.github.io/reference/numeric/lcm.html)

std::lcm(m, n)

|m|と|n|の最小公倍数を返す

[std::exclusive_scan](https://cpprefjp.github.io/reference/numeric/exclusive_scan.html)

std::exclusive_scan(first, last, result, init)
std::exclusive_scan(first, last, result, init, op)

[0, i)間の要素の部分演算結果をresultに書き込む(result.size() == last-first)
つまり、result[0]=init, result[1]=op(result[0], r[0]), result[2]=op(result[1], r[1]), ...のようになる
入力側の最終要素に対する演算は出力されないので注意
デフォルトではop(a, b) = a+b


[std::inclusive_scan](https://cpprefjp.github.io/reference/numeric/inclusive_scan.html)

std::inclusive_scan(first, last, result)
std::inclusive_scan(first, last, result, op)
std::inclusive_scan(first, last, result, op, init)

[0, i]間の要素の部分演算結果をresultに書き込む(result.size() == last-first)
つまり、result[0]=r[0] $~$ (initがある場合はop(init, r[0])), result[1]=op(result[0], r[1]), result[2]=op(result[1], r[2]), ...のようになる
デフォルトではop(a, b) = a+b


[std::reduce](https://cpprefjp.github.io/reference/numeric/reduce.html)

std::reduce(first, last)
std::reduce(first, last, init)
std::reduce(first, last, init, op)

[first, last)間の要素を集計する
accumulateとは異なり、並列計算のために集計順を規定しない
initと[first, last)を合わせたリストの任意の組み合わせに対し、順不同でop(op(a,b), op(c,d))のように適用していく
デフォルトでは init=0 および op(a, b) = a+b

[std::transform_exclusive_scan](https://cpprefjp.github.io/reference/numeric/transform_exclusive_scan.html)

std::transform_exclusive_scan(first, last, result, init, binary_op, unary_op)

[0, i)間の要素に対して、要素を変換しながらの部分演算結果をresultに書き込む(result.size() == last-first)
つまり、result[0]=init, result[1]=binary_op(result[0], unary_op(r[0])), result[2]=binary_op(result[1], unary_op(r[1])), ...のようになる
入力側の最終要素に対する演算は出力されないので注意

[std::transform_inclusive_scan](https://cpprefjp.github.io/reference/numeric/transform_inclusive_scan.html)

std::transform_inclusive_scan(first, last, result, binary_op, unary_op)
std::transform_inclusive_scan(first, last, result, binary_op, unary_op, init)

[0, i]間の要素の部分演算結果をresultに書き込む(result.size() == last-first)
つまり、result[0]=unary_op(r[0])(initがある場合はbinary_op(init, unary_op(r[0])), result[1]=binary_op(result[0], unary_op(r[1])), result[2]=binary_op(result[1], unary_op(r[2])), ...のようになる

[std::transform_reduce](https://cpprefjp.github.io/reference/numeric/transform_reduce.html)

std::transform_reduce(first1, last1, first2, init)
std::transform_reduce(first1, last1, first2, init, op1, op2)
std::transform_reduce(first, last, init, binary_op, unary_op)

[first1, last1)間の要素xと[first1, first2+(last1-first1))間の要素yに対して、initとop2(x,y)を合わせたリストの任意の組み合わせに対し、順不同にop1(op1(a,b), op1(c,d))を適用し、集計値を計算する

もしくは

initと、[first,last)間の要素にunary_opを適用した要素を合わせたリストの任意の組み合わせに対し、順不同にbinary_op(binary_op(a, b), binary_op(c, d))を適用し、集計値を計算する

(おそらく、並列計算のために集計順を規定しない)

# C++20で追加

[std::midpoint](https://cpprefjp.github.io/reference/numeric/midpoint.html)

std::midpoint(a, b)

aとbの中点((a+b)/2)を求める
その際、オーバーフローが起こりにくいように工夫が入る