CRANBERRIES INTERVAL LIBRARY Boost の Interval のののののののの のののののののの
CRANBERRIES INTERVAL LIBRARY
Boost の Interval が使いにくいので作っちゃいました
自己紹介• Twitter : いなむ先生 @_EnumHack
• 高校で化学・物理を教えている• 趣味で数値解析の研究をしている• プログラミング歴約 6 年、 C++ 歴約 3 年• ちょうど 1 週間前に「 C++ の会」というオンラインのコミュニティを立ち上げた
C++ の会の宣伝• C++ の会は C++ 超初心者や C++ 中級者が集う会です• 競プロ、ゲーム制作、趣味、いろいろな人が、現在 38 人集まっています• いなむ先生(私)は設立メンバー( 2 人の owner うちの 1 人)です• slack 上で C++ の質問をしたり答えたり Ruby やら洗濯物の雑談をしたりしています• 基本フラットで、習熟度はあまり関係なく話し合う会を目指しています• C++ の会では C++ をイチから勉強したい方や• 鉞を投げ込んでくれる本物の C++ プログラマーを募集してます!• 興味を持った方は @_EnumHack まで
開発経緯• 大学時代の研究室の教授の方針で使用するコードはすべて書く• 区間演算ライブラリを書いた• 自分の書いたコードと既存の区間演算ライブラリのコードを比べた• 違うところがある• 自分のライブラリも便利な気がした• せっかく作ったから車輪の再々発明だけど公開しよう←いまここ
目次• 区間演算の概要• Boost Interval ではダメな理由• Cranberries Interval Library の特徴
区間演算の概要https://github.com/LoliGothick/Interval-Analysis
区間演算の使い方(一例)
そもそも区間とは?• 定義 区間 X とはある実数を上下限とする実数の集合
区間は中学生でも使っている• 変域と値域
区間
区間
区間演算の性質• 変数を区間にして関数を計算すると値域が求まる
(関数の区間拡張)
• ただし、区間演算は実際の値域より広い区間になる性質がある• その場合も、必ず値域を包み込みます(区間包囲)
実用例 – 区間最適化• Levy3 関数の最小化
• [-10,10] で関数値を区間演算すると• ans = [ -54.5403, 54.5403 ]
• 真の値域は [-14.976,14.976]
• どうするか?
こうする• 区間の幅を狭くすればよいoptimize.exe
なぜ BOOST ではダメなのか区間演算の根本的な問題があった
区間の比較という問題、その前に•比較には 3 種類ある
•Total Ordering•Weak Ordering•Partial Ordering
•ソートするには Weak Ordering を満たす比較演算子が必要
区間の比較という問題• 区間の比較には 3 種類ほど定義があるらしい• どの定義も Partial Ordering である• 正しくソートされる保証がない!• kvライブラリなどほかの区間演算ライブラリでも同様
CRANBERRIES INTERVAL LIBRARYの特徴
新しい区間比較方法の提案提供する機能の紹介
区間比較の定義を新しく作った•Cranberries Interval には比較の種類が4つある
•Total Ordering•Weak Ordering•Partial Ordering•Interval Ordering
Interval Ordering•区間についてあるとは
Partial Ordering•区間についてあるとは
Weak Ordering•区間についてあるとは
Total Ordering
比較演算子について• これらの比較方法は 4 種類の関数として提供される
• bool operator<(interval<T> const&, interval<T> const&)• はデフォルトでは total_ordering
bool interval_ordering(interval<T> const&, interval<T> const&)bool partial_ordering(interval<T> const&, interval<T> const&)bool weak_ordering(interval<T> const&, interval<T> const&)bool partial_ordering(interval<T> const&, interval<T> const&);
Semantics Switchingauto&& a = interval<>{ 1,3 };auto&& b = interval<>{ 2,4 };a < b; // default では total ordering なので true{
using namespace interval_ordering;a < b; // interval ordering に意味が変わるので falseになる
}
仕組みinline namespace total_ordering_policy {
template < typename T, typename U >
inline constexpr bool operator<( interval<T> const& x, interval<U> const& y ){return total_less( x, y ) ;
}}namespace interval_ordering_policy {
template < typename T, typename U>constexpr bool operator<( T&& x, U&& y ) {return interval_less( std::forward<T>( x ), std::forward<U>( y ) ) ; }
}
関数オブジェクトもあるtemplate < order = order::Total >struct less {
template < typename T, typename U >constexpr bool operator()( interval<T> const& a, interval<U> const& b ) const {
return total_less( a, b ) ;}template < typename T, typename U >constexpr bool operator()( U const& a, interval<T> const& b ) const {
return total_less( a, b ) ;}template < typename T, typename U >constexpr bool operator()( interval<T> const& a, U const& b ) const {
return total_less( a, b ) ;}
} ;
関数オブジェクトの使いどころinterval<double> a{1,2}, b{3,4}, c{5,6}, d{6,7} ;vector<interval<double>> vec{a,b,c,d} ;std::sort(vec.begin(),vec.end(),less<order::Weak>()) ;
提供される演算子operator+operator-operator*operator/operator++
operator<operator<=operator>operator>=operator==operator!=
operator+=operator-=operator*=operator/=operator--
trigonometric functionssin()cos()tan()asin()acos()atan()
hyperbolic functionssinh()cosh()tanh()asinh()acosh()atanh()
その他log()log10()log2()log1p()exp()exp2()expm1()
pow(int)sqrt()abs()erf()erfc()fma(T1,T2,T3)
区間専用関数mid()wid()is_singleton()upper()lower()
2項演算子と2、3引数関数•2項演算子と2,3引数関数は interval の value type が違ってもよい•戻り値型は型変換もしくはプロモーションが起こった結果の型• 計算不可能なときはコンパイルエラー
型変換の仕組み•異なる value type をもつ区間クラスの演算での型変換規則
template < typename L, typename R >struct promotion {
typedef decltype( L{} + R{} ) type ; } ;
template < typename L, typename R >using promotion_t = typename promotion<L, R>::type ;
次のリリース(予定)auto&& a = interval<>{ 1,3 };auto&& b = interval<>{ 2,4 };{
using namespace Expression;auto&& expr = a + b; // Expression Template になる !
}
課題• 区間用の関数が少ない( norm, mig, mag etc… )• C++始めたてのころの稚拙なコードが残っている• 使っている人がいない