gpt4 book ai didi

c++ - arma::find_unique 如何确定唯一索引?

转载 作者:行者123 更新时间:2023-11-30 03:39:23 27 4
gpt4 key购买 nike

我正在使用 arma::find_unique,我认为它返回了 vector 中每个唯一值第一次出现的索引,但它似乎返回了其他内容。

这是一个玩具函数:

// [[Rcpp::export]]
arma::uvec test(arma::vec& x_) {
vec x=arma::sort(x_);
return arma::find_unique(x);
}

如果我用一个简单的 vector test(5:1) 在 R 中运行该函数,我会得到一个包含所有索引的 vector 0,1,2,3,4 这是有道理的,因为每个值都是唯一的。

如果我尝试这样的事情:

set.seed(1991)
var=sample(1:8,20,TRUE)
test(var)

输出:

1,3,6,7,19,12,14,18.

除了第一个之外,所有这些值都有意义。为什么索引 1 处的第一个唯一值不是 0?显然我误解了 arma::find_unique 打算这样做,如果有人能启发我,我将不胜感激。

编辑我的 session 信息

sessionInfo()

最佳答案

好的,以下是@nrussell 的礼貌,这个人很了不起,并且在评论中给出了这个“答案”。 (我不值得打勾,也不值得投票。)

Actually, I'm pretty sure this is all just a misinterpretation of the Armadillo documentation, which never actually guarantees that a stable sort is used, as @Carl was expecting. Underneath, std::sort is being called, which is not guaranteed to be a stable sort by the C++ standard; also stated here:

"The order of equal elements is not guaranteed to be preserved."

我可以演示这个here , 复制 "packet" structure在 Armadillo 算法中使用。我的猜测是 libc++(通常由 OS X 使用)确实将 std::sort 实现为稳定排序,而 libstdc++ 没有。

轮到我了:稳定排序,或维护具有相同键(即值)的记录的相对顺序,是这个问题背后的关键问题。例如,请考虑以下内容:

dog car pool dig

使用稳定排序的第一个字母排序给我们:

car dog dig pool

因为单词“dog”出现在 vector 中的“dig”之前,因此它必须出现在输出中的“dig”之前。

使用不稳定排序的第一个字母排序给我们:

car dig dog pool

car dog dig pool

主体与数字相关,因为每个 key 生成字面上都存在于其他地方。所以,我们有:

2, 3, 2, 4

因此,当找到唯一值时:

2, 3, 4

2 的 id 可以是 0 或 2。

正如@nrussell 所解释的,自 OS X Mavericks (10.9) 以来,macOS 默认依赖于 --stdlib=libc++ 与传统的 --stdlib=libstdc++ 标志编译。这可能是我无法复制它的原因,因为一种实现选择了稳定性而另一种则没有。

原始答案

首先,我无法在 macOS 上复制它...(见结尾)

虽然我们似乎能够在 Linux 上重现它 (@nrussel)。这意味着在某些时候,链接代码中存在问题。

其次,arma::find_unique已实现here使用 matrix opsop_find_unique .后者是关键,因为它实现了比较器。

因此,简而言之,假设您对 vector 进行排序并且第一项始终被认为是唯一的,那么应该没有任何可能。

测试函数

#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::uvec test(arma::vec& x_) {
Rcpp::Rcout << "Input:" << x_.t() << std::endl;
arma::vec x = arma::sort(x_);
Rcpp::Rcout << "Sorted:" << x.t() << std::endl;
arma::uvec o = arma::find_unique(x);
Rcpp::Rcout << "Indices:" << o.t() << std::endl;
return o;
}

/*** R
set.seed(1991)
(v=sample(1:8,20,TRUE))
## [1] 2 2 1 5 7 6 7 6 4 1 5 3 1 4 4 2 8 7 7 8
sort(v)
## [1] 1 1 1 2 2 2 3 4 4 4 5 5 6 6 7 7 7 7 8 8

test(v)
### Received
## 2.0000 2.0000 1.0000 5.0000 7.0000 6.0000 7.0000 6.0000 4.0000 1.0000 5.0000 3.0000 1.0000 4.0000 4.0000 2.0000 8.0000 7.0000 7.0000 8.0000

### Sorted
## 1.0000 1.0000 1.0000 2.0000 2.0000 2.0000 3.0000 4.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 7.0000 7.0000 8.0000 8.0000

### Output
## 0 3 6 7 10 12 14 18
*/

关于c++ - arma::find_unique 如何确定唯一索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38903126/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com