Hi, I have a nonsymmetric matrix Q, which is actually what's called a generator matrix in continuous-time markov chain theory (see: https://en.wikipedia.org/wiki/Continuous-time_Markov_chain). I need to get the eigenvectors and eigenvalues of Q so that I can find probabilities of state transitions computationally efficiently. It seems like the Stan users removed the eigenvector() and eigenvalue() functions. Why is this? Is there still a way to get the eigenvectors and eigenvalues of a nonsymmetric matrix? Best Regards, Arya
It seems like the Stan users removed the eigenvector() and eigenvalue() functions. Why is this?
Is there still a way to get the eigenvectors and eigenvalues of a nonsymmetric matrix?
--
You received this message because you are subscribed to a topic in the Google Groups "Stan users mailing list" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/stan-users/QJe1TNioiyg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to stan-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I need a little help understanding. My log posterior probability includes the sum of all the elements in a matrix P where P=U exp(tD) U^-1 and Q=UDU^-1. Q is my actual matrix of parameters I'm trying to learn and UDU^-1 is the eigendecomposition of Q. The unnormalized log posterior density seems easy to compute, but the derivative of P with respect to Q is only possible to symbolically differentiate when the eigenvalues of Q are all real?Is there any way I can get around this to implement my model in Stan to get the benefits of the NUTS? Is it possible to use HMC at all or do I have to use a sampler that doesn't rely on derivative like Metropolis Hastings?
There are some constructions such that Q is guaranteed to have real eigenvalues, in which case autodifferentiation would work fine if Stan implemented the eigendecomposition of an asymmetric matrix. But Stan doesn't implement the eigendecomposition of an asymmetric matrix because it generally can't verify from its elements that an asymmetric matrix has real eigenvalues only (I suppose we could implement it for some verifiable special cases like a triangular matrix or a right stochastic matrix).
#ifndef STAN__MATH__MATRIX__PSEUDOEIGENDECOMPOSITION_HPP
#define STAN__MATH__MATRIX__PSEUDOEIGENDECOMPOSITION_HPP
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <Eigen/Eigenvalues>
#include <stan/math/prim/scal/err/check_square.hpp>
#include <stan/math/prim/scal/err/check_nonzero_size.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
namespace stan {
namespace math {
template <typename T>
std::vector<Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> >
pseudoeigendecomposition(const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& m) {
typedef Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> matrix_t;
stan::math::check_nonzero_size("pseudoeigendecomposition", "m", m);
stan::math::check_square("pseudoeigendecomposition", "m", m);
stan::math::check_finite("pseudoeigendecomposition", "m", m);
Eigen::EigenSolver<matrix_t> es(m);
std::vector<matrix_t> out(2);
out[0] = es.pseudoEigenvectors();
out[1] = es.pseudoEigenvalueMatrix();
return out;
}
}
}
#endif
add("pseudoeigendecomposition",MATRIX_T,expr_type(MATRIX_T,1));
into a file called lib/stan_math_2.7.0/stan/math/prim/mat/fun/pseudoeigendecomposition.hpp once Stan 2.7.0 comes out (doing this for Stan 2.6.x would involve a different path). And then change src/stan/lang/function_signatures.h to include the lineadd("pseudoeigendecomposition",MATRIX_T,expr_type(MATRIX_T,1));
#include <stan/math/prim/mat/fun/pseudoeigendecomposition.hpp>Unfortunately, I can't guarantee my Q has real eigenvalues.
Is the problem specifically that Stan's auto-differentiation module doesn't support derivatives of complex number
or that auto-differentiation of complex numbers if not possible?
For example would PyMC3 which uses Theano for auto-differentiation be able to accomplish what I want?
I'd much rather prefer to use Stan, but I guess my only option would be to do the second bullet point you mentioned. How can I get an idea for how difficult that would that be? If it means I get to use Stan with all its optimizations and easy interface it could be worth it.
Q having complex eigenvalues is indeed admissible. In fact, in my toy example, the TRUE value of Q does indeed have complex eigenvalues.> Q[,1] [,2] [,3] [,4] [,5][1,] -6 2 2 1 1[2,] 1 -4 0 1 2[3,] 1 0 -4 2 1[4,] 2 1 0 -3 0[5,] 1 1 1 1 -4> eigen(Q)$values[1] -6.453264e+00+1.63114e-01i -6.453264e+00-1.63114e-01i -4.046736e+00+7.02911e-01i -4.046736e+00-7.02911e-01i -5.907916e-16+0.00000e+00i
But then the question remains if you had V and D such that QV = VD where D has (some) 2x2 blocks along its diagonal, could you write your log-posterior handling the real and imaginary parts of the eigenvalues separately?
Not sure what you mean here. Could you elaborate? Maybe it's because I don't understand what the "pseudo-eigendecomposition" is. I don't think 2x2 along the diagonal would work, because I need to compute a matrix exponential and that's only computationally feasible when the matrix is diagonal.
That's good news! Does this just mean I can download your branch that implements pseudo-eigendecomposition and go to work? I would have to create a function in my Stan model file that computes the matrix exponential of the block diagonal matrix, but that doesn't sound too difficult.
It would be really great if a function could be included in Stan which calculates the matrix exponential for cases when the eigenvalues are real.
I understand the difficulty that you cannot validate the user-input, but how about giving huge Warning messages during model startup or mode compilation?
If having eigenvalues with non-zero imaginary parts is admissible, then what I wrote in my previous post is not quite sufficient because Eigen utilizes a few unnecessary operations on complex numbers when it does a pseudo-eigendecomposition.
I do have some local C++ code that reimplemented that in Stan with only real operations, but it would probably be better if I proposed that in a patch to the Eigen developers. But then the question remains if you had V and D such that QV = VD where D has (some) 2x2 blocks along its diagonal, could you write your log-posterior handling the real and imaginary parts of the eigenvalues separately?
Not quite. We really need an unwritten patch to Eigen first because my local implementation was for a generalized eigenvalue problem rather than a plain eigenvalue problem.
If having eigenvalues with non-zero imaginary parts is admissible, then what I wrote in my previous post is not quite sufficient because Eigen utilizes a few unnecessary operations on complex numbers when it does a pseudo-eigendecomposition.Are you saying that Eigen is too inefficient at pseudo-eigendecomposition involving complex numbers or that Eigen simply can't do it for some reason?
I do have some local C++ code that reimplemented that in Stan with only real operations, but it would probably be better if I proposed that in a patch to the Eigen developers. But then the question remains if you had V and D such that QV = VD where D has (some) 2x2 blocks along its diagonal, could you write your log-posterior handling the real and imaginary parts of the eigenvalues separately?What do you mean by handling the real and imaginary parts of the log-posterior separately?
c = a + i * b
I need to use pseudoeigendecomposition function but I am having trouble getting it work. I modified the paths to reflect the change in folder structure, but Stan still cannot find the function. Would someone be able to provide updated instructions?
A branc on stan-dev/math? Is there anything holding up
merging it?