I've just started using Eigen and have read from their documentation that the best performance comes from their lazy evaluation of matrix expressions. Hence, expressions like this are very efficient once evaluated:
Eigen::Matrix<float, 3, 1> a;
a << 0, 1, 2;
Eigen::Matrix<float, 3, 1> b;
b << 3, 4, 5;
Eigen::Matrix<float, 3, 1> c;
c << (a + b).sum(),
(a - b).sum(),
a.sum();
std::cout << c << std::endl;
I ran into a problem when constructing matrices whose column count depends on a template parameter. For example:
template <std::size_t w>
auto buildGradient() {
Eigen::Matrix<float, 3, w> matrix;
matrix << /* ? */;
return matrix;
}
My first inclination was to use a recursive c++ template do do this.
template <std::size_t w, typename Functor>
auto buildGradientExpr(Functor functor) {
if constexpr (w == 0) {
return;
} else if constexpr (w == 1) {
return functor();
} else {
return functor(), buildGradientExpr<w - 1, Functor>(functor);
}
}
But using this leads to runtime errors issued by Eigen, since the expression only has one initializer.
template <std::size_t w>
auto buildGradient() {
Eigen::Matrix<float, 3, w> gradient;
/* Emits an error about too few coefficients being passed to the initializer. */
gradient << buildGradientExpr<w>([]() { /* Return 3x1 matrix */ });
return gradient;
}
Here's a complete runnable example.
#include <Eigen/Dense>
#include <iostream>
#include <cstddef>
namespace {
template <std::size_t w, typename Functor>
auto buildGradientExpr(Functor functor) {
if constexpr (w == 0) {
return;
} else if constexpr (w == 1) {
return functor(w);
} else {
return functor(w), buildGradientExpr<w - 1, Functor>(functor);
}
}
template <std::size_t w, typename Functor>
auto buildGradient(Functor functor) {
Eigen::Matrix<float, 3, w> gradient;
gradient << buildGradientExpr<w>(functor);
return gradient;
}
} // namespace
int main() {
constexpr std::size_t gradient_width = 10;
auto gradient_functor = [](std::size_t w) {
return Eigen::Matrix<float, 3, 1>::Constant(float(w) / gradient_width);
};
auto gradient = buildGradient<gradient_width>(gradient_functor);
std::cout << gradient << std::endl;
return 0;
}
Is there a way of constructing matrices with sizes that depend on template parameters, without resorting to a for loop? Nothing against for loops, that's what I'm using in the mean time. I'd just like to know if there's a way to initialize a matrix expression using template loops.
Edit:* I updated the example, because the gradient functor was suppose to be returning a vector and not a scalar. The sample problem occurs, though.
If I understand correctly your issue here, and you can use c++11, a possible solution could be the following:
(a) extend the Eigen::Matrix class as explained here to include the constructor from std::initializer_list<T>:
// File "Eigen_plugin.h"
template<class T>
Matrix(std::initializer_list<T> elems) : Base()
{
Base::_check_template_params();
int idx = 0;
for(auto el : elems)
coeffRef(idx++) = el;
}
(b) define your buildGradient function using variadic templates:
// File main.cpp
#include <iostream>
#include <eigen3/Eigen/Dense>
template<class... Args>
Eigen::Matrix<double, 3, sizeof...(Args)/3> buildGradient(Args&&... args)
{
static_assert(sizeof...(Args) % 3 == 0, "Wrong number of elements");
return Eigen::Matrix<double, 3, sizeof...(Args)/3>{ args... };
}
int main()
{
std::cout << buildGradient(1.0,2.0,3.0) << std::endl;
std::cout << buildGradient(1.0,2.0,3.0,4.0,5.0,6.0) << std::endl;
}
Note
As explained in the first link, to make this compile you need to define the preprocessor variable EIGEN_MATRIX_PLUGIN to point at the absolute path of your plugin file:
g++ -std=c++11 main.cpp -D EIGEN_MATRIX_PLUGIN=\"path-to-Eigen_plugin.h\"
Related
I'm practicing Algorithms textbook and modern C++ coding.
I wrote a brief test that verifies sorting functions as the following:
(I know using namespace std; is discouraged in production, so please don't advice on that)
namespace frozenca {
using namespace std;
template <ranges::input_range R>
void print(R&& r, ostream& os = cout) {
for (auto elem : r) {
os << elem << ' ';
}
os << '\n';
}
mt19937 gen(random_device{}());
template <typename F, ranges::forward_range R = vector<int>> requires regular_invocable<F, R>
void verify_sorting(F&& f, int num_trials = 1'000, int max_length = 1'000) {
uniform_int_distribution<> len_dist(0, max_length);
for (int i = 0; i < num_trials; ++i) {
R v;
int n = len_dist(gen);
generate_n(back_inserter(v), n, ref(gen));
f(v);
if (!ranges::is_sorted(v)) {
throw runtime_error("Sorting verification failed");
}
}
std::cout << "Sorting verification success!\n";
}
} // namespace frozenca
and I wrote an insertion sort code like this:
namespace frozenca {
using namespace std;
struct insertion_sort_func {
template <ranges::bidirectional_range R = vector<int>, typename F = ranges::greater>
constexpr void operator()(R&& r, F comp = {}) const {
if (ranges::empty(r)) return;
for (auto i = next(begin(r)); i != end(r); ++i) {
auto key = *i;
auto j = i;
while (j != begin(r) && comp(*prev(j), key)) {
iter_swap(prev(j), j);
--j;
}
*j = key;
}
}
};
inline constexpr insertion_sort_func insertion_sort{};
} // namespace frozenca
And here is my test code, which works nicely:
int main() {
namespace fc = frozenca;
std::vector<int> v{5, 2, 4, 6, 1, 3};
fc::insertion_sort(v);
fc::print(v); // outputs "1 2 3 4 5 6"
fc::verify_sorting(std::ranges::sort); // outputs "Sorting verification success!"
fc::verify_sorting(fc::insertion_sort); // outputs "Sorting verification success!"
}
My verify_sorting function tests the sorting function for type std::vector<int> by default. Of course it can test other std::ranges::forward_range, but it becomes extremely verbose. For testing std::vector<float>, what I checked working is like this:
fc::verify_sorting<decltype(fc::insertion_sort), std::vector<float>>
(std::forward<decltype(fc::insertion_sort)>(fc::insertion_sort));
// OK
This is way too verbose. Is there any less verbose way?
Running code: https://wandbox.org/permlink/4UPLxeJxDlOkXcN1
This is way too verbose. Is there any less verbose way?
Just change the order of template parameters
template <ranges::forward_range R = vector<int>, typename F>
requires regular_invocable<F, R>
void verify_sorting(F&& f, /* */);
Then you can just invoke like this
fc::verify_sorting(std::ranges::sort);
fc::verify_sorting(fc::insertion_sort);
fc::verify_sorting<std::vector<float>>(fc::insertion_sort);
Demo
So basically, I want to create a function like this:
total_sum(1, 2, 5, 4, 2) // return 14
total_sum(5, 6, 2) // return 13
One way that I can use is ellipsis, something like this:
#include <cstdarg>
int total_sum(int count, ...)
{
int sum{0};
va_list list;
va_start(list, count);
for (int arg{0}; arg < count; ++arg)
{
sum += va_arg(list, int);
}
va_end(list);
return sum;
}
But when I call total_sum(), I have to provide an extra argument. So in the example, I have to call:
total_sum(5, 1, 2, 5, 4, 2);
total_sum(3, 5, 6, 2);
which I don't really like. Also, ellipsis is really prone to error, so I want to stay away from them.
Another way I can think of is using some container:
#include <vector>
int total_sum(std::vector<int> values)
{
int sum{0};
for(const auto &i : values)
{
sum += i;
}
return sum;
}
and I call it like:
total_sum({1, 2, 5, 4, 2});
total_sum({3, 5, 6, 2});
But, I want to not have those curly braces, so what can I do? Is there some C++ feature that allows me to do this?
Some relevant links: restrict variadic template arguments, fold expression, parameter packs and a
C++11 "equivalent" of fold expressions
Use C++17 fold expression:
template<class... Args>
constexpr auto total_sum(const Args&... args) {
return (args + ... + 0);
}
static_assert(total_sum(1, 2, 5, 4, 2) == 14);
static_assert(total_sum(3, 5, 6, 2) == 16);
In C++11 and newer you can use template parameter packs to create a recursive implementation, like this:
#include <iostream>
// base function
int total_sum()
{
return 0;
}
// recursive variadic function
template<typename T, typename... Targs>
int total_sum(T firstValue, Targs... Fargs)
{
return firstValue + total_sum(Fargs...);
}
int main(int, char **)
{
int s = total_sum(1, 5, 10, 20);
std::cout << "sum is: " << s << std::endl;
return 0;
}
Running the above program produces this output:
sum is: 36
All of the code below is is based on this article.
You can also do this kind-of C++11 "equivalent" of fold expressions:
#include <iostream>
#include <algorithm>
#include <utility>
#include <type_traits>
/*
Overload a total_sum() function with no arguments.
so it works when calling total_sum() with no argument.
*/
int total_sum()
{
return 0;
}
template<typename ... I>
int total_sum(const I &... i)
{
int result{};
static_cast<void>(std::initializer_list<int>{(result += i, 0)... });
return result;
}
int main()
{
std::cout << total_sum() << '\n';
std::cout << total_sum(1, 2, 5, 4, 2) << '\n';
std::cout << total_sum(5, 6, 2) << '\n';
}
See this online!
This one can add anything that can convert to an add-able value:
#include <iostream>
#include <algorithm>
#include <utility>
#include <type_traits>
int total_sum()
{
return 0;
}
template<typename ... V>
typename std::common_type<V...>::type total_sum(const V &... v)
{
typename std::common_type<V...>::type result = {};
static_cast<void>(std::initializer_list<int>{ (result += v, 0)... });
return result;
}
int main()
{
std::cout << total_sum() << '\n';
std::cout << total_sum(5, 6, 2) << '\n';
}
See this online!
The code above can be cleaner using C++14:
#include <iostream>
#include <algorithm>
#include <utility>
#include <type_traits>
int total_sum()
{
return 0;
}
template<typename ... V>
auto total_sum(const V &... v) {
std::common_type_t<V...> result = {};
static_cast<void>(std::initializer_list<int>{ (result += v, 0)... });
return result;
}
int main()
{
std::cout << total_sum() << '\n';
std::cout << total_sum(5, 6, 2) << '\n';
}
See this online!
How does one do two type variadic expansion? Here is what I am trying to achieve:
#include <vector>
#include <iostream>
class test
{
public:
std::vector< std::pair< float, int > > vec;
template<typename... T1, typename... T2>
test( T1... one, T2... two )
{
(
[&](float first, int second)
{
vec.emplace_back( std::pair< float, int >( first, second ) );
std::cout << first << ", " << second << std::endl;
}( one, two ),
...
);
}
};
int main()
{
test t
{
1.f,
1,
2.f,
2,
3.f,
3
};
return 0;
}
test must be initialized exactly like in main. I'd like usage in the constructor of test to remain similar.
Here is a working concept with va_list. Unfortunately, I need to pass a count for the parameters or I need to pass a magic-number terminator (I opted for the magic-number terminator).
#include <cstdarg>
#include <iostream>
#include <vector>
constexpr int END_OBJECT = 890123; // magic number
class test {
public:
std::vector<std::pair<int, double>> vec;
enum { is_name, is_data, is_max };
test(char ch, ...) {
std::pair<int, double> buf;
va_list b;
va_start(b, ch);
for (int i = 0;; i++) {
auto is = i % is_max;
if (is == is_name) {
if ( (buf.first = va_arg(b, int)) == END_OBJECT )
break;
} else if (is == is_data) {
buf.second = va_arg(b, double);
vec.emplace_back(buf);
}
}
va_end(b);
std::cout << ch << std::endl;
for (auto &x : vec)
std::cout << '\t' << x.first << ", " << x.second << std::endl;
}
};
int main() {
test t
{
'x',
1,
2.0,
3,
4.0,
5,
6.0,
END_OBJECT
};
return 0;
}
I'd like a more modern version of this using pack-expansion.
It's funny how this is basically FizzBuzz with template arguments and it's actually a nice challenge.
The easiest way in C++14 I could come up with is to use std::index_sequence.
https://godbolt.org/z/dm3F9u
#include <vector>
#include <utility>
#include <tuple>
template <typename... TArgs, size_t... Is>
std::vector<std::pair<float, int>> pair_off(std::tuple<TArgs...> args, std::index_sequence<Is...>) {
return std::vector<std::pair<float, int>> { std::make_pair(std::get<(Is << 1)>(args), std::get<((Is << 1) + 1)>(args))... };
}
template <typename... TArgs>
std::vector<std::pair<float, int>> pair_off(TArgs&&... args) {
return pair_off(std::forward_as_tuple(std::forward<TArgs>(args)...), std::make_index_sequence<(sizeof...(TArgs) >> 1)>{});
}
std::vector<std::pair<float, int>> test() {
return pair_off(1.1f, 1, 2.2f, 2, 3.3f, 3);
}
Basically, first you pack the arguments into a tuple. Then you make an index sequence half the size of the argument list. Then you expand that index sequence, passing it into std::get.
What that does is the template equivalent of:
for (int i=0; i<list.size()/2; i++) {
output.push_back( std::make_pair(list[i*2], list[i*2+1]) );
}
Is it a better idea to use boost::join to access and change the values of different arrays?
I have defined a member array inside class element.
class element
{
public:
element();
int* get_arr();
private:
int m_arr[4];
}
At different place, I'm accessing these arrays and joined together using boost::join and changing the array values.
//std::vector<element> elem;
auto temp1 = boost::join(elem[0].get_arr(),elem[1].get_arr());
auto joined_arr = boost::join(temp1,elem[2].get_arr());
//now going to change the values of the sub array
for(auto& it:joined_arr)
{
it+= sample[i];
i++;
}
Is this a good idea to modify the values of array in the class as above?
In your code you probably want to join the 4-elements arrays. To do that change the signature of get_arr to:
typedef int array[4];
array& get_arr() { return m_arr; }
So that the array size does not get lost.
Performance-wise there is a non-zero cost for accessing elements through the joined view. A double for loop is going to be most efficient, and easily readable too, e.g.:
for(auto& e : elem)
for(auto& a : e.get_arr())
a += sample[i++];
boost::join returns a more complicated type every composition step. At some point you might exceed the compiler's limits on inlining so that you're going to have a runtime cost¹.
Thinking outside the box, it really looks like you are creating a buffer abstraction that allows you to do scatter/gather like IO with few allocations.
As it happens, Boost Asio has nice abstractions for this², and you could use that: http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/MutableBufferSequence.html
As I found out in an earlier iteration of this answer code that abstraction sadly only works for buffers accessed through native char-type elements. That was no good.
So, in this rewrite I present a similar abstraction, which consists of nothing than an "hierarchical iterator" that knows how to iterate a sequence of "buffers" (in this implementation, any range will do).
You can choose to operate on a sequence of ranges directly, e.g.:
std::vector<element> seq(3); // tie 3 elements together as buffer sequence
element& b = seq[1];
Or, without any further change, by reference:
element a, b, c;
std::vector<std::reference_wrapper<element> > seq {a,b,c}; // tie 3 elements together as buffer sequence
The C++ version presented at the bottom demonstrates this approach Live On Coliru
The Iterator Implementation
I've used Boost Range and Boost Iterator:
template <typename Seq,
typename WR = typename Seq::value_type,
typename R = typename detail::unwrap<WR>::type,
typename V = typename boost::range_value<R>::type
>
struct sequence_iterator : boost::iterator_facade<sequence_iterator<Seq,WR,R,V>, V, boost::forward_traversal_tag> {
using OuterIt = typename boost::range_iterator<Seq>::type;
using InnerIt = typename boost::range_iterator<R>::type;
// state
Seq& _seq;
OuterIt _ocur, _oend;
InnerIt _icur, _iend;
static sequence_iterator begin(Seq& seq) { return {seq, boost::begin(seq), boost::end(seq)}; }
static sequence_iterator end(Seq& seq) { return {seq, boost::end(seq), boost::end(seq)}; }
// the 3 facade operations
bool equal(sequence_iterator const& rhs) const {
return ((_ocur==_oend) && (rhs._ocur==rhs._oend))
|| (std::addressof(_seq) == std::addressof(rhs._seq) &&
_ocur == rhs._ocur && _oend == rhs._oend &&
_icur == rhs._icur && _iend == rhs._iend);
}
void increment() {
if (++_icur == _iend) {
++_ocur;
setup();
}
}
V& dereference() const {
assert(_ocur != _oend);
assert(_icur != _iend);
return *_icur;
}
private:
void setup() { // to be called after entering a new sub-range in the sequence
while (_ocur != _oend) {
_icur = boost::begin(detail::get(*_ocur));
_iend = boost::end(detail::get(*_ocur));
if (_icur != _iend)
break;
++_ocur; // skid over, this enables simple increment() logic
}
}
sequence_iterator(Seq& seq, OuterIt cur, OuterIt end)
: _seq(seq), _ocur(cur), _oend(end) { setup(); }
};
That's basically the same kind of iterator as boost::asio::buffers_iterator but it doesn't assume an element type. Now, creating sequence_iterators for any sequence of ranges is as simple as:
template <typename Seq> auto buffers_begin(Seq& seq) { return sequence_iterator<Seq>::begin(seq); }
template <typename Seq> auto buffers_end(Seq& seq) { return sequence_iterator<Seq>::end(seq); }
Implementing Your Test Program
Live On Coliru
// DEMO
struct element {
int peek_first() const { return m_arr[0]; }
auto begin() const { return std::begin(m_arr); }
auto end() const { return std::end(m_arr); }
auto begin() { return std::begin(m_arr); }
auto end() { return std::end(m_arr); }
private:
int m_arr[4] { };
};
namespace boost { // range adapt
template <> struct range_iterator<element> { using type = int*; };
// not used, but for completeness:
template <> struct range_iterator<element const> { using type = int const*; };
template <> struct range_const_iterator<element> : range_iterator<element const> {};
}
#include <algorithm>
#include <iostream>
#include <vector>
template <typename Output, typename Input, typename Operation>
size_t process(Output& output, Input const& input, Operation op) {
auto ib = boost::begin(input), ie = boost::end(input);
auto ob = boost::begin(output), oe = boost::end(output);
size_t n = 0;
for (;ib!=ie && ob!=oe; ++n) {
op(*ob++, *ib++);
}
return n;
}
int main() {
element a, b, c;
std::vector<std::reference_wrapper<element> > seq {a,b,c}; // tie 3 elements together as buffer sequence
//// Also supported, container of range objects directly:
// std::list<element> seq(3); // tie 3 elements together as buffer sequence
// element& b = seq[1];
std::vector<int> const samples {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32
};
using boost::make_iterator_range;
auto input = make_iterator_range(samples);
auto output = make_iterator_range(buffers_begin(seq), buffers_end(seq));
while (auto n = process(output, input, [](int& el, int sample) { el += sample; })) {
std::cout << "Copied " << n << " samples, b starts with " << b.peek_first() << "\n";
input.advance_begin(n);
}
}
Prints
Copied 12 samples, b starts with 5
Copied 12 samples, b starts with 22
Copied 8 samples, b starts with 51
Full Listing, C++11 Compatible
Live On Coliru
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/iterator_range.hpp>
#include <functional> // std::reference_wrapper
namespace detail {
template<typename T> constexpr T& get(T &t) { return t; }
template<typename T> constexpr T const& get(T const &t) { return t; }
template<typename T> constexpr T& get(std::reference_wrapper<T> rt) { return rt; }
template <typename T> struct unwrap { using type = T; };
template <typename T> struct unwrap<std::reference_wrapper<T> > { using type = T; };
}
template <typename Seq,
typename WR = typename Seq::value_type,
typename R = typename detail::unwrap<WR>::type,
typename V = typename boost::range_value<R>::type
>
struct sequence_iterator : boost::iterator_facade<sequence_iterator<Seq,WR,R,V>, V, boost::forward_traversal_tag> {
using OuterIt = typename boost::range_iterator<Seq>::type;
using InnerIt = typename boost::range_iterator<R>::type;
// state
Seq& _seq;
OuterIt _ocur, _oend;
InnerIt _icur, _iend;
static sequence_iterator begin(Seq& seq) { return {seq, boost::begin(seq), boost::end(seq)}; }
static sequence_iterator end(Seq& seq) { return {seq, boost::end(seq), boost::end(seq)}; }
// the 3 facade operations
bool equal(sequence_iterator const& rhs) const {
return ((_ocur==_oend) && (rhs._ocur==rhs._oend))
|| (std::addressof(_seq) == std::addressof(rhs._seq) &&
_ocur == rhs._ocur && _oend == rhs._oend &&
_icur == rhs._icur && _iend == rhs._iend);
}
void increment() {
if (++_icur == _iend) {
++_ocur;
setup();
}
}
V& dereference() const {
assert(_ocur != _oend);
assert(_icur != _iend);
return *_icur;
}
private:
void setup() { // to be called after entering a new sub-range in the sequence
while (_ocur != _oend) {
_icur = boost::begin(detail::get(*_ocur));
_iend = boost::end(detail::get(*_ocur));
if (_icur != _iend)
break;
++_ocur; // skid over, this enables simple increment() logic
}
}
sequence_iterator(Seq& seq, OuterIt cur, OuterIt end)
: _seq(seq), _ocur(cur), _oend(end) { setup(); }
};
template <typename Seq> auto buffers_begin(Seq& seq) { return sequence_iterator<Seq>::begin(seq); }
template <typename Seq> auto buffers_end(Seq& seq) { return sequence_iterator<Seq>::end(seq); }
// DEMO
struct element {
int peek_first() const { return m_arr[0]; }
auto begin() const { return std::begin(m_arr); }
auto end() const { return std::end(m_arr); }
auto begin() { return std::begin(m_arr); }
auto end() { return std::end(m_arr); }
private:
int m_arr[4] { };
};
namespace boost { // range adapt
template <> struct range_iterator<element> { using type = int*; };
// not used, but for completeness:
template <> struct range_iterator<element const> { using type = int const*; };
template <> struct range_const_iterator<element> : range_iterator<element const> {};
}
#include <algorithm>
#include <iostream>
#include <vector>
template <typename Output, typename Input, typename Operation>
size_t process(Output& output, Input const& input, Operation op) {
auto ib = boost::begin(input), ie = boost::end(input);
auto ob = boost::begin(output), oe = boost::end(output);
size_t n = 0;
for (;ib!=ie && ob!=oe; ++n) {
op(*ob++, *ib++);
}
return n;
}
int main() {
element a, b, c;
std::vector<std::reference_wrapper<element> > seq {a,b,c}; // tie 3 elements together as buffer sequence
//// Also supported, container of range objects directly:
// std::list<element> seq(3); // tie 3 elements together as buffer sequence
// element& b = seq[1];
std::vector<int> const samples {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32
};
using boost::make_iterator_range;
auto input = make_iterator_range(samples);
auto output = make_iterator_range(buffers_begin(seq), buffers_end(seq));
while (auto n = process(output, input, [](int& el, int sample) { el += sample; })) {
std::cout << "Copied " << n << " samples, b starts with " << b.peek_first() << "\n";
input.advance_begin(n);
}
}
¹ I'm ignoring the compile-time cost and the lurking dangers with the pattern of auto x = complicated_range_composition when that complicated range composition contains references to temporaries: this is a frequent source of UB bugs
² which have been adopted by various other libraries, like Boost Beast, Boost Process and seem to have found their way into the Networking TS for C++20: Header <experimental/buffer> synopsis (PDF)
The following code concatenates a vector of ones to a matrix:
using Eigen::VectorXd;
using Eigen::MatrixXd;
MatrixXd cbind1(const Eigen::Ref<const MatrixXd> X) {
const unsigned int n = X.rows();
MatrixXd Y(n, 1 + X.cols());
Y << VectorXd::Ones(n), X;
return Y;
}
The function copies the contents of X to Y. How do I define the function so that it avoids doing the copy and returns a reference to a matrix containing VectorXd::Ones(n), X?
Thanks.
If you had followed and read ggael's answer to your previous question (and it appears you did, as you accepted his answer), you would have read this page of the docs. By modifying the example slightly, you could have written as part of an MCVE:
#include <iostream>
#include <Eigen/Core>
using namespace Eigen;
template<class ArgType>
struct ones_col_helper {
typedef Matrix<typename ArgType::Scalar,
ArgType::SizeAtCompileTime,
ArgType::SizeAtCompileTime,
ColMajor,
ArgType::MaxSizeAtCompileTime,
ArgType::MaxSizeAtCompileTime> MatrixType;
};
template<class ArgType>
class ones_col_functor
{
const typename ArgType::Nested m_mat;
public:
ones_col_functor(const ArgType& arg) : m_mat(arg) {};
const typename ArgType::Scalar operator() (Index row, Index col) const {
if (col == 0) return typename ArgType::Scalar(1);
return m_mat(row, col - 1);
}
};
template <class ArgType>
CwiseNullaryOp<ones_col_functor<ArgType>, typename ones_col_helper<ArgType>::MatrixType>
cbind1(const Eigen::MatrixBase<ArgType>& arg)
{
typedef typename ones_col_helper<ArgType>::MatrixType MatrixType;
return MatrixType::NullaryExpr(arg.rows(), arg.cols()+1, ones_col_functor<ArgType>(arg.derived()));
}
int main()
{
MatrixXd mat(4, 4);
mat << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16;
auto example = cbind1(mat);
std::cout << example << std::endl;
return 0;
}