Question

I am using the Gnu Scientific Library (GSL), where I have initialized different vectors.

Now I want to combine these vectors into a single vector in order to iterate over the full vector. Does anyone know of a method, where it is possible to do this?

This question discusses the same problem in a more general fashion, but I wanted to know if anyone knew a way to do this directly using GSL (I am to use the sort function implemented in GSL afterwards).

Thank you, Rasmus

Was it helpful?

Solution 2

If by " initialized different vectors " you meant initialized different std::vectors, then the answer of your question is here use std::assign.

EDIT 1: In this case, std::assign is the best answer (and not std::copy as many places would suggest) because std::copy will insert the new elements one by one (instead of inserting the whole array at once) and that can cause multiple reallocation (meaning: when you try to insert a new element to a vector where its current size (given by std::vector::size) is equal to its current capacity (given by std::vector::capacity), a reallocation is made that doubles vector capacity. Depending of the size of your vector, this can happen multiple times and it is a very (very!) expensive operation. With std::assign this will only happen once.

If not (meaning you have a collection of gsl_vectors), then in principle it is possible to use STL algorithms with C arrays see here (gsl_vectors holds a C array called data). However it is quite dangerous because the way the memory is aligned inside gsl_vectors is tricky. In this case, you need to convert them manually to std::vector or merge then manually to a bigger gsl_vector)

But, unless you need to implement matrices or need very fast BLAS operations with vectors (see here) I would always work with std::vector (and use std::vector::data to pass the C pointers to GSL functions). For these two exceptions, you should use Armadillo Linear Algebra Package or Blaze if you want to work in C++ (otherwise you would need to write a wrapper or code like C).

OTHER TIPS

If you want to stick to GSL, but not set all vector coordinates individually you can use gsl_vector_view obtained from gsl_vector_subvector.

To this end, allocate the output gsl_vector large enough to hold the concatenation of all your different vectors. Then for each of these use gsl_vector_subvector to obtain a gsl_vector_view to the portion of the output vector. You can then gsl_vector_memcpy from each of your input vectors to that corresponding portion. Note that a gsl_vector_view is a struct which contains a gsl_vector called 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 );
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top