I got different results using auto and using Vector when summing two vectors.
My code:
#include "stdafx.h"
#include <iostream>
#include "D:\externals\eigen_3_1_2\include\Eigen\Geometry"
typedef Eigen::Matrix<double, 3, 1> Vector3;
void foo(const Vector3& Ha, volatile int j)
{
const auto resAuto = Ha + Vector3(0.,0.,j * 2.567);
const Vector3 resVector3 = Ha + Vector3(0.,0.,j * 2.567);
std::cout << "resAuto = " << resAuto <<std::endl;
std::cout << "resVector3 = " << resVector3 <<std::endl;
}
int main(int argc, _TCHAR* argv[])
{
Vector3 Ha(-24.9536,-29.3876,65.801);
Vector3 z(0.,0.,2.567);
int j = 7;
foo(Ha,j);
return 0;
}
The results:
resAuto = -24.9536, -29.3876,65.801
resVector3 = -24.9536,-29.3876,83.77
Press any key to continue . . .
I understand that Eigen does internal optimization that generate different results. But it looks like a bug in Eigen and C++11.
The auto keyword tells the compiler to "guess" the best object based on the right hand side of the =. You can check the results by adding
std::cout << typeid(resAuto).name() <<std::endl;
std::cout << typeid(resVector3).name() <<std::endl;
to foo (don't forget to include <typeinfo>).
In this case, after constructing the temporary Vector3, the operator+ method is called, which creates a CwiseBinaryOp object. This object is part of Eigens lazy evaluation (can increase performance). If you want to force eager evaluation (and therefore type determination), you could use
const auto resAuto = (Ha + Vector3(0.,0.,j * 2.567)).eval();
instead of your line in foo.
A few side notes:
Vector3 is identical to the Vector3d class defined in Eigen
You can use #include <Eigen/Core> instead of #include <Eigen/Geometry> to include most of the Eigen headers, plus certain things get defined there that should be.
Related
I have following use case
Instance - Consider this as a black box on which transformation happens and each type of transformation changes the state of the instance
Transformation - An action applied on the instance which changes the instance's state. For example and upgrade is a type of transformation that can upgrade the version of the instance from v1 to v2
end - end signifies that no more transformation can be done on the instance anymore
so we can have following for example:
create (instance1) , upgrade(instance1), delete (instance1),recover(instance1), change_domain(instance1), end
create(instance2), delete(instance2), end
create(instance3), change_domain(instance3), delete (instance3), recover(instance3),end
create(instance4), delete (instance4), end
My goal is to find the occurence of a specific transformation path taken by all the instances.. so in above example..
create -> upgrade -> delete -> recover -> change_domain (1 time)
create -> delete (2 times instance2 and instance 4)
create -> change_domain-> delete -> recover( 1 time)
What kind of data structure would be a fit to store the data and what sort of algorithm would work for this? I am thinking along the lines of graph where edges are transformation but not too sure what nodes would be and how will be I calculate occurence of a particular path..
Assign each transformation type an 1-based index. e.g. create 1, upgrade 2, delete 3, ...
Let I be the number of different transformation types.
When the transformation path for an instance is input, convert to a number base I. Call this the instance's history number
For example:
create(instance2), delete(instance2), end => 13
Store the instance indexes in a mulitimap keyed by its history number
To find the occurrences of a specific transformation path, convert it to a history number and do a look up on the multimap.
A sensible trick would be to round up I to the nearest, larger power of 10. Then you do not need to muck around with numbers of unusual base and can employ a standard library multimap keyed with a decimal number.
Here is a C++ implementation
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
/** Store transormation paths for fast lookup
https://stackoverflow.com/q/70818186/16582
*/
class cTranformation
{
public:
/** add a transformation path
* #param[in] path e.g. "create delete"
* #return 0-based index of instance
*/
int add(const std::string &path);
/** Search for instances with a transformation path
* #param[in] path e.g. "create delete"
* #return vector of instance indices, 0-based
*/
std::vector<int> search(const std::string &path);
private:
/// multimap storage of instances keyed by their hustory number
std::multimap<int, int> mympHistory;
/// vector storage of transormation paths as they were input
std::vector<std::string> myvInput;
/// map transformations indices, keyed by transformation name
std::map<std::string, int> mympTransform;
int makeHistory(const std::string &path);
int transformationIndex(const std::string &transform);
std::vector<std::string> ParseSpaceDelimited(
const std::string &line);
};
int cTranformation::add(const std::string &path)
{
myvInput.push_back(path);
int instance = (int)myvInput.size() - 1;
mympHistory.insert(
std::make_pair(
makeHistory(path),
instance));
return instance;
}
int cTranformation::makeHistory(const std::string &path)
{
// assumes there are less than 10 different transformations
const int base = 10;
int history = 0;
auto steps = ParseSpaceDelimited(path);
for (auto &st : steps)
{
history = base * history + transformationIndex(st);
}
//std::cout << path << " => " << history << "\n";
return history;
}
int cTranformation::transformationIndex(const std::string &transform)
{
int index;
try
{
index = mympTransform.at(transform);
}
catch (...)
{
index = mympTransform.size();
mympTransform[transform] = index;
}
return index;
}
std::vector<int> cTranformation::search(const std::string &path)
{
auto range = mympHistory.equal_range(makeHistory(
path));
std::vector<int> v;
for (auto it = range.first;
it != range.second;
++it)
v.push_back(it->second);
return v;
}
std::vector<std::string> cTranformation::ParseSpaceDelimited(
const std::string &l)
{
std::vector<std::string> token;
std::stringstream sst(l);
std::string a;
while (getline(sst, a, ' '))
token.push_back(a);
token.erase(
remove_if(
token.begin(),
token.end(),
[](std::string t)
{
return (t.empty());
}),
token.end());
return token;
}
int main(int argc, char const *argv[])
{
// construct input transformation paths
std::vector<std::string> vInput{
"create upgrade delete recover change_domain",
"create delete",
"create change_domain delete recover",
"create delete"};
// construct path to search for
std::string searchpath("create delete");
// construction transformation path store
cTranformation T;
// add paths to store
for (auto &p : vInput)
{
T.add(p);
}
// search for instances with a path
auto v = T.search(searchpath);
// display results
std::cout << searchpath << " instances ";
for (int i : v)
std::cout << i << " ";
std::cout << "\n";
return 0;
}
Output is
create delete instances 1 3
#include <memory> // for std::unique_ptr and std::make_unique
#include <iostream>
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction(int numerator, int denominator) :
m_numerator{ numerator }, m_denominator{ denominator }
{
}
friend std::ostream& operator<<(std::ostream& out, const Fraction &f1)
{
out << f1.m_numerator << "/" << f1.m_denominator;
return out;
}
friend operator=(const Fraction &f1,const int numerator,const int denominator){
f1.m_numerator=numerator;
f1.m_denominator=denominator;
}
};
int main()
{
// Create a single dynamically allocated Fraction with numerator 3 and denominator 5
std::unique_ptr<Fraction> f1{ std::make_unique<Fraction>(3, 5) };
std::cout << *f1 << '\n';
// Create a dynamically allocated array of Fractions of length 4
// We can also use automatic type deduction to good effect here
auto f2{ std::make_unique<Fraction[]>(4) };
f2[0]=(3,5);
f2[1]=(67,82,5,543345);
std::cout << f2[0] << '\n';
std::cout << f2[1] << '\n';
return 0;
}
First, operator= can be implemented only as member function, not free function. So your approach is just wrong. Second, overloaded operator= can accept only one parameter. The closest thing you want, can be achived by passing initializer_list as this parameter:
Fraction& operator=(std::initializer_list<int> il){
// some code validating size of il here
this->m_numerator=*il.begin();
this->m_denominator = *(il.begin()+1);
return *this;
}
the use looks like:
f2[0]={3,5};
f2[1]={67,84};
Full demo
I cannot understand what is template class used for?
I am new to c++. Can I get a detail explanation.
// constructing unordered_sets
#include <iostream>
#include <string>
#include <unordered_set>
template<class T>
T cmerge (T a, T b) { T t(a); t.insert(b.begin(),b.end()); return t; }
std::unordered_set<std::string> second ( {"red","green","blue"} ); // init list
std::unordered_set<std::string> third ( {"orange","pink","yellow"} ); // init list
std::unordered_set<std::string> fourth ( second );
std::unordered_set<std::string> fifth ( cmerge(third,fourth) ); // move
C++ template class/function is basically a generic class/function i.e., you just have to define the class or function once and you can use this definition for different data types(int,char,float etc).
for Example:-
#include <iostream>
using namespace std;
// One function works for all data types. This would work
// even for user defined types if operator '>' is overloaded
template <typename T>
T myMax(T x, T y)
{
return (x > y)? x: y;
}
int main()
{
cout << myMax<int>(3, 7) << endl; // Call myMax for int
cout << myMax<double>(3.0, 7.0) << endl; // call myMax for double
cout << myMax<char>('g', 'e') << endl; // call myMax for char
return 0;
}
I have 2 vector container which contains 2 different kind of value with data type uint32_t. I want to print both of them together.
Like this is what I have
vector<uint32_t> data1;
vector<uint32_t> data2;
Now I know a method for single data like below
for(auto const& d1: data1)
cout<< d1 << endl;
But I want to print both data together like this,
cout<< d1 << "\t" << d2 << endl;
How can I do this using auto? (where d2 is auto converted value from data2)
You could use a normal for loop over the index:
for (auto i = 0u; i != n; ++i)
std::cout << data1[i] << "\t" << data2[i] << "\n";
Edit: if you want to convert the uint32_t to an int, for example, you could do:
auto d1 = static_cast<int>(data1[i]);
but it is up to you to ensure the conversion is safe. i.e the value fits in the target type.
Use the Boost Zip Iterator, which will let you have a range of pairs rather than two ranges of the vectors' data types. Something along the lines of:
#include <boost/iterator/zip_iterator.hpp>
#include <boost/range.hpp>
#include <stdint.h>
#include <vector>
#include <iostream>
template <typename... TContainer>
auto zip(TContainer&... containers) -> boost::iterator_range<boost::zip_iterator<decltype(boost::make_tuple(std::begin(containers)...))>> {
auto zip_begin = boost::make_zip_iterator(boost::make_tuple(std::begin(containers)...));
auto zip_end = boost::make_zip_iterator(boost::make_tuple(std::end(containers)...));
return boost::make_iterator_range(zip_begin, zip_end);
}
int main()
{
std::vector<uint32_t> data1( { 11, 22, 33 } );
std::vector<uint32_t> data2( { 44, 55, 66 } );
for (auto t : zip(data1, data2)) {
std::cout << boost::get<0>(t) << "\t" << boost::get<1>(t) << "\n";
}
}
The zip() function is due to this question and you can put it in a separate header file since it's not specific to your case.
If possible (and plausible for your use case): work with a container of pairs
If your application is not in a bind w.r.t. computer resources, and you know that you will be working with the values of your two containers as pairs (assuming same-length containers, as in your example), it might be useful to actually work with a container of pairs, which also ease the use of the neat range-based for loops ( >= C++11).
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<uint32_t> data1 = {1, 2, 3};
std::vector<uint32_t> data2 = {4, 5, 6};
// construct container of (int, int) pairs
std::vector<std::pair<int, int>> data;
data.reserve(data1.size());
std::transform(data1.begin(), data1.end(), data2.begin(), std::back_inserter(data),
[](uint32_t first, uint32_t second) {
return std::make_pair(static_cast<int>(first), static_cast<int>(second));
}); /* as noted in accepted answer: you're responsible for
ensuring that the conversion here is safe */
// easily use range-based for loops to traverse of the
// pairs of your container
for(const auto& pair: data) {
std::cout << pair.first << " " << pair.second << "\n";
} /* 1 4
2 5
3 6 */
return 0;
}
Eigen::Matrix has a setRandom() method which will set all coefficients of the matrix to random values. However, is there a built in way to set all the matrix coefficients to random values while specifying the distribution to use.
Is there a way to achieve something like the following:
Eigen::Matrix3f myMatrix;
std::tr1::mt19937 gen;
std::tr1::uniform_int<int> dist(0,MT_MAX);
myMatrix.setRandom(dist(gen));
You can do what you want using Boost and unaryExpr. The function you pass to unaryExpr needs to accept a dummy input which you can just ignore.
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace boost;
using namespace Eigen;
double sample(double dummy)
{
static mt19937 rng;
static normal_distribution<> nd(3.0,1.0);
return nd(rng);
}
int main()
{
MatrixXd m =MatrixXd::Zero(2,3).unaryExpr(ptr_fun(sample));
cout << m << endl;
return 0;
}
If anyone is coming across this thread, I'm posting an easier answer that is possible nowadays and does not require boost. I found this in an old Eigen Bugzilla Report. All credits go to the author Gael Guennebaud for proposing the following simple method:
#include <Eigen/Sparse>
#include <iostream>
#include <random>
using namespace Eigen;
int main() {
std::default_random_engine generator;
std::poisson_distribution<int> distribution(4.1);
auto poisson = [&] (int) {return distribution(generator);};
RowVectorXi v = RowVectorXi::NullaryExpr(10, poisson );
std::cout << v << "\n";
}
Note that the signature with an int argument of the lambda function is required of Eigen NullaryExpr, despite not being used here in the example.
I had a problem with a similar problem and tried to solve it by using NullaryExpr. But a problem with NullaryExpr is that it cannot be vectorized explicitly. Thus, the solution with NullaryExpr runs quite slowly.
Because of this, I developed EigenRand, an add-on of random distribution for Eigen. I think it will help ones who want to generate random number fast and easily.
#include <Eigen/Dense>
#include <EigenRand/EigenRand>
#include <iostream>
using namespace Eigen;
int main() {
Rand::Vmt19937_64 generator;
// poisson distribution with rate = 4.1
MatrixXi v = Rand::poisson<MatrixXi>(4, 4, generator, 4.1);
std::cout << v << std::endl;
// normal distribution with mean = 3.0, stdev = 1.0
MatrixXf u = Rand::normal<MatrixXf>(4, 4, generator, 3.0, 1.0);
std::cout << u << std::endl;
return 0;
}
Apart the uniform distribution I am not aware of any other types of distribution that can be used directly on a matrix.
What you could do is to map the uniform distribution provided by Eigen directly to your custom distribution (if the mapping exists).
Suppose that your distribution is a sigmoid.
You can map an uniform distribution to the sigmoid distribution using the function y = a / ( b + c exp(x) ).
By temporary converting your matrix to array you can operate element-wise on all values of your matrix:
Matrix3f uniformM;
uniformM.setRandom();
Matrix3f sigmoidM;
sigmoidM.array() = a * ((0.5*uniformM+0.5).array().exp() * c + b).inv();