Mais conteúdo relacionado
Semelhante a データサイエンスワールドからC++を眺めてみる (20)
Mais de Shintaro Fukushima (20)
データサイエンスワールドからC++を眺めてみる
- 14. 2.2 フィボナッチ数列
$ R
> install.packages("Rcpp")
> library(Rcpp)
> sourceCpp("fibCpp.cpp")
> fibCpp(20)
[1] 6765
13
- 15. 2.2 フィボナッチ数列
Rで実⾏した場合に⽐べて,約1,000倍のスピードアップ.
> sourceCpp("fibCpp.cpp")
> benchmark(fibCpp(20), fibR(20),
replications=5000)[, 1:4]
test replications elapsed relative
2
fibR(20)
5000 200.434 756.355
1 fibCpp(20)
5000
0.265
1.000
参考:@teramonagi
Tokyo.R ⽩熱教室「これからのRcppの話をしよう」
14
- 17. 3.1 C++での統計処理
取り急ぎ調べたところ,以下のライブラリなどがある模様.
良いライブラリがあったら教えてください(^^;
ライブラリ
記述統計量
統計的検定
多変量解析
機械学習
○
×
×
×
Apophenia
○
○
△
△
ROOT
△
△
△
△
GSL
△
×(?)
△
×(?)
ALGLIB
○
○
○
△
Boost.
Accumulators
○:多くの⼿法を提供 △:少数の⼿法を提供 ×:⾮提供
16
- 19. 3.2 Boost.Accumulators
boost::accumulators::accumulator_setというコンテ
ナにデータを⼊⼒.
テンプレートパラメータに実⾏する処理を指定(統計量計算)
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
using namespace boost::accumulators;
int main()
{
accumulator_set<double, stats<tag::min, tag::mean, tag::sum> > acc;
acc(3.0);
acc(1.0);
acc(4.0);
acc(2.0);
acc(5.0);
}
std::cout << extract::min(acc) << std::endl; // 最小値
std::cout << extract::mean(acc) << std::endl; // 平均値
std::cout << extract::sum(acc) << std::endl; // 合計値
18
- 20. 3.2 Boost.Accumulators
std::vectorや配列などのコンテナに格納されたデータに対し
ては,for_eachを使⽤してaccumulator_setに代⼊.
#include <iostream>
#include <boost/array.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include
#include
#include
#include
<boost/bind.hpp>
<boost/ref.hpp>
<boost/accumulators/accumulators.hpp>
<boost/accumulators/statistics.hpp>
using namespace boost::accumulators;
int main()
{
int ar[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
accumulator_set<double, stats<tag::min, tag::mean, tag::max> > acc;
boost::for_each(ar, boost::bind(boost::ref(acc), _1));
std::cout << extract::min(acc) << std::endl; // 最小値
std::cout << extract::mean(acc) << std::endl; // 平均値
std::cout << extract::max(acc) << std::endl; // 最大値
}
return 0;
19
- 22. 3.3 ALGLIB
#include <iostream>
#include "statistics.h"
using namespace std;
using namespace alglib;
int main()
{
real_1d_array x = "[0,1,4,9,16,25,36,49,64,81]";
real_1d_array y = "[0,1,2,3,4,5,6,7,8,9]";
double v;
ナゾの値の代⼊⽂
cout.precision(8);
// 共分散
v = cov2(x, y);
cout << "共分散: " << double(v) << endl;
// Pearson 相関係数
v = pearsoncorr2(x, y);
cout << "Pearson 相関係数: " << double(v) << endl;
// Spearman 相関係数
v = spearmancorr2(x, y);
cout << "Spearman 相関係数: " << double(v) << endl;
return 0;
}
21
- 24. 3.4.1 式の評価
#include <RInside.h>
int main(int argc, char *argv[]) {
RInside R(argc, argv);
R["x"] = 10 ;
R["y"] = 20 ;
// C++に埋め込むRのインスタンスの⽣成
// Rのインスタンスにオブジェクトの名前と値を代⼊
R.parseEvalQ("z <- x + y") ;
// Rでの評価式
int sum = R["z"];
// []演算⼦でオブジェクトの値を取得
std::cout << "10 + 20 = " << sum << std::endl ;
// 以下の⽅法で評価してもO.K.
sum = R.parseEval("x + y") ;
std::cout << "10 + 20 = " << sum << std::endl ;
exit(0);
}
以下のRInlineパッケージのソースのinst/examples/standard/rinside_sample8.cpp
http://cran.r-project.org/src/contrib/RInside_0.2.11.tar.gz
23
- 25. Makefile
3.4.1 式の評価
## -*- mode: make; tab-width: 8; -*R_HOME :=
$(shell R RHOME)
sources :=
programs :=
$(wildcard *.cpp)
$(sources:.cpp=)
## Rのためのヘッダやライブラリ
RCPPFLAGS :=
$(shell $(R_HOME)/bin/R CMD config --cppflags)
RLDFLAGS :=
$(shell $(R_HOME)/bin/R CMD config --ldflags)
RBLAS :=
$(shell $(R_HOME)/bin/R CMD config BLAS_LIBS)
RLAPACK :=
$(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS)
## Rcppのヘッダやライブラリ
RCPPINCL :=
$(shell echo 'library(Rcpp, lib.loc="/home/sfchaos/lib/R");Rcpp:::CxxFlags()' |
$(R_HOME)/bin/R --vanilla --slave)
RCPPLIBS :=
$(shell echo 'library(Rcpp, lib.loc="/home/sfchaos/lib/R");Rcpp:::LdFlags()' |
$(R_HOME)/bin/R --vanilla --slave)
## include headers and libraries for RInside embedding classes
RINSIDEINCL :=
$(shell echo 'library(RInside,
lib.loc="/home/sfchaos/lib/R");RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RINSIDELIBS :=
$(shell echo 'library(RInside,
lib.loc="/home/sfchaos/lib/R");RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave)
24
- 26. Makefile(続 )
3.4.1 式の評価
## makeするための各種のルール
CXX :=
$(shell $(R_HOME)/bin/R CMD config CXX)
CPPFLAGS :=
-Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS)
CXXFLAGS :=
$(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD
config CXXFLAGS)
LDLIBS :=
$(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)
all:
$(programs)
@test -x /usr/bin/strip && strip $^
run:
$(programs)
@for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done
clean:
rm -vf $(programs)
rm -vrf *.dSYM
runAll:
for p in $(programs); do echo ""; echo ""; echo "Running $$p"; ./$$p; done
25
- 27. 3.4.1 式の評価
$ make rinside_sample8.cpp
$ ./rinside_sample8
10 + 20 = 30
10 + 20 = 30
26
- 28. lm.cpp
3.4.2 回帰分析
#include <RInside.h>
int main(int argc, char *argv[])
{
RInside R(argc, argv); // C++ 埋 込 R
生成
std::vector<double> x;
x.push_back(1.0); x.push_back(2.0); x.push_back(3.0);
R["x"] = x;
std::vector<double> y;
y.push_back(2.0); y.push_back(4.0); y.push_back(6.0);
R["y"] = y;
// R 回帰分析 実行(y = 2*x)
R.parseEvalQ("fit.lm <- lm(y ~ x); fit.lm.coef <- fit.lm$coef");
std::vector<double> coef;
coef = R["fit.lm.coef"]; // 回帰係数 取得
std::cout << "傾 : " << coef[1] << std::endl;
std::cout << "切片: " << coef[0] << std::endl;
}
return 0;
27
- 29. 3.4.2 回帰分析
$ make lm
g++ -I/usr/local/lib/R/include -I/home/sfchaos/lib/R/Rcpp/include I/home/sfchaos/lib/R/RInside/include -g -O2 -Wall I/usr/local/include
lm.cpp -L/usr/local/lib/R/lib -lR L/usr/local/lib/R/lib -lRblas -L/usr/local/lib/R/lib -lRlapack L/home/sfchaos/lib/R/RInside/lib -lRInside -Wl,rpath,/home/sfchaos/lib/R/RInside/lib -o lm
$ ./lm
傾き: 2
切⽚: -0
28
- 32. R ⇔ C++の誰得な発表.
• R ⇒ C++: Rcpp
• C++ ⇒ R: RInside
C++で統計解析を⾏うための良いツールがあれば,
是⾮教えてください.
31