Mixing Scalar Types in Eigen - eigen

#include <iostream>
#include <Eigen/Core>
namespace Eigen {
// float op double -> double
template <typename BinaryOp>
struct ScalarBinaryOpTraits<float, double, BinaryOp> {
enum { Defined = 1 };
typedef double ReturnType;
};
// double op float -> double
template <typename BinaryOp>
struct ScalarBinaryOpTraits<double, float, BinaryOp> {
enum { Defined = 1 };
typedef double ReturnType;
};
}
int main() {
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> m1(2, 2);
m1 << 1, 2, 3, 4;
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> m2(2, 2);
m2 << 1, 2, 3, 4;
std::cerr << m1 * m2 <<std::endl; // <- boom!!
}
I'd like to know why the above code does not compile. Here is the full error messages. Please note that if I define m1 and m2 to have fixed sizes, it works fine.
I'm using Eigen3.3.1. It's tested on a Mac running OSX-10.12 with Apple's clang-800.0.42.1.

This is because the general matrix-matrix product is highly optimized with aggressive manual vectorization, pipelining, multi-level caching, etc. This part does not support mixing float and double. You can bypass this heavily optimized implementation with m1.lazyProduct(m2) that corresponds to the implementations used fro small fixed-size matrices, but there is only disadvantages of doing so: the ALUs does not support mixing float and double, so float values have to be promoted to double anyway and you will loose vectorization. Better cast the float to double explicitly:
m1.cast<double>() * m2

Related

Variadic Template Recursion

I am trying to use recursion to solve this problem where if i call
decimal<0,0,1>();
i should get the decimal number (4 in this case).
I am trying to use recursion with variadic templates but cannot get it to work.
Here's my code;
template<>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a*2 + decimal<pack...>();
};
int main(int argc, char *argv[]){
cout<<decimal<0,0,1>()<<endl;
return 0;
}
What would be the best way to solve this?
template<typename = void>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a + 2*decimal<pack...>();
};
The problem was with the recursive case, where it expects to be able to call decltype<>(). That is what I have defined in the first overload above. You can essentially ignore the typename=void, the is just necessary to allow the first one to compile.
A possible solution can be the use of a constexpr function (so you can use it's values it's value run-time, when appropriate) where the values are argument of the function.
Something like
#include <iostream>
constexpr int decimal ()
{ return 0; }
template <typename T, typename ... packT>
constexpr int decimal (T const & a, packT ... pack)
{ return a*2 + decimal(pack...); }
int main(int argc, char *argv[])
{
constexpr int val { decimal(0, 0, 1) };
static_assert( val == 2, "!");
std::cout << val << std::endl;
return 0;
}
But I obtain 2, not 4.
Are you sure that your code should return 4?
-- EDIT --
As pointed by aschepler, my example decimal() template function return "eturns twice the sum of its arguments, which is not" what do you want.
Well, with 0, 1, true and false you obtain the same; with other number, you obtain different results.
But you can modify decimal() as follows
template <typename ... packT>
constexpr int decimal (bool a, packT ... pack)
{ return a*2 + decimal(pack...); }
to avoid this problem.
This is a C++14 solution. It is mostly C++11, except for std::integral_sequence nad std::index_sequence, both of which are relatively easy to implement in C++11.
template<bool...bs>
using bools = std::integer_sequence<bool, bs...>;
template<std::uint64_t x>
using uint64 = std::integral_constant< std::uint64_t, x >;
template<std::size_t N>
constexpr uint64< ((std::uint64_t)1) << (std::uint64_t)N > bit{};
template<std::uint64_t... xs>
struct or_bits : uint64<0> {};
template<std::int64_t x0, std::int64_t... xs>
struct or_bits<x0, xs...> : uint64<x0 | or_bits<xs...>{} > {};
template<bool...bs, std::size_t...Is>
constexpr
uint64<
or_bits<
uint64<
bs?bit<Is>:std::uint64_t(0)
>{}...
>{}
>
from_binary( bools<bs...> bits, std::index_sequence<Is...> ) {
(void)bits; // suppress warning
return {};
}
template<bool...bs>
constexpr
auto from_binary( bools<bs...> bits={} )
-> decltype( from_binary( bits, std::make_index_sequence<sizeof...(bs)>{} ) )
{ return {}; }
It generates the resulting value as a type with a constexpr conversion to scalar. This is slightly more powerful than a constexpr function in its "compile-time-ness".
It assumes that the first bit is the most significant bit in the list.
You can use from_binary<1,0,1>() or from_binary( bools<1,0,1>{} ).
Live example.
This particular style of type-based programming results in code that does all of its work in its signature. The bodies consist of return {};.

C++ Tuples and Readability

I think this is more of a philosophical question about readability and tupled types in C++11.
I am writing some code to produce Gaussian Mixture Models (the details are kind of irrelevant but it serves and a nice example.) My code is below:
GMM.hpp
#pragma once
#include <opencv2/opencv.hpp>
#include <vector>
#include <tuple>
#include "../Util/Types.hpp"
namespace LocalDescriptorAndBagOfFeature
{
// Weighted gaussian is defined as a (weight, mean vector, covariance matrix)
typedef std::tuple<double, cv::Mat, cv::Mat> WeightedGaussian;
class GMM
{
public:
GMM(int numGaussians);
void Train(const FeatureSet &featureSet);
std::vector<double> Supervector(const BagOfFeatures &bof);
int NumGaussians(void) const;
double operator ()(const cv::Mat &x) const;
private:
static double ComputeWeightedGaussian(const cv::Mat &x, WeightedGaussian wg);
std::vector<WeightedGaussian> _Gaussians;
int _NumGaussians;
};
}
GMM.cpp
using namespace LocalDescriptorAndBagOfFeature;
double GMM::ComputeWeightedGaussian(const cv::Mat &x, WeightedGaussian wg)
{
double weight;
cv::Mat mean, covariance;
std::tie(weight, mean, covariance) = wg;
cv::Mat precision;
cv::invert(covariance, precision);
double detp = cv::determinant(precision);
double outter = std::sqrt(detp / 2.0 * M_PI);
cv::Mat meanDist = x - mean;
cv::Mat meanDistTrans;
cv::transpose(meanDist, meanDistTrans);
cv::Mat symmetricProduct = meanDistTrans * precision * meanDist; // This is a "1x1" matrix e.g. a scalar value
double inner = symmetricProduct.at<double>(0,0) / -2.0;
return weight * outter * std::exp(inner);
}
double GMM::operator ()(const cv::Mat &x) const
{
return std::accumulate(_Gaussians.begin(), _Gaussians.end(), 0, [&x](double val, WeightedGaussian wg) { return val + ComputeWeightedGaussian(x, wg); });
}
In this case, am I gaining anything (clarity, readability, speed, ...) by using a tuple representation for the weighted Gaussian distribution over using a struct, or even a class with its own operator()?
You're reducing the size of your source code a little bit, but I'd argue that you're reducing its overall readability and type safety. Specifically, if you defined:
struct WeightedGaussian {
double weight;
cv::Mat mean, covariance;
};
then you wouldn't have a chance of writing the incorrect
std::tie(weight, covariance, mean) = wg;
and you'd guarantee that your users would use wg.mean instead of std::get<0>(wg). The biggest downside is that std::tuple comes with definitions of operator< and operator==, while you have to implement them yourself for a custom struct:
operator<(const WeightedGaussian& lhs, const WeightedGaussian& rhs) {
return std::tie(lhs.weight, lhs.mean, lhs.covariance) <
std::tie(rhs.weight, rhs.mean, rhs.covariance);
}

c++ 11. Matrices multiplication

Hello. I write matrix class but i have some problem with matrices multiplication which have different dimensions.
template< typename T, size_t Row, size_t Col >
class Matrix
{
public:
.....................................
template< typename MulT >
auto operator * (const MulT& other) -> Matrix<T, Row, other.getColNum()>
{
if (other.getRowNum() != getColNum())
throw std::logic_error("Multiplication are not possible");
Matrix<T, Row, other.getColNum()> temp;
// Some operations.
return temp; // Must return matrix with this type Matrix<T, Row, other.getColNum()>
// but it dont work.
}
.....................................
}; // class Matrix
This code don't work. It is possible to resolve this problem?
other.getColNum() is probably not a constexpr function and can therefore not be used as a template non-type argument.
Read up on constexpr here: http://en.cppreference.com/w/cpp/language/constexpr
You don't want to check the if if (other.getRowNum() != getColNum()) at runtime, this should be done at compile time. One way to do this is to define the operator only for when the multiplication is valid. In this case:
template< typename T, size_t Row, size_t Col >
class Matrix
{
public:
.....................................
template<size_t _RHSWIDTH>
Matrix<_T, _RHSWIDTH, Row> operator * (const Matrix<T, _RHSWIDTH, Col> &rhs) const
{
Matrix<_T, _RHSWIDTH, Row> temp;
// Some operations.
return temp;
}
.....................................
}; // class Matrix
As a result, any attempt to multiply matrices which cannot be multiplied will fail at compile time. For a complete example, I wrote a complete matrix template a long time ago which uses very similar syntax: https://github.com/Enseed/GenericGeometry/blob/master/Matrix.h

constexpr template functions don't see member array sizes as const expressions

Both clang and gcc fail to compile the code below when ArrayCount is a template. This seems wrong, especially in light of the fact that the sizeof ArrayCount solution work. The template version of ArrayCount is normally a better solution, but it's getting in the way here and constexpr is seemingly not living up to the spirit of its promise.
#if 1
template<typename T, size_t N>
constexpr size_t ArrayCount(T (&)[N])
{
return N;
}
// Results in this (clang): error : static_assert expression is not an integral constant expression
// Results in this (gcc): error: non-constant condition for static assertion, 'this' is not a constant expression
#else
#define ArrayCount(t) (sizeof(t) / sizeof(t[0]))
// Succeeds
#endif
struct X
{
int x[4];
X() { static_assert(ArrayCount(x) == 4, "should never fail"); }
};
The right solution doesn't use homebrew code, but a simple type trait:
int a[] = {1, 2, 3};
#include <type_traits>
static_assert(std::extent<decltype(a)>::value == 3, "You won't see this");
It makes sense to me that this code would fail to compile since ArrayCount is a function taking a non-constexpr argument. According to the standard, I believe this means that ArrayCount must be intstantiated as a non-constexpr function.
There are workarounds, of course. I can think of two off the top of my head (one implemented in terms of the other):
template<typename T> struct ArrayCount;
template<typename T, size_t N>
struct ArrayCount<T[N]> {
static size_t const size = N;
};
template<typename T>
constexpr size_t ArrayCount2() {
return ArrayCount<T>::size;
}
struct X {
int x[4];
X() {
static_assert(ArrayCount<decltype(x)>::size == 4, "should never fail");
static_assert(ArrayCount2<decltype(x)>() == 4, "should never fail");
}
};
It does mean having to use decltype() when you might not wish to, but it does break the pro-forma constraint on taking a non-constexpr parameter.

C++11: std::max(a,b) in static_assert()?

I noticed, that in [24.4.7] of the last C++-Std Doc N3291 max ist not constexpr:
template<class T> const T& max(const T& a, const T& b);
Therefore, it is not allowed to use it in a static_assert for example. Correct?
static_assert( max(sizeof(int),sizeof(float)) > 4, "bummer" );
That is correct.
I imagine the reason is simply that std::max calls T::operator< for an arbitrary type T and for std::max to be constexpr, it would require T::operator< to be constexpr, which is unknown.
This is correct; std::min and std::max are not constexpr, not even in the latest draft of C++14 (N3690), so they cannot be used within constant expressions.
There is no good reason for this, only bad reasons. The most significant bad reason is that the C++ committee is composed of individuals who have a limited amount of time to work on standardization, and no-one has put in the work required to make these functions constexpr yet.
Note N3039, a change to the C++ standard adopted in 2010, that slightly extended the constexpr facility specifically so that function such as min and max could be made constexpr.
You can work around this by defining your own min and max functions:
template<typename T>
constexpr const T &c_min(const T &a, const T &b) {
return b < a ? b : a;
}
template<typename T, class Compare>
constexpr const T &c_min(const T &a, const T &b, Compare comp) {
return comp(b, a) ? b : a;
}
template<typename T>
constexpr const T &c_min_impl(const T *a, const T *b) {
return a + 1 == b ? *a : c_min(*a, c_min_impl(a + 1, b));
}
template<typename T>
constexpr T c_min(std::initializer_list<T> t) {
return c_min_impl(t.begin(), t.end());
}
// ... and so on
this works on c++ 11
template<const Sz a,const Sz b> constexpr Sz staticMax() {return a>b?a:b;}
use:
staticMax<a,b>()
and of course a and b must be constexpr

Resources