I have a method that takes a std::vector as one of its parameters. Is there a way I can initialize a matrix by assigning the std::vector to the matrix? Here's what I tried to do below. Does anyone know how i can achieve assigning the vector (or even a pointer of doubles) to the matrix? Thanks in advance. Mike
void Foo(std::vector v)
{
matrix<double> m(m, n, v);
// work with matrix...
}
Here is yet another example of how this can be done:
#include <algorithm>
#include <vector>
#include <boost/numeric/ublas/storage.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
namespace ublas = boost::numeric::ublas;
template <typename T, typename F=ublas::row_major>
ublas::matrix<T, F> makeMatrix(std::size_t m, std::size_t n, const std::vector<T> & v)
{
if(m*n!=v.size()) {
; // Handle this case
}
ublas::unbounded_array<T> storage(m*n);
std::copy(v.begin(), v.end(), storage.begin());
return ublas::matrix<T>(m, n, storage);
}
int main () {;
std::vector<double> vec {1, 2, 3, 4, 5, 6};
ublas::matrix<double> mm = makeMatrix(3,2,vec);
std::cout << mm << std::endl;
}
According to the boost matrix documentation, there are 3 constructors for the matrix class: empty, copy, and one taking two size_types for the number of rows and columns. Since boost doesn't define it (probably because there are many ways to do it and not every class is gong to define a conversion into every other class) you are going to need to define the conversion.
Here's an approach that I would use, but since there are multiple ways to do this and the question doesn't specify how you want this done you may find a different approach more applicable to your situation.
void Foo(const std::vector<double> & v) {
size_t m = ... // you need to specify
size_t n = ... // you need to specify
if(v.size() < m * n) { // the vector size has to be bigger or equal than m * n
// handle this situation
}
matrix<double> mat(m, n);
for(size_t i=0; i<mat.size1(); i++) {
for(size_t j=0; j<mat.size2(); j++) {
mat(i,j) = v[i+j*mat.size1()];
}
}
}
A couple of notes about your provided code: std::vector needs a templated argument and you are declaring m as a matrix and an input argument to it's constructor.
A more convenient way is like this:
matrix<double> m(m*n);
std::copy(v.begin(), v.end(), m.data().begin());
Simple answer, but not very apparent from the Boost documentation.
You may just use std::vector<> as type of storage array template paramerter instead of default unbounded_array<> for your matrix. (It's mentioned in footnote 2 of documentation on matrix<> class.)
void Foo(const std::vector<double> &v, size_t n)
{
using namespace boost::numeric::ublas;
size_t m = v.size() / n;
matrix< double, row_major, std::vector<double> > M(m, n);
M.data() = v;
// work with matrix...
}
More variants of initialization can be found in your boost source:
boost/libs/numeric/ublas/doc/samples/assignment_examples.cpp, as pointed out here: assign multiple values to boost::numeric::ublas::vector in c++
Or here: uBLAS examples, example 3, which is mentioned by related question: ublas: Wrap ublas::vector as ublas::matrix_expression
Related
Suppose I have a Matrix class and I'd like to initialize my Matrix objects in two ways:
Matrix a = {1,2,3} // for a row vector
and
Matrix b = {{1,2,3},{4,5,6},{7,8,9}} // for a matrix
As a result, I implemented two copy constructors as below
class Matrix {
private:
size_t rows, cols;
double* mat;
public:
Matrix() {}
Matrix(initializer_list<double> row_vector) { ... }
Matrix(initializer_list< initializer_list<double> > matrix) { ... }
...
}
No matter how I change my interface, such as adding an explicit keyword or change the nested version to Matrix(initializer_list< vector<double> > matrix). It will always cause ambiguities between these two cases:
Matrix a = {1,2,3};n
Matrix b = {{1}, {2}, {3}};
I'm not quite familiar with the stuff like direct/copy initialization or implicit type conversion. Are there any solutions for this problem?
There is no solution which will unambiguously work in every case. However, you can create ways to disambiguate cases:
template<typename T>
auto il(std::initializer_list<T> the_il) -> std::initializer_list<T> { return the_il; }
Matrix b = {il({1}), {2}, {3}};
However, I would personally suggest that you be explicit about it. If a user wants a matrix containing one row, then it should look like a matrix containing one row, not like a vector:
Matrix a = {{1,2,3}};
So I would suggest ditching the first overload altogether.
Well, here's a very dirty trick:
#include <iostream>
#include <initializer_list>
struct Matrix
{
template<class = void> Matrix(std::initializer_list<double>) { std::cout << "vector\n"; }
Matrix(std::initializer_list<std::initializer_list<double>>) { std::cout << "matrix\n"; }
};
int main()
{
Matrix a = {1, 2, 3};
Matrix b = {{1}, {2}, {3}};
(void)a; (void)b;
}
The two overloads cannot be distinguished based on conversions, so we rely on a subsequent step in the overload resolution process: a non-template function is preferred over a template specialization.
Why not just create one constructor that takes a matrix, create a private function copy and inside copy you check for a row_vector.
private void Matrix::copy(const Matrix &matrix)
{
if (matrix.rows == 1)
{
//row vector stuff here
}
else if (matrix.cols == 1)
{
//col vector stuff here
}
else
{
//matrix stuff here
}
}
Is it possible to merge the two initialization lines into a single statement with the help of initializer lists or other C++ features? The vector values always increment with one, but the size n is not fixed.
#include <numeric>
#include <vector>
#include <iostream>
int main()
{
int n = 10;
// Can the two lines below be combined into a single statement?
std::vector<int> v(n);
std::iota(v.begin(), v.end(), 1);
for (int i : v)
std::cout << i << std::endl;
return 0;
}
You can use Boost.counting_iterator for this:
std::vector<int> v(boost::counting_iterator<int>(1),
boost::counting_iterator<int>(n + 1));
(Live) Now whether this is worth it and easier to read than what you already have is for you to decide.
Not really, no. If n is a runtime variable, the best you could probably do is to just throw this in a function somewhere:
std::vector<int> ints(int n) {
std::vector<int> v;
v.reserve(n);
for (int i = 0; i < n; ++i) {
v.push_back(n+1);
}
return v;
}
// now it's one line?
std::vector<int> v = ints(n);
If it's compile time, you can use std::index_sequence to provide an initializer list:
template <int... Is>
std::vector<int> ints(std::integer_sequence<int, Is...> ) {
return std::vector<int>{ (Is+1)... };
}
template <int N>
std::vector<int> ints() {
return ints(std::make_integer_sequence<int, N>{});
}
But either way, you need a helper function.
What I am trying to do is to shuffle an existing array (vector). There is a catch here, there are actually two arrays (vectors) that depend on each other.
To be more exact, I have a 2d vector which contains patterns , so each row denotes a single pattern, and then there is another 2d vector which contains the desired output of each pattern.
So it would look like something like this :
vector<vector<float>> P{ vector < float > {0, 0},
vector < float > {1, 0},
vector < float > {0, 1},
vector < float > {1, 1} };
vector<vector<float>> T{ vector < float > {0},
vector < float > {1},
vector < float > {1},
vector < float > {0} };
Now I need to shuffle the patterns collection, so their individual rows order differ each time we traverse P. again I mean, since P's size() here is 4, and thus we have 4 patterns, and we want to select one at a time till we access all of them.
When all of the patterns are selected one after the other, an epoch is completed, and we need to change the patterns order for the next epoch. We are going to do this for an arbitrary number of times, and each time, these patterns order need to get changed, (e.g. the first time (0,0) is first, followed by (0,1) and (1,0) and finally (1,1), in the second epoch we might be having (1,1) (1,0) (0,0) (0,1) as the patterns).
So when we shuffle the pattern collection, we need to have the targets collection shuffled exactly the same as well. What is fastest way of doing so? There are different ways that ran through my head, such as:
creating a map out of these two arrays, and map each pattern with the corresponding target, and then shuffle the the patterns collection. Whenever there is a need for a target it can easily be accessed by the map.
use tuples to create a new list and shuffle the newly created tuple and get going.
just use a random number between 0 to 3 and pick a number, (a pattern index) and use that, store the index in an array, which is used to prevent selecting the same index twice in one epoch.
What would you suggest in this scenario?
It seems that you want to shuffle indexes:
std::vector<std::size_t> indexes{0, 1, 2, 3}; // or initialize with std::iota
std::shuffle(indexes.begin(), indexes.end(), my_random_generator);
Your question is very hard to answer definitively as it lacks a lot of information. And even with all the information needed, a definitive answer would still be very hard to give without measuring different options.
The first and most important question is: what is it that you're trying to make fast - generating a new epoch or accessing your data? Answering this question would require knowing the size of the actual data you have, the ways and number of times you access your data in the other code, how is your data modified/generated during runtime, etc.
Here's some general advice though. If you know the size of inner vectors of your T and P - use std::array instead of std::vector. This way your inner arrays will be laid out in a single chunk of memory improving cache behaviour. For the same reason, if you can, combine the patterns and outputs into a std::tuple or a std::pair or a struct for that matter and put them all in one array.
Let's assume you can put them into a single vector. Then the regarding the shuffling itself, you can either take the approach with shuffling indices into a static vector or shuffling the vector itself. Shuffling a vector of indices will likely be faster, but you will pay an additional indirection every time you access your pattern-outcome pairs which might make your overall performance way worse than shuffling the vector itself. Your access patterns are of the utmost importance when making the decision - measure your options!
If for some reason you absolutely cannot put everything in one vector and additional array of indices is too expensive, consider using this code (note, you need boost and c++14 compiler for this to work, live demo here):
#include <iostream>
#include <string>
#include <random>
#include <vector>
#include <tuple>
#include <utility>
#include <algorithm>
#include <boost/iterator/iterator_facade.hpp>
template <typename... IteratorTypes>
using value_tuple = std::tuple<typename IteratorTypes::value_type...>;
template <typename... IteratorTypes>
class reference_tuple : public std::tuple<typename IteratorTypes::value_type&...> {
using std::tuple<typename IteratorTypes::value_type&...>::tuple;
};
template<typename... IteratorTypes, size_t... Index>
void swap_impl(reference_tuple<IteratorTypes...> left, reference_tuple<IteratorTypes...> right, std::index_sequence<Index...>)
{
using std::swap;
int dummy[] = {(swap(std::get<Index>(left), std::get<Index>(right)), 0)...};
(void)dummy;
}
template <typename... IteratorTypes>
void swap(reference_tuple<IteratorTypes...> left, reference_tuple<IteratorTypes...> right)
{
swap_impl(left, right, std::index_sequence_for<IteratorTypes...>{});
}
template <typename... IteratorTypes>
class zip_iter
: public boost::iterator_facade<
zip_iter<IteratorTypes...> // Derived
, value_tuple<IteratorTypes...> // Value
, boost::random_access_traversal_tag
, reference_tuple<IteratorTypes...> // Reference
>
{
public:
zip_iter() = default;
explicit zip_iter(IteratorTypes... iters)
: iterators(iters...)
{
}
private:
friend class boost::iterator_core_access;
void increment() { increment_impl(std::index_sequence_for<IteratorTypes...>()); }
template<size_t... Index>
void increment_impl(std::index_sequence<Index...>)
{
int dummy[] = {(++std::get<Index>(iterators), 0)...};
(void)dummy;
}
void decrement() { decrement_impl(std::index_sequence_for<IteratorTypes...>()); }
template<size_t... Index>
void decrement_impl(std::index_sequence<Index...>)
{
int dummy[] = {(--std::get<Index>(iterators), 0)...};
(void)dummy;
}
template<typename diff_t>
void advance(diff_t n) { advance_impl(n, std::index_sequence_for<IteratorTypes...>()); }
template<typename diff_t, size_t... Index>
void advance_impl(diff_t n, std::index_sequence<Index...>)
{
int dummy[] = {(std::advance(std::get<Index>(iterators), n), 0)...};
(void)dummy;
}
bool equal(zip_iter const& other) const
{
return std::get<0>(iterators) == std::get<0>(other.iterators);
}
auto dereference() const {
return dereferenceImpl(std::index_sequence_for<IteratorTypes...>{});
}
template<std::size_t... Index>
auto dereferenceImpl(std::index_sequence<Index...>) const
{
return reference_tuple<IteratorTypes...>(*std::get<Index>(iterators)...);
}
auto distance_to(zip_iter const& r) const
{
return std::distance(std::get<0>(iterators), std::get<0>(r.iterators));
}
std::tuple<IteratorTypes...> iterators;
};
template<typename... Iterators>
auto make_zip_iter(Iterators... iters)
{
return zip_iter<Iterators...>(iters...);
}
int main()
{
std::mt19937 rng(std::random_device{}());
std::vector<int> ints(10);
std::iota(ints.begin(), ints.end(), 0);
std::cout << "Before: ";
for (auto i : ints) {
std::cout << i << " ";
}
std::cout << "\n";
std::vector<int> ints2{ints};
std::shuffle(make_zip_iter(ints.begin(), ints2.begin()), make_zip_iter(ints.end(), ints2.end()), rng);
std::cout << "Are equal: " << (ints == ints2) << "\n";
std::cout << "After: ";
for (auto i : ints) {
std::cout << i << " ";
}
}
Let's say I have the following object:
struct Foo
{
int size() { return 2; }
};
What's the best way (most maintainable, readable, etc.) to get the total size of all objects in a vector<Foo>? I'll post my solution but I'm interested in better ideas.
Update:
So far we have:
std::accumulate and a functor
std::accumulate and a lambda expression
plain ol' for-loop
Are there any other workable solutions? Can you make something maintainable using boost::bind or std::bind1st/2nd?
In addition to your own suggestion, if your compiler supports C++0x lambda expressions, you can use this shorter version:
std::vector<Foo> vf;
// do something to populate vf
int totalSize = std::accumulate(vf.begin(),
vf.end(),
0,
[](int sum, const Foo& elem){ return sum + elem.size();});
Use std::accumulate and a functor.
#include <functional>
#include <numeric>
struct SumSizes : public std::binary_function<int, Foo, int>
{
int operator()(int total, const Foo& elem) const
{
return total + elem.size();
}
};
std::vector<Foo> vf;
// do something to populate vf
int totalSize = std::accumulate(vf.begin(),
vf.end(),
0,
SumSizes());
I find Boost iterators elegants, although they can be a bit verbose (range-based algorithms would make this better). In this case transform iterators can do the job:
#include <boost/iterator/transform_iterator.hpp>
//...
int totalSize = std::accumulate(
boost::make_transform_iterator(vf.begin(), std::mem_fn(&Foo::size)),
boost::make_transform_iterator(vf.end(), std::mem_fn(&Foo::size)),0);
Edit: replaced "boost::bind(&Foo::size,_1)" by "std::mem_fn(&Foo::size)"
Edit: I just found that the Boost.Range library has been updated to introduce range algorithms! Here is a new version of the same solution:
#include <boost/range/distance.hpp> // numeric.hpp needs it (a bug?)
#include <boost/range/numeric.hpp> // accumulate
#include <boost/range/adaptor/transformed.hpp> // transformed
//...
int totalSize = boost::accumulate(
vf | boost::adaptors::transformed(std::mem_fn(Foo::size)), 0);
Note: the performances are approximately the same (see my comment): internally, transformed uses transorm_iterator.
using C++11 (and beyond) range-based for loop
std::vector<Foo> vFoo;
// populate vFoo with some values...
int totalSize = 0;
for (const auto& element: vFoo) {
totalSize += element.size();
}
Here is the down-to-earth solution:
typedef std::vector<Foo> FooVector;
FooVector vf;
int totalSize = 0;
for (FooVector::const_iterator it = vf.begin(); it != vf.end(); ++it) {
totalSize += it->size();
}
I am writing a Matlab extension using the C++ ublas library, and I would like to be able to initialize my ublas vectors from the C arrays passed by the Matlab interpeter.
How can I initialize the ublas vector from a C array without (for the sake of efficiency) explicitly copying the data. I am looking for something along the following lines of code:
using namespace boost::numeric::ublas;
int pv[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
vector<int> v (pv);
In general, is it possible to initialize a C++ std::vector from an array? Something like this:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int pv[4] = { 4, 4, 4, 4};
vector<int> v (pv, pv+4);
pv[0] = 0;
cout << "v[0]=" << v[0] << " " << "pv[0]=" << pv[0] << endl;
return 0;
}
but where the initialization would not copy the data. In this case the output is
v[0]=4 pv[0]=0
but I want the output to be the same, where updating the C array changes the data pointed to by the C++ vector
v[0]=0 pv[0]=0
I'm not sure how your question relates to MATLAB/MEX, but a side note, you might want to know that MATLAB implements a copy-on-write strategy.
This means that when you copy an array for example, only some headers are actually copied, while the data itself is shared between the two arrays. And once one of them is modified, a copy of the data is actually made.
The following is a simluation of what might be happening under the hood (borrowed from this old post):
-----------------------------------------
>> a = [35.7 100.2 1.2e7];
mxArray a
pdata -----> 35.7 100.2 1.2e7
crosslink=0
-----------------------------------------
>> b = a;
mxArray a
pdata -----> 35.7 100.2 1.2e7
crosslink / \
| / \ |
| | |
| | |
\ / | |
crosslink |
mxArray b |
pdata --------
-----------------------------------------
>> a(1) = 1;
mxArray a
pdata -----> (1) 100.2 1.2e7
crosslink=0
crosslink=0
mxArray b
pdata ------> 35.7 100.2 1.2e7 ...
I know this doesn't really answer your question, I just thought you might find the concept helpful.
Both std::vector and ublas::vector are containers. The whole point of containers is to manage the storage and lifetimes of their contained objects. This is why when you initialize them they must copy values into storage that they own.
C arrays are areas of memory fixed in size and location so by their nature you can only get their values into a container by copying.
You can use C arrays as the input to many algorithm functions so perhaps you can do that to avoid the initial copy?
You can initialize a std::vector from a C array easily:
vector<int> v(pv, pv+10);
There are two undocumented classes in uBLAS storage.hpp. You can change the default storage class (unbounded_array) in ublas::vector with one of these.
The first class, array_adaptor, makes a copy of your data when ublas::vector calls to copy constructor, not very useful class at all. I would rather simply the appropriate constructor to do this in unbounded_array or bounded_array classes.
The second, shallow_array_adaptor, only hold a reference of your data, so you can use vector to directly modify your C array. Unfortunately, it has some bugs, when you assign an expression it losses the original data pointer. But you can create a derived class that fix this problem.
Here the patch and an example:
// BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR must be defined before include vector.hpp
#define BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
#include <boost/numeric/ublas/vector.hpp>
#include <algorithm>
#include <iostream>
// Derived class that fix base class bug. Same name, different namespace.
template<typename T>
class shallow_array_adaptor
: public boost::numeric::ublas::shallow_array_adaptor<T>
{
public:
typedef boost::numeric::ublas::shallow_array_adaptor<T> base_type;
typedef typename base_type::size_type size_type;
typedef typename base_type::pointer pointer;
shallow_array_adaptor(size_type n) : base_type(n) {}
shallow_array_adaptor(size_type n, pointer data) : base_type(n,data) {}
shallow_array_adaptor(const shallow_array_adaptor& c) : base_type(c) {}
// This function must swap the values of the items, not the data pointers.
void swap(shallow_array_adaptor& a) {
if (base_type::begin() != a.begin())
std::swap_ranges(base_type::begin(), base_type::end(), a.begin());
}
};
void test() {
using namespace boost::numeric;
typedef ublas::vector<double,shallow_array_adaptor<double> > vector_adaptor;
struct point {
double x;
double y;
double z;
};
point p = { 1, 2, 3 };
vector_adaptor v(shallow_array_adaptor<double>(3, &p.x));
std::cout << p.x << ' ' << p.y << ' ' << p.z << std::endl;
v += v*2.0;
std::cout << p.x << ' ' << p.y << ' ' << p.z << std::endl;
}
Output:
1 2 3
3 6 9
The usual suggestion to use shallow array adaptor seems kind of sarcastic to me - to be able to simply access an array through a pointer you're supposed to put it into a shared_array with all the reference counting shebang (that comes to nothing, since you don't own the array) and what's more with a nightmare of data-aliasing.
Actually, uBLAS has a fully-fledged implementation of storage (array_adaptor) which allows to use vectors with external c arrays. The only catch is vector constructor which makes a copy. Why this nice feature is not used in the library is quite beyond me, but anyway, we can use a little extension (it's actually 2 lines of code surrounded with usual c++ bloat)
template<class T>
class extarray_vector :
public vector<T, array_adaptor<T> >
{
typedef vector<T, array_adaptor<T> > vector_type;
public:
BOOST_UBLAS_INLINE
extarray_vector(size_type size, pointer p)
{ data().resize(size, p); }
template <size_type N>
BOOST_UBLAS_INLINE
extarray_vector(T (&a)[N])
{ data().resize(N, a); }
template<class V>
BOOST_UBLAS_INLINE
extarray_vector& operator = (const vector<T, V>& v)
{
vector_type::operator = (v);
return *this;
}
template<class VC>
BOOST_UBLAS_INLINE
extarray_vector& operator = (const vector_container<VC>& v)
{
vector_type::operator = (v);
return *this;
}
template<class VE>
BOOST_UBLAS_INLINE
extarray_vector& operator = (const vector_expression<VE>& ae)
{
vector_type::operator = (ae);
return *this;
}
};
you can use it like this:
int i[] = {1, 4, 9, 16, 25, 36, 49};
extarray_vector<int> iv(i);
BOOST_ASSERT_MSG(i == &iv[0], "Vector should attach to external array\n");
iv[3] = 100;
BOOST_ASSERT(i[3] == 100);
iv.resize(iv.size() + 1, true);
BOOST_ASSERT_MSG(i != &iv[0], "And detach from the array on resize\n");
iv[3] = 200;
BOOST_ASSERT(i[3] == 100);
iv.data().resize(7, i, 0);
BOOST_ASSERT_MSG(i == &iv[0], "And attach back to the array\n");
BOOST_ASSERT(i[3] == 200);
You can dynamically attach and detach vector to external storage via array_adaptor's resize method (keeping or discarding data). On resize it detaches from storage automatically and becomes regular vector. Assignment from containers goes directly into storage, but assignment from expression is done via a temporary and vector is detached from storage, use noalias() to prevent that. There's a small overhead in constructor since data_ is private member and we have to default initialize it with new T[0], then reassign to external array. You may change it to protected and assign to storage directly in the constructor.
Here are a couple of functions for syntactically convenient assignment (admittedly not initialization):
vector<int> v;
setVector(v, 3,
1, 2, 3);
matrix<int> m;
setMatrix(m, 3, 4,
1, 2, 3, 4,
11, 22, 33, 44,
111, 222, 333, 444);
The functions:
/**
* Resize a ublas vector and set its elements
*/
template <class T> void setVector(vector<T> &v, int n, ...)
{
va_list ap;
va_start(ap, n);
v.resize(n);
for (int i = 0; i < n; i++) {
v[i] = va_arg(ap, T);
}
va_end(ap);
}
/**
* Resize a ublas matrix and set its elements
*/
template <class T> void setMatrix(matrix<T> &m, int rows, int cols ...)
{
va_list ap;
va_start(ap, cols);
m.resize(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m(i, j) = va_arg(ap, T);
}
}
va_end(ap);
}