Registered Member
|
I am working with Eigen 3 to do linear algebra for a numerical algebraic geometry tool, and am using my own complex class wrapped around Boost.Multiprecision's mpfr_float class. I can use Eigen to do LU solves on linear algebra problems using my own type, and it passes my tests. What I am stuck on now is computing the norm of a vector.
Here's my code calling norm():
I have defined the NumTraits for mpfr_float, and for my own type, the bertini::complex. I further implemented what I believed were the necessary free functions on my complex type, including abs and abs2. Yet, the compiler error seems to refer to the abs2 function, and complains that it wants a conversion to mpfr_float from complex. This is despite my abs2(bertini::complex) function returning an mpfr_float. Here is the compiler error I get:
I feel like I am missing something. In my searching for a solution to this problem, I saw other similar posts (but none exactly dealing with this particular compiler error) where the user was instructed to consult the MathFunctions.h file. In other posts, it seems like users were instructed to provide ei_abs and other related functions. I add that my abs() and other functions are given in my bertini:: namespace, the same in which the class is defined. I further provide them as both free and member functions for my complex class. What am I missing? Or, more precisely, what is the set of (names of) functions I need to provide for my number class in order to get 100% compatibility with Eigen? Looking at the online documentation for NumTraits<> and MathFunctions.h has not been enough for me. Do I have to provide ei_*() functions? For bonus points, help me provide the correct function for using the Eigen::...::Random(bla) function to generate random matrices. |
Moderator
|
You probably have to add something like:
In the future, we should replace calls like "numext::abs2(x);" to "using numext::abs2; abs2(x);" so that your overload of abs2 can be accessible. And/or maybe we could specialize for NumTraits<Scalar>::IsComplex instead of std::complex so that our own implementation can work on arbitrary complex types providing real()/imag() accessors. btw, why cannot you directly use std::complex<mpfr_float > ? |
Registered Member
|
because std::complex only supports float, double, and long double. while you can stuff a boost::multiprecision::mpfr_float in there, the internal fields will convert into low-precision numbers (double, etc) when computing things like abs(). not only that, but it will do so silently, with no warning that the resulting computation is essentially garbage. that is, the std::implementation does not use overloading based on templated type in all functions except for with the three standard floating types. i currently view this as the major failure of the standard double type. at least it is clearly documented, e.g. at http://en.cppreference.com/w/cpp/numeric/complex, where it says (types from previous paragraph added by me) As far as the actual fix in Eigen you self-suggest,
I had believed (assumed) before reading MathFunctions that this was the case -- it is not documented that implementation is contrary. As a consequence, I have struggled to get all the bits and pieces into place for my own complex number type. Now I am having problems with negation of a vector... But I will ask about it separately if I cannot solve it myself by reading MathFunctions.hpp. Perhaps the thing I struggle with the most in extending Eigen to work with bertini::complex is that there is no authoritative and comprehensive list of dependencies of Eigen methods on implementations of specializations. That is, I still yearn to be able to look at a single webpage, and read off exactly what I have to add to my code in the eigen:: namespace in order to achieve 100% compatibility with Eigen, including vectorization and other features. Even the NumTraits documentation is pretty incomplete. In absence of my desired list, I thank you for your quick reply. For now, I was able to get my code to compile by adding the following in the Eigen:: namespace:
If the above code is incorrect or violates principles of Eigen, I would appreciate a response so indicating, so that it doesn't make it into production code. I conjecture that I am not done with my class and Eigen yet, as there are other similar structs I have not implemented for my type... Perhaps you could speak to that? Thanks again for your time! |
Moderator
|
for the record, this was done in changeset 1ff681424639 |
Registered users: bartoloni, Bing [Bot], Evergrowing, Google [Bot], q.ignora