【问题标题】:Matrix and vector multiplication, outputting incorrect product矩阵和向量乘法,输出不正确的乘积
【发布时间】:2026-01-28 07:55:02
【问题描述】:

我创建了一个向量和矩阵类,我正在尝试执行诸如矩阵和向量的乘法、矩阵和矩阵的乘法以及矩阵和浮点数(标量)的乘法之类的操作。我似乎在为矩阵 * 向量和矩阵 * 矩阵获取正确的产品时遇到问题。 这是 Matrix 类中用于处理这些操作的部分:

// Matrix * vector, result vector
Vector Matrix::operator*(const Vector & other) const
{
if (other.getDimensions() == 4)
{
    float floats[4];
    const float* temp = other.getData();
    for (int j = 0; j < 4; j++)
    {
        Vector myCol = column(j);
        floats[j] = (temp[0] * myCol.getData(0)) + (temp[1] * myCol.getData(1)) + (temp[2] * myCol.getData(2)) + (temp[3] * myCol.getData(3));
    }
    return Vector(floats[0], floats[1], floats[2], floats[3]);
}
else
{
    return Vector();
}
}

// Matrix * scalar, result matrix
Matrix Matrix::operator*(float c) const 
{
Matrix myMatrix;
for (int i = 0; i < 16; i++)
{
    myMatrix.data[i] = this->data[i] * c;
}
return myMatrix;
}

在我的 main.cpp 中,

Matrix m = Matrix(Vector(1, 0, 0, 1), Vector(0, 1, 0, 2), Vector(0, 0, 1, 3), Vector(0, 0, 0, 1));

是矩阵的值和

    v = Vector(1, 0, -1, 1);

是向量的值。 当我乘以 m * v 我得到 ,但答案是 。

当使用上面相同的 m 矩阵和带有值的向量 v 进行矩阵 * 标量时

v = Vector(1, 0, -1, 0);

当 m*v 应该是 时,我得到 m*v 是 。 我的 Vector 类工作正常,所以我怀疑我在某个地方搞砸了用于实现矩阵运算的数学。

【问题讨论】:

  • Vector 不就是一个只有一列的矩阵吗?如果是这样,为什么要让Vector 成为一个单独的类,为什么在Matrix * Matrix 仍然可以工作的情况下编写一个单独的例程用于矩阵和向量的乘法?
  • @PaulMcKenzie Vector 类旨在表示多个不同维度的数学向量。这是任务的一部分。我们的目的是练习使用内存管理、指针、运算符重载等实现多个类。
  • 矩阵乘以向量产生一个新矩阵,而不是向量。你为什么要返回一个向量?此外,即使返回了Vector,为什么在出错时返回默认的Vector?我假设默认 Vector 具有与任何其他向量一样的有效值,如果是这种情况,调用者不知道返回的向量应该意味着“这是一个坏向量”。
  • @PaulMcKenzie 好吧,只有当矩阵的维度为 4 时,它才应该起作用。由于矩阵 m 的维度确实为 4,并且向量为 4 x 1,因此它应该返回一个向量。
  • 一个矩阵由行和列组成。矩阵的“维度为 4”是什么意思?其次,这一切听起来都违反直觉——矩阵乘以向量,得到一个矩阵——你正在做的是一些违反惯例的虚构数学。第三,如果一个人调用了multiply函数,并且维度不是4,那这个人怎么知道有错误?他们不是,相反,他们得到了一个 Vector() 被扔回给他们,这并不表示发生了错误——这就是我的观点。

标签: c++ matrix vector


【解决方案1】:

为了扩展@Klaus 的答案,数学上在表达式M*V 中,向量V 是一个,结果的元素是矩阵的(点)积V。将column(j) 替换为row(j)

【讨论】:

  • 谢谢。显然我混淆了行和列这两个词,这解决了构造函数或运算符是否错误的问题......要编辑我的答案。
【解决方案2】:

我现在手动计算了您的示例,如果您希望结果为 ,那么您肯定交换了矩阵中的行和列。当您将矩阵与向量相乘时,您希望将矩阵行和向量的乘积放入结果向量中。种类:

Vector Matrix::operator*(const Vector & other) const
{
    float floats[4];
    const float* temp = other.getData();
    for (int j = 0; j < 4; j++)
    {
        Vector my_row = row(j);
        floats[j] = 0;
        for(int i=0; i!=4; ++i)
            floats[j]+=temp[i] * myCol.getData(i);
    }
    //(maybe provide a better constructor to take an array)
    return Vector(floats[0], floats[1], floats[2], floats[3]);
}

对于带有标量的示例,我不明白这一点。如果您将矩阵与向量相乘,我不明白您如何期望矩阵与标量相乘。

如果您只使用大小为 4 的向量,您还可以通过仅接受大小为 4 的向量(将其作为向量类中的要求)来改进错误处理。

PS:也许你也应该把你的添加代码放在循环中,放到第二个循环中,这样它更具可读性和可扩展性。

【讨论】:

    最近更新 更多