低 RAM 消耗 C++ 特征求解器

2024-01-09

我是新手C++编程,但我有一个任务来计算特征值和特征向量(标准特征问题Ax=lx)对于对称矩阵(和厄米矩阵))对于尺寸非常大的矩阵:二项式(L,L/2) where L大约是18-22。现在我正在具有大约 7.7 GB 可用内存的机器上进行测试,但最终我将可以访问具有 64GB RAM 的 PC。

我已经开始了Lapack++。一开始我的项目假设只针对对称实矩阵解决这个问题。

这个图书馆很棒。非常快且占用内存小。它可以选择计算特征向量并将其放入输入矩阵 A 以节省内存。有用!我以为Lapack++eigensolver 可以处理埃尔米特矩阵,但由于未知原因而不能处理(也许我做错了什么)。我的项目已经发展,我应该也能够计算埃尔米特矩阵的这个问题。

所以我尝试将库更改为犰狳图书馆。它工作得很好,但它并不那么好Lapack++它取代了mat A所有eigenvec,但当然支持埃尔米特矩阵。

L=14 的一些统计

  • Lapack++RAM 126MB 时间 7.9s 特征值 + 特征向量

  • 犰狳RAM 216MB 时间 12s 特征值

  • 犰狳RAM 396MB 时间 15s 特征值+特征向量

我们来做一下计算:double变量是关于8B。我的矩阵有大小二项式(14,7) = 3432,所以在理想情况下它应该有3432^2*8/1024^2 = 89 MB.

我的问题是:是否可以修改或强制犰狳做一个漂亮的把戏Lapack++? 犰狳 uses LAPACK and BLAS例程。或者也许有人可以推荐使用另一个库解决这个问题的另一种方法?

附: 我的矩阵非常稀疏。它有大约2 * 二项式(L,L/2)非零元素。 我尝试用以下方法计算这个SuperLUCSC 格式,但效果不是很好,L=14 -> RAM 185MB,但时间为 135 秒。


Lapackpp 和 Armadillo 都依赖 Lapack 来计算复矩阵的特征值和特征向量。 Lapack 库提供了不同的方法来对复杂厄米矩阵执行这些操作。

  • 功能zgeev() http://www.netlib.org/lapack/explore-html/dd/dba/zgeev_8f.html不关心矩阵是 Hermitian 矩阵。该函数由 Lapackpp 库针对类型矩阵调用LaGenMatComplex在函数中LaEigSolve http://lapackpp.sourceforge.net/html/laslv_8h.html#086357d17e9cdcaec69ab7db76998769。功能eig_gen() http://arma.sourceforge.net/docs.html#eig_genArmadillo 库的 调用此函数。

  • 功能zheev() http://www.netlib.org/lapack/explore-html/d6/dee/zheev_8f.html致力于复杂的埃尔米特矩阵。它首先调用 ZHETRD 将 Hermitian 矩阵简化为三对角形式。根据是否需要特征向量,然后使用二维码算法 https://en.wikipedia.org/wiki/QR_algorithm计算特征值和特征向量(如果需要)。功能eig_sym() http://arma.sourceforge.net/docs.html#eig_sym犰狳库的调用此函数,如果该方法std被选中。

  • 功能zheevd() http://www.netlib.org/lapack/explore-html/d6/dae/zheevd_8f.html做同样的事情zheev()如果不需要特征向量。否则,它会使用分治算法(请参阅zstedc() http://www.netlib.org/lapack/explore-3.1.1-html/zstedc.f.html<code>)。功能eig_sym() http://arma.sourceforge.net/docs.html#eig_sym犰狳库的调用此函数,如果该方法dc被选中。由于事实证明分治法对于大型矩阵更快,因此它现在是默认方法。

Lapack 库中提供了具有更多选项的函数。 (看zheevr() http://www.netlib.org/lapack/explore-html/d9/dd2/zheevr_8f.html or zheevx http://www.netlib.org/lapack/explore-html/dd/d95/zheevx_8f.html)。如果你想保持密集矩阵格式,你也可以尝试ComplexEigenSolver本征图书馆。

这是使用 C 包装器进行的一点 C++ 测试LAPACKE拉帕克图书馆。它是由g++ main.cpp -o main2 -L /home/...../lapack-3.5.0 -llapacke -llapack -lblas

#include <iostream>

#include <complex>
#include <ctime>
#include <cstring>

#include "lapacke.h"

#undef complex
using namespace std;

int main()
{
    //int n = 3432;

    int n = 600;

    std::complex<double> *matrix=new std::complex<double>[n*n];
    memset(matrix, 0, n*n*sizeof(std::complex<double>));
    std::complex<double> *matrix2=new std::complex<double>[n*n];
    memset(matrix2, 0, n*n*sizeof(std::complex<double>));
    std::complex<double> *matrix3=new std::complex<double>[n*n];
    memset(matrix3, 0, n*n*sizeof(std::complex<double>));
    std::complex<double> *matrix4=new std::complex<double>[n*n];
    memset(matrix4, 0, n*n*sizeof(std::complex<double>));
    for(int i=0;i<n;i++){
        matrix[i*n+i]=42;
        matrix2[i*n+i]=42;
        matrix3[i*n+i]=42;
        matrix4[i*n+i]=42;
    }

    for(int i=0;i<n-1;i++){
        matrix[i*n+(i+1)]=20;
        matrix2[i*n+(i+1)]=20;
        matrix3[i*n+(i+1)]=20;
        matrix4[i*n+(i+1)]=20;

        matrix[(i+1)*n+i]=20;
        matrix2[(i+1)*n+i]=20;
        matrix3[(i+1)*n+i]=20;
        matrix4[(i+1)*n+i]=20;
    }

    double* w=new double[n];//eigenvalues

    //the lapack function zheev
    clock_t t;
    t = clock();
    LAPACKE_zheev(LAPACK_COL_MAJOR,'V','U', n,reinterpret_cast< __complex__ double*>(matrix), n, w);
    t = clock() - t;
    cout<<"zheev : "<<((float)t)/CLOCKS_PER_SEC<<" seconds"<<endl;
    cout<<"largest eigenvalue="<<w[n-1]<<endl;

    std::complex<double> *wc=new std::complex<double>[n];
    std::complex<double> *vl=new std::complex<double>[n*n];
    std::complex<double> *vr=new std::complex<double>[n*n];

    t = clock();
    LAPACKE_zgeev(LAPACK_COL_MAJOR,'V','V', n,reinterpret_cast< __complex__ double*>(matrix2), n, reinterpret_cast< __complex__ double*>(wc),reinterpret_cast< __complex__ double*>(vl),n,reinterpret_cast< __complex__ double*>(vr),n);
    t = clock() - t;
    cout<<"zgeev : "<<((float)t)/CLOCKS_PER_SEC<<" seconds"<<endl;
    cout<<"largest eigenvalue="<<wc[0]<<endl;

    t = clock();
    LAPACKE_zheevd(LAPACK_COL_MAJOR,'V','U', n,reinterpret_cast< __complex__ double*>(matrix3), n, w);
    t = clock() - t;
    cout<<"zheevd : "<<((float)t)/CLOCKS_PER_SEC<<" seconds"<<endl;
    cout<<"largest eigenvalue="<<w[n-1]<<endl;

    t = clock();
    LAPACKE_zheevd(LAPACK_COL_MAJOR,'N','U', n,reinterpret_cast< __complex__ double*>(matrix4), n, w);
    t = clock() - t;
    cout<<"zheevd (no vector) : "<<((float)t)/CLOCKS_PER_SEC<<" seconds"<<endl;
    cout<<"largest eigenvalue="<<w[n-1]<<endl;

    delete[] w;
    delete[] wc;
    delete[] vl;
    delete[] vr;
    delete[] matrix;
    delete[] matrix2;
    return 0;
}

我的计算机的输出是:

zheev : 2.79 seconds
largest eigenvalue=81.9995
zgeev : 10.74 seconds
largest eigenvalue=(77.8421,0)
zheevd : 0.44 seconds
largest eigenvalue=81.9995
zheevd (no vector) : 0.02 seconds
largest eigenvalue=81.9995

这些测试可以通过使用 Armadillo 库来执行。直接调用 Lapack 库可能会让您获得一些内存,但 Lapack 的包装器在这方面也可以很高效。

真正的问题是您是否需要所有特征向量、所有特征值或仅需要最大特征值。因为最后一种情况确实有有效的方法。看看阿诺尔迪/Lanczos https://en.wikipedia.org/wiki/Lanczos_algorithm迭代算法。如果矩阵是稀疏的,则可能会获得巨大的内存增益,因为仅执行矩阵向量乘积:无需保持密集格式。这就是 SlepC 库中所做的事情,它利用了 Petsc 的稀疏矩阵格式。这是一个 Slepc 的例子 http://slepc.upv.es/documentation/current/src/eps/examples/tutorials/ex1.c.html可以作为起点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

低 RAM 消耗 C++ 特征求解器 的相关文章

  • 具有子列表属性映射问题的自动映射器

    我有以下型号 Models public class Dish Required public Int64 ID get set Required public string Name get set Required public str
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • 为什么libc++的shared_ptr实现使用完整内存屏障而不是宽松内存屏障?

    在boost的实现中shared ptr 它用放松内存排序以增加其引用计数 https github com boostorg smart ptr blob master include boost smart ptr detail sp
  • ASP.NET MVC 中的经典 ASP (C#)

    我有一个应用程序想要 最终 转换为 ASP NET MVC 我想要进行全面的服务升级 到 ASP NET 但想要使用当前的 ASP 内容来运行当前的功能 这样我就可以在对新框架进行增量升级的同时升级小部分 该站点严重依赖于不太成熟的 VB6
  • asp.net 文本框文本模式数字,仅允许数字

    我只是想知道 ASP NET 中是否有一种方法只允许文本框中的数字textmode number 当我使用这个时
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • POCO HTTPSClientSession 发送请求时遇到问题 - 证书验证失败

    我正在尝试使用 POCO 库编写一个向服务器发出 HTTPS 请求的程序 出于测试目的 我正在连接到具有自签名证书的服务器 并且我希望允许客户端进行连接 为了允许这种情况发生 我尝试安装InvalidCertificateHandler这是
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 如何挤出平面 2D 网格并赋予其深度

    我有一组共面 连接的三角形 即二维网格 现在我需要将其在 z 轴上挤出几个单位 网格由一组顶点定义 渲染器通过与三角形数组匹配来理解这些顶点 网格示例 顶点 0 0 0 10 0 0 10 10 0 0 10 0 所以这里我们有一个二维正方
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检

随机推荐

  • 将C++类代码分成多个文件,有什么规则?

    思考时间 为什么你要分割你的文件 正如标题所示 我遇到的最终问题是多重定义链接器错误 我实际上已经解决了问题 但我没有以正确的方式解决问题 在开始之前 我想讨论一下将一个类文件拆分为多个文件的原因 我已经尝试将所有可能的情况都放在这里 如果
  • 以编程方式选择 UITextField 中的所有文本

    如何以编程方式选择 UITextField 中的所有文本 这就是我的窍门 self titleField setSelectedTextRange self titleField textRangeFromPosition self tit
  • 从 GridFS 中清除孤立文件

    我有一个引用 GridFS 文件的集合 通常每条记录 1 2 个文件 这些集合相当大 父集合中大约有 705k 条记录 以及 790k GridFS 文件 随着时间的推移 出现了许多孤立的 GridFS 文件 父记录已被删除 但引用的文件并
  • 防止 XSS 但仍允许 PHP 中使用某些 HTML

    我想阻止 XSS 攻击 但我仍然想允许 HTML 标签 例如 b u i img a 和 YouTube 视频播放器 我不想接受 XSS 攻击 我正在使用 PHP 我建议使用html净化器 http htmlpurifier org 它是最
  • 找不到 Microsoft.VisualBasic.Powerpacks.ShapeContainer

    我正在用 C 开发一个游戏 它在我的笔记本电脑上运行正常 但是当我尝试在其他电脑上运行它时 它出现错误 找不到 Microsoft VisualBasic Powerpacks ShapeContainer 我使用 Visual Studi
  • Vue 元素不通过 v-show 隐藏

    我假设 v show 将根据传递的数据显示 隐藏元素 由于某种原因 当 v show 为 false 时 我的元素不会动态隐藏 当我手动将变量 showNav 更改为 false 时 它 将在页面加载时隐藏 因此它似乎可以正常运行 我的变量
  • 无法在 Wear OS Samsung Galaxy Watch 4 上请求蓝牙权限

    我创建了一个示例 Wear OS 应用程序 它应该发现 BLE 设备 但我的代码需要蓝牙权限 当我将这些行放入清单中时
  • 角度 2 中的条件图像 Src 绑定

    三元条件如何写 img src在角度 2 中 下面是我尝试过的代码 但这不起作用 img class lib img height 500 width 500 alt default image src item pictureUrl nu
  • Nsdateformatter 以所选手机的语言返回日期。它可以一直只返回英文吗?

    我正在使用 dateformatter 来获取应用程序中的日期和时间 但是 当我更改手机日期格式器的语言时 我遇到了一个问题 它返回了手机所选语言的日期和时间 由于我们不支持多种语言 因此我的应用程序崩溃了 请找到下面的代码片段 NSDat
  • Android LocationManager 网络提供商返回 null

    我想使用 Android 应用程序获取我的 GPS 坐标 我开始开发 我可以获取GPS坐标 但它们不准确 我想使用 NETWORK PROVIDER 但该提供程序的位置始终为空 更有趣的是 isProvicerEnabled 返回 true
  • 通过 url 参数根据区域设置在 nginx 上设置自定义 404 错误页面

    我正在运行最新的稳定版本Nginx on GNU Linux操作系统并拥有以下虚拟主机 我正在尝试setup custom localized 404 error pages avoiding if但我总是陷入重定向循环 到目前为止 我只考
  • 对齐 html 电子邮件中表格中的数据单元格元素

    我有一个如下所示的屏幕截图 我必须在 HTML CSS 中复制它 附件是fiddle https jsfiddle net dehg79qs embedded result我现在可以复制它 我正在编写 HTML 电子邮件代码 因此这就是我在
  • 等待 asyncio.Future 会引发并发.futures._base.CancelledError,而不是等待设置值/异常

    当我运行以下 python 代码时 import asyncio import logging logging basicConfig level logging DEBUG async def read future fut print
  • 使用bundle exec运行rails控制台

    当我执行时bundle exec rails c我得到一个带有以下提示的 ruby 控制台 Loading development environment Rails 3 0 3 jruby 1 6 3 001 gt 一切看起来都按顺序进行
  • 将 console.log 转换为输出到 div

    我正在使用本主题中的简单 rss feed 解析器示例 Rss 解析器示例 https stackoverflow com questions 10943544 how to parse an rss feed using javascri
  • 应用程序关闭时发送通知

    当应用程序完全关闭时 如何以编程方式发送通知 示例 用户关闭了应用程序 也在 Android 任务管理器中 然后等待 应用程序应在 X 秒后或当应用程序检查更新时发送通知 我尝试使用这些代码示例 但是 应用程序关闭时推送通知 https s
  • sbt-assemble:跳过特定测试

    我想配置sbt assembly跳过特定的测试课程 有什么办法可以做到这一点吗 如果有帮助 我使用 ScalaTest 标记了测试 Network tag See 具有共享源的附加测试配置 http www scala sbt org 0
  • 0 在socket()系统调用中表示什么?

    下一行中的 0 表示什么 我还可以使用哪些其他标志 server socket AF UNIX SOCK STREAM 0 正如其他人可能所说的那样 第三个论点socket一般是一个int指示协议 0表示调用者不想指定协议并将其留给服务提供
  • 在 OSX 10.8 SDK/objective-c 中拖动按钮

    我开始使用 Objective Ctoday为了开发 OSX 山狮 的应用程序 我有一堆按钮 我想将它们拖到其他对象中 例如文本字段 我按照苹果开发网站上的教程进行操作 但我无法让拖动部分工作 放置部分工作 例如 我可以将文件从查找器拖到文
  • 低 RAM 消耗 C++ 特征求解器

    我是新手C 编程 但我有一个任务来计算特征值和特征向量 标准特征问题Ax lx 对于对称矩阵 和厄米矩阵 对于尺寸非常大的矩阵 二项式 L L 2 where L大约是18 22 现在我正在具有大约 7 7 GB 可用内存的机器上进行测试