C++ 中的点积实现

Posted

技术标签:

【中文标题】C++ 中的点积实现【英文标题】:Dot product implementation in C++ 【发布时间】:2012-04-10 00:44:48 【问题描述】:

我正在努力让我的方法发挥作用。我是 C++ 的初学者。我试图找到两个向量的点积。我在 for 循环中遇到了一些错误。我该如何解决?

float dot(Matrixf const& vec1, Matrixf const& vec2) 

    // error check
    if (!vec1.isVector() || !vec2.isVector()) 
        throw std::runtime_error("Unable to do dot product: not column vectors.");
    
    if (vec1.nrows() != vec2.nrows()) 
        throw std::runtime_error("Unable to do dot product: vector lengths not equal.");
    

    /** implementing dot product *************************************/

    float ret = 0;

    for(unsigned i = 0; i < vec1.ncols(); ++i)
        for(unsigned j =0; j< vec2.nrows(); ++j)
            ret += vec1[i] * vec2[j];
        
    
    return ret;

Matrixf 类

#include "matrixf.h"

#include <iostream>

Matrixf::Matrixf(unsigned int rows, unsigned int cols) 
    rows_ = rows;
    cols_ = cols;
    data_ = new float[rows_ * cols_];

    // set all initial values to zero
    for (unsigned int r = 0; r < rows_; ++r) 
        for (unsigned int c = 0; c < cols_; ++c) 
            data_[r * cols_ + c] = 0;
        
    


Matrixf::~Matrixf() 
    delete data_;


Matrixf::Matrixf(Matrixf const& other) 
    rows_ = other.rows_;
    cols_ = other.cols_;
    data_ = new float[rows_ * cols_];
    for (unsigned int i = 0; i < rows_ * cols_; ++i) 
        data_[i] = other.data_[i];
    


Matrixf& Matrixf::operator=(Matrixf const& other) 
    // handles self assignment
    if (this == &other) 
        return *this;
    

    delete data_;
    rows_ = other.rows_;
    cols_ = other.cols_;
    data_ = new float[rows_ * cols_];
    for (unsigned int i = 0; i < rows_ * cols_; ++i) 
        data_[i] = other.data_[i];
    
    return *this;


float Matrixf::get(unsigned int row, unsigned int col) const 
    #ifndef NDEBUG
        if (row >= rows_ || col >= cols_) 
            throw std::runtime_error("Matrix index out of bounds.");
        
    #endif

    return data_[row * cols_ + col];


void Matrixf::set(unsigned int row, unsigned int col, float val) 
    #ifndef NDEBUG
        if (row >= rows_ || col >= cols_) 
            throw std::runtime_error("Matrix index out of bounds.");
        
    #endif
    data_[row * cols_ + col] = val;


float& Matrixf::operator()(unsigned int row, unsigned int col) 
    return data_[row * cols_ + col];


float Matrixf::operator()(unsigned int row, unsigned int col) const 
    return data_[row * cols_ + col];


unsigned int Matrixf::nrows() const 
    return rows_;


unsigned int Matrixf::ncols() const 
    return cols_;


bool Matrixf::isVector() const 
    return (cols_ == 1);


Matrixf Matrixf::eye(unsigned int size) 
    Matrixf e(size, size);
    for (unsigned int i = 0; i < size; ++i) 
        e.set(i, i, 1);
    

    return e;


std::ostream& operator << (std::ostream& os, Matrixf const& matrix) 
    for (unsigned int r = 0; r < matrix.nrows(); ++r) 
        for (unsigned int c = 0; c < matrix.ncols(); ++c) 
            os << matrix.data_[r * matrix.cols_ + c] << " ";
        
        os << "\n";
    
    return os;

【问题讨论】:

【参考方案1】:

我认为你只想要一个循环:

for(unsigned i = 0; i < vec1.ncols(); ++i)
  ret += vec1[i] * vec2[i];


我也注意到你比较

vec1.nrows() != vec2.nrows()

但你在循环中使用ncols()。你要哪一个?

【讨论】:

我仍然收到有关 vec1[i] 的错误,它说“错误:没有操作数 [] 匹配这些操作数 您是否为您的班级operator[] 超载Matrixf 那里再次检查问题 啊,你超载了operator()。这与operator[] 不同。 你在说什么?使点积工作?你的代码不会编译!你还没有超载operator[]。你不明白吗?【参考方案2】:

我从你的另一个问题中看到你写了一个光线追踪器。

在光线追踪器中,向量和矩阵具有单独的数据结构是很常见的,而且几乎总是如此,因为它们几乎总是以不同的方式使用,而编程方面的专业化几乎总能带来更快的代码。

如果您随后只为向量定义点积,点积代码将变得简单。

【讨论】:

以上是关于C++ 中的点积实现的主要内容,如果未能解决你的问题,请参考以下文章

二维坐标系中的点积叉积多边形面积

使用原子操作的 CUDA 中的点积 - 得到错误的结果

向量与 SIMD 的点积

仅影响零值的两个稀疏矩阵的点积

如何在 C++ 中的矩阵和向量之间进行点积

向量的点乘与叉乘概念理解以及C++代码实现