因此,我正在尝试实现Power iteration来查找C++中最大的特征值和相应的特征 vector 。我正在使用本征库。奇怪的是,当我在一行中用标量将 vector 除以标量(在第(1)行中标记)时,它会引发错误,并且与C++错误一样有用:

No viable conversion from 'typename internal::enable_if<true, const CwiseBinaryOp<internal::scalar_quotient_op<typename internal::traits<Product<Product<Transpose<Matrix<double, -1, 1, 0, -1, 1> >, Matrix<double, -1, -1, 1, -1, -1>, 0>, Matrix<double, -1, 1, 0, -1, 1>, 0> >::Scalar, typename internal::promote_scalar_arg<Scalar, double, (Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<Scalar, double, Eigen::internal::scalar_quotient_op<Scalar, double> > >::value)>::type>, const Product<Product<Transpose<Matrix<double, -1, 1, 0, -1, 1> >, Matrix<double, -1, -1, 1, -1, -1>, 0>, Matrix<double, -1, 1, 0, -1, 1>, 0>, const typename internal::plain_constant_type<Product<Product<Transpose<Matrix<double, -1, 1, 0, -1, 1> >, Matrix<double, -1, -1, 1, -1, -1>, 0>, Matrix<double, -1, 1, 0, -1, 1>, 0>, typename internal::promote_scalar_arg<Scalar, double, (Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<Scalar, double, Eigen::internal::scalar_quotient_op<Scalar, double> > >::value)>::type>::type> >::type'
(aka 'const Eigen::CwiseBinaryOp<Eigen::internal::scalar_quotient_op<double, double>, const Eigen::Product<Eigen::Product<Eigen::Transpose<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::Matrix<double, -1, -1, 1, -1, -1>, 0>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, const Eigen::Matrix<double, 1, 1, 0, 1, 1> > >')
to 'double'

但是当我分两步进行操作(在第(2)行中标记)时,一切都很好,并且不会引发任何错误。因此,我发现Eigen无法一步完成标量除法,这很奇怪。这里发生了什么,为什么单行执行却失败?
pair<double, Vector> power_iteration(const Matrix& X, unsigned num_iter, double eps)
{
    Vector b = Vector::Random(X.cols());
    b.normalize();
    Vector b_old;
    for(unsigned int i = 0; i < num_iter; i++){
        b_old =b;
        b = X*b_old;
        b.normalize();
        double cos_angle = b.dot(b_old);
        if(cos_angle > 1-eps){
            i= num_iter+1;
        }
    }

   (1)  double eigenvalue = (b.transpose() * X * b)/(b.transpose().dot(b));

   (2)  double eigenvalue2 = b.transpose() * X * b;
    eigenvalue2 = eigenvalue2/b.transpose().dot(b);

    return make_pair(eigenvalue, b / b.norm());
}

最佳答案

本征区分1x1矩阵和标量,例如b.transpose()*b实际上是1x1矩阵。在某些特殊情况下,生成1x1矩阵的乘积可以隐式转换为标量,但是首选方式是始终对这些乘积使用a.dot(b)(如果确实要有标量)。

此外,b.tranpose().dot(b)实际上与b.dot(b)b.squaredNorm()相同(后者可能会稍快一些,因为b只需要读取一次,尽管编译器通常足够聪明,可以将它们优化为相同的汇编代码)。

总体而言,我建议使用以下表示法:

double eigenvalue = b.dot(X * b) / b.squaredNorm();
// or:
double eigenvalue = (b.transpose()*X).dot(b) / b.squaredNorm();

关于c++ - Eigen :将 vector 除以标量可以分为两步,但不能一步一步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62110515/

10-12 14:56