Eigen: Comparing each element of vector with constant - c++

is there a way how to compare each element of a vector with a constant? So far, I am comparing 2D vector Eigen::Vector2d with a constant double tolerance like this:
if (x(0) > tolerance && x(1) > tolerance)
{
...
}
I have found the function isApprox() but it did not worked somehow. Is there is a nicer or recommended way on how to do it?

One way to do this is to use the array method of the Vector class. Like this:
#include <Eigen/Dense>
#include <iostream>
int main(int argc, char * argv[]) {
Eigen::Vector2d A{ 7.5, 8.2 };
std::cout << A << '\n';
auto res = A.array() >= 8.0;
std::cout << res << '\n';
if (res.all()) {
std::cout << "True" << '\n';
}
else {
std::cout << "False" << '\n';
}
A(0) = 10.2;
auto res2 = A.array() >= 8.0;
std::cout << res2 << '\n';
if (res2.all()) {
std::cout << "True" << '\n';
}
else {
std::cout << "False" << '\n';
}
return 0;
}
In this case res and res2 are CwiseBinaryOp which contains booleans for each element in A. Use all to find when both are True.

I feel like a good call on this one is to write a simple function:
bool is_componentwise_greater_than(
Eigen::Ref<Eigen::VectorXd const> const &vector, double lower_bound) {
for (auto value : vector) {
if (value <= lower_bound)
return false;
}
return true;
}
The drawback of this way compared to the solution by #Matt is, that for more complicated use cases, using an Eigen expression can be more performant (no idea, if this applies here).
The (in my opinion huge) advantage of such an solution is, that you
can see exactly what it does from its usage.
Of course you can also pack Matts solution in an aptly named function to get this advantage. Another advantage is, that with the function I provided you know exactly what it does and never have to wonder, whether using auto with an Eigen type could bite you. I guess it won't and Matt probably knows exactly why. But I (and you?) do not and therefore wouldn't want to rely on it.

Related

CGAL normalize vector

I want to normalize the vectors, yet I could not understand how to do such a basic operation. There does not exist a direct method like Vector_3::normalize().
I call squared_length() and then CGAL::sqr_root() to find the vector length. Then when I want to divide my vector to its length, compiler does not permit since CGAL types are not compatible. Where am I wrong?
I'm expanding here the comment by #MarcGlisse.
There are two scenarios - you want exact calculations or you don't. In the first case you can use the Exact_predicates_exact_constructions_kernel_with_sqrt and the normalized vector will be exact.
In the second case you can use many kernels, but the normalized vector will probably have the length, slightly different from 1. Also some kernels don't have the function CGAL::sqrt at all - however you can always convert squared distances to the double type, using the function CGAL::to_double. Another way is to use a function CGAL::approximate_sqrt, which automatically does this conversion if it's necessary. These conversions make calculations not exact. Please see the example below:
#include <iostream>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
using KernelExactWithSqrt = CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt;
using KernelExact = CGAL::Exact_predicates_exact_constructions_kernel;
using KernelInexact = CGAL::Simple_cartesian<double>;
template <typename T>
auto normalize(T const& V)
{
auto const slen = V.squared_length();
auto const d = CGAL::approximate_sqrt(slen);
return V / d;
}
template <typename T>
auto check()
{
typename T::Point_2 const p{0, 0}, q{1, 1};
auto const n = normalize(typename T::Vector_2{p, q});
return n.squared_length() == 1;
}
int main()
{
std::cout << "====== Exact kernel with square root ======" << std::endl;
std::cout << check<KernelExactWithSqrt>() << std::endl;
std::cout << "====== Inexact kernel ======" << std::endl;
std::cout << check<KernelInexact>() << std::endl;
std::cout << "====== Exact kernel with automatic conversion to double ======" << std::endl;
std::cout << check<KernelExact>() << std::endl;
}
The output:
====== Exact kernel with square root ======
1
====== Inexact kernel ======
0
====== Exact kernel with automatic conversion to double ======
0
So, this example shows that the Exact_predicates_exact_constructions_kernel_with_sqrt guarantees you that the normalized vector will be what you expect.

Determine whether a value is within the maximum range for that data type in c++

What is the correct way to determine if a number (in my case it is a value of power of two calculated by pow(2,n)) is within the limits of values that one variable type can take? I'm doing it like this: if(pow (2,128)>std::numeric_limits<float>::max()), but this is evaluated as true although it is expected that float's maximum value is 2^128 or something more. Is there any better way to do this comparison?
For these kinds of limit checking, you can move the terms around to stay within the limits of the type.
In this case, pow(2,n) == exp(ln(2)*n) mathematically, so, rearranging terms, you can use n > ln(maxval)/ln(2)
You can take the base 2 logarithm of the maximum limit for the type of variable and compare it to n. For example: if(n > std::log2(std::numeric_limits<float>::max()). You probably don't want n to be exactly on the limit though, since I think stuff like floating point error might cause some problems.
First of all can you answer what is the result of pow(2, 128)?
The real question is what is the type for this expression?
The second question is do you know how floating point numbers work?
Take a look on this code to give you a hints:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void printInfo(const std::string& desc, T x)
{
std::cout << desc << ' ' << typeid(x).name() << ' ' << x << std::endl;
}
int main()
{
printInfo("A", std::pow(2, 128));
printInfo("B", std::pow(2.0f, 128));
printInfo("A", std::pow(2, 128.0f));
auto c = std::pow(2.0f, 128.0f);
printInfo("C", c);
std::cout << (c > std::numeric_limits<float>::max()) << std::endl;
std::cout << (c == std::numeric_limits<float>::infinity()) << std::endl;
return 0;
}
https://wandbox.org/permlink/bHdKqToDKdC0hSvW
I recommend review documentation of numeric_limits.
And analyze this code:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void print2exp()
{
std::cout << typeid(T).name() << '\n';
std::cout << "Radix = " << std::numeric_limits<T>::radix << '\n';
auto maxExp = std::numeric_limits<T>::max_exponent;
std::cout << "Max exp = " << maxExp << '\n';
std::cout << "2^maxExp = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp)) << '\n';
std::cout << "2^(maxExp - 1) = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp - 1)) << '\n';
}
int main()
{
print2exp<float>();
print2exp<double>();
print2exp<long double>();
return 0;
}
https://wandbox.org/permlink/J0hACKUKvKlV8lYK
So proper approach to this is (assuming that radix is 2):
if (x < std::numeric_limits<T>::max_exponent) {
return std::pow(static_cast<T>(2), static_cast<T>(x));
} else {
throw invalid_argument("x is to big to be use as 2^x");
}

Read and write different types in vector

How can I pack in a vector several different primitive data types as well as strings to examine the contents then?
(In Java, this went via Object [] objects = {1.0, "Hello", - 42, 'b'})
The task is as follows:
Given the following array: [3.0,42, "Monkey", 7.2, b]
This array is to be passed to a method that outputs the contents of the array on the console. If it is a string, each letter of the string should be added as an ASCII value in the same variable, and finally returned as an int on the console. With char exactly the same.
I know from today as I create a vector so with std::vector<double> numbers = {1.0,2.0}; How to write functions and how to access the indexes numbers[i]; as well as the length of the vector numbers.size().
How can I solve this problem now? Since I have unfortunately found no simple <- solution for the multiple types in a vector.
Thanks in advance :)
C++ does not do type erasure the same way that Java does. To create a heterogeneous container (which is the technical term for what you're trying to do) you'll need to make extensive use of std::any or std::variant, which are new classes introduced with C++17.
std::vector<std::any> values{1.0, "Hello", -42, 'b'};
for(auto & any : values) {
int * i;
if(val = std::any_cast<int>(&any)) std::cout << "int: " << *i << std::endl;
const char ** s;
if(s = std::any_cast<const char *>(&any)) std::cout << "string-literal: " << *s << std::endl;
double * d;
if(d = std::any_cast<double>(&any)) std::cout << "double: " << *d << std::endl;
char * c;
if(c = std::any_cast<char>(&any)) std::cout << "char: " << *c << std::endl;
}
Note how messy that code is. Not least of which because many people would desire "hello" to be stored as a std::string object, but this can't be done unless the user expressly designates it as such:
std::vector<std::any> values{1.0, std::string{"Hello"}, -42, 'b'};
At any rate, my personal opinion is that the use of std::variant would be a much better fit, as you can make it much clearer how the container is meant to be used, and you can avoid the dynamic allocations associated with std::any:
typedef std::variant<std::string, char, double, int> my_variant;
struct visitor {
void operator()(std::string const& v) const {
std::cout << "std::string: " << v<< std::endl;
}
void operator()(double const& v) const {
std::cout << "double: " << v << std::endl;
}
void operator()(int const& v) const {
std::cout << "int: " << v << std::endl;
}
void operator()(char const& v) const {
std::cout << "char: " << v << std::endl;
}
};
int main() {
std::vector<my_variant> values{1.0, "Hello", -42, 'b'};
for(my_variant & variant : values) {
std::visit(visitor{}, variant);
}
return 0;
}
We can even make the variant version a lot simpler with auto lambdas if we don't need to know the type:
typedef std::variant<std::string, char, double, int> my_variant;
int main() {
std::vector<my_variant> values{1.0, "Hello", -42, 'b'};
for(my_variant & variant : values) {
std::visit(
[](auto const& val) {std::cout << "Some unknown type: " << val << std::endl;},
variant
);
}
return 0;
}
I haven't run this through my compiler, but this should give a pretty good sense of how to accomplish this kind of task in C++.
If you don't have access to C++17, you can use boost.any and boost.variant, which I'm reasonably sure are both header-only libraries, and thus easy to import into your project.

Skip first iteration over unordered_map

In a for loop with auto, an iterator iterates over an unordered_map. Like this:
using RuleIndex = std::unordered_map<uint, Symbol*>;
RuleIndex rule_index;
for(const auto & rule_pair : rule_index ) {
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
Assume all variables are defined properly, since the code works fine. My question, how can I exclude the first iteration? For example, the map contains 3 rows and current loop iterates for 0, 1, 2. I want to iterate over 1 and 2 only.
bool is_first_iteration = true;
for(const auto & rule_pair : rule_index) {
if (std::exchange(is_first_iteration, false)) continue;
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
The std::exchange call assigns false to is_first_iteration and returns the previous value. This is actually one of the use cases discussed in the paper proposing std::exchange for C++14. That paper also shows a reference implementation you can use if you are stuck with C++11.
If you can't use std::exchange (due to C++11 restriction), this simple solution could work as well:
bool is_first_iteration = true;
for (const auto & rule_pair : rule_index)
{
if (is_first_iteration)
{
is_first_iteration = false;
continue;
}
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
A terse C++11 option I sometimes use, which keeps a sometimes-handy counter too. I've shown if (i++) below which relies on 0's conversion to false while other numbers convert to true, but you could put if (++i > 1) if you were more comfortable with that:
size_t i = 0;
for (const auto & rule_pair : rule_index)
if (i++)
{
...
}
...or if (++i == 1) continue;... if you prefer...
While easy to write, concise and sometimes helpful, these may be less ammenable to optimisation than a boolean version - benchmark if you care.
Yet another approach that's sometimes useful:
for (const auto & rule_pair : rule_index)
if (&rule_pair != &*std::begin(rule_index))
{
...
}

Printing a pointer-to-member-field

I was debugging some code involving pointers to member fields, and i decided to print them out to see their values. I had a function returning a pointer to member:
#include <stdio.h>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
I tried using cout:
#include <iostream>
int main()
{
std::cout << select(0) << " and " << select(3) << '\n';
}
I got 1 and 0. I thought the numbers indicated the position of the field inside the struct (that is, 1 is y and 0 is x), but no, the printed value is actually 1 for non-null pointer and 0 for null pointer. I guess this is a standard-compliant behavior (even though it's not helpful) - am i right? In addition, is it possible for a compliant c++ implementation to print always 0 for pointers-to-members? Or even an empty string?
And, finally, how can i print a pointer-to-member in a meaningful manner? I came up with two ugly ways:
printf("%d and %d\n", select(0), select(3)); // not 64-bit-compatible, i guess?
ptr_to_member temp1 = select(0); // have to declare temporary variables
ptr_to_member temp2 = select(3);
std::cout << *(int*)&temp1 << " and " << *(int*)&temp2 << '\n'; // UGLY!
Any better ways?
Pointers to members are not as simple as you may think. Their size changes from compiler to compiler and from class to class depending on whether the class has virtual methods or not and whether it has multiple inheritance or not. Assuming they are int sized is not the right way to go. What you can do is print them in hexadecimal:
void dumpByte(char i_byte)
{
std::cout << std::hex << static_cast<int>((i_byte & 0xf0) >> 4);
std::cout << std::hex << static_cast<int>(i_byte & 0x0f));
} // ()
template <typename T>
void dumpStuff(T* i_pStuff)
{
const char* pStuff = reinterpret_cast<const char*>(i_pStuff);
size_t size = sizeof(T);
while (size)
{
dumpByte(*pStuff);
++pStuff;
--size;
} // while
} // ()
However, I'm not sure how useful that information will be to you since you don't know what is the structure of the pointers and what each byte (or several bytes) mean.
Member pointers aren't ordinary pointers. The overloads you expect for << aren't in fact there.
If you don't mind some type punning, you can hack something up to print the actual values:
int main()
{
ptr_to_member a = select(0), b = select(1);
std::cout << *reinterpret_cast<uint32_t*>(&a) << " and "
<< *reinterpret_cast<uint32_t*>(&b) << " and "
<< sizeof(ptr_to_member) << '\n';
}
You can display the raw values of these pointer-to-members as follows:
#include <iostream>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
int main()
{
ptr_to_member x = select(0) ;
ptr_to_member y = select(1) ;
ptr_to_member z = select(2) ;
std::cout << *(void**)&x << ", " << *(void**)&y << ", " << *(void**)&z << std::endl ;
}
You get warnings about breaking strict anti-aliasing rules (see this link), but the result is what you might expect:
0, 0x4, 0x8
Nevertheless, the compiler is free to implement pointer-to-member functionality however it likes, so you can't rely on these values being meaningful.
I think you should use printf to solve this problen
#include <stdio.h>
struct test{int x,y,z;}
int main(int argc, char* argv[])
{
printf("&test::x=%p\n", &test::x);
printf("&test::y=%p\n", &test::y);
printf("&test::z=%p\n", &test::z);
return 0;
}