push_back/append 或在 C++ Armadillo 中附加带有循环的向量
push_back/append or appending a vector with a loop in C++ Armadillo
我想创建一个整数向量 (arma::uvec) - 我事先不知道向量的大小。我在犰狳文档中找不到合适的函数,而且我没有成功地通过循环创建向量。我认为问题在于初始化矢量或跟踪其长度。
arma::uvec foo(arma::vec x){
arma::uvec vect;
int nn=x.size();
vect(0)=1;
int ind=0;
for (int i=0; i<nn; i++){
if ((x(i)>0)){
ind=ind+1;
vect(ind)=i;
}
}
return vect;
}
错误信息是:Error: Mat::operator(): index out of bounds.
我不想将 1 分配给向量的第一个元素,但如果需要可以接受。
PS: 我很想知道如何通过追加得到未知长度的向量,这样我就可以在更一般的情况下使用它。
从性能的角度来看,向向量重复添加元素是一个非常糟糕的主意,因为它会导致重复的内存重新分配和复制。
主要有两个解决方案。
将向量的大小设置为你操作的理论最大长度(在本例中为nn
),然后使用循环设置向量中的一些值。到目前为止,您需要为向量中集合元素的数量保留一个单独的计数器。循环后,使用 .head() 函数获取向量的子向量。这里的好处是只会有一份。
另一种解决方案是使用两个循环,以减少内存使用。在第一个循环中计算出向量的最终长度。然后将向量的大小设置为最终长度。在第二个循环中设置向量中的元素。显然使用两个循环比一个循环效率低,但它可能仍然比追加快得多。
如果您仍然想成为一个懒惰的编码员并且低效地附加元素,请使用 .insert_rows() 函数。
作为旁注,您的 foo(arma::vec x)
已经在对输入向量进行不必要的复制。 C++ 中的参数默认通过值 传递 ,这基本上意味着 C++ 将在 运行 函数之前复制 x
。为避免这种不必要的复制,请将您的函数更改为 foo(const arma::vec& x)
,这意味着 对 x
进行常量引用 。 &
在这里很关键。
除了我同意的mtall的回答,
对于不需要性能的情况,我使用了这个:
void uvec_push(arma::uvec & v, unsigned int value) {
arma::uvec av(1);
av.at(0) = value;
v.insert_rows(v.n_rows, av.row(0));
}
我想创建一个整数向量 (arma::uvec) - 我事先不知道向量的大小。我在犰狳文档中找不到合适的函数,而且我没有成功地通过循环创建向量。我认为问题在于初始化矢量或跟踪其长度。
arma::uvec foo(arma::vec x){
arma::uvec vect;
int nn=x.size();
vect(0)=1;
int ind=0;
for (int i=0; i<nn; i++){
if ((x(i)>0)){
ind=ind+1;
vect(ind)=i;
}
}
return vect;
}
错误信息是:Error: Mat::operator(): index out of bounds.
我不想将 1 分配给向量的第一个元素,但如果需要可以接受。
PS: 我很想知道如何通过追加得到未知长度的向量,这样我就可以在更一般的情况下使用它。
从性能的角度来看,向向量重复添加元素是一个非常糟糕的主意,因为它会导致重复的内存重新分配和复制。
主要有两个解决方案。
将向量的大小设置为你操作的理论最大长度(在本例中为
nn
),然后使用循环设置向量中的一些值。到目前为止,您需要为向量中集合元素的数量保留一个单独的计数器。循环后,使用 .head() 函数获取向量的子向量。这里的好处是只会有一份。另一种解决方案是使用两个循环,以减少内存使用。在第一个循环中计算出向量的最终长度。然后将向量的大小设置为最终长度。在第二个循环中设置向量中的元素。显然使用两个循环比一个循环效率低,但它可能仍然比追加快得多。
如果您仍然想成为一个懒惰的编码员并且低效地附加元素,请使用 .insert_rows() 函数。
作为旁注,您的 foo(arma::vec x)
已经在对输入向量进行不必要的复制。 C++ 中的参数默认通过值 传递 ,这基本上意味着 C++ 将在 运行 函数之前复制 x
。为避免这种不必要的复制,请将您的函数更改为 foo(const arma::vec& x)
,这意味着 对 x
进行常量引用 。 &
在这里很关键。
除了我同意的mtall的回答, 对于不需要性能的情况,我使用了这个:
void uvec_push(arma::uvec & v, unsigned int value) {
arma::uvec av(1);
av.at(0) = value;
v.insert_rows(v.n_rows, av.row(0));
}