行时间列不是标量,具有自定义标量类型
row times column is not a scalar, with custom scalar type
我正在尝试将 CppAD 标量类型与 Eigen 一起使用。
以下编译失败:
#include <Eigen/Dense>
#include <cppad/cppad.hpp>
#include <cppad/example/cppad_eigen.hpp>
int main()
{
using Scalar = CppAD::AD<double>;
//using Scalar = double;
Eigen::Matrix<Scalar, 1,4> row;
Eigen::Matrix<Scalar, 4,1> col;
Scalar scalar = 5;
Scalar res2 = row * col + scalar; //fails
return 0;
}
错误基本上是它不能将标量加到乘法结果上。但是,乘法的结果本身就是一个标量,所以这应该不是问题。事实上,当使用 double
作为 Scalar
类型时,没有问题。
这是编译错误:
cppad-eigen-problem.cpp:14:29: error: no match for ‘operator+’ (operand types are ‘const Eigen::Product<Eigen::Matrix<CppAD::AD<double>, 1, 4>, Eigen::Matrix<CppAD::AD<double>, 4, 1, 0, 4, 1>, 0>’ and ‘Scalar’ {aka ‘CppAD::AD<double>’})
14 | Scalar res2 = row * col + scalar; //fails
| ~~~~~~~~~ ^ ~~~~~~
| | |
| | Scalar {aka CppAD::AD<double>}
| const Eigen::Product<Eigen::Matrix<CppAD::AD<double>, 1, 4>, Eigen::Matrix<CppAD::AD<double>, 4, 1, 0, 4, 1>, 0>
有一个issue on the CppAD project,但我不确定问题出在哪里:
如果我使用另一个简单的自定义标量,我将无法重现错误...
另一方面,他们的标量类型 CppAD Eigen traits 在我看来还不错。
版本:Eigen 3.3.7,CppAD最新大师,g++ 9.3.0
有线索吗?
谢谢
虽然 (1x1)
矩阵是标量在数学上是正确的,但 C++ 是另一回事: row * col
中 operator*
的 return 类型不是标量,既不是 (1x1)
矩阵,而是乘积表达式。此乘积表达式可隐式转换为其操作数的标量类型,在本例中为 CppAD::AD<double>
.
您看到错误的原因是 CppAD::AD<double>
是一个模板,因此它的运算符是函数模板,例如像
template<typename T>
CppAD::AD<T> operator+(const CppAD::AD<T>& lhs, const CppAD::AD<T>& rhs);
现在的问题是上面的 templated operator+
无法调用,因为模板参数中没有隐式转换,而这正是转换产品所需要的表达式 CppAD::AD<double>
.
这也是避免产品有效的原因(例如,通过使用 Eigen 的 .dot
函数)。
尽管如此,您可以通过例如定义适当的 operator+
,类似(未测试)
template<typename Derived>
CppAD::AD<double> operator+(const MatrixBase<Derived>& lhs, const CppAD::AD<double> & rhs) {
return lhs.derived().coeff(0, 0) + rhs;
//^^^^^^^^^^^ No need for an implicit conversion
}
或者您可以使用 Eigen's plugin mechanism 并向 MatrixBase
添加一个运算符。
我正在尝试将 CppAD 标量类型与 Eigen 一起使用。
以下编译失败:
#include <Eigen/Dense>
#include <cppad/cppad.hpp>
#include <cppad/example/cppad_eigen.hpp>
int main()
{
using Scalar = CppAD::AD<double>;
//using Scalar = double;
Eigen::Matrix<Scalar, 1,4> row;
Eigen::Matrix<Scalar, 4,1> col;
Scalar scalar = 5;
Scalar res2 = row * col + scalar; //fails
return 0;
}
错误基本上是它不能将标量加到乘法结果上。但是,乘法的结果本身就是一个标量,所以这应该不是问题。事实上,当使用 double
作为 Scalar
类型时,没有问题。
这是编译错误:
cppad-eigen-problem.cpp:14:29: error: no match for ‘operator+’ (operand types are ‘const Eigen::Product<Eigen::Matrix<CppAD::AD<double>, 1, 4>, Eigen::Matrix<CppAD::AD<double>, 4, 1, 0, 4, 1>, 0>’ and ‘Scalar’ {aka ‘CppAD::AD<double>’})
14 | Scalar res2 = row * col + scalar; //fails
| ~~~~~~~~~ ^ ~~~~~~
| | |
| | Scalar {aka CppAD::AD<double>}
| const Eigen::Product<Eigen::Matrix<CppAD::AD<double>, 1, 4>, Eigen::Matrix<CppAD::AD<double>, 4, 1, 0, 4, 1>, 0>
有一个issue on the CppAD project,但我不确定问题出在哪里:
如果我使用另一个简单的自定义标量,我将无法重现错误...
另一方面,他们的标量类型 CppAD Eigen traits 在我看来还不错。
版本:Eigen 3.3.7,CppAD最新大师,g++ 9.3.0
有线索吗?
谢谢
虽然 (1x1)
矩阵是标量在数学上是正确的,但 C++ 是另一回事: row * col
中 operator*
的 return 类型不是标量,既不是 (1x1)
矩阵,而是乘积表达式。此乘积表达式可隐式转换为其操作数的标量类型,在本例中为 CppAD::AD<double>
.
您看到错误的原因是 CppAD::AD<double>
是一个模板,因此它的运算符是函数模板,例如像
template<typename T>
CppAD::AD<T> operator+(const CppAD::AD<T>& lhs, const CppAD::AD<T>& rhs);
现在的问题是上面的 templated operator+
无法调用,因为模板参数中没有隐式转换,而这正是转换产品所需要的表达式 CppAD::AD<double>
.
这也是避免产品有效的原因(例如,通过使用 Eigen 的 .dot
函数)。
尽管如此,您可以通过例如定义适当的 operator+
,类似(未测试)
template<typename Derived>
CppAD::AD<double> operator+(const MatrixBase<Derived>& lhs, const CppAD::AD<double> & rhs) {
return lhs.derived().coeff(0, 0) + rhs;
//^^^^^^^^^^^ No need for an implicit conversion
}
或者您可以使用 Eigen's plugin mechanism 并向 MatrixBase
添加一个运算符。