* added ei_sqrt for complex

* updated Cholesky to support complex
* correct result_type for abs and abs2 functors
This commit is contained in:
Gael Guennebaud
2008-04-27 14:05:40 +00:00
parent 4ffffa670e
commit 64bacf1c3f
7 changed files with 98 additions and 64 deletions

View File

@@ -158,7 +158,8 @@ struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs
*/
template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
const Scalar operator() (const Scalar& a) const { return ei_abs(a); }
typedef typename NumTraits<Scalar>::Real result_type;
const result_type operator() (const Scalar& a) const { return ei_abs(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
@@ -170,8 +171,8 @@ struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs2
*/
template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
const Scalar operator() (const Scalar& a) const { return ei_abs2(a); }
enum { Cost = NumTraits<Scalar>::MulCost };
typedef typename NumTraits<Scalar>::Real result_type;
const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >

View File

@@ -181,6 +181,43 @@ inline std::complex<double> ei_exp(std::complex<double> x) { return std::exp(x)
inline std::complex<double> ei_sin(std::complex<double> x) { return std::sin(x); }
inline std::complex<double> ei_cos(std::complex<double> x) { return std::cos(x); }
template<typename T>
inline std::complex<T> ei_sqrt(const std::complex<T>& x)
{
if (std::real(x) == 0.0 && std::imag(x) == 0.0)
return std::complex<T>(0);
else
{
T a = ei_abs(std::real(x));
T b = ei_abs(std::imag(x));
T c;
if (a >= b)
{
T t = b / a;
c = ei_sqrt(a) * ei_sqrt(0.5 * (1.0 + ei_sqrt(1.0 + t * t)));
}
else
{
T t = a / b;
c = ei_sqrt(b) * ei_sqrt(0.5 * (t + ei_sqrt (1.0 + t * t)));
}
T d = std::imag(x) / (2.0 * c);
if (std::real(x) >= 0.0)
{
return std::complex<T>(c, d);
}
else
{
std::complex<T> res(d, c);
if (std::imag(x)<0.0)
res = -res;
return res;
}
}
}
template<> inline std::complex<double> ei_random()
{
return std::complex<double>(ei_random<double>(), ei_random<double>());