是否可以将GSL载体组合成单个载体?

时间:2013-10-22 15:49:45

标签: c++ vector gsl

我正在使用Gnu科学图书馆(GSL),我在那里初始化了不同的载体。

现在我想将这些向量组合成一个向量,以迭代整个向量。有没有人知道一种方法,哪有可能做到这一点?

这个question以更一般的方式讨论了同样的问题,但我想知道是否有人知道如何使用GSL直接执行此操作(我之后使用GSL中实现的排序功能)。 / p>

谢谢你, 拉斯穆斯

2 个答案:

答案 0 :(得分:0)

如果通过“初始化的不同向量”意味着初始化了不同的std :: vectors,那么你的问题的答案就在use std::assign

编辑1:在这种情况下,std :: assign是最好的答案(而不是像许多地方所建议的std :: copy)因为std :: copy将逐个插入新元素(而不是插入整个数组一次)并且可以导致多次重新分配(意思是:当你尝试将一个新元素插入一个向量时,其当前大小(由std :: vector :: size给出)等于其当前容量(由std给出: :vector :: capacity),重新分配,使矢量容量加倍。根据矢量的大小,这可能会发生多次,这是一个非常(非常!)昂贵的操作。使用std :: assign这只会发生一次。

如果不是(意味着你有一个gsl_vectors的集合),那么原则上可以使用带有C数组see here的STL算法(gsl_vectors包含一个名为data的C数组)。但是它非常危险,因为内存在gsl_vectors中对齐的方式很棘手。在这种情况下,您需要手动将它们转换为std :: vector或手动合并到更大的gsl_vector)

但是,除非您需要实现矩阵或需要使用向量(see here)进行非常快速的BLAS操作,否则我将始终使用std :: vector(并使用std :: vector :: data来传递C指针)到GSL功能)。对于这两个例外,如果您想使用C ++,则应使用Armadillo Linear Algebra PackageBlaze(否则您需要编写包装器或C代码)。

答案 1 :(得分:0)

如果您想坚持使用GSL,但未单独设置所有矢量坐标,则可以使用从gsl_vector_view获得的gsl_vector_subvector

为此,将输出gsl_vector分配得足够大,以保存所有不同向量的串联。然后,对于这些中的每一个使用gsl_vector_subvector来获得输出向量的部分的gsl_vector_view。然后,您可以从每个输入向量gsl_vector_memcpy到相应的部分。请注意,gsl_vector_view是一个包含名为vector的gsl_vector的结构:

#include <stdio.h>
#include <gsl/gsl_vector.h>

#define length1 4
#define length2 6

int main () {
    /* allocate all vectors */
    gsl_vector
        *vectorIn1 = gsl_vector_alloc( length1 ),
        *vectorIn2 = gsl_vector_alloc( length2 ),
        *vectorOut = gsl_vector_alloc( length1+length2 );

    /* fill input vectors with some test data */
    for ( size_t index = 0; index < length1; ++index ) {
        gsl_vector_set( vectorIn1, index, -(double)index );
    }
    for ( size_t index = 0; index < length2; ++index ) {
        gsl_vector_set( vectorIn2, index, (double)index );
    }

    /* perform the copy to portions of the output */
    {
        gsl_vector_view
            viewOut1 = gsl_vector_subvector( vectorOut, 0, length1 ),
            viewOut2 = gsl_vector_subvector( vectorOut, length1, length2 );
        gsl_vector_memcpy( &viewOut1.vector, vectorIn1 );
        gsl_vector_memcpy( &viewOut2.vector, vectorIn2 );
    }

    /* display the result to see it is correct */
    for ( size_t index = 0; index < length1 + length2; ++index ) {
        printf( "%3.1f\n", gsl_vector_get( vectorOut, index ) );
    }

    /* be nice and tidy: release resources after use */
    gsl_vector_free( vectorOut );
    gsl_vector_free( vectorIn2 );
    gsl_vector_free( vectorIn1 );
}