I can't do:
Vector2i vec(0, 1, 2);
cout << vec.norm() << endl;
as it gives a compiler error which mentions: THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES in some failing assertion.
I could do:
Vector2i i_vec(0, 1, 2);
Vector2f f_vec;
f_vec = i_vec.cast<float>();
cout << f_vec.norm() << endl;
which works obviously.
Question: Any reason why the norm method isn't defined for VectorXi?
Maybe Eigen uses the element type of the Vector to determine the return type for norm() (in which case it makes sense that norm() wouldn't be defined for a return type of int)?
Just curious.
If I remember the action of a norm() function correctly, it takes a square root of some input. Square root, obviously, is non-integer in many cases. On the other hand, if I remember logic of eigen package, once you have declared a matrix of particular elements (int, double, complex<double>), it works with elements of this type only. So you were absolutely right with your suggestion.
Related
Given an array of bytes, there are several well-known good algorithms for calculating a hash code, such as FNV or MD5. (Not talking about cryptography here, just general purpose hash codes.)
Suppose what you have is an array of bytes plus one extra piece of information, a small integer (which is not located next to the array in memory), and you want a hash code based on the whole lot. What's the best way to do this? For example, one could take the hash code of the array and add it to the small integer, or exclusive-or them. But is there a better way?
I think, more easiest and efficient way - just init "hash" accumulator with your small value, and thereafter compute hash by ordinary way.
Following example illustrates my approach, where we compute hash from int and C-style string:
uint32_t hash(const char *str, uint32_t x) {
char c;
while((c = *str++) != 0)
x = ((x << 5) | (x >> (32 - 5))) + c;
return x ^ (x >> 16);
}
I am working with Eigen Eigen. I have a sparse Matrix defined by a set of Triplet and I would like to print the Matrix in a formatted way. I have seen that it is possible with ordinary Matrix by doing Matrix.format(FORMAT_TYPE) Eigen: IOFormat. But i do not find a way to do the same for sparse Matrix. I would like to obtain an output like the Matlab output for matrices.
Many thanks in advance.
To get nice formatting, you need to first convert it to a dense matrix:
SparseMatrix<double> spmat;
...
std::cout << MatrixXd(spmat) << std::endl;
Probably not of interest for the OP anymore, but I came here via Google and so others will maybe too...
It's not pratical to print the whole sparse matrix directly, because they are usually very big. The block operator works for sparse also, so you can do something like:
int nElements = 10;
std::cout <<
compMat.block( compMat.rows() - nElements, compMat.cols() - nElements, nElements, nElements )
<< std::endl;
to print the last 10 elements in the bottom right corner of a square sparse matrix.
This takes 6ms in release mode on my machine.
The following code does the same on the full matrix with roughly 35000*35000 entries, but takes ~25000ms...
int nElements = 10;
std::cout <<
Eigen::MatrixXd( compMat ).block( compMat.rows() - nElements, compMat.cols() - nElements, nElements,
nElements )
<< std::endl;
#include <iostream>
int main()
{
for (int i = 0; i < 4; ++i)
std::cout << i*5000000000 << std::endl;
}
getting a warning from gcc whenever i try to run this.
:-
warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations]
std::cout << i*5000000000 << std::endl;
Whats the cause of this error?
Signed integer overflow (as strictly speaking, there is no such thing as "unsigned integer overflow") means undefined behaviour.
Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.I suspect that it's something like: (1) because every iteration with i of any value larger than 2 has undefined behavior -> (2) we can assume that i <= 2 for optimization purposes -> (3) the loop condition is always true -> (4) it's optimized away into an infinite loop.
What is going on is a case of strength reduction, more specifically, induction variable elimination. The compiler eliminates the multiplication by emitting code that instead increments i by 1e9 each iteration (and changing the loop condition accordingly). This is a perfectly valid optimization under the "as if" rule as this program could not observe the difference were it well-behaving. Alas, it's not, and the optimization "leaks"
How can i initialize a 2D vector using an initialization list?
for a normal vector doing :
vector<int> myvect {1,2,3,4};
would suffice. But for a 2D one doing :
vector<vector<int>> myvect{ {10,20,30,40},
{50,60,70,80}
};
What is a correct way of doing it?
And how can i iterate through it using for?
for(auto x: myvect)
{
cout<<x[j++]<<endl;
}
this for only shows:
10,1 !
And by the way what does this mean ?
vector<int> myvect[5] {1,2,3,4};
i saw it here and cant understand it! Link
What is a correct way of doing it?
The way you showed is a possible way. You could also use:
vector<vector<int>> myvect = { {10,20,30,40},
{50,60,70,80} };
vector<vector<int>> myvect{ vector<int>{10,20,30,40},
vector<int>{50,60,70,80} };
The first one constructs a std::initializer_list<std::vector<int>> where the elements are directly initialized from the inner braced-initializer-lists. The second one explicitly constructs temporary vectors which then are moved into a std::initializer_list<std::vector<int>>. This will probably not make a difference, since that move can be elided.
In any way, the elements of the std::initializer_list<std::vector<int>> are copied back out into myvect (you cannot move out of a std::initializer_list).
And how can i iterate through it using for?
You essentially have a vector of vectors, therefore you need two loops:
for(vector<int> const& innerVec : myvect)
{
for(int element : innerVec)
{
cout << element << ',';
}
cout << endl;
}
I refrained from using auto to explicitly show the resulting types.
And by the way what does this mean ?
This is probably a typo. As it stands, it's illegal. The declaration vector<int> myvect[5]; declares an array of 5 vector<int>. The following list-initialization therefore needs to initialize the array, but the elements of this list are not implicitly convertible to vector<int> (there's a ctor that takes a size_t, but it's explicit).
That has already been pointed out in the comments of that side.
I guess the author wanted to write std::vector<int> vArray = {3, 2, 7, 5, 8};.
For a std::for_each call, is it legal to have both iterators be the end iterator? For example,
std::vector<int> some_ints;
std::for_each(ints.end(), ints.end(), [&](int i) {
std::cout << i;
});
Yes this is perfectly legal and produces an empty range. The result will be that nothing happens but the behavior is well defined.
Here is a relevant quote from the SGI reference page on iterators and their use as ranges (Documentation)
Most algorithms are expressed not in terms of a single iterator but in terms of a range of iterators; the notation [first, last) refers to all of the iterators from first up to, but not including, last. Note that a range may be empty, i.e. first and last may be the same iterator.