Eigen求解LSCG问题

本文探讨了使用Eigen库求解线性方程组Ax=b的方法,特别是针对稀疏矩阵的情况。通过对比不同求解器如LSCG和SimplicialLDLT的性能,发现对于对称正定矩阵,SimplicialLDLT求解器更为高效。文章还提供了代码示例和运行时间对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考网址  https://blog.youkuaiyun.com/xuezhisdc/article/details/54634080

 

 

       Eigen中的求解Ax=b问题,应该采用什么方法, 才能较快的实现出来呢? 主要结果是这样的:  

 

Eigen中有一些求解稀疏系数矩阵的线性方程组。由于稀疏矩阵的特殊的表示方式,因此获得较好的性能需要格外注意。查看《Eigen教程3 - 稀疏矩阵操作》,了解更多有关稀疏矩阵的内容。本文列出了Eigen中的稀疏求解器。同时也介绍了所有线性求解器的共同步骤。用户可以根据矩阵的性质,准确度的要求,来调整求解步骤,以提升代码的性能。注意:没有必要深入了解这些步骤后面隐藏的内容。


本文最后一部分列出了一个基准例程,可以用于窥探所有的求解器的性能。

稀疏求解器的列表


Eigen提供了一系列的内建求解器和封装了一些外部求解器库。


内建的直接求解器
* 说明:此处的SPD (symmetric positive definite) 表示对称正定。

 

 

用Auto最快 将Tolerance设置的大一些 是更好的。 

 

 

#include <Eigen/Sparse> //system solving and Eigen::SparseMatrix
#include <ctime>        //measure time to execute
#include <unsupported/Eigen/SparseExtra> //loadMarket

// Use typedefs instead of using if c++11 is not supported by your compiler
using SpMatrix = Eigen::SparseMatrix<double>;
using Matrix = Eigen::MatrixXd;

int main() {
  // Use multi-threading. If you don't have OpenMP on your system
  // it will simply use 1 thread and it will not crash. So do not worry about
  // that.
  Eigen::initParallel();
  Eigen::setNbThreads(6);

  // Load system matrices
  SpMatrix A, B;
  Eigen::loadMarket(A, "/home/iason/Desktop/Thesis/build/A.mtx");
  Eigen::loadMarket(B, "/home/iason/Desktop/Thesis/build/B.mtx");

  // Initialize the clock which will measure the solvers
  std::clock_t start;


LSCG Time Using auto: 0.000415 s
  {
    // Reset clock
    start = std::clock();
    // Solve system using LSCG
    Eigen::LeastSquaresConjugateGradient<SpMatrix> LSCG_solver;
    LSCG_solver.setTolerance(pow(10, -10));
    LSCG_solver.compute(A);
    // Use auto specifier to hold the return value of solve. Eigen::Solve object
    // is being returned
    auto LSCG_solution = LSCG_solver.solve(B);
    std::cout << "LSCG Time Using auto: "
              << (std::clock() - start) / (double)(CLOCKS_PER_SEC) << " s"
              << std::endl;
  }





LSCG Time Using Matrix: 52.7668 s
  {
    // Reset clock
    start = std::clock();
    // Solve system using LSCG
    Eigen::LeastSquaresConjugateGradient<SpMatrix> LSCG_solver;
    LSCG_solver.setTolerance(pow(10, -10));
    LSCG_solver.compute(A);
    // Use Matrix specifier instead of auto. Implicit conversion taking place(?)
    Matrix LSCG_solution = LSCG_solver.solve(B);
    std::cout << "LSCG Time Using Matrix: "
              << (std::clock() - start) / (double)(CLOCKS_PER_SEC) << " s"
              << std::endl;
  }




SimplicialLDLT Time Using auto: 0.216593 s
  {
    // Reset clock
    start = std::clock();
    // Solve system using SimplicialLDLT
    Eigen::SimplicialLDLT<SpMatrix> SLDLT_solver;
    SLDLT_solver.compute(A.transpose() * A);
    auto SLDLT_solution = SLDLT_solver.solve(A.transpose() * B);

    std::cout << "SimplicialLDLT Time Using auto: "
              << (std::clock() - start) / (double)(CLOCKS_PER_SEC) << " s"
              << std::endl;
  }


SimplicialLDLT Time Using Matrix: 0.239976 s
  {
    // Reset clock
    start = std::clock();
    // Solve system using SimplicialLDLT
    Eigen::SimplicialLDLT<SpMatrix> SLDLT_solver;
    SLDLT_solver.compute(A.transpose() * A);
    // Use Matrix specifier instead of auto. Implicit conversion taking place(?)
    Matrix SLDLT_solution = SLDLT_solver.solve(A.transpose() * B);

    std::cout << "SimplicialLDLT Time Using Matrix: "
              << (std::clock() - start) / (double)(CLOCKS_PER_SEC) << " s"
              << std::endl;
  }
  return 0;

上述代码的运行时间分别为: 

LSCG Time Using auto : 0.000415 s

LSCG Time Using Matrix: 52.7668 s

SimplicialLDLT Time Using auto: 0.216593 s

SimplicialLDLT Time Using Matrix: 0.239976 s

As the results proove when I use Eigen::MatrixXd instead of auto I get the situation ggael described in one of his comments, namely LSCG not achieving a solution without setting a higher tolerance and SimplicialLDLT being much faster.

  1. Are the solvers actually solving the system when I use auto?
  2. Is the Solver object being implicitly converted to a Matrix Object when I use the Matrix specifier? Since When using LSCG the only change in the first two cases is the use of auto and Matrix respectively,does this implicit conversion to Matrix take 52.7668-0.000415 seconds?
  3. Is there a faster way to extract the solution Matrix from the Solve object?

 

由于A'*A是对称正定,用LDLT的求解方法可以更快

Given the sparsity pattern of your matrix A, forming the normal equation explicitly and using a direct solver such as SimplicialLDLT will be much faster. Also better use a dense type for B since it is dense anyway and that internally, all solvers will convert the sparse right-hand-side to dense columns:

Eigen::MatrixXd dB = B; // or directly fill dB
Eigen::SimplicialLDLT<SpMatrix> solver;
solver.compute(A.transpose()*A);
MatrixXd x = solver.solve(A.transpose()*dB);

This takes 0.15s, in contrast to 6s for LSCG after the setting the tolerance of LSCG to 1E-14.  

 

 

 

 

### 中职学校网络安全理论课程大纲和教学内容 #### 2025年中职学校网络安全理论课程概述 随着信息技术的发展,网络安全已成为信息化社会的重要组成部分。为了适应这一需求,中职学校的网络安全理论课程旨在培养学生具备基本的网络安全意识和技术能力,使学生能够在未来的职业生涯中应对各种网络威胁。 #### 教学目标 该课程的目标是让学生理解网络安全的基本概念、原理和技术手段,掌握常见的安全防护措施,并能应用这些知识解决实际问题。具体来说,学生应达到以下几点: - 掌握计算机网络基础架构及其工作原理; - 理解信息安全管理体系框架及其实现方法; - 学习密码学基础知识以及加密算法的应用场景; - 能够识别常见攻击方式并采取有效防御策略; #### 主要章节安排 ##### 第一章 计算机网络与互联网协议 介绍计算机网络的基础结构和服务模型,重点讲解TCP/IP五层体系结构中的各层次功能特点,特别是传输控制协议(TCP)和用户数据报协议(UDP)[^1]。 ##### 第二章 信息系统安全保障概论 探讨信息系统的脆弱性和风险评估机制,阐述如何通过物理隔离、访问控制等措施来保障系统安全性。 ##### 第三章 密码学入门 讲述对称密钥体制和非对称密钥体制的区别与发展历程,分析公钥基础设施(PKI)的工作流程及其重要性。 ##### 第四章 防火墙技术与入侵检测系统(IDS) 解释防火墙的作用原理及其分类形式(包过滤型、代理服务器型),讨论IDS的功能特性及部署建议。 ##### 第五章 Web应用程序安全 针对Web环境下的特殊挑战展开论述,如SQL注入漏洞利用、跨站脚本(XSS)攻击防范等内容。 ##### 实践环节设置 除了上述理论部分外,在每学期还设有专门实践课时用于模拟真实环境中可能遇到的安全事件处理过程,增强学生的动手操作能力和应急响应水平。 ```python # Python代码示例:简单的MD5哈希函数实现 import hashlib def md5_hash(text): hasher = hashlib.md5() hasher.update(text.encode('utf-8')) return hasher.hexdigest() print(md5_hash("example")) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值