I downloaded some opensource using lapack/blas and i want to change that into Eigenbased source for auto SIMD code generation.
Is there any function in Eigen library same as dsyev in LAPACK.
dsyve returns info value for several purposes.
but as far as i know, eigensolver in Eigen library returns eigenvalue or eigenvector.
Is there a function what i want in Eigen library.
I think what you want is .info(), as well as other APIs provided by SelfAdjointEigenSolver.
The tutorial page also shows how to use it.
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix2f A;
A << 1, 2, 2, 3;
cout << "Here is the matrix A:\n" << A << endl;
SelfAdjointEigenSolver<Matrix2f> eigensolver(A);
if (eigensolver.info() != Success) abort();
cout << "The eigenvalues of A are:\n" << eigensolver.eigenvalues() << endl;
cout << "Here's a matrix whose columns are eigenvectors of A \n"
<< "corresponding to these eigenvalues:\n"
<< eigensolver.eigenvectors() << endl;
}
If you really want to know the details of NoConvergence as reported by dsyev(), you may have to use the low-level LAPACK API.
This function returns a value info.
If info=0, the execution is successful.
If info = -i, the i-th parameter had an illegal value.
If info = i, then the algorithm failed to converge; i indicates the
number of elements of an intermediate tridiagonal form which did not
converge to zero.
Related
I'm using eigen to do some matrix operation, but the compile time for the src files using eigen is very slow, by slow I mean it take about 40s when the file is only 300 lines. I only use Matrix smaller than Matrix4f and not even use dynamic size matrix, for only some matrix multiplication and matrix decomposition(SVD and FullPivLU).
In my other project where a cpp file is 1000 lines, it take minutes to compile, and the output .so file is really big, about 100M. I have to open the -bigobj choice.
This happens both in debug(where I set the opimization to -O0) and release(-O3) mode. I've tried add #define NDEBUG and EIGEN_NO_DEBUG in the header, not help.
I write this piece of very small code test.cpp below:
#include </home/user/mywork/software/eigen-3.3.9/Eigen/Dense>
#include "iostream"
using namespace std;
using namespace Eigen;
void test()
{
Matrix3f A;
A << 1,2,3,4,2,8,5,4,9;
BDCSVD<Matrix3f> svd(A, ComputeFullU | ComputeFullV);
Matrix3f U = svd.matrixU();
Matrix3f V = svd.matrixV();
cout << "------Eigen------" << endl;
cout << "A" << A << endl;
cout << "U" << U << endl;
cout << "V" << V << endl;
}
int main()
{
test();
return 0;
}
compile command
g++ test.cpp -o test_eigen
it take 20s to compile, and the output 'test_eigen' is 5.6M!!!
my os is ubuntu 16.04 and I use cmake, in the CMakelist, only thing related to eigen is include its directory. eigen version is 3.3.9.
does anyone have any clue? Thanks a lot.
Eigen consists of 7.8MB of pure header files. So any .cpp including it will have a hard life compiling (uses giga-bytes of memory and extremely slow). In addition, due to extensive use of templates and inline functions, the DEBUG version will be so slow and unusable for debug purpose. (For example, google's Cartographer will warn about debug version) and I also made some tests.
So I think Eigen should be used as follow:
Encapsulate Eigen. Create simple interface according to your own needs. (For example, create matrix_4x4.h, vector4.h, standard_deviation_calculaor.h, etc.) Include Eigen only in .cpp files. The exposed .h files will be so simple and will not propagate to slow down compiling of other files.
Proper Modularization. Precompile the library into static/shared libraries. And use the simple headers in other parts of your program.
Restrain Use eigen only in performance-critical parts of my program. For example, the following function will not use eigen and should be inlined(exposed in header):
// vector3.h
inline Vector3 operator + (const Vector3& l, const Vector3& r) {
return Vector3(l.x + r.x, l.y + r.y, l.z + r.z);
}
But Matrix4x4::multiplyInplace(const Matrix4x4& r) will be
implemented in .cpp and use Eigen.
I want to read a binary file in 16 bit words. Right now, I'm using an std::ifstream to read into a 2 character array c.
#include <iostream>
#include <fstream>
#include <stdint.h>
int main() {
std::ifstream file("./tetris.rom", std::ios::in | std::ios::binary);
char c[2];
while (file.read(c, 2)) {
uint16_t word = (static_cast<uint8_t>(c[0]) << 8) | static_cast<uint8_t>(c[1]);
std::cout << "word\t" << std::hex << word << std::endl;
}
}
This works for me, but is there a better (either safer or faster) way of doing this in C++11?
There are no new APIs of reading files in C++11.
If the file fits into your RAM, the most optimal way is to map it into memory and access it as a byte array. However, the C++ standard library does not provide an API for that. You can do that with Boost though, see Boost.Interprocess Memory Mapped Files.
The usual advice stands though: start with your simple and correctly working code, benchmark and see if file reading is the bottleneck.
I am trying to do arbitrary precision arithmetic combined with the nice array syntax from blitz++. My problem is, that the generic math functions like cos, exp and so on don't work:
#include <blitz/array.h>
#include <boost/multiprecision/float128.hpp>
using namespace boost::multiprecision;
using namespace blitz;
int main() {
float128 a = 1;
a = cos(a);
cout << a << endl;
Array<float128,3> myarray(2,3,4);
myarray = 1;
myarray = cos(myarray);
cout << myarray;
}
g++ test.cpp -lquadmath -o test
The first block, using only float128 but not blitz, works fine. The second block with blitz however won't do the cos(myarray). The compiler seemingly figures out the iteration, but can not find the function to do the actual cos(x) for the values: Compiler error log
I would also like to use boost::multiprecision::mpfr, but one thing at a time. I hope someone can help.
I have found a solution, but it involves patching blitz. I have written this patch for blitz-0.10 and with the modified blitz the above code just works.
C++11
I'm having trouble using the move constructor. I have a simple container class, called Number, whose only data member is an integer. I have the following code:
//Number.h
#ifndef NUMBER_H
#define NUMBER_H
#include <iostream>
class Number
{
public:
Number();
Number(int ipar);
Number(const Number& src);
Number(Number&& src);
private:
int num;
};
#endif
and
//Number.cpp
#include "Number.h"
Number::Number()
{
std::cout << "default ctor" << std::endl;
}
Number::Number(int ipar) : num(ipar)
{
std::cout << "integer argument ctor" << std::endl;
}
Number::Number(const Number& src) : num(src.num)
{
std::cout << "copy ctor" << std::endl;
}
Number::Number(Number&& src) : num(src.num)
{
std::cout << "move ctor" << std::endl;
}
and
//main.cpp
#include "Number.h"
using namespace std;
int main()
{
cout << "Part A:" << endl;
Number n1(1);
cout << "Part B:" << endl;
Number n2(n1);
cout << "Part C:" << endl;
Number n3{Number{n1}};
cout << "Part D:" << endl;
Number n4(Number(n1));
return 0;
}
This outputs:
Part A:
integer argument ctor
Part B:
copy ctor
Part C:
copy ctor
Part D:
Notice there is no output for Part D. The output for Parts A and B are what I expected, but the output for the others aren’t.
I expected this for Parts C and D:
Part C:
copy ctor
move ctor
Part D:
copy ctor
move ctor
Expectation for Part C:
I expected the Number{n1} part of Number n3{Number{n1}} to make a temporary nameless Number object, because there is no name between Number and the opening curly brace, by calling the copy constructor with n1. Then I expected Number n3 to be constructed by calling the move constructor with the temporary object.
Expectation for Part D:
Since this is like Part C, except with parentheses instead of curly braces, I expected this part to behave and output in the same way I expected Part C to.
Question:
Why does the actual output differ from my expectations and what is the correct way to get my desired output?
Note: If you want to compile this in Visual Studio, you need the Visual C++ Compiler November 2012 CTP or later for Visual Studio 2012 in order to support the uniform initialization syntax.
n4 is a function declaration. n3 is caused by copy elision.
Check that here I've enabled -fno-elide-constructors to avoid copy elision. n3 then shows a sequence of copy and move constructors.
There's a commented out line that tries to use n4 as an object. If you uncomment it, you'll see the compiler error telling it's a function instead.
For n4 do not be interpreted as a function declaration you could put extra parentheses around the temporary to prevent it from being viewed as a function parameter: Number n4((Number(n1))). With this and -fno-elide-constructors all you've expected happens.
Note that -fno-elide-constructors is not present as an option in MSVC.
In Boost.Test, how can I obtain the name of the current auto test case?
Example:
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(MyTest)
{
std::cerr << "Starting " << test_name << std::endl;
// lots of code here
std::cerr << "Ending " << test_name << std::endl;
}
In the example, I want the variable test_name to contain "MyTest".
There is an undocumented* function that may be called for that purpose. The following line will flush the name of the current test to cerr:
#include <boost/test/framework.hpp>
...
std::cerr << boost::unit_test::framework::current_test_case().p_name
<< std::endl;
Note however that using this API does not flush the parameters in case of parametrized tests.
You might also be interested in the test checkpoints** (which seems to be what you want to do.)
#include <boost/test/included/unit_test.hpp>
...
BOOST_AUTO_TEST_CASE(MyTest)
{
BOOST_TEST_CHECKPOINT("Starting");
// lots of code here
BOOST_TEST_CHECKPOINT("Ending");
}
EDIT
* The current_test_case() function is now documented, see the official Boost documentation.
** BOOST_TEST_CHECKPOINT was previously called BOOST_CHECKPOINT. See the Boost changelog (1.35.0).
A different question about suite names gives a way to extract the name rather than just printing it:
auto test_name = std::string(boost::unit_test::framework::current_test_case().p_name)