用于矩阵向量乘积函数的签名

时间:2012-11-02 15:14:32

标签: c++ arrays multidimensional-array signature

我对C ++比较陌生,但仍然混淆了如何传递和返回数组作为参数。我想写一个简单的矩阵 - 矢量 - 乘积c = A * b函数,其签名类似于

times(A, b, c, m, n)

其中A是二维数组,b是输入数组,c是结果数组,mnA的维度。我想通过mn指定数组维度,而不是通过A

(并行)函数的主体是

int i, j;
double sum;

#pragma omp parallel for default(none) private(i, j, sum) shared(m, n, A, b, c)
for (i = 0; i < m; ++i) {
    sum = 0.0;
    for (j = 0; j < n; j++) {
        sum += A[i][j] * b[j];
    }
    c[i] = sum;
}
  1. 这样的函数的正确签名是什么?
  2. 现在假设我想在函数中创建结果数组c并返回它。我怎么能这样做?

3 个答案:

答案 0 :(得分:2)

这是你应该使用的答案......所以解决这个问题的一个好方法是创建一个structclass来包装你的数组(好吧,数据缓冲区 - 我是使用std::vector)。而不是像times(A, b, c, m, n)这样的签名,请使用这种语法:

Matrix<4,4> M;
ColumnMatrix<4> V;
ColumnMatrix<4> C = M*V;

其中M的宽度/高度为<4,4>个数字。

Matrix类的快速草图可能(有些不完整 - 例如没有const访问)

template<size_t rows, size_t columns>
class Matrix
{
private:
  std::vector<double> values;
public:
  struct ColumnSlice
  {
    Matrix<rows,columns>* matrix;
    size_t row_number;
    double& operator[](size_t column) const
    {
      size_t index = row_number * columns + column;
      Assert(matrix && index < matrix->values.size());
      return matrix->values[index];
    }
    ColumnSlice( Matrix<rows,columns>* matrix_, size_t row_number_ ):
      matrix(matrix_), row_number(row_number_)
    {}
  };
  ColumnSlice operator[](size_t row)
  {
    Assert(row < rows); // note: zero based indexes
    return ColumnSlice(this, row);
  }
  Matrix() {values.resize(rows*columns);}
  template<size_t other_columns>
  Matrix<rows, other_columns> operator*( Matrix<columns, other_columns> const& other ) const
  {
    Matrix<rows, other_columns> retval;
    // TODO: matrix multiplication code goes here
    return std::move(retval);
  }
};

template<size_t rows>
using ColumnMatrix = Matrix< rows, 1 >;

template<size_t columns>
using RowMatrix = Matrix< 1, columns >;

以上使用了编译器可能没有的C ++ 0x功能,并且可以在没有这些功能的情况下完成。

所有这一切的要点?你可以让数学看起来像数学并且在C ++中做正确的事情,同时真正有效率,而 是“适当的”C ++方法。

如果您习惯使用C ++,还可以使用C ++的某些功能(如std::vector来处理数组内存管理),以类似C的方式编程。但这是对这个问题的不同答案。 :)

(注意:上面的代码尚未编译,也不是完整的Matrix实现。但是,您可以找到基于模板的Matrix实现。)

答案 1 :(得分:2)

所以不要“你应该宁愿”回答(我会放弃,因为你真的应该宁可!),这里是“你要求的答案”。

我会使用std::vector来保存您的数组数据(因为它们具有O(1)移动功能)而不是std::array(这可以为您节省间接费用,但移动费用更高)。 std::vectormalloc'd(和realloc'd)缓冲区的C ++“改进”,而std::arraychar foo[27];的C ++“改进”风格缓冲区。

std::vector<double> times(std::vector<double> const& A, std::vector<double> const& b, size_t m, size_t n)
{
  std::vector<double> c;
  Assert(A.size() = m*n);
  c.resize(n);

  // .. your code goes in here.
  // Instead of A[x][y], do A[x*n+y] or A[y*m+x] depending on if you want column or
  // row-major order in memory.
  return std::move(c); // O(1) copy of the std::vector out of this function
}

你会注意到我稍微更改了签名,因此它返回std :: vector而不是将其作为参数。我这样做是因为我可以,它看起来更漂亮!

如果您确实必须将c传递给该函数,请将其作为std::vector<double>&传递 - 对std::vector的引用。

答案 2 :(得分:0)

法向量 - 矩阵乘法如下:

friend Vector operator*(const Vector &v, const Matrix &m);

但是如果你想分别传递尺寸,则如下:

friend Vector mul(const Vector &v, const Matrix &m, int size_x, int size_y);

由于Vector和Matrix是1d和2d数组,它们看起来像这样:

struct Vector { float *array; };
struct Matrix { float *matrix; };