How do I calculate the exponential of a complex matrix? - c++

I'm having trouble trying to calculate the exponential of a complex matrix with the C++ Eigen library.
Below is an example code I try to make work.
#include <iostream>
#include "Dense"
#include <complex>
#include "unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h"
int main()
{
using namespace std::complex_literals;
Eigen::MatrixXcd test(2,2);
test(0,0)=1i+std::complex<double>(5);
test(1,0)=1i*2.;
test(0,1)=std::complex<double>(2);
test(1,1)=3.*1i+std::complex<double>(3);
std::cout << "The matrix exponential is:\n"
<< test.exp() << "\n\n";
}
When I run this program I get the error:
Implicit instantiation of undefined template 'Eigen::MatrixFunctionReturnValue<Eigen::Matrix<std::__1::complex<double>, -1, -1, 0, -1, -1> >'
I have tried to find an answer but I haven't found one yet.
Any help would be greatly appreciated.
Edit:
The standard matrix operations in Eigen work and the Eigen file/folder are located in my project folder. The only functions that don't seem to work are the matrix functions in the unsupported folder for complex matrixes (they do work for real ones).

You must not directly include headers from the Eigen/src or unsupported/Eigen/src subdirectories. Also, instead of #include "Dense" use #include <Eigen/Dense> (in many cases <Eigen/Core> is actually sufficient).
In your case you actually just need these includes, because all necessary dependencies are included by MatrixFunctions:
#include <iostream>
#include <unsupported/Eigen/MatrixFunctions>
Godbolt-Demo: https://godbolt.org/z/PmJWP3 (compilation may occasionally time out).

Related

C++ compilling errors when using Quadprog++ with Eigen together

this is my first question here, I've searched it all over for a long time yet no solution.
I'm using QUadprog++ to solve a quadratic problem. When I use it in a test alone, it was alright. But when I implement it into my project, which contains Eigen, the Eigen operations will have errors like "Matrix A has no member named ‘lu_inverse’". If I comment the header files of Quadprog++ (Array.hh and Quadprog++.hh) out, the errors just disappear. So I assume that it was a conflict error between the header files of Eigen and Quadprog++. Does anyone have some clue? Thanks in advance!
You can also switch to one of QuadProgpp versions which can work with Eigen types directly: https://github.com/asherikov/QuadProgpp, https://www.cs.cmu.edu/~bstephe1/eiquadprog.hpp; or try an alternative implementation of the same algorithm (also Eigen based) https://github.com/asherikov/qpmad.
if your using namespace quadprogpp; then dont. your different libraries have the same typenames and thats causing the errors you have. It may be a few more characters to type quadprogpp::someFunction(); but its worth it. This is also why you shouldn't ever put a using namespace in a header ever. Its because you pollute all files that include that header with the namespace symbols and name conflicts can ensue which is the same kind of error your having right now.
the Quadprog library is in it's own namespace.
#if !defined(_ARRAY_HH)
#define _ARRAY_HH
#include <set>
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
namespace quadprogpp {
enum MType { DIAG };
template <typename T>
class Vector
notice how just after the #includes there is a decleration of namespace quadprogpp{} and everything that is defined in its enclosing brackets will be defined in scope to quadprogpp, so to use any of this library you have to prefix eveything with the namespace name. this is no different than using things from the standard library. I'm quite sure you've written the standard c++ hello world
#include<iostream>
int main()
{
std::cout << "hello world!" << std::endl;
return 0;
}
cout and endl being part of namespace std have to be prefixed with std:: to access them. Many new programmers to c++ dislike this and one of the very first things they google is how to not have to type out namespaces.
#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
the next thing new programmers often do is learn to place their definitions in header files and their program logic in cpp files. Thats when they commit the next common mistake.
#ifndef MYHEADER
#define MYHEADER
#include<string>
#include<vector>
#include<iostream>
using namespace std; //Never do this in a header.
doing that pollutes all of your code with everything in the standard library. That may seem like a trivial thing but when you start using another library or perhaps you create your own type that has the same name as things in the standard library that causes name collisions.
That's when the compiler simply cant reason about which Vector you want. But both Quadprog.hh and Array.hh in Quadprog++ are wrapped in namespace quadprogpp to specifically prevent name collision, which is the whole purpose of namespaces. So there is somewhere in your code, likely a header file, where you've made the statement of using namespace quadprogpp;, or some other namespace that defines an Array type, and the compiler can't deduce which type your referring to in your code.
Other than removing your using namespace statements you can also prefix a typename with its namespace qualifer to disambiguate which type your talking about. In your case I'm confident your Array should be declared as quadprogpp::Array arraynamme; rather than simply Array arrayname;

C++: Bessel function with non-integers

I have been trying to find a library/function that computes the Bessel function of the first kind, but with non-integer values.
I have the following program.
// Include standard libraries
#include <cstdlib>
#include <cmath>
#include <vector>
#include <array>
#include <iostream>
int main(int nargs, char* args[])
{
std::cout << "bessel function " << jn(5./2., 1.) << "\n" ;
}
However, it seems this function only calculates for integer values, so in the example I get the first Bessel function for n=2.
Anyone knows how I can determine the first Bessel function with non-integer values?
EDIT: I want to find a function in C++ that calculate J_(5/2)(x) for me.
boost library could be an answer. The Bessel function of the first kind is called cyl_bessel_j(v, x). Second kind cyl_neumann(v, x). Both works for real v.
Interesting alteranative here is the ROOT library from CERN with a lot of functions for scientific computation.

C++ Cosine works without the std namespace - Why? [duplicate]

This question already has answers here:
Why are some functions in <cmath> not in the std namespace?
(3 answers)
Closed 9 years ago.
I have a fairly large application and I am working without the std namespace, I noticed I wasn't including std::cos or std::sin yet I am getting the right results. Why?
An example of some cut down code would be:
#include <ctime>
#include <cmath>
#include <iostream>
#include <vector>
//#include <unistd.h>
#include <fstream>
#include <sstream>
#include <iomanip>
using std::cout;
using std::endl;
int main()
{
double pi = 4*(atan(1));
cout << "pi = " << pi << endl
<< "cos(pi) = " << cos(pi) << endl
<< "sin(pi) = " << sin(pi) << endl;
return 0;
}
I have left all the headers in, I am using them all in the main code. The output returns ~3.14, -1 and 1e-16 as expected. Why does this work? cos and sin are in std aren't they?
I'm using the g++ compiler on a remote unix server
Thanks
When you include <cmath>, all of the functions are declared in
std::. For the C headers, there is also a special rule, which
allows (but doesn't require) the implementation to make them
visible in the global namespace; this is because most
implementations will simply adapt the C headers, something like:
#include <math.h>
namespace std
{
using ::sin;
using ::cos;
// ...
}
This is an obvious way of implementing the library without
having to rewrite everything, just to have it in C++, and it
will result in all of the names also being present in the global
namespace.
Formally, this is a C++11 feature; pre-C++11 required that
<cmath> only introduce the symbols into std::. Practically,
all, or at least most implementations did something like the
above, and did introduce them, illegally, into the global
namespace, so C++11 changed the standard to reflect reality.
Unfortunately, library implementations are allowed to dump names from the C library into the global namespace as well as std, and many do. Even worse, in some cases only some overloads are available in the global namespace, leading to unexpected loss of precision if you don't specify the std version.
You should always use the std versions, but sadly there's no reliable way to enforce that, so you'll just have to tread carefully through this particular minefield.

srand(time(NULL)) "Function 'srand' could not be resolved."

I have been trying to debug this problem for a while and quite honestly, I just can't see what I'm doing wrong.
Why is there a syntax error?
#include <iostream>;
#include <time.h>;
#include <stdio.h>;
#include <stdlib.h>;
using namespace std;
class Problem3 {
public:
bool isPrime(long double num) {
srand(time(NULL));
return 0;
}
};
The error I'm getting is,
"Function 'srand' could not be resolved."
I'm well aware now that I don't need the semi-colons after 'include' statements
I'm using Eclipse CDT along with MinGW as my compiler
How I resolved the problem:
It had to do with the MinGW compiler I was using. Switching over to Visual Studio solved the problem.
; at the end of the #include directives are the problem in your code. #include directives don't need (wrong to place indeed) semicolons at the end unlike C++ statements.
[Warning] extra tokens at end of #include directive [enabled by default]
It seems any character after > in the directive causes this error/warning.
#include<iostream>a //error
Change to this:
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class Problem3 {
public:
bool isPrime(long double num) {
srand(time(NULL));
return 0;
}
};
int main(){
cout<<"Hello Main";
}
EDIT:
Regarding the linker issue:
One suggestion is C++ expects types to be explicitly casted between types (more than C). So, use a cast to convert time_t which is returned by the time to unsigned int which is the input parameter type of srand. (And of course this might not be the problem with linker error)
Instead of using stdlib.h, try using <cstdlib>, try if it helps. Because it uses namespace.
Apart from that, I have seen this snippet here. Use that pattern if it helps.
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(time(0)); //use current time as seed for random generator
int random_variable = rand();
cout << "Random value on [0 " << RAND_MAX << "]: "
<< random_variable << '\n';
}
there is already question in SO check if that helps Eclipse Method could not be resolved in a simple program C++
Never use time() to initialize srand()..
EDIT:
Now it seems many people got this kind of problem. I found a question How do I fix Eclipse CDT Error “Function 'isdigit' could not be resolved. He is facing the same problem. The asker suggested a work around to this in his question edit.
Quoted from that question:
I now believe this to be a Code Analysis problem. A better solution is
to edit the Code Analysis options to make "Function could not be
resolved" be a warning instead of an error. That way you can see the
warnings in Problems view, but continue to work. If the function is
REALLY missing, the compiler will tell you! I also have a new theory,
that the problem is with the Code Analyzer following symlinks, because
all of the "missing" functions are in symlinked include files. Would
love any input on this theory.
Hope that points to solve the problem.
; should not be there after #include.
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include files shoule not end with ;

eigen library selfadjointView problem

I am persistently getting error messages whenever I try to use the selfadjointView property of any matrix or sparse matrix using the eigen library. Below is a simple code to check that. In my program I do try with self-adjoint matrix:
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Sparse>
#include <Eigen/Dense>
#include <Eigen/Core>
#include <iostream>
using namespace Eigen;
int main ()
{
SparseMatrix<float> mat(3,3);
Matrix<float, 3, 1> vec;
std::cout<<mat.selfadjointView<>()*vec;
}
The error message I get is:
error: no matching function for call to ‚'Eigen::SparseMatrix::selfadjointView()‚
You have to specify the template argument, so it should read mat.selfadjointView<Upper>() or mat.selfadjointView<Lower>() . The first one means that it should use the entries in the upper triangular part of mat and fill the lower triangular part to make the matrix self-adjoint. The second one is the other way around.