Cranberries interval library 開発の話

Post on 09-Apr-2017

700 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

Transcript

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++始めたてのころの稚拙なコードが残っている• 使っている人がいない

top related