【问题标题】:(C++) Matrix multiplication in a templated Matrix class(C++) 模板化 Matrix 类中的矩阵乘法
【发布时间】:2012-12-15 16:44:19
【问题描述】:

我的矩阵类遇到了问题,我找不到解决方案。

Matrix = ROWSxCOLUMNS

Let A be a 3x4 matrix
Let B be a 4x5 matrix

操作AxB(仅当A 的列与B 的行匹配时才定义)导致3x5 matrix。 我想创建一个模板类来做这件事。

Matrix<int,3,4> A;
Matrix<int,4,5> B;
Matrix<int,3,5> matrix = A*B;

我的代码:

    template <class T, unsigned int ROWS, unsigned int COLUMNS>
    class Matrix {
      public:

        /* blabla */

        const Matrix<T, ROWS, /* ? */ >&
          operator*(const Matrix<T, COLUMNS, /* ? */ >& matrix) const
        {
          /* multiplication */
        }

        /* blabla */
    };

我不知道在/* ? */ 部分中插入什么。 有没有办法让编译器接受任何无符号整数值?我应该以不同的方式重写代码吗?

注意:我创建这个类是为了学术目的,我不在乎是否已经有图书馆这样做。

【问题讨论】:

标签: c++ templates matrix matrix-multiplication


【解决方案1】:

使用带有整数模板参数的模板成员函数:

template<class T, unsigned int ROWS, unsigned int COLUMNS>
class Matrix {
public:
    ... 
    template<unsigned int N>
    Matrix<T, ROWS, N>
    operator*(const Matrix<T, COLUMNS, N>& matrix) const
    {
          /* multiplication */
    }
    ...
};

另外,不要通过引用返回值。

【讨论】:

  • 如何在乘法中指定模板参数?在我的示例中, Matrix 矩阵 = A*B;在不指定 N 的情况下可以使用吗?
  • 是的,不指定 N 也可以工作。编译器通过查看 B 的类型来确定 N 是什么。(称为模板参数推导。)
【解决方案2】:

您可以查看this Example,但我没有执行三重循环(非常低效),而是委托给英特尔 MKL dgemm

还要注意,将operator*() 用于矩阵类型是一个坏主意,因为您需要按值返回结果,除非您确定您有一个启用了命名返回值优化 (NRVO) 的编译器并对其进行了测试.也就是说,您不想按值返回矩阵并导致非常昂贵的矩阵复制。这就是为什么在我的实现中我选择定义一个方法multiply而不是重载operator*()

operator*() 的一种有效替代方法是定义operator*=(),这样您就可以这样使用它,并且乘法的结果直接存储到 A 中:

A *= B; // or A = A*B 

【讨论】:

  • 非常有趣!经过一段时间的推理,我想我会像你一样做。乘法方法对我来说似乎也是一个更好的选择。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
相关资源
最近更新 更多