I would like to extend the C++ Eigen library to include a command v.sort(); I'm using the EIGEN_MATRIXBASE_PLUGIN based approach outlined here.
The code below (in my "MatrixBaseAddons.h") does not work, because the "result" object does not get loaded with a copy of "this"---in the debugger, "result.rows()" is an uninitialized value not equal to derived()->rows(). How do I actually make a copy of "this" and put it in "result"?
// DOES NOT WORK
MatrixBase<Derived> sort(bool ascending = true) const {
MatrixBase<Derived> result = derived();
result.sortInPlace(ascending);
return result;
}
// WORKS!
void sortInPlace(bool ascending = true) {
std::sort(derived().data(), derived().data() + derived().size());
if (!ascending)
this->reverseInPlace();
}
MatrixBase is an abstract class. You need to return a Matrix<> object with appropriate scalar type and sizes. You can directly use the typedef PlainObject for that:
PlainObject sort(bool ascending = true) const {
PlainObject res = derived();
...
return res;
}
Related
This simple object return works fine.
Bubbles& Foo() {
static Bubbles foo(10);
foo.print();
return foo;
}
int main() {
Bubbles *bar;
bar = &Foo();
bar->print();
printf("Program Ends");
return 0;
}
Now I need to know how to return an Array of Objects!
I have 0 idea on how I should declare it All I know is:
Bubbles& createBubbles() {
static Bubbles *BubblesArray[arrayNumber];
for (int i = 0; i < arrayNumber; i++) {
BubblesArray[i] = new Bubbles(i);
BubblesArray[i]->print();
}
return BubblesArray;
}
seems to create an array of Objects the way I need. So how can I return this array so I can use it outside the function?
Your return type expects only 1 Bubbles object. If you want to return an array, you have to change the function return type. I would strongly recommend not playing with raw array and stick with the std library. Using C++11 (DISCLAIMER: CODE UNTESTED) will look something along the line of:
std::vector<Bubbles> createBubbles(const int& arrayNumber) {
std::vector<Bubbles> bubblesVector;
for (int i = 0; i < arrayNumber; i++) {
bubblesVector.push_back(Bubbles(i));
bubblesVector[i].print();
}
return bubblesVector;
}
Note that this assume your Bubbles object has appropriate default/copy/move constructor, destructor, assignment operator...
Simple return type std::vector<Bubbles> can take advantage of copy-elision which is extremely efficient.
You can get the same behavior as in your first example. You just have to specify the type correctly:
using BubblesArrayType = Bubbles*[arrayNumber];
BubblesArrayType& createBubbles() {
static BubblesArrayType BubblesArray;
//...
return BubblesArray;
}
or you can let type deduction figure the type out for you:
auto& createBubbles() {
static Bubbles *BubblesArray[arrayNumber];
//...
return BubblesArray;
}
But as mentioned in comments and other answers, this is unlikely to be a good design and style. Without further information it is not really clear though, why you are using static and return-by-reference in the first place.
I am working on improving my C++ skills - specifically the use of templates. I am creating a filtering mathematical library that through the use of templates is compatible for different vector/matrix classes including Boost and Eigen. So far I am very happy with the library, but am encountering issues as I am expanding functionality.
Eigen and Boost are different in that for example the latter does not have multiply operators (see 1) so this presented a choice in my implementation. I decided to make sure that the matrix/vector methods and operators used within the template library use those that are defined for Eigen so that at least one library works really well with the mathematical library. In my library I would use * to multiply matrices which is unavailable for boost. For boost I created a wrapper class for both matrix and vector to allow the use of * through custom operators. Example of wrapper for matrix is below:
class matrixBoost{
private:
boost::numeric::ublas::matrix<double> value;
public:
matrixBoost(){
}
matrixBoost(boost::numeric::ublas::matrix<double> value):value(value){}
static matrixBoost Identity(int dimension,int dimension2){
return matrixBoost(boost::numeric::ublas::identity_matrix<double>(dimension,dimension2));
}
matrixBoost transpose(){
matrixBoost t(boost::numeric::ublas::trans(value));
return t;
}
boost::numeric::ublas::matrix<double> getSystemValue() const{
return value;
}
};
//example operator - one of many
matrixBoost operator*(const matrixBoost &lhs, const matrixBoost &rhs){
matrixBoost res(boost::numeric::ublas::prod(lhs.getSystemValue(),rhs.getSystemValue()));
return res;
}
I am now trying to add Eigen's block to boost's wrapper class that allows for the following behaviour in Eigen's library:
Eigen::MatrixXd m(2,2);m<<1,2,3,4;
Eigen::MatrixXd n = m.block(0, 0, 1, 2) + m.block(0,0,1,2);
m.block(0,0,1,2) = n;
with m now equalling
2 4
3 4
My first question is can someone please link or show examples of how the block function would be coded (without considering a wrapper class even). I have tried googling but either Google has gotten worse or I am not using the right key words - the results are swarmed with operator[] results. I am having difficulty understanding. I tried searching within the Eigen library source and imagine the code must be located here but the template language is a little difficult for me to parse easily.
I know that boost also has a similar concept as shown in here:
project(A, r1, r2) = C; // assign the submatrix of A specified by the two index ranges r1 and r2
C = project(A, r1, r2); // the submatrix of A specified by the two index ranges r1 and r2
I am not sure if adding a block function to my wrapper class is even possible. For now I have the following:
matrixBoost block(int index1,int index2, int length1, int length2){
boost::numeric::ublas::range r1(i1,l1);
boost::numeric::ublas::range r2(i2,l2);
return matrixBoost(boost::numeric::ublas::project(value,r1,r2));
}
This will work for when the method is on the right hand side of the the equal sign. However, I am having difficulty as to how to proceed to allowing for the method being called on the left hand side. Perhaps I should make use of boost's project method. Any help would be much appreciated!
Thank you.
So I found a solution for the problem of wrapping the boost class, but the solution is a little messy. The block function as deduced in the question above must return a reference. If it is on the right hand side of the equal sign then we need to return the submatrix wrapped within matrixBoost for the other */+ multiplications that might be in the expression. However, what if this is called on the left hand side of the equal sign?
My solution was to use a boolean flag (subMatrixCopy) where I would set it to true as well as backup the full matrix value in valBack through the use of std::swap and return with the submatrix. This modification would allow for proper expression evaluation on the right hand side. For the left hand side, once the = operator is called then the boolean flag makes sure that the right hand side is properly assigned to the specified block of the backed up matrix value in valBack.
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/qvm/mat_operations.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <lapacke.h>
class matrixBoost{
private:
boost::numeric::ublas::matrix<double> value;
boost::numeric::ublas::range r1;
boost::numeric::ublas::range r2;
boost::numeric::ublas::matrix<double>valBack;
bool subMatrixCopy = false;
void setSystemValue(boost::numeric::ublas::matrix<double> v){
value = v;
}
public:
matrixBoost(){}
matrixBoost(int rowCount, int colCount){
value = boost::numeric::ublas::zero_matrix<double>(rowCount,colCount);
}
matrixBoost(boost::numeric::ublas::matrix<double> value):value(value){}
static matrixBoost Identity(int dimension,int dimension2){
return matrixBoost(boost::numeric::ublas::identity_matrix<double>(dimension,dimension2));
}
matrixBoost transpose(){
matrixBoost t(boost::numeric::ublas::trans(value));
return t;
}
boost::numeric::ublas::matrix<double> getSystemValue() const{
return value;
}
matrixBoost & block(int i1, int i2, int l1, int l2){
if(subMatrixCopy){
std::swap(valBack,value);
}
subMatrixCopy = true;
r1 = boost::numeric::ublas::range(i1,i1+l1);
r2 = boost::numeric::ublas::range(i2,i2+l2);
valBack = boost::numeric::ublas::project(value,r1,r2);
std::swap(valBack,value);
return *this;
}
matrixBoost &operator=( const matrixBoost other){
if(subMatrixCopy){
subMatrixCopy = false;
boost::numeric::ublas::project(valBack,r1,r2) = other.getSystemValue();
std::swap(valBack,value);
}else{
value = other.getSystemValue();
}
return *this;//better be no chaining of equal signs
}
};
and here is an example of the code in action that I used to test. It works! However, I believe the solution prevents doing certain things such as chaining equal signs.
int main(){
boost::numeric::ublas::matrix<double> value(3,3);
value(0,0) = 1;
value(1,1) = 2;
value(2,2) = 3;
matrixBoost valueWrap(value);
boost::numeric::ublas::vector<double> v(3);
v(0) = 1;
v(1) = 1;
v(2) = 1;
cout<<vectorBoost::solve(valueWrap,vectorBoost(v))<<endl;
cout<<valueWrap<<endl;
matrixBoost newMatrix = valueWrap.block(1,1,2,2);
cout<<newMatrix<<endl;
cout<<valueWrap.block(1,1,2,2)<<endl;
valueWrap.block(1,1,2,2) =
valueWrap.block(1,1,2,2)*newMatrix + newMatrix;
cout<<valueWrap<<endl;
}
Guys I have a function like this (this is given and should not be modified).
void readData(int &ID, void*&data, bool &mybool) {
if(mybool)
{
std::string a = "bla";
std::string* ptrToString = &a;
data = ptrToString;
}
else
{
int b = 9;
int* ptrToint = &b;
data = ptrToint;
}
}
So I want to use this function in a loop and save the returned function parameters in a vector (for each iteration).
To do so, I wrote the following struct:
template<typename T>
struct dataStruct {
int id;
T** data; //I first has void** data, but would not be better to
// have the type? instead of converting myData back
// to void* ?
bool mybool;
};
my main.cpp then look like this:
int main()
{
void* myData = nullptr;
std::vector<dataStruct> vec; // this line also doesn't compile. it need the typename
bool bb = false;
for(int id = 1 ; id < 5; id++) {
if (id%2) { bb = true; }
readData(id, myData, bb); //after this line myData point to a string
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
}
}
Or is there a better way to do that without template? I used c++11 (I can't use c++14)
The function that you say cannot be modified, i.e. readData() is the one that should alert you!
It causes Undefined Behavior, since the pointers are set to local variables, which means that when the function terminates, then these pointers will be dangling pointers.
Let us leave aside the shenanigans of the readData function for now under the assumption that it was just for the sake of the example (and does not produce UB in your real use case).
You cannot directly store values with different (static) types in a std::vector. Notably, dataStruct<int> and dataStruct<std::string> are completely unrelated types, you cannot store them in the same vector as-is.
Your problem boils down to "I have data that is given to me in a type-unsafe manner and want to eventually get type-safe access to it". The solution to this is to create a data structure that your type-unsafe data is parsed into. For example, it seems that you inteded for your example data to have structure in the sense that there are pairs of int and std::string (note that your id%2 is not doing that because the else is missing and the bool is never set to false again, but I guess you wanted it to alternate).
So let's turn that bunch of void* into structured data:
std::pair<int, std::string> readPair(int pairIndex)
{
void* ptr;
std::pair<int, std::string> ret;
// Copying data here.
readData(2 * pairIndex + 1, ptr, false);
ret.first = *reinterpret_cast<int*>(ptr);
readData(2 * pairIndex + 2, ptr, true);
ret.second = *reinterpret_cast<std::string*>(ptr);
}
void main()
{
std::vector<std::pair<int, std::string>> parsedData;
parsedData.push_back(readPair(0));
parsedData.push_back(readPair(1));
}
Demo
(I removed the references from the readData() signature for brevity - you get the same effect by storing the temporary expressions in variables.)
Generally speaking: Whatever relation between id and the expected data type is should just be turned into the data structure - otherwise you can only reason about the type of your data entries when you know both the current ID and this relation, which is exactly something you should encapsulate in a data structure.
Your readData isn't a useful function. Any attempt at using what it produces gives undefined behavior.
Yes, it's possible to do roughly what you're asking for without a template. To do it meaningfully, you have a couple of choices. The "old school" way would be to store the data in a tagged union:
struct tagged_data {
enum { T_INT, T_STR } tag;
union {
int x;
char *y;
} data;
};
This lets you store either a string or an int, and you set the tag to tell you which one a particular tagged_data item contains. Then (crucially) when you store a string into it, you dynamically allocate the data it points at, so it will remain valid until you explicitly free the data.
Unfortunately, (at least if memory serves) C++11 doesn't support storing non-POD types in a union, so if you went this route, you'd have to use a char * as above, not an actual std::string.
One way to remove (most of) those limitations is to use an inheritance-based model:
class Data {
public:
virtual ~Data() { }
};
class StringData : public Data {
std::string content;
public:
StringData(std::string const &init) : content(init) {}
};
class IntData : public Data {
int content;
public:
IntData(std::string const &init) : content(init) {}
};
This is somewhat incomplete, but I think probably enough to give the general idea--you'd have an array (or vector) of pointers to the base class. To insert data, you'd create a StringData or IntData object (allocating it dynamically) and then store its address into the collection of Data *. When you need to get one back, you use dynamic_cast (among other things) to figure out which one it started as, and get back to that type safely. All somewhat ugly, but it does work.
Even with C++11, you can use a template-based solution. For example, Boost::variant, can do this job quite nicely. This will provide an overloaded constructor and value semantics, so you could do something like:
boost::variant<int, std::string> some_object("input string");
In other words, it's pretty what you'd get if you spent the time and effort necessary to finish the inheritance-based code outlined above--except that it's dramatically cleaner, since it gets rid of the requirement to store a pointer to the base class, use dynamic_cast to retrieve an object of the correct type, and so on. In short, it's the right solution to the problem (until/unless you can upgrade to a newer compiler, and use std::variant instead).
Apart from the problem in given code described in comments/replies.
I am trying to answer your question
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
Before that you need to modify vec definition as following
vector<dataStruct<void>> vec;
Now you can simple push element in vector
vec.push_back({id, &mydata, bb});
i have tried to modify your code so that it can work
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
struct dataStruct
{
int id;
T** data;
bool mybool;
};
void readData(int &ID, void*& data, bool& mybool)
{
if (mybool)
{
data = new string("bla");
}
else
{
int b = 0;
data = &b;
}
}
int main ()
{
void* mydata = nullptr;
vector<dataStruct<void>> vec;
bool bb = false;
for (int id = 0; id < 5; id++)
{
if (id%2) bb = true;
readData(id, mydata, bb);
vec.push_back({id, &mydata, bb});
}
}
I am writing a code for Cellular Automata and I need an evolution function to calculate the state of the automata after a time step.
I choose to call this function evol, to test it I created an elementary function in C++. Unfortunately it does not compile since the compiler cannot understand that I need it to return an array. Here is the code :
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
const int N = 51; // Size of the grid; two columns/rows are added at the beginning and the end of the array (no evolution of the CA on the boundaries)
class Cell{
//defining whats a cell here
};
void showCA(Cell CA[N+2][N+2]){
//function to print the CA grid in the terminal
}
Cell[N+2][N+2] evol(Cell CA[N+2][N+2]){
return CA;
}
int main()
{
// Initialisation
cout << "Initialisation" << endl;
static Cell CA[N+2][N+2];
// some code here to initialize properly the Cell array.
showCA(CA);
CA = evol(CA);
showCA(CA);
return 0;
}
The compiler returns this error :
error: expected unqualified-id
Cell[N+2][N+2] evol(Cell CA[N+2][N+2]){
Any idea on how I should implement this ?
You cannot return arrays from functions:
ยง 8.3.5/8
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.
If you are wishing to return raw, C-style arrays from functions, then you have to use a reference or pointer. For example, here's how it is done using a reference (you can do the same using a pointer by replacing & with *):
Cell (&evol(Cell (&CA)[N+2][N+2]))[N+2][N+2];
However, this is very unintuitive and hard to read. If your compiler supports the latest standard (C++11) the return type can be cleaned up using a trailing return type:
auto evol(Cell (&CA)[N+2][N+2]) -> Cell(&)[N+2][N+2];
But again, this is probably still harder to read.
C++11 facilitates the handling of C-style arrays with the container std::array<>. Non-C++11 code should use std::vector<>:
using Cells = std::array<std::array<Cell, N+2>, N+2>;
Cells const& evol(Cells const& CA);
You can use
typedef std::vector<std::vector<Cell>> CellArray;
CellArray Cells(N+2); // resize main dimension
for (size_t i=0; i<N+2; i++)
Cells[i].resize(N+2); // resize all cells of main dimension
to hold your cell array, but you also need to add a copy constructor and operator= in Cell class
class Cell {
public:
Cell() { ... default ctor code here ... }
Cell(const Cell &c) { *this = c; }
Cell &operator=(const Cell&c)
{
if (this != &c)
{
... copy data from c members to this members here ...
}
return *this;
}
};
Your evol function then can return a CellArray:
CellArray evol(CellArray &c)
{
CellArray r;
... do some calculations with c and r ...
return r;
}
once you have declared a variable using the array syntax like you have:
Cell CA[N+2][N+2];
you cannot assign CA to be something else. You can only assign values to its contents. Hence,
CA = evol(CA);
is wrong.
You can do the following:
Cell (*CA2)[N+2] = evol(CA);
As the number of elements seems to be fixed, I suggest you use the std::array container:
const int N = 51;
typedef std::array<std::array<Cell,N+2>, N+2> datatype;
You can then use this type as a return type:
datatype Evol( const datatype& d );
You can access elements just as if it was a "C" array:
datatype d;
Cell c;
d[10][20] = c;
I would strongly suggest encapsulate your array into a class. You cannot return an array, but you can return an object that contains an array.
I have a C++ class containing a bunch of data members of the same type and I want to iterate over them:
// C.h
class C {
// other members
double foo;
double bar;
...
double barf; // 57th double declared since foo, nothing else in between
// other members
};
Pointer arithmetic seems to work, e.g. here using the constructor to initialize those 58 member doubles:
// C.cpp
C::C() {
for (int i = 0; i < 58; i++) {
*(&this->foo + i) = 0;
}
}
I found related questions here How to iterate through variable members of a class C++, here C++: Iterating through all of an object's members?, here Are class members garaunteed to be contiguous in memory? and here Class contiguous data, with some people suggesting this kind of thing is ok and others a no-no. The latter say there's no guarantee it won't fail, but don't cite any instances of it actually failing. So my question is, does anyone else use this, or has tried and got into trouble?
Or maybe there's a better way? Originally in my application I did actually use an array instead to represent my object, with indices like so:
int i_foo = 0, i_bar = 1, ..., i_barf = 57;
However once I introduced different objects (and arrays thereof) the index naming started to get out of hand. Plus I wanted to learn about classes and I'm hoping some of the other functionality will prove useful down the line ;-)
I use the iteration pretty heavily, e.g. to calculate statistics for collections of objects. Of course I could create a function to map the class members to an array one-by-one, but performance is a priority. I'm developing this application for myself to use on Windows with VS. I would like to keep other platform options open, but it's not something I intend to distribute widely. Thanks
George:
I think you can have a better solution (like a method that will return the i-th attribute:
double get(size_t idx)
{
switch (idx)
{
case 0: return foo;
case 1: return bar;
case 2: return foo_bar;
....
}
}
Using pointer arithmetic to iterate over class data members can cause problems during code optimization. Example:
struct Vec3
{
double x, y, z;
inline Vec3& operator =(const Vec3& that)
{
x = that.x;
y = that.y;
z = that.z;
return *this;
}
inline double& operator [](int index)
{
return (&x)[index];
}
};
...
Vec3 foo = bar; // operator =
double result = foo[2]; // operator []
...
Both operators are inlined, the value of the result depends on the final instructions reordering. Possible cases:
foo.x = bar.x;
foo.y = bar.y;
foo.z = bar.z;
result = (&foo.x)[2]; // correct -- result contains new value
foo.x = bar.x;
foo.y = bar.y;
result = (&foo.x)[2]; // incorrect -- result contains old value
foo.z = bar.z;
foo.x = bar.x;
result = (&foo.x)[2]; // incorrect -- result contains old value
foo.y = bar.y;
foo.z = bar.z;
Some compilers just do not realise that (&foo.x)[2] is the same data as foo.z and they reorder instructions incorrectly. It is very hard to find bugs like this.