I'm using boost for matrix and vector operations in a code and one of the libraries I am using (CGNS) has an array as an argument. How do I copy the vector into double[] in a boost 'way', or better yet, can I pass the data without creating a copy?
I'm a bit new to c++ and am just getting going with boost. Is there a guide I should read with this info?
Contents between any two input iterators can be copied to an output iterator using the copy algorithm. Since both ublas::vector and arrays have iterator interfaces, we could use:
#include <boost/numeric/ublas/vector.hpp>
#include <algorithm>
#include <cstdio>
int main () {
boost::numeric::ublas::vector<double> v (3);
v(0) = 2;
v(1) = 4.5;
v(2) = 3.15;
double p[3];
std::copy(v.begin(), v.end(), p); // <--
printf("%g %g %g\n", p[0], p[1], p[2]);
return 0;
}
Depends on the types involved. For std::vector you just make sure that it's non-empty and then you can pass &v[0]. Most likely the same holds for the Boost types you're using.
Related
I understand how to go from a vector to a raw pointer but im skipping a beat on how to go backwards.
// our host vector
thrust::host_vector<dbl2> hVec;
// pretend we put data in it here
// get a device_vector
thrust::device_vector<dbl2> dVec = hVec;
// get the device ptr
thrust::device_ptr devPtr = &d_vec[0];
// now how do i get back to device_vector?
thrust::device_vector<dbl2> dVec2 = devPtr; // gives error
thrust::device_vector<dbl2> dVec2(devPtr); // gives error
Can someone explain/point me to an example?
http://code.google.com/p/thrust/source/browse/examples/cuda/wrap_pointer.cu
Thrust provides a good example for this question.
#include <thrust/device_ptr.h>
#include <thrust/fill.h>
#include <cuda.h>
int main(void)
{
size_t N = 10;
// obtain raw pointer to device memory
int * raw_ptr;
cudaMalloc((void **) &raw_ptr, N * sizeof(int));
// wrap raw pointer with a device_ptr
thrust::device_ptr<int> dev_ptr = thrust::device_pointer_cast(raw_ptr);
// use device_ptr in Thrust algorithms
thrust::fill(dev_ptr, dev_ptr + N, (int) 0);
// access device memory transparently through device_ptr
dev_ptr[0] = 1;
// free memory
cudaFree(raw_ptr);
return 0;
}
And getting the raw pointer from thrust containers is as answered already by yourself..
dbl2* ptrDVec = thrust::raw_pointer_cast(&d_vec[0]);
You initialize and populate thrust vectors just like standard containers, i.e. via iterators:
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
int main()
{
thrust::device_vector<double> v1(10); // create a vector of size 10
thrust::device_ptr<double> dp = v1.data(); // or &v1[0]
thrust::device_vector<double> v2(v1); // from copy
thrust::device_vector<double> v3(dp, dp + 10); // from iterator range
thrust::device_vector<double> v4(v1.begin(), v1.end()); // from iterator range
}
In your simple example there's no need to go the detour via pointers, as you can just copy the other container directly. In general, if you have a pointer to the beginning of an array, you can use the version for v3 if you supply the array size.
dbl2* ptrDVec = thrust::raw_pointer_cast(&d_vec[0]); is there a way to get back to a device_vector from this?
There is not. Although you should be able to reuse the initial vector variable.
I have two vectors. I want to make a new vector which contains the values of these two vectors. I found that a fast way can be use as
vector<int> original_vector
vector<int> copy_to_vector(original_vector)
However, it does not show how to copy two vectors (above only for one to other). Now my problem is
vector<int> original_vector1
vector<int> original_vector2
//Copy original_vector1 and original_vector2 to copy_to_vector
// Note that original_vector1 or original_vector2 maybe empty
vector<int> copy_to_vector
How can I do it in C++. I am using g++ in Ubuntu
My current solution is
std::vector<U32> copy_to_vector(original_vector1);
copy_to_vector.insert(copy_to_vector.end(), original_vector2.begin(), original_vector2.end());
vector<int> copy_to_vector(original_vector1)
copy_to_vector.reserve(original_vector1.size() + original_vector2.size());
copy_to_vector.insert( copy_to_vector.end(), original_vector2.begin(), original_vector2.end());
This solution works fine if one of the vectors or both of them are empty
live demo
It's often a good idea to encapsulate operations like this in a utility function.
RVO takes are of eliding the copy of the return value so this code is as efficient as inlining the operations, but more maintainable and easier to reason about:
#include <iostream>
#include <vector>
#include <algorithm>
// utility function to return a new vector which is the
// result of v1 with v2 appended. order is preserved
std::vector<int> combine(const std::vector<int>& v1,
const std::vector<int>& v2)
{
std::vector<int> result;
result.reserve(v1.size() + v2.size());
result = v1;
result.insert(result.end(), v2.begin(), v2.end());
return result;
}
int main()
{
using namespace std;
vector<int> x = { 1, 2, 3 };
vector<int> y = { 4, 5, 6 };
auto z = combine(x, y);
copy(begin(z), end(z), ostream_iterator<int>(cout, "\n"));
return 0;
}
Use std::back_inserter
#include <iterator> // back_inserter
#include <algorithm> // copy
vector<int> copy_to_vector;
copy_to_vector.reserve( original_vector1.size() + original_vector2.size() ) // reserve memory for both vectors at once
copy_to_vector = original_vector1;
std::copy(original_vector2.begin(),original_vector2.end(),std::back_inserter(copy_to_vector));
Is there any std container which would be fixed size like std::array, but the size would not be compile time, but runtime?
I want to pass a part of some data I have stored in std::array to std::acculumate and similar functions. I do not want to use std::vector (working on embedded platform), therefore I am looking for something in between.
Assume code like this, what I want is something to be used in place of array_part:
#include <array>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
int main()
{
std::array<float,100> someData;
// fill the data
int dataCount = 50;
std::array_part<float> partOfData(someData.data(),dataCount)); // <<<<< here
const auto s_x = std::accumulate(partOfData.begin(), partOfData.end(), 0.0);
}
If there is no such container, how can I wrap the raw data I have and present them to std::accumulate and other std algorithms?
std::accumulate takes iterators. You can pass it iterators that contain the range of interest:
auto start = partOfData.begin() + 42;
auto end = partOfData.begin() + 77;
const auto s_x = std::accumulate(start, end, 0.0);
Alternatively, you can roll out your own non-owning container-like object. See this question for an example.
It seems to me that I should be able to use std::begin() and std::end() to convert ArrayXd to std::vector<double>; however, when I tried it in the following code, my attempt failed. My understanding is that .data() method on any Eigen object returns a pointer to a continuous block of memory similar to c style array. Therefore, since I can use std::begin(), std::end() on a c style array, I expected that to work with .data() as well. However, Eigen classes are templated, and I think this is what causes me problems, but don't see a way to fix this. How should this be done?
#include <iostream>
#include <vector>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
ArrayXd e_array(5);
e_array << 3,4,5,6,7;
double c_array[] = {1,2,3,4,5};
//Fails
// std::vector<double> my_vec(std::begin(e_array.data()), std::end(e_array.data()));
// Works
// std::vector<double> my_vec(e_array.data(), e_array.data() + 5);
// Works
// std::vector<double> my_vec(std::begin(c_array), std::end(c_array));
// Works
// std::vector<double> my_vec(c_array, c_array + 5);
return 0;
}
My error message(First lines, the whole message is long):
error: no matching function for call to
‘begin(Eigen::PlainObjectBase >::Scalar*)’
std::vector my_vec(std::begin(e_array.data()),
std::end(e_array.data()))
std::begin(vec.data()) cannot work because data() returns a raw pointer which cannot convey the number of elements in the vector. This version is the best one of yours:
std::vector<double> my_vec(e_array.data(), e_array.data() + 5);
And slightly better:
std::vector<double> my_vec(e_array.data(), e_array.data() + e_array.size());
And you may also be able to do this with many containers, but not with Eigen's ArrayXd in particular, because it lacks begin() and end() (related: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=231).
std::vector<double> my_vec(foo.begin(), foo.end());
Could you guys Please help me in providing good notes or links ?
For Ex : I need to create a vector and dump these x,y values in Vector ..
Data { X , Y } = {1,1} , {1,2} , {1,3}, {2,1},{2,2},{2,3},{3,1},{3,2},{3,3}
A vector of point in OpenCV is just a standard C++ STL vector containing OpenCV Point objects :
std::vector<Point> data;
data.push_back(Point(1,1));
data.push_back(Point(1,2));
data.push_back(Point(1,3));
data.push_back(Point(2,1));
...
Alternatively, if you're using C++11 or later you can use a list initialization:
std::vector<Point> data = {Point(1,1), Point(1,2), Point(1,3), Point(2,1)};
Take a look at the C++ reference for STL Vector
So... you want to use a vector to store data... wherein each element is a pair of ints? Well, if you don't want to create your own type, use a tuple or pair:
#include <vector>
#include <utility>
// ...
std::vector<std::pair<int, int> v;
// ...
v.push_back(std::make_pair(1, 1));
// ...
auto p = c[offset];
int x = p.first;
int y = p.second;