Is there a single-expression way to assign a scalar to all elements of of a boost matrix or vector? I'm trying to find a more compact way of representing:
boost::numeric::ublas::c_vector<float, N> v;
for (size_t i=0; i<N; i++) {
v[i] = myScalar;
}
The following do not work:
boost::numeric::ublas::c_vector<float, N>
v(myScalar, myScalar, ...and so on..., myScalar);
boost::numeric::ublas::c_vector<float, N> v;
v = myScalar;
-
Been a while since I used C++. Does the following work?
for (size_t i = 0; i < N; v[i++] = myScalar) ;
Mr Fooz : That'll work, though it is a full statement as opposed to an expression.Mikko Rantanen : True, but it is more compact way which is what you wanted to find based on the post.Mr Fooz : Yes, hence the +1.j_random_hacker : -1 sorry. You must use "v[i++]" -- "v[++i]" will skip initialisation of v[0] and overwrite the memory past the end of the vector.Mikko Rantanen : Ack. Sorry! I did acknowledge that I had to use the correct unary operator but for some reason I kept thinking ++i is the one that increments i after evaluating. Mostly since everyone prefer i++ and the "i += 1" behaviour seems more logical. Fixed now in any case.. And I guess I should thank you as well, I like 600 rep more than 601! -
Because the vector models a standard random access container you should be able to use the standard STL algorithms. Something like:
c_vector<float,N> vec; std::fill_n(vec.begin(),N,0.0f);
or
std::fill(vec.begin(),vec.end(),0.0f);
It probably also is compatible with Boost.Assign but you'd have to check.
Mr Fooz : The STL algorithms do seem to work. Thanks. Boost.Assign doesn't seem to work for me, but I think it's because I'm using a c_vector (const-sized vector) instead of a vector (dynamically sized vector), so push_back doesn't work. -
I have started using
boost::assign
for cases that I want to statically assign specific values (examples lifted from link above).#include <boost/assign/std/vector.hpp> using namespace boost::assign; // bring 'operator+()' into scope { vector<int> values; values += 1,2,3,4,5,6,7,8,9; }
You can also use
boost::assign
for maps.#include <boost/assign/list_inserter.hpp> #include <string> using boost::assign; std::map<std::string, int> months; insert( months ) ( "january", 31 )( "february", 28 ) ( "march", 31 )( "april", 30 ) ( "may", 31 )( "june", 30 ) ( "july", 31 )( "august", 31 ) ( "september", 30 )( "october", 31 ) ( "november", 30 )( "december", 31 );
You can allow do direct assignment with
list_of()
andmap_list_of()
#include <boost/assign/list_of.hpp> // for 'list_of()' #include <list> #include <stack> #include <string> #include <map> using namespace std; using namespace boost::assign; // bring 'list_of()' into scope { const list<int> primes = list_of(2)(3)(5)(7)(11); const stack<string> names = list_of( "Mr. Foo" )( "Mr. Bar") ( "Mrs. FooBar" ).to_adapter(); map<int,int> next = map_list_of(1,2)(2,3)(3,4)(4,5)(5,6); // or we can use 'list_of()' by specifying what type // the list consists of next = list_of< pair<int,int> >(6,7)(7,8)(8,9); }
There are also functions for
repeat()
,repeat_fun()
, andrange()
which allows you to add repeating values or ranges of values.Daniel Newby : The first example seems to be for std::vector (for which it works), not boost::numeric::ublas::vector (for which it does not work). -
Have you tried this?
ublas::c_vector v = ublas::scalar_vector(N, myScalar);
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.