我对C ++比较陌生,但仍然混淆了如何传递和返回数组作为参数。我想写一个简单的矩阵 - 矢量 - 乘积c = A * b
函数,其签名类似于
times(A, b, c, m, n)
其中A
是二维数组,b
是输入数组,c
是结果数组,m
和n
是A
的维度。我想通过m
和n
指定数组维度,而不是通过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;
}
答案 0 :(得分:2)
这是你应该使用的答案......所以解决这个问题的一个好方法是创建一个struct
或class
来包装你的数组(好吧,数据缓冲区 - 我是使用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::vector
是malloc
'd(和realloc
'd)缓冲区的C ++“改进”,而std::array
是char 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; };