计算机系统应用教程网站

网站首页 > 技术文章 正文

C++ 计算两个向量的误差和 计算两个向量的相似度

btikc 2024-10-17 08:43:06 技术文章 7 ℃ 0 评论


给定两个仅在量化或分辨率上有所不同的相似向量,我们可以使用inner_product()算法来计算误差和,定义为:



其中,e是误差和,表示两个向量中一系列点差的平方和。

我们可以使用来自<numeric>头文件的inner_product()算法来计算两个向量之间的误差和。

如何做……

在这个示例中,我们定义了两个向量,每个向量都包含一个正弦波。一个向量是double类型的值,另一个是int类型的值。这给了我们两个在量化上有所不同的向量,因为int类型无法表示分数值。然后,我们使用inner_product()来计算这两个向量之间的误差和:

在main()函数中,我们定义了两个向量和一个方便的索引变量:

int main() {  
    constexpr size_t vlen{ 100 };  
    vector<double> ds(vlen);  
    vector<int> is(vlen);  
    size_t index{};  
    // ...  
}


ds是double正弦波的向量,is是int正弦波的向量。每个向量都有100个元素来保存一个正弦波。索引变量用于初始化向量对象。

我们使用循环和lambda来在double向量中生成正弦波:

auto sin_gen = [&index]{  
    return 5.0 * sin(index++ * 2 * pi / 100);  
};  
for(auto& v : ds) v = sin_gen();


lambda捕获对索引变量的引用,以便它可以递增。

pi常量来自std::numbers库。

现在我们有了double正弦波,我们可以用它来推导int版本:

index = 0;  
for(auto& v : is) {  
    v = static_cast<int>(round(ds.at(index++)));  
}


这从ds中获取每个点,四舍五入它,将其转换为int,并在is容器中更新它的位置。

我们使用一个简单的循环来显示我们的正弦波:

for(const auto& v : ds) cout << format("{:-5.2f} ", v);  
cout << "\n\n";  
for(const auto& v : is) cout << format("{:-3d} ", v);  
cout << "\n\n";


我们的输出是两个容器中作为数据点的正弦波:

// 输出正弦波数据点


现在我们使用inner_product()来计算误差和:

double errsum = inner_product(ds.begin(), ds.end(),  
    is.begin(), 0.0, std::plus<double>(),  
    [](double a, double b){ return pow(a - b, 2); });  
cout << format("error sum: {:.3f}\n\n", errsum);


lambda表达式返回公式中的(ai - bi)2部分。std::plus()算法执行求和操作。

输出:

error sum: 7.304


它是如何工作的……

inner_product()算法计算第一个输入范围内的乘积和。其签名是:

T inner_product(InputIt1 first1, InputIt1 last1,  
    InputIt2 first2, T init, BinaryOperator1 op1,  
    BinaryOperator2 op2)


该函数接受两个二元操作符函数对象,op1和op2。第一个op1用于求和,第二个op2用于乘积。我们使用std::plus()作为求和操作符,并使用lambda作为乘积操作符。

init参数可以用作起始值或偏差。我们传递字面值0.0。

返回值是乘积的累积和。

还有更多……

我们可以通过将inner_product()放入循环中来计算累积误差和:

cout << "accumulated error:\n";  
for (auto it{ds.begin()}; it != ds.end(); ++it) {  
    double accumsum = inner_product(ds.begin(), it,  
        is.begin(), 0.0, std::plus<double>(),  
        [](double a, double b){ return pow(a - b, 2); });  
    cout << format("{:-5.2f} ", accumsum);  
}  
cout << '\n';


输出:

// 输出累积误差


这在一些统计应用中可能是有用的。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表