【SLAM】稀疏矩阵的乘法优化小结

news2024/11/23 15:12:01

1. 思路小结

要优化你提供的稀疏矩阵乘法代码,我们可以引入CSR(压缩稀疏行)格式来避免遍历零元素,从而提高效率。CSR格式通过仅存储非零元素以及它们的行和列索引,可以有效减少稀疏矩阵计算时的时间复杂度。下面是对代码的优化版本,采用CSR格式进行稀疏矩阵的乘法:

优化步骤:
将稀疏矩阵转换为CSR格式,存储非零元素的位置和对应的值。
在矩阵乘法过程中,仅对非零元素进行计算,从而跳过零值。
对每一行的非零元素,在相应的列上执行乘法操作。

1.1 优化思路

进行的是两个稀疏矩阵的乘法。稀疏矩阵通常具有大量的零元素,因此直接使用常规矩阵乘法会导致大量的无效计算。为了提高效率,常用的优化方法是只对非零元素进行计算,而跳过零值。为此,我们采用**CSR(压缩稀疏行,Compressed Sparse Row)**格式进行稀疏矩阵存储和乘法计算。

1.1.1 核心步骤如下:
  1. 矩阵的稀疏表示

    • 原矩阵A和B可能有大量的零元素,因此我们采用CSR格式来存储这些矩阵。
    • CSR格式由以下三个部分组成:
      • values[]: 存储所有非零元素的值。
      • colIndex[]: 存储每个非零元素所在的列索引。
      • rowPtr[]: 记录每行的非零元素在 values[] 中的起始位置。
  2. 矩阵的稀疏乘法

    • 对于矩阵A的每一行,我们找到其所有非零元素的位置及其值。
    • 对于每一个非零元素,我们在矩阵B的相应列中查找与之匹配的非零元素。
    • 最后将这些匹配的非零元素相乘,并累加到结果矩阵的对应位置。
  3. 优化

    • 通过CSR格式,避免了遍历和处理零元素,从而减少了不必要的计算。
    • 我们直接对非零元素进行乘法运算,结果累积到结果矩阵C的对应位置。

1.2 算法复杂度分析

在这里插入图片描述

1.2.1 常规矩阵乘法的复杂度:

对于两个大小分别为 m x nn x p 的矩阵,常规的矩阵乘法复杂度为O(m * n * p)。因为对于每一个 m x p 的结果元素,我们需要计算 n 次乘法操作。

1.2.2 稀疏矩阵乘法的复杂度:

由于稀疏矩阵大部分元素为零,我们只需要处理非零元素。假设矩阵A和矩阵B的非零元素分别为 nnzAnnzB,稀疏矩阵乘法的复杂度可以近似表示为:

  • 对于每个非零元素 A[i][k],我们只需遍历矩阵B的第k列的非零元素进行乘法。因此稀疏矩阵乘法的复杂度大约为 O(nnzA * nnzB),其中 nnzAnnzB 是矩阵A和矩阵B的非零元素数量。

这相比于常规矩阵乘法的复杂度有了显著的提升,尤其是当矩阵非常稀疏时(即大部分元素为0),非零元素的数量远小于矩阵的总大小。

1.2.3 空间复杂度:

使用CSR格式的空间复杂度为:

  • O(nnz):用于存储所有非零元素及其列索引。
  • O(m):用于存储每一行的起始位置。
    总体空间复杂度为 O(nnz + m),其中 nnz 是矩阵的非零元素数量,m 是矩阵的行数。

1.2.4 总结

通过使用CSR格式存储稀疏矩阵,我们能够有效避免对零元素的计算,显著提升了稀疏矩阵乘法的计算效率。时间复杂度从常规的O(m * n * p)降低到接近于非零元素的数量 O(nnzA * nnzB),特别适合处理大规模稀疏矩阵的场景。

2. 优化后代码及其复杂度为

代码解析:
toCSR 函数:将普通的二维稀疏矩阵转换为CSR格式。values数组存储非零元素,colIndex存储每个非零元素的列索引,rowPtr则记录每行的非零元素在 values 数组中的起始位置。

multiplySparseMatricesCSR 函数:使用CSR格式进行矩阵乘法。通过 rowPtr 和 colIndex 来快速定位非零元素,避免了对零值的无效计算。

优化效果:
通过CSR格式存储非零元素,并跳过零元素的乘法操作,能够显著减少计算时间。
避免遍历零值,提高了计算效率,尤其在大规模稀疏矩阵的场景下。

#include <iostream>
#include <vector>

using namespace std;

// CSR格式的稀疏矩阵
struct CSRMatrix {
    vector<int> values;      // 存储非零元素的值
    vector<int> colIndex;    // 存储非零元素的列索引
    vector<int> rowPtr;      // 每一行的开始位置
};

// 将稀疏矩阵转换为CSR格式
CSRMatrix toCSR(const vector<vector<int>>& matrix) {
    CSRMatrix csr;
    int row = matrix.size();
    int col = matrix[0].size();
    
    csr.rowPtr.push_back(0);  // 第一行的开始位置是0
    
    // 遍历矩阵,收集非零元素的信息
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (matrix[i][j] != 0) {
                csr.values.push_back(matrix[i][j]);
                csr.colIndex.push_back(j);
            }
        }
        csr.rowPtr.push_back(csr.values.size());  // 记录下一行的开始位置
    }
    
    return csr;
}

// 使用CSR格式进行稀疏矩阵乘法
vector<vector<int>> multiplySparseMatricesCSR(const CSRMatrix& A, const CSRMatrix& B, int colB) {
    int rowA = A.rowPtr.size() - 1;
    vector<vector<int>> C(rowA, vector<int>(colB, 0));  // 初始化结果矩阵
    
    // 遍历A的每一行
    for (int i = 0; i < rowA; i++) {
        // A的第i行的非零元素从A.rowPtr[i]到A.rowPtr[i+1]-1
        for (int aPos = A.rowPtr[i]; aPos < A.rowPtr[i+1]; aPos++) {
            int colA = A.colIndex[aPos];  // 该非零元素所在的列
            int aValue = A.values[aPos];  // 非零元素的值
            
            // 对应B的第colA行
            for (int j = B.rowPtr[colA]; j < B.rowPtr[colA+1]; j++) {
                int colBIndex = B.colIndex[j];
                int bValue = B.values[j];
                C[i][colBIndex] += aValue * bValue;
            }
        }
    }
    
    return C;
}

int main() {
    // 定义稀疏矩阵A
    vector<vector<int>> A = {
        {1, 0, 0},
        {-1, 0, 3}
    };

    // 定义稀疏矩阵B
    vector<vector<int>> B = {
        {7, 0, 0},
        {0, 0, 0},
        {0, 0, 1}
    };

    // 将矩阵A和B转换为CSR格式
    CSRMatrix csrA = toCSR(A);
    CSRMatrix csrB = toCSR(B);

    // 计算A和B的乘积
    vector<vector<int>> C = multiplySparseMatricesCSR(csrA, csrB, B[0].size());

    // 输出结果矩阵
    cout << "Result of A * B:" << endl;
    for (const auto& row : C) {
        for (int elem : row) {
            cout << elem << " ";
        }
        cout << endl;
    }

    return 0;
}

3. 优化前原始代码及其复杂度为O(m * n * p),这里是最朴素的思路,没有利用稀疏特性做任何优化

#include <iostream>
#include <vector>

using namespace std;

// 定义稀疏矩阵乘法函数
vector<vector<int>> multiplySparseMatrices(vector<vector<int>>& A, vector<vector<int>>& B) {
    int rowA = A.size();
    int colA = A[0].size();
    int rowB = B.size();
    int colB = B[0].size();

    // 初始化结果矩阵,大小为rowA * colB
    vector<vector<int>> C(rowA, vector<int>(colB, 0));

    // 遍历矩阵A的每一行
    for (int i = 0; i < rowA; i++) {
        // 遍历矩阵A的每个列,寻找非零元素
        for (int k = 0; k < colA; k++) {
            if (A[i][k] != 0) {
                // 当A的某个位置非零时,计算该元素和矩阵B的第k行
                for (int j = 0; j < colB; j++) {
                    if (B[k][j] != 0) {
                        C[i][j] += A[i][k] * B[k][j];
                    }
                }
            }
        }
    }
    
    return C;
}

int main() {
    // 定义稀疏矩阵A
    vector<vector<int>> A = {
        {1, 0, 0},
        {-1, 0, 3}
    };

    // 定义稀疏矩阵B
    vector<vector<int>> B = {
        {7, 0, 0},
        {0, 0, 0},
        {0, 0, 1}
    };

    // 计算A和B的乘积
    vector<vector<int>> C = multiplySparseMatrices(A, B);

    // 输出结果矩阵
    cout << "Result of A * B:" << endl;
    for (const auto& row : C) {
        for (int elem : row) {
            cout << elem << " ";
        }
        cout << endl;
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2125644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

讲解GPU 训练大模型步骤

GPU在训练大模型的工作过程中&#xff0c;扮演着至关重要的角色&#xff0c;其强大的并行计算能力能够显著提升训练速度和效率。以下是GPU训练大模型的详细步骤&#xff1a; 选择合适的GPU和云平台 1. 考虑计算能力 计算能力需求&#xff1a;大模型训练通常需要强大的计算能…

Qt实现登录界面

本文基于Qt实现一个简单的登录界面&#xff0c;主要使用到Widget、button、edit等控件&#xff0c;基于自定义的信号槽实现界面的跳转&#xff0c;使用绘图设备添加背景图等。 1. 创建主界面 设计主界面的样式&#xff0c;并添加相关的控件。如下显示&#xff1a; 代码如下&…

搜索功能技术方案

1. 背景与需求分析 门户平台需要实现对服务信息的高效查询&#xff0c;包括通过关键字搜索服务以及基于地理位置进行服务搜索。面对未来可能的数据增长和性能需求&#xff0c;选择使用 Elasticsearch 来替代 MySQL 的全文检索功能。这一选择的背景与需求可以总结为以下几点&am…

对标世界一流!望繁信科技受邀参加2023企业财务数智化转型论坛

2023年7月21日&#xff0c;由中国CFO发展中心联合浙江省总会计师协会、南京审计大学会计学院、安徽财经大学会计学院举办的“2023企业财务数智化转型论坛&#xff08;长三角站&#xff09;”在上海隆重举办。论坛现场座无虚席&#xff0c;全天候、多维度的话题探讨为广大CFO呈现…

[WEBPWN]BaseCTF week1 题解(新手友好教程版)

WEB A Dark Room 这道题的考点是查看网页源代码 网页源代码这里看到的是网页的html css js在用户浏览器上执行的代码 有时候很多铭感信息&#xff0c;或者关键信息。 查看网页源代码的几种方式 1 右键点击查看网页源代码 2 F12 3 Ctrl U 快捷键 HTTP是什么 HTTP&#x…

车路云一体化系统中的数据交互内容

车路云与相关支撑平台的数据交互是构建智能交通系统的重要组成部分&#xff0c;它涉及到车辆、道路基础设施&#xff08;路侧单元RSU&#xff09;与云端平台及其相关支撑平台之间的复杂信息流通与协同工作。以下是对这一过程的详细解析&#xff1a; 一、数据交互的组成部分 车…

DMDRS学习

DMDRS学习 产品介绍 达梦数据复制软件&#xff08;简称DMDRS&#xff09;是一种用于同构数据库、异构数据库以及各种数据管理系统之间的数据复制软件。DMDRS采用模块化的设计&#xff0c;通过灵活配置不同的功能模块&#xff0c;实现多功能的数据复制服务&#xff0c;以满足多…

Java虚拟机 - 实战篇

一、内存调优 1. 什么是内存泄漏 &#xff08;1&#xff09;内存溢出和内存泄漏 2. 监控Java内存的常用工具 &#xff08;1&#xff09;Top命令 &#xff08;2&#xff09;VisualVM &#xff08;3&#xff09;Arthas &#xff08;4&#xff09;Prometheus Grafana &#xff…

人工智能--模型评估指标

背景 1、分类回归模型的评估指标 分类模型的目标是将输入数据分配到一个离散类别中&#xff0c;常见的评估指标如下&#xff1a; 准确率 (Accuracy) 解释&#xff1a;表示模型预测正确的样本占总样本的比例。适用于类分布平衡的情况&#xff0c;但在类别不平衡时表现不佳。…

十张图“拿捏”MySQL中B+树的生成过程

hello&#xff0c;我是大都督周瑜&#xff0c;这篇文章带你用十张图“拿捏”MySQL中B树的生成过程。 更多干货技术文章、面试题&#xff0c;欢迎关注我的公众号&#xff1a;IT周瑜 当MySQL接收到一条以下SQL时&#xff0c;表示要从t1表中查询数据&#xff1a; select * from t…

基于java+springboot+vue实现的林业产品推荐系统(文末源码+Lw)135

基于SpringBootVue的实现的林业产品推荐系统&#xff08;源码数据库万字Lun文流程图ER图结构图演示视频软件包&#xff09; 系统功能&#xff1a; 林业产品推荐系统是在MySQL中建立数据表保存信息&#xff0c;运用SpringBoot框架和Java语言编写。 并按照软件设计开发流程进行…

新书宣传:《量子安全:信息保护新纪元》

《量子安全&#xff1a;信息保护新纪元》 前言本书的看点本书的目录结语 前言 你好&#xff01; 这是我第一次发布类广告的博文&#xff0c;目的也很单纯&#xff0c;希望以作者的身份介绍一下自己出版的图书——《量子安全&#xff1a;信息保护新纪元》。此书于2024年7月出版…

【go】pprof 性能分析

前言 go pprof是 Go 语言提供的性能分析工具。它可以帮助开发者分析 Go 程序的性能问题&#xff0c;包括 CPU 使用情况、内存分配情况、阻塞情况等。 主要功能 CPU 性能分析 go pprof可以对程序的 CPU 使用情况进行分析。它通过在一定时间内对程序的执行进行采样&#xff0…

17个常见的电子邮件营销错误及避免方法

我们都在邮件营销中犯过错误。你点击发送&#xff0c;然后感到一阵沉重的感觉。你搞砸了&#xff0c;现在全世界都能看到你的错误。这就像把一封信放在瓶子里扔进无边的互联网海洋&#xff0c;你无法把它收回来。 有些邮件营销错误显而易见&#xff0c;可能会让你所有的努力化…

Redis学习Day3——项目工程开发`

扩展阅读推荐&#xff1a; 黑马程序员Redis入门到实战教程_哔哩哔哩_bilibili 使用git命令行将本地仓库代码上传到gitee/github远程仓库-CSDN博客 一、项目介绍及其初始化 学习Redis的过程&#xff0c;我们还将遇到各种实际问题&#xff0c;例如缓存击穿、雪崩、热Key等问题&…

想将桌面移动到D盘,但是不小心将D盘整个改成桌面的快捷方式了的解决办法

本帖为经验分享&#xff0c;因而附带了解释。 着急的uu请直接按照红色&#xff08;蓝色&#xff09;加粗标号直接操作&#xff01; 目录 一、问题描述 二、问题出现的原因 三、解决方法 一、问题描述 想将桌面移动到D盘&#xff0c;但是不小心将D盘整个改成桌面的快捷方式。…

老旧电力系统安全隐患增加 该如何预防电气线路老化等因素引发的电气火灾呢?

为应对我国电气火灾事故频发的挑战&#xff0c;安科瑞电气股份有限公司开发了AcrelCloud-6000安全用电管理云平台。这一平台依托移动互联网和云计算技术&#xff0c;结合物联网传感器&#xff0c;将办公楼、学校、医院、工厂、体育场馆、宾馆及福利院等人员密集场所的电气安全数…

爬虫--基于python的旅游网站数据分析与可视化实现---附源码78517

摘要 在数字化时代&#xff0c;旅游网站积累了大量用户数据&#xff0c;这些数据中蕴藏着丰富的信息和价值。为了更好地理解用户行为、优化旅游服务体验和提高业务运营效率&#xff0c;对旅游网站数据进行深度挖掘和可视化展示显得尤为重要。本文借助Python编程语言&#xff0c…

前端Excel热成像数据展示及插值算法

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏:《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 目录 &#x1f4d8; 前言 &#x1f4d8;一、热成像数…

最受欢迎的10款电脑监控软件大揭秘,员工电脑监控软件真心推荐

随着科技的迅猛发展&#xff0c;越来越多的企业和个人开始关注电脑监控软件的使用。这类软件能够帮助企业管理者更好地了解员工的工作状况&#xff0c;提升工作效率&#xff0c;并确保公司数据安全&#xff1b;个人用户也可以利用这些软件监控电脑活动&#xff0c;保护家人尤其…