push_back/append或在C ++ Armadillo中附加带有循环的向量 [英] push_back/append or appending a vector with a loop in C++ Armadillo

查看:225
本文介绍了push_back/append或在C ++ Armadillo中附加带有循环的向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个整数的向量(arma :: uvec)-我不事先知道向量的大小.我在Armadillo文档中找不到合适的函数,但是我并没有成功地通过循环创建矢量.我认为问题在于初始化向量或跟踪其长度.

I would like to create a vector (arma::uvec) of integers - I do not ex ante know the size of the vector. I could not find approptiate function in Armadillo documentation, but moreover I was not successfull with creating the vector by a loop. I think the issue is initializing the vector or in keeping track of its length.

 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赋给向量的第一个元素,但是可以在需要的情况下使用它.

I would not want to assign 1 to the first element of the vector, but could live with that if necessary.

PS:我真的很想知道如何通过追加获得未知长度的向量,以便在更一般的情况下也可以使用它.

PS: I would really like to know how to obtain the vector of unknown length by appending, so that I could use it even in more general cases.

推荐答案

从性能的角度来看,将元素重复添加到向量上是一个真正的坏主意,因为它可能导致重复的内存重新分配和副本.

Repeatedly appending elements to a vector is a really bad idea from a performance point of view, as it can cause repeated memory reallocations and copies.

有两种主要解决方案.

  1. 将向量的大小设置为操作的理论最大长度(在这种情况下为nn),然后使用循环设置向量中的某些值.到目前为止,您将需要为向量中的set元素数量保留一个单独的计数器.循环之后,使用 .head()函数获取向量的子向量.这样做的好处是只有一个副本.

  1. Set the size of the vector to the theoretical maximum length of your operation (nn in this case), and then use a loop to set some of the values in the vector. You will need to keep a separate counter for the number of set elements in the vector so far. After the loop, take a subvector of the vector, using the .head() function. The advantage here is that there will be only one copy.

另一种解决方案是使用两个循环,以减少内存使用量.在第一个循环中,计算出向量的最终长度.然后将向量的大小设置为最终长度.在第二个循环中,设置向量中的元素.显然,使用两个循环的效率不如一个循环,但可能仍会比附加循环快得多.

An alternative solution is to use two loops, to reduce memory usage. In the first loop work out the final length of the vector. Then set the size of the vector to the final length. In the second loop set the elements in the vector. Obviously using two loops is less efficient than one loop, but it's likely that this is still going to be much faster than appending.

如果您仍然想成为惰性编码器并且效率低下地追加元素,请使用 .insert_rows() 函数.

If you still want to be a lazy coder and inefficiently append elements, use the .insert_rows() function.

作为旁注,您的foo(arma::vec x)已经在不必要地复制输入向量.默认情况下,C ++中的参数是按值传递 ,这基本上意味着C ++将在运行函数之前复制x.为避免不必要的复制,请将您的函数更改为foo(const arma::vec& x),这意味着x采用恒定引用. &在这里很重要.

As a sidenote, your foo(arma::vec x) is already making an unnecessary copy the input vector. Arguments in C++ are by default passed by value, which basically means C++ will make a copy of x before running your function. To avoid this unnecessary copy, change your function to foo(const arma::vec& x), which means take a constant reference to x. The & is critical here.

这篇关于push_back/append或在C ++ Armadillo中附加带有循环的向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆