I'm a very noob at Boost::uBLAS.
I have a function which take a ublas::matrix_expression<double> as input:
namespace ublas = boost::numeric::ublas;
void Func(const ublas::matrix_expression<double>& in,
ublas::matrix_expression<double>& out);
A caller is holding a row vector as ublas::vector<double>, and I want it to be passed to Func.
Until now I have not found any way to do this.
What is the best way, preferably without any temporary allocation?
Thanks.
Well, there is an option to create a read-only adapter of a contiguous area of memory into a read-only matrix. Have a look at example 3. It is pretty straightforward to use:
#include "storage_adaptors.hpp"
#include <boost/numeric/ublas/assignment.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
ublas::vector<double> v(6);
v <<= 1, 2, 3, 4, 5, 6;
ublas::matrix<double> m = ublas::make_matrix_from_pointer(2, 3, &v(0));
std::cout << m << std::endl;
Possibly you could tweak that further to fit your needs/example.
You can avoid allocating if you're ready to sacrifice some multiplication, use
outer_prod(scalar_vector<double>(1, 1), vec)
to transform vector into matrix expression. Also, your function probably should be
template<class C>
void Func(const matrix_expression<C>& in...
matrix_expression itself doesn't model matrix expression concept, it's just the base class.
Related
As the title says, I am trying to convert an Eigen::VectorXd to an std::vector. The vector is obtained by diagonalizing a matrix and then taking the first eigenvector of the process.
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
using namespace std;
int main()
{
vector<double> vec;
MatrixXd ones = MatrixXd::Ones(3,3);
VectorXd firstEvector;
SelfAdjointEigenSolver<MatrixXd> es(ones);
firstEvector = es.eigenvectors().col(1);
cout << "The first eigenvector of the 3x3 matrix of ones is:" << endl << firstEvector << endl;
vec(&firstEvector[0], firstEvector.data() + firstEvector.cols()*firstEvector.rows());
return 0;
}
I thought this was the way to do it, however, it doesn't work. I get the following error.
C:\CBProjects\eigenVectors\main.cpp|20|error: no match for call to '(std::vector<double>) (Eigen::DenseCoeffsBase<Eigen::Matrix<double, -1, 1>, 1>::Scalar*, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1> >::Scalar*)'|
I can't see what I am doing wrong. Any help would be greatly appreciated.
You are using a constructor syntax for the std::vector vec although the vector was already declared. That doesn't work.
There are two efficient possibilities to copy the content of an Eigen::VectorXd into a std::vector<double>. You can either construct a new std::vector vec2, like this:
vector<double> vec2(firstEvector.data(), firstEvector.data() + firstEvector.size());
or use the previously declared vector vec and transfer the data from the Eigen::VectorXd by using Eigen::Map. But in that case the std::vector first needs to be resized:
vec.resize(firstEvector.size());
Map<VectorXd>(vec.data(), vec.size()) = firstEvector;
I'm doing a problem where I need to create a stack of n-dimensional coordinates. I have implemented the coordinates as type std::array<std::size_t, n_dims>, where n_dims is a compile-time constant.
Q: What is the best way to push a coordinate to the stack?
Possibilities:
Creating the array as a variable, then pushing it to the stack. This seems wasteful. A bit less bad if I use move semantics:
std::array<std::size_t, 2> my_array = {1, 3};
my_stack.push(std::move(my_array));
// or my_stack.emplace(...)
but still unnecessarily complicated.
Using std::stack::emplace. This doesn't seem to work. I think it's because std::array is an aggregate type. (I'd like to understand this point better -- I believe one important consequence is that aggregate types have only default and copy constructors.)
#include <array>
#include <stack>
int main()
{
std::stack<std::array<int, 2>> st;
st.emplace(1,3); // doesn't work
st.emplace({1,3}); // doesn't work
st.emplace({{1,3}}); // doesn't work
}
What should I do?
You can use std::experimental::make_array
#include <experimental/array>
#include <array>
#include <stack>
int main()
{
std::stack<std::array<int, 2>> st;
st.emplace(std::experimental::make_array(1,3));
}
I have a function that operates on a Vector reference, e.g.
void auto_bias(const Eigen::VectorXf& v, Eigen:Ref<Eigen::VectorXf>> out)
{
out = ...
}
and at some point I need to have this function operate on a Matrix row. Now, because the default memory layout is column-major, I can't just Map<> the data the row points to into a vector. So, how do I go about passing the row into the above function so that I can operate on it?
The not-so-pretty solution is to have a temp vector, e.g.
VectorXf tmpVec = matrix.row(5);
auto_bias(otherVector, tmpVec);
matrix.row(5) = tmpVec;
but is there a way of doing it directly?
You can modify your function to take a reference to the row type (which is a vector expression) instead of a vector. This is really only manageable with a template to infer that type for you:
#include <iostream>
#include <Eigen/Core>
template<typename V>
void set_row(V&& v) {
v = Eigen::Vector3f(4.0f, 5.0f, 6.0f);
}
int main() {
Eigen::Matrix3f m = Eigen::Matrix3f::Identity();
set_row(m.row(1));
std::cout << m;
return 0;
}
You can allow Ref<> to have a non default inner-stride (also called increment), as follows:
Ref<VectorXf, 0, InnerStride<>>
See the example function foo3 of the Ref's documentation.
The downside is a possible loss of performance even when you are passing a true VectorXf.
I have an optimisation algorithm which finds the best partition of a graph.
There are many measures for the quality of a partition (the variable being optimised), so I thought it would be a good idea to use function pointers to these quality functions, and pass that into my optimisation algorithm function.
This works fine, but the problem is different quality functions take some different arguments.
For example one quality function is find_linearised_stability and it requires a markov_time parameter:
float find_linearised_stability(cliques::Graph<T> &my_graph, cliques::Partition &my_partition,
std::vector<float> &markov_times, std::vector<float> &stabilities)
and is used in the optimisation function :
cliques::find_optimal_partition_louvain(my_new_graph, markov_times, &cliques::find_linearised_stability);
however another quality function find_modularityrequires no markov_time parameter. Of course I could just include it as an argument and not use it in the function but that seems like bad practice, and would get unwieldy once I start adding a lot of different quality functions.
What is a better design for this kind of situation?
Use function objects. One of those function objects can have a markov_time member that is passed in to the constructor:
struct find_linearised_stability {
std::vector<float> & markov_times_;
find_linearised_stability(std::vector<float> & markov_times)
:markov_times_(markov_times)
{}
float operator () (cliques::Graph<T> &my_graph, cliques::Partition &my_partition,
std::vector<float> &stabilities)
{
// use markov_times_ in here, we didn't need to pass it since it's a member
}
};
(you may need to make adjustments to constness/referenceness to suit your needs)
Then you can call your function like this:
cliques::find_optimal_partition_louvain(my_new_graph, cliques::find_linearised_stability(markov_times));
"what type for the function object do I use when declaring the ... function?"
Make it a function template that takes the function object type as a template parameter, thusly:
template<typename PR>
whatever find_optimal_partition_louvain(my_new_graph, PR & pr)
{
...
pr(my_new_graph, partition, stabilities);
...
}
Your only option is boost::bind or something like it stored in a boost::function or something like it.
If profiling shows that to be too slow then you'll be stuck with the "poor practice" version because any alternative is going to run afoul of UB and/or end up being just as 'slow' as the more reasonable alternative.
parameter is not known before: add argument to every function (reference/pointer) that contains all info, every function uses whatever it needs
parameter is known before: use boost::bind, e.g.:
sample source code:
#include <iostream>
#include <cstddef>
#include <algorithm>
#include <boost/bind.hpp>
using namespace std;
void output(int a, int b)
{
cout << a << ", " << b << '\n';
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
for_each(arr, arr + 5, bind(output, 5, _1));
return 0;
}
Outputs:
5, 1
5, 2
5, 3
5, 4
5, 5
As the function accepted by for_each take only one parameter (the element of the vector), I have to define a static int sum = 0 somewhere so that It can be accessed
after calling the for_each . I think this is awkward. Any better way to do this (still use for_each) ?
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
static int sum = 0;
void add_f(int i )
{
sum += i * i;
}
void test_using_for_each()
{
int arr[] = {1,2,3,4};
vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
for_each( a.begin(),a.end(), add_f);
cout << "sum of the square of the element is " << sum << endl;
}
In Ruby, We can do it this way:
sum = 0
[1,2,3,4].each { |i| sum += i*i} #local variable can be used in the callback function
puts sum #=> 30
Would you please show more examples how for_each is typically used in practical programming (not just print out each element)? Is it possible use for_each simulate 'programming pattern' like map and inject in Ruby (or map /fold in Haskell).
#map in ruby
>> [1,2,3,4].map {|i| i*i}
=> [1, 4, 9, 16]
#inject in ruby
[1, 4, 9, 16].inject(0) {|aac ,i| aac +=i} #=> 30
EDIT: Thank you all. I have learned so much from your replies. We have so many ways to do the same single thing in C++ , which makes it a little bit difficult to learn. But it's interesting :)
No, don't use std::accumulate() use std::inner_product(). No functor required.
#include <vector>
#include <numeric>
void main()
{
std::vector <int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
int x = std::inner_product( v1.begin(), v1.end(), v1.begin(), 0 );
}
Use std::accumulate
#include <vector>
#include <numeric>
// functor for getting sum of previous result and square of current element
template<typename T>
struct square
{
T operator()(const T& Left, const T& Right) const
{
return (Left + Right*Right);
}
};
void main()
{
std::vector <int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
int x = std::accumulate( v1.begin(), v1.end(), 0, square<int>() );
// 0 stands here for initial value to which each element is in turn combined with
// for our case must be 0.
}
You could emulate std::accumulate as in nice GMan's answer, but I believe that using std::accumulate will make your code more readable, because it was designed for such purposes. You could find more standard algorithms here.
for_each returns (a copy of) the functor that it was using. So, something like this:
#include <algorithm>
#include <vector>
#include <iostream>
template <typename T>
class square_accumulate
{
public:
square_accumulate(void) :
_sum(0)
{
}
const T& result(void) const
{
return _sum;
}
void operator()(const T& val)
{
_sum += val * val;
}
private:
T _sum;
};
int main(void)
{
int arr[] = {1,2,3,4};
std::vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
int sum = std::for_each(a.begin(), a.end(), square_accumulate<int>()).result();
std::cout << "sum of the square of the element is " << sum << std::endl;
}
As demonstrated by other answers, though, std::accumulate is the best way to go.
Don't use for_each() for this, use accumulate() from the <numeric> header:
#include <numeric>
#include <iostream>
using namespace std;
struct accum_sum_of_squares {
// x contains the sum-of-squares so far, y is the next value.
int operator()(int x, int y) const {
return x + y * y;
}
};
int main(int argc, char **argv) {
int a[] = { 4, 5, 6, 7 };
int ssq = accumulate(a, a + sizeof a / sizeof a[0], 0, accum_sum_of_squares());
cout << ssq << endl;
return 0;
}
The default behaviour of accumulate() is to sum elements, but you can provide your own function or functor as we do here, and the operation it performs need not be associative -- the 2nd argument is always the next element to be operated on. This operation is sometimes called reduce in other languages.
You could use a plain function instead of the accum_sum_of_squares functor, or for even more genericity, you could make accum_sum_of_squares a class template that accepts any numeric type.
As a general solution to such issue with STL: instead of passing a function, you can pass a functor -- for example, an instance of any class implementing operator(). This is much better than relying on global variables, since said instance can keep and update its own state! You could think of it as a kind of "compile time duck typing": generic programming does not constrain you to pass a "function" in that place, anything that "behaves like a function" (i.e., has a proper operator()) will do as well!-)
std::for_each is for doing something with each element. If you want get a result from a calculation on all the elements, there's std::accumulate. If you are wanting Haskell's map behaviour, use std::transform.
You can abuse either of these three to do the same thing as any of the others, since ultimately they are just iterating over an iterator (except for transform's form that takes two iterators as input.) The point is that for_each is not a replacement for map/fold - that should be done by transform/accumulate - although C++ doesn't natively have something that expresses the map/fold concept as well as Haskell does - but both gcc and VC++ support OpenMP which has a much better analogue in #pragma omp parallel for.
Inject in Ruby is a much closer match to calling for_each with a full-fledged functor, like GMan explained above. Lambda functions with variable capture in C++0X will make the behaviour between the two languages even more similar:
int main(void)
{
int arr[] = {1,2,3,4};
std::vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
int sum = 0;
std::for_each(a.begin(), a.end(), [&](int i) { sum += i*i;} );
std::cout << "sum of the square of the element is " << sum << std::endl;
}