#c #r #rcpp
#c #r #rcpp
Вопрос:
Я новичок в Rcpp (и, следовательно, cpp), и я застрял на том, как правильно использовать std::pair .
Я работаю с графами, и структура данных для графика: std::vector<std::vector<std::pair<int, double> > >
Мне нужно расширить концепцию единого веса. Я написал пару минималистичных примеров. Все это принимает матрицу и возвращает ту же самую матрицу (после выполнения необходимых операций она будет проходить в реальном коде. Поэтому важно, чтобы структура данных графа была std::vector<std::vector<std::pair<int, ?> > >
такой, чтобы holding
вектор выполнял обратные действия и чтобы a Rcpp::NumericMatrix
возвращался с использованием элементов holding
в конце):
1.
Rcpp::cppFunction('
NumericMatrix test_stdvector(Rcpp::NumericMatrix x) {
std::vector<std::pair<int, std::vector<double> > > holding(x.nrow());
for (int i=0; i < x.nrow(); i ) {
NumericVector nv_x = x.row(i);
std::vector<double> b = Rcpp::as<std::vector<double> >(nv_x);
holding.push_back(std::make_pair(i, b));
}
Rcpp::NumericMatrix y(x.nrow(), x.ncol());
for (int i=0; i < x.nrow(); i ) {
NumericVector b = wrap(holding[i].second);
y(i, _) = b;
}
return y;
}
')
Rcpp::cppFunction('
NumericMatrix test_numericvector(Rcpp::NumericMatrix x) {
std::vector<std::pair<int, Rcpp::NumericVector> > holding(x.nrow());
for (int i=0; i < x.nrow(); i ) {
holding.push_back(std::make_pair(i, x(i, _)));
}
Rcpp::NumericMatrix y(x.nrow(), x.ncol());
for (int i=0; i < x.nrow(); i ) {
y(i, _) = holding[i].second;
}
return y;
}
')
Обе функции компилируются нормально, однако для ввода x = matrix(1:100, nrow=10)
вывод получается странным:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1.356944e-311 2.121996e-314 1.356944e-311 1.355961e-311 1.355961e-311 1.355967e-311 1.356944e-311 1.356944e-311 2.121996e-314
[2,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[3,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[4,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[5,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[6,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[7,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.262910e-314
[8,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[9,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[10,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[,10]
[1,] 1.356944e-311
[2,] 1.356944e-311
[3,] 1.356944e-311
[4,] 1.356944e-311
[5,] 1.356944e-311
[6,] 1.356944e-311
[7,] 1.356944e-311
[8,] 1.356944e-311
[9,] 1.356944e-311
[10,] 1.356944e-311
Может кто-нибудь, пожалуйста, объяснить, что происходит?
Заранее спасибо
Ответ №1:
Я бы рекомендовал тщательную отладку и проверку индекса, возможно, с меньшими примерами.
Вы также можете распечатать матрицу по пути, чтобы проверить, что вы получаете данные в начале, достаточно простого print(x);
на уровне C . То же самое для y
before return .
Я бы начал, возможно, с примеров 3×3 и попытался бы сделать это правильно. И я не думаю, что у нас есть конвертеры для std::pair
.
Наконец, иногда это мелочи: на y(i, _) = holding[i].second;
самом деле вы делаете несколько вещей одновременно, когда вы извлекаете и переназначаете. Иногда это помогает извлечь временную переменную, а затем назначить эту временную переменную.
Комментарии:
1. Спасибо, Дирк, похоже, что при вызове
push_back
удерживающего вектора вектор добавляется за пределы его диапазона, поскольку он был инициализированholding(x.nrow())
.