本征:矢量或矩阵逐项幂? [英] Eigen: vector or matrix componentwise to power?

查看:131
本文介绍了本征:矢量或矩阵逐项幂?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个实数 c 的向量和一个整数 rw 的向量,我想创建一个向量 z 和元素 z_i = c_i ^ rw_i 。我尝试使用组件级函数 pow 来执行此操作,但出现编译器错误。

Given a vector of reals c and a vector of integers rw, I want to create a vector z with elements z_i=c_i^rw_i. I tried to do this using the component-wise function pow, but I get a compiler error.

#include <Eigen/Core>

typedef Eigen::VectorXd RealVector;
typedef Eigen::VectorXi IntVector; // dynamically-sized vector of integers
RealVector c; c << 2, 3, 4, 5;
IntVector rw; rw << 6, 7, 8, 9;
RealVector z = c.pow(rw);    **compile error**

编译器错误为

error C2664: 'const Eigen::MatrixComplexPowerReturnValue<Derived> Eigen::MatrixBase<Derived>::pow(const std::complex<double> &) const': cannot convert argument 1 from 'IntVector' to 'const double &'
      with
      [
          Derived=Eigen::Matrix<double,-1,1,0,-1,1>
      ]
c:\auc\sedanal\LammSolve.h(117): note: Reason: cannot convert from 'IntVector' to 'const double'
c:\auc\sedanal\LammSolve.h(117): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

此代码有什么问题?并且,假设它可以固定,当c为实矩阵而不是向量时,我将如何执行相同的操作,以计算c中所有元素的 c_ij ^ b_i

What is wrong with this code? And, assuming it can be fixed, how would I do the same operation when c is a real matrix instead of a vector, to compute c_ij^b_i for all elements of c?

编译器是Visual Studio 2015,在64位Windows 7下运行。

Compiler is Visual Studio 2015, running under 64-bit Windows 7.

推荐答案

首先, MatrixBase :: pow 是一个计算方矩阵的矩阵幂的函数(如果矩阵具有特征值分解,则该函数是相同的

First of all, MatrixBase::pow is a function that computes the matrix power of a square matrix (if the matrix has an eigenvalue decomposition, it is the same matrix, but with the eigenvalues raised to the given power).

您想要的是元素智能,因为没有 cwisePow MatrixBase 中的函数需要切换到 Array 域。此外,没有幂的整数专业化(这可能是有效的,但只能达到一定的阈值,并且检查每个元素的阈值会浪费计算时间),因此您需要将指数转换为类型

What you want is an element-wise power, which since there is no cwisePow function in MatrixBase, requires switching to the Array-domain. Furthermore, there is no integer-specialization for the powers (this could be efficient, but only up to a certain threshold -- and checking for that threshold for every element would waste computation time), so you need to cast the exponents to the type of your matrix.

还要回答您的奖金问题:

To also answer your bonus-question:

#include <iostream>
#include <Eigen/Core>

int main(int argc, char **argv) {
    Eigen::MatrixXd A; A.setRandom(3,4);
    Eigen::VectorXi b = (Eigen::VectorXd::Random(3)*16).cast<int>();

    Eigen::MatrixXd C = A.array() // go to array domain
        .pow(                 // element-wise power
             b.cast<double>() // cast exponents to double
            .replicate(1, A.cols()).array() // repeat exponents to match size of A
        );

    std::cout << A << '\n' << b << '\n' << C << '\n';
}

本质上,这将称为 C(i,j )= std :: pow(A(i,j),b(i))每个 i j 。如果所有指数都很小,实际上可能比使用
简单嵌套循环(调用专门的 pow(double,int)实现(例如gcc的))要快。 __ builtin_powi ),但是您应该使用实际数据进行基准测试。

Essentially, this will call C(i,j) = std::pow(A(i,j), b(i)) for each i, j. If all your exponents are small, you might actually be faster than that with a simple nested loop that calls a specialized pow(double, int) implementation (like gcc's __builtin_powi), but you should benchmark that with actual data.

这篇关于本征:矢量或矩阵逐项幂?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆