Why the following Eigen example won't compile? - c++

I am trying to compile this MWE, but getting lots of errors:
#include <eigen/Eigen/Core>
#include <eigen/unsupported/Eigen/CXX11/Tensor>
#include <array>
using namespace Eigen;
int main()
{
// Create 2 matrices using tensors of rank 2
Eigen::Tensor<int, 2> a(2, 3);
a.setValues({{1, 2, 3}, {6, 5, 4}});
Eigen::Tensor<int, 2> b(3, 2);
a.setValues({{1, 2}, {4, 5}, {5, 6}});
// Compute the traditional matrix product
array<IndexPair<int>, 1> product_dims = { IndexPair<int>(1, 0) };
Eigen::Tensor<int, 2> AB = a.contract(b, product_dims);
// Compute the product of the transpose of the matrices
array<IndexPair<int>, 1> transpose_product_dims = { IndexPair<int>(0, 1) };
Eigen::Tensor<int, 2> AtBt = a.contract(b, transpose_product_dims);
}
This is actually from an example for Eigen tensors:
https://bitbucket.org/eigen/eigen/src/default/unsupported/Eigen/CXX11/src/Tensor/README.md?fileviewer=file-view-default
about contraction but I think it has some errors and wasn't compiled properly, which I tried to fix.
errors:
1.cc:11:3: error: no member named 'setValues' in 'Eigen::Tensor<int, 2, 0, long>'
a.setValues({{1, 2, 3}, {6, 5, 4}});
~ ^
1.cc:11:13: error: expected expression
a.setValues({{1, 2, 3}, {6, 5, 4}});
^
1.cc:13:3: error: no member named 'setValues' in 'Eigen::Tensor<int, 2, 0, long>'
a.setValues({{1, 2}, {4, 5}, {5, 6}});
~ ^
1.cc:13:13: error: expected expression
a.setValues({{1, 2}, {4, 5}, {5, 6}});
^
1.cc:16:26: error: non-aggregate type 'array<IndexPair<int>, 1>' cannot be initialized with an initializer list
array<IndexPair<int>, 1> product_dims = { IndexPair<int>(1, 0) };
^ ~~~~~~~~~~~~~~~~~~~~~~~~
1.cc:20:26: error: non-aggregate type 'array<IndexPair<int>, 1>' cannot be initialized with an initializer list
array<IndexPair<int>, 1> transpose_product_dims = { IndexPair<int>(0, 1) };
^ ~~~~~~~~~~~~~~~~~~~~~~~~
6 errors generated.

This example requires c++11, so you need to enable it on your compiler, for instance using -std=c++11 with gcc prior to gcc 6 or clang.

Related

How to use numeric library function with a vector of pairs?

I am trying to use the function adjacent_difference from the numeric library on the second element of each entry of a vector of pairs (vector<pair<double,double>>). How can I do it?
Update: here's my code so far (obviously wrong xD):
vector <pair<double,double>> initvalues; //receives pairs with the structure (174.386, 10)
for(int i = 0; i < 10; ++i)
{
initvalues.push_back(make_pair(i, 2+i));
}
vector <pair<double,double>> result(initvalues.size()-1);
adjacent_difference((initvalues.second).begin(),(initvalues.second).end(), (result.second).begin());
initvalues is my main vector that allocates pairs of valus with the structure (174.386, 10) as example. result is the output I want and it will store the first entry of the initvalues vector in the first pair entry and the adjacent_difference in the second entry of the pair.
However, I obtain the following output in the terminal compiling the code I've pasted in here:
stack.C: In function ‘int main()’:
stack.C:16:35: error: ‘class std::vector<std::pair<double, double> >’ has no member named ‘second’
16 | adjacent_difference((initvalues.second).begin(), (initvalues.second).end(), (result.second).begin());
| ^~~~~~
stack.C:16:64: error: ‘class std::vector<std::pair<double, double> >’ has no member named ‘second’
16 | adjacent_difference((initvalues.second).begin(), (initvalues.second).end(), (result.second).begin());
| ^~~~~~
stack.C:16:87: error: ‘class std::vector<std::pair<double, double> >’ has no member named ‘second’
16 | nitvalues.second).begin(), (initvalues.second).end(), (result.second).begin());
| ^~~~~~
If I understand you, this is what you want:
vector<pair<double, double>> initvalues;
for (int i = 0; i < 10; ++i) {
initvalues.push_back(make_pair(i, 2 + i));
}
vector<pair<double, double>> result;
result.reserve(initvalues.size());
adjacent_difference(initvalues.begin(), initvalues.end(),
std::back_inserter(result),
[](const auto& l, const auto& r) {
return std::pair<double, double>{l.first, l.second - r.second};
});
This gives you:
initValues = {0, 2} {1, 3} {2, 4} {3, 5} {4, 6} {5, 7} {6, 8} {7, 9} {8, 10} {9, 11}
result = {0, 2} {1, 1} {2, 1} {3, 1} {4, 1} {5, 1} {6, 1} {7, 1} {8, 1} {9, 1}

too many initializers for array in struct

I have:
struct X {
int i, j;
};
struct XArray {
X xs[3];
};
X xs1[3] { {1, 2}, {3, 4}, {5, 6} };
XArray xs2 { {1, 2}, {3, 4}, {5, 6} };
The xs1 initializes fine, initializing xs2 gives compiler error:
error: too many initializers for 'XArray'
XArray xs2 { {1, 2}, {3, 4}, {5, 6} };
^
What is wrong? Why can't I initialize?
You need another level of curly-braces:
XArray xs2 { { {1, 2}, {3, 4}, {5, 6} } };
// ^ ^ ^
// | | |
// For XArray structure | |
// | |
// For xs array |
// |
// For the X structure
The compileŕ assumes that xs is one field, the array will only be resolved when you add another brace like:
XArray xs2 { {{1, 2}, {3, 4}, {5, 6}} };
When you would add another element, e.g.
struct YArray {
X a;
X xs[3];
}
then it becomes clear that a and xs both need to be put into braces:
YArray y{
{1,2}, // a
{ {1, 2}, {3, 4}, {5, 6} } // xs
};
X xs[3] = { {1,2}, {3,4}, {5,6}};
Then you plug the whole part to the right into your code:
XArray x2 = { { {1,2}, ... {5,6} }};
This is because XArray has only one member, and it needs one pair of brackets enclosing it:
XArray t = { /* value */ };
And value happens to be an array, which also needs brackets:
X xs[3] = { /* value2 */ };
Since this array holds three values, each of them has to be initialized with a pair of numbers.
You have to use:
XArray xs2 { { {1, 2}, {3, 4}, {5, 6} } };
This way the first element of XArray is initialized with: { {1, 2}, {3, 4}, {5, 6} }.
Online here

Having some trouble with initializing a 2D array and then sending it off to a function

I am making a TicTacToe program and I'm trying to use OOP techniques. Within my 'Board' class I am wanting the program to store each way a set of moves can be won.
I hope this can be demonstrated here:
Board.h
#pragma once
class Board
{
private:
int winningRows[8][3]; //Variable in question
public:
static const char X = 'X'; //Game piece 'X'
static const char O = 'O'; //Game piece 'O'
static const char EMPTY = ' '; //Empty game piece
static const char TIE = 'T'; //Game is tie
static const char NOONE = 'N'; //Nobody has won game yet
static const int numbOfSquares = 9; //Number of squares on the board
int InitializeWinningCombinations();
void FindWinner();
};
Board.cpp
#include "stdafx.h"
#include "Board.h"
int Board::InitializeWinningCombinations()
{
/*
The playing board
0, 1, 2
3, 4, 5
6, 7, 8
*/
//All possible ways player can win game
winningRows[8][3] = {
//Horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
//Vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
//Diagonal
{2, 4, 6},
{0, 4, 8}
};
//return winnigRows[8][3];
}
void Board::FindWinner()
{
//I am wanting to get the variable here so I can play around with it later.
int winningRows = InitializeWinningCombinations();
}
I could just have the 'winningRows' variable inside the 'FindWinnner' function but from my understanding it is best to abstract as much as possible and have it as a member of the 'Board' class
Thank you for your time.
winningRows[8][3] = {
//Horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
//Vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
//Diagonal
{2, 4, 6},
{0, 4, 8}
};
Is an attempted array assignment not an initialization and it cannot be done. You can initialize the array in a constructor like
Board() : winningRows{
//Horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
//Vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
//Diagonal
{2, 4, 6},
{0, 4, 8}
} {}
Live Example
You'd have to change the signature to
int** InitializeWinningCombinations();
Then you could call it as
int** winningRows = InitializeWinningCombinations();

Initializing multiple data structures inside of each other c++11

I was looking for help on how to initialize the following data structure inside of my constructor for backtracking:
stack<tuple<vector<set<int> >, int, int> > record; //none of the structures have been initialized yet
Thank you all for your help.
When you have a complex type like that, it is helpful to divide the type into fundamental types before figuring out how to initialize it.
Divide your type into fundamental types, it looks like:
stack<tuple<vector<set<int> >, int, int> > record;
^ ^
| |
tuple<vector<set<int> >, int, int>
^ ^ ^ ^ ^ ^
| | | | | |
vector<set<int> >
^ ^
| |
set<int>
^ ^
| |
To initialize an object of such a type, you'll have to figure out how to build up from the constituent fundamental types.
Initialize an int.
int a{0};
Initialize a set<int>.
set<int> b{1, 2};
Initialize a vector<set<int>>.
vector<set<int>> c{ {1, 2}, {2, 3, 4}, {4, 5, 6, 8} };
Initialize a tuple<vector<set<int>>, int, int>.
tuple<vector<set<int>>, int, int> d{ { {1, 2}, {2, 3, 4}, {4, 5, 6, 8} }, 10, 20};
However, you cannot use the same strategy to initialize stack since std::stack does not have a constructor that you can use like:
stack<int> e{1, 3, 5};
That means, you can't initialize a stack<tuple<vector<set<int>>, int, int>> as:
stack<tuple<vector<set<int> >, int, int> > record
{
{{ {1, 2}, {2, 3, 4}, {4, 5, 6, 8} }, 10, 20},
{{ {1, 2}, {2, 3, 4}, {4, 5, 6, 8} }, 10, 20}
};
Your only choice is to default construct record and add items to it.
stack<tuple<vector<set<int> >, int, int> > record;
using item_type = decltype(record)::value_type;
record.push(item_type{{ {1, 2}, {2, 3, 4}, {4, 5, 6, 8} }, 10, 20});
record.push(item_type{{ {1, 2}, {2, 3, 4}, {4, 5, 6, 8} }, 10, 20});

How to create a 2D array in C++ using this specific container

I'm trying to port a
int a[][]
from Java to C++. I'm using this class as a container ArrayRef for ints because it handles references, and the project uses it extensively. In the AbstractReader class I declared
const ArrayRef<int> START_END_PATTERN_;
const ArrayRef<int> MIDDLE_PATTERN_;
const ArrayRef<ArrayRef<int> > L_PATTERNS_;
const ArrayRef<ArrayRef<int> > L_AND_G_PATTERNS_;
and
static int START_END_PATTERN[];
static int MIDDLE_PATTERN[];
static int L_PATTERNS[10][4];
static int L_AND_G_PATTERNS[20][4];
Note the trailing underscore to differentiate the two variables.
I'm not sure what to do in order to initialize the two-dimensional ArrayRef. What I'm posting here will segfault because those ArrayRefs are being allocated on the stack. Anybody have a clever way to do this?
The only way I've actually managed to get it to work is using a ArrayRef< Ref<ArrayRef<int> > > by making ArrayRef inherit from Counted, which is basically a class that allows for Reference Counting in C++. But in order to access the elements I hen have to do something like *(foo[i])[j], which is slightly nastier than foo[i][j].
int AbstractReader::L\_AND\_G_PATTERNS[20][4] = {
{3, 2, 1, 1}, // 0
{2, 2, 2, 1}, // 1
{2, 1, 2, 2}, // 2
{1, 4, 1, 1}, // 3
{1, 1, 3, 2}, // 4
{1, 2, 3, 1}, // 5
{1, 1, 1, 4}, // 6
{1, 3, 1, 2}, // 7
{1, 2, 1, 3}, // 8
{3, 1, 1, 2}, // 9
// G patterns
{1, 1, 2, 3}, // 0
{1, 2, 2, 2}, // 1
{2, 2, 1, 2}, // 2
{1, 1, 4, 1}, // 3
{2, 3, 1, 1}, // 4
{1, 3, 2, 1}, // 5
{4, 1, 1, 1}, // 6
{2, 1, 3, 1}, // 7
{3, 1, 2, 1}, // 8
{2, 1, 1, 3} // 9
};
AbstractReader::AbstractReader()
: decodeRowStringBuffer_(ostringstream::app),
START_END_PATTERN_(START_END_PATTERN, 3),
MIDDLE_PATTERN_(MIDDLE_PATTERN, 5),
L_PATTERNS_(10),
L_AND_G_PATTERNS_(20) {
for (int i = 0; i < 20; i++) {
if (i < 10) {
L_PATTERNS_[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
}
ArrayRef<int> lgpattern((L_AND_G_PATTERNS[i]), 4);
L_AND_G_PATTERNS_[i] = lgpattern;
}
}
What you have should be safe. The (stack allocated) ArrayRefs create heap allocated Arrays to back them, and then share those Arrays.
Edit: Thanks for posting Counted. Took a bit of work, but I think I see what's going on.
Solution: Don't declare L_PATTERNS_ or L_AND_G_PATTERNS_ as const. Alternately, const_cast to get the desired operator[]. E.g.
const_cast<ArrayRef<ArrayRef<int> > &>(L_PATTERNS_)[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
Rationale:
In AbstractReader, you declare:
const ArrayRef<ArrayRef<int> > L_PATTERNS_;
Then in its constructor, you attempt an assignment:
AbstractReader::AbstractReader() :
{
...
L_PATTERNS_[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
...
}
Since L_PATTERNS_ is const, L_PATTERNS_[i] invokes a method from ArrayRef<ArrayRef<int> >:
T operator[](size_t i) const { return (*array_)[i]; }
This returns a brand new copy of what was at L_PATTERNS_[i]. The assignment then occurs (into a temporary), leaving the original unchanged. When you later go back to access L_PATTERNS_[xxx], you're looking at the original, uninitialized value (which is a NULL reference/pointer). Thus the segfault.
Somewhat surprising is that ArrayRef even allows this assignment. Certainly it breaks the "Principle of Least Surprise". One would expect the compiler to issue an error. To make sure that the compiler is more helpful in the future, we need to give a slightly different definition of ArrayRef's operator[] const (Array.h:121), such as:
const T operator[](size_t i) const { return (*array_)[i]; }
or perhaps (with caveats):
const T& operator[](size_t i) const { return (*array_)[i]; }
After making either change, the compiler disallows allow the assignment. GCC, for example, reports:
error: passing 'const common::ArrayRef<int>' as 'this' argument of 'common::ArrayRef<T>& common::ArrayRef<T>::operator=(const common::ArrayRef<T>&) [with T = int]' discards qualifiers
Causes may be several. For instance, you don't include in your paste the "Counted" class, and at some point, a->retain() is called (line 130). This method is not shown.