用于未定方程组的 C++ 库 [关闭]

2024-02-08

我一直在寻找一个 C++ 库来解决这样的不确定系统

q 是向量,w、x、y、z 变量和 a、b、c、d 常量。

argmin_q MAX(q) - MIN(q)

s.t.

q[1] = a - w - y
q[2] = b - w - z
q[3] = c - x - y
q[4] = d - x - z 

找到一个求解器、算法等将非常有用。我找到了几个能够解决未定系统的库,但此外我还需要最小化系数之间的距离。

先感谢您

altober


尽管您可能没有意识到,您的问题可能更多是线性代数问题,而不是编程问题,尽管它确实具有编程维度。

在这个答案中,我假设您的实际问题可能比您在插图中提出的 N = 8 草图大得多。数学讨论是第一位的。示例代码如下。

线性代数问题的本质似乎是它们要么实际上可以用一般的线性代数技术来处理,要么不能。 L-U 分解和奇异值分解等通用线性代数技术自 20 世纪 60 年代以来已得到彻底发展,并具有坚实的理论基础。问题在于,这种通用技术在计算处理上往往是 O(N*N*N),也就是说,让你的向量长 10 倍需要 1000 倍的计算机处理时间。超出某个最大实际尺寸,您的问题在计算上变得难以解决——至少通过一般线性代数技术是这样。

如果您的问题非常严重

幸运的是,存在多种令人眼花缭乱的专用技术可以将 O(N*N*N) 问题简化为 O(N*N) 问题。这些技术大多自 20 世纪 60 年代以来出现,是一个活跃的研究领域。不幸的是,要知道应用哪种技术以及如何应用,需要对问题有深入的了解并且对矩阵数学有相当好的掌握。在 O(N*N*N) 下,通用技术是已知的。在 O(N*N) 中,没有通用技术,只有许多适用于有限类型系统的专用技术。如果您工作足够长的时间,您通常可以找到合适的限制,但它永远不会像将矩阵转储到某些通用求解器中那么简单。不是 O(N*N)。

我读过的关于这个主题的最好的书是 Henk A. van der Vorst 的大型线性系统的迭代 Krylov 方法。令人高兴的是,这本书的价格很合理。当然,在解决范德沃斯特问题之前,您需要在一般线性代数技术方面有坚实的基础。我推荐乔尔·N·富兰克林 (Joel N. Franklin) 1968 年出版的短书矩阵理论,多佛 1993 年推出廉价平装本。 (Van der Vorst 并没有提到 Kapp 和 Brown 的巧妙、简单且通常有效的有序多重交互方法,我多次发现该方法很有用,所以让我在这里提一下,以便您需要时可以查找它。披露:我个人认识布朗,因此可能会偏袒;但是,他和卡普的技术仍然是一项很好的技术,范德沃斯特确实忽略了这一点。)

由于我不完全理解的原因,大多数最近的技术(尽管不是卡普和布朗的)似乎更喜欢在实数中工作,将复数视为特殊情况或完全忽略它们。您没有提到您的数字是否复杂,但如果是,那么这可能会在一定程度上限制您的选择。

作为富兰克林和范德沃斯特之间的中间水平,如果您缺乏时间或兴趣来解决后者,您至少应该查找并熟悉共轭梯度方法。

如果您的问题只是中等程度

如果您的问题只是中等大小(例如,N

LAPACK 库及其低级助手 BLAS 快速、高效、彻底且正确,是该领域的标准。你应该使用它们。

LAPACK、BLAS 和 C++

我和我的同事都尝试过 LAPACK 和 BLAS 的各种 C 和 C++ 接口。由于各种原因,我们发现他们中没有一个是完全令人满意的,尽管他们确实试图提供帮助。我们每个人最终决定完全跳过接口并直接使用 LAPACK 和 BLAS。这就是我倾向于向您推荐的。

LAPACK 和 BLAS 应该从 FORTRAN 77 中调用,而不是从 C++ 中调用。尽管如此,从 C++ 调用它们并不是那么困难,而且您不需要 C++ 接口来完成它。事实上,您可能不想要 C++ 接口,至少不想要其他人准备的通用接口。如果你不把 LAPACK 和 BLAS 合二为一的话,他们会更高兴。 (请记住,FORTRAN 77 的链接功能虽然有效但有限,但缺乏 C 风格的头文件。)

直接使用LAPACK和BLAS首先要知道的是这个,不明白的话你会很惨:矩阵按列优先存储。也就是说,矩阵的每一列(而不是每一行)在内存中顺序表示为一个单元。因此,矩阵元素直接存储在其上方和下方的元素之间,而不是直接存储在其左侧和右侧的元素之间。事实上,LAPACK和BLAS以这种方式存储矩阵是谨慎的,因为发明C的Kernighan和Ritchie似乎对线性代数从来没有很感兴趣。 C 是一种很好的语言,但 C 的默认矩阵存储约定可能从一开始就是一个错误。从数学家的角度来看,LAPACK 和 BLAS 以应有的存储方式存储矩阵,即列优先;而且,如果您正在编写线性代数代码,那么您也应该以这种方式存储矩阵。忽略 C 的默认行优先约定:它与矩阵数学的约定无关,并且您不需要它。

这是一个完整的例子:

#include <iostream>

extern "C" {
    void dgesv_(
        const int *N,
        const int *NRHS,
        double    *A,
        const int *LDA,
        int       *IPIV,
        double    *B,
        const int *LDB,
        int       *INFO
    );
}

int main()
{

    const int N = 2;

    // Let A = | 3.0 6.1 |
    //         |-1.2 1.7 |
    double A[N*N] = {3.0, -1.2, 6.1, 1.7};

    // Let b = | 5.5 |
    //         | 0.4 |
    double x[N] = {5.5, 0.4};
    // (Why is b named x?  Answer:  because b and x share
    // the same storage, because Lapack will write x over b.)

    // Solve the linear system A*x = b.
    const int NRHS = 1;
    const int LDA  = N;
    int       IPIV  [N];
    const int LDB  = N;
    int       INFO;
    dgesv_(&N, &NRHS, A, &LDA, IPIV, x, &LDB, &INFO);
    // Uncomment the next line if you wish to see
    // the error code Lapack returns.
    //std::cout << "INFO == " << INFO << "\n";

    // Output x.
    for (int i = 0; i < N; ++i) std::cout << x[i] << "\n";

    return 0;

}

【为什么函数名为dgesv_()?答案:不是,至少在 FORTRAN 77 中不是,它被命名为 DGESV。然而,FORTRAN 77 不区分大小写,当我们将其转换为 C 的链接约定时,我们得到 dgesv_()。至少,这是我和我的同事在我们尝试过的每台 Linux、BSD 或 OSX 机器上得到的结果。在 Debian 或 Ubuntu 上,shell 命令“readelf --symbols /usr/lib/liblapack.so | grep -i DGESV”会发现这一点。在 Microsoft 平台上,C 连接符号可能有其他名称:您必须调查这是否与您相关。]

LAPACK 和 BLAS 非常擅长他们的工作。你应该使用它们。

将数据存储在 C 样式数组(如示例所示)中还是 C++ 样式 std::valarrays 中取决于您。 LAPACK 和 BLAS 并不关心,只要存储是列优先的即可。

系数最小化

您没有提供足够的信息让我准确地告诉我您希望如何处理系数,但有人怀疑您可能需要的是 N×(2*N) 欠定系统的解决方案。这超出了富兰克林书的范围,但是,如果您已经吸收了富兰克林的材料,那么我自己关于伪逆的笔记 http://derivations.org/可能会帮助你。

显然,如果您正在寻找快速解决方案,我没有。可能有一个预装软件包可以完全满足您的要求,但我的经验表明,这样做的可能性对您不利。实践中会出现数百种不同类型的矩阵问题,预装软件无法破解。然而,LAPACK 和 BLAS 以及 Franklin、van der Vorst 以及您现在正在阅读的答案,提供了解决您的特定问题所需的所有工具。

祝你好运。

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

用于未定方程组的 C++ 库 [关闭] 的相关文章

  • 谁能建议我一种在 C++ 中分割名称的简单方法

    我一直在尝试将名称分为名字和姓氏 但我确信我的实现就简单性而言并不是最好的 string name John Smith string first string last name name find getting lastname fo
  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 在 C# 中按元素相乘数组具有意想不到的性能

    我想找到按元素相乘两个数组的最佳方法 这是更广泛项目的一部分 其中性能而不是唯一的考虑因素 我今天开始用 C Linqpad 编写一些函数 因此它还没有以任何方式进行优化 下面代码的输出如下 Environment ProcessorCou
  • 使用 Enumerable.OfType() 或 LINQ 查找特定类型的所有子控件

    Existed MyControl1 Controls OfType
  • 读取 C# 中的默认应用程序设置

    我的自定义网格控件有许多应用程序设置 在用户范围内 其中大部分是颜色设置 我有一个表单 用户可以在其中自定义这些颜色 并且我想添加一个用于恢复默认颜色设置的按钮 如何读取默认设置 例如 我有一个名为的用户设置CellBackgroundCo
  • 防止 boost::asio::io_context 在空轮询调用时停止

    此代码调用发布的句柄 boost asio io context ioc boost asio post ioc std cout lt lt lol lt lt std endl ioc poll 而这并没有 boost asio io
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 类特定的新删除运算符是否必须声明为静态

    标准中是否要求类特定的 new new delete 和 delete 是静态的 我可以让它们成为非静态成员运算符吗 为什么需要它们是静态的 它们被隐式声明为静态 即使您没有键入 static
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • 为什么 set_symmetry_difference 无法与比较器一起使用?

    Example program include
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959

随机推荐

  • Amazon S3 下载index.html 而不是提供服务

    我已设置 Amazon S3 来为我的静态站点提供服务 speakeasylinguistics com 所有 DNS 东西似乎都工作正常 因为dig recurse trace www speakeasylinguistics com输出
  • 如何将 content:// URI 转换为实际文件路径?

    如何获取 SD 卡上 content uri 指向图像的实际文件路径 我已经调整了 hooked82链接到的代码 protected String convertMediaUriToPath Uri uri String proj Medi
  • 在 HTML 中添加引导程序

    我要使用引导程序 http getbootstrap com 建立我的前端 我还使用 JSP 和 JSTL 我在互联网上的一些文章中读到的是添加外部 javascript 文件的正确方法应该写在正文结束标记之前 以便更好地优化页面 现在我正
  • Java 语言规范第三版勘误表

    我广泛使用 JLS 作为学习和教学资源 但我注意到其中存在一些错误 有一些简单的拼写错误 例如金龙5 1 4 http java sun com docs books jls third edition html conversions h
  • 负载均衡 Amazon EC2 上的节点 socket.io

    我有一个在 Amazon AWS 上运行的标准 LAMP EC2 实例设置 为了满足实时更新的需求 我还安装了 Node js socket io 和 Express 现在正处于应用程序负载平衡的阶段 这一切都有效 但我的套接字却不起作用
  • 删除非 ASCII 字符(使用 Microsoft.Office.Interop.Excel)

    我正在尝试从 excel csv 文件中删除所有非 ascii 字符 在线阅读和搜索后 我发现了一篇帖子 其中给了我代码xlWorksheet UsedRange Replace u0000 u007F 删除字符但每次但字符仍然存在于文件中
  • 如何在管道内使用“if”语句

    我正在尝试使用if管道内 我知道有where alias 过滤器 但是如果我想仅在满足特定条件时才激活过滤器怎么办 我的意思是 例如 get something someone eq somespecific format table 如何
  • 从 gtsummary 包中的 tbl_summary 对象获取 LaTex 输出的最佳方法[关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 我正在努力准备一份文档出版 并且正在 LaTeX 中完成所有工作 然而 我现在才注意到gtsummary尚不支持其表格的 LaTeX
  • 帧持续时间 - UIImage 数组到电影

    我已经通过此代码成功完成了 将 UIImage 数组导出为电影 部分 在导出的视频中 每个图像显示 1 秒 但我需要 每个图像将在导出的视频中显示 5 秒 我需要做的最小改变是什么 这是我的代码 var outputSize CGSize
  • java正则表达式模式分割逗号

    String line a 1 b 1 2 c d 1 e 1 11 String tokens line split for String t tokens System out println gt t System out print
  • 异常日志文件的最佳位置 (Windows)

    异常日志应该放在哪里的问题已经在这里讨论过一两次 或多次 其中一个建议是应用程序永远不应该写入安装文件夹 但是 如果我将日志放在 appdata 中的某个位置 这意味着每个用户都有自己的一组日志 我更喜欢将所有日志放在一个位置 在最新的 M
  • 循环进口地狱

    Python 是一种极其优雅的语言 好吧 除了 除了进口 我仍然无法让它按照我认为自然的方式工作 我有课MyObjectA这是在文件中mypackage myobjecta py 该对象使用一些实用函数 这些函数位于mypackage ut
  • 停止将 typescript-eslint/explicit-module-boundary-types 应用于不使用 Typescript 的 vue 组件

    我在用着vue我刚刚更新了 typescript eslint eslint plugin 3 10 1 我的项目包含几个组件 其中一些正在使用javascript和别的typescript Warning 我对里面的方法有这个警告non
  • 在 SQL LIKE 语句中使用变量

    我有一个存储过程 MSSQL 2k5 它将为 LIKE 子句接受一个变量 如下所示 DECLARE SearchLetter2 char 1 SET SearchLetter t SET SearchLetter2 SearchLetter
  • 为什么glBufferSubData需要等到VBO不被glDrawElements使用?

    在 OpenGL Insights 中 它说 OpenGL 驱动程序必须等待 因为使用了 VBO 由上一帧的 glDrawElements 绘制 这让我很困惑 据我所知 glBufferSubData会将数据复制到临时内存 然后再传输到GP
  • 使用 Box Windows SDK v2 库对 C# 桌面应用程序中的 Box 进行身份验证

    看起来这应该是一件简单的事情 但我找不到示例或足够详尽的文档来弄清楚 我有一个 C 桌面应用程序 我想通过 Box API 与 Box 集成 我认为使用 Box Windows SDK v2 for NET 将是最佳选择 有人能给我指一个适
  • Php:检查电子邮件内容是否为垃圾邮件

    我正在创建一个新闻通讯功能 允许用户发送电子邮件 由于存在恶意人员想要发送垃圾邮件 因此我希望能够检查并查看创建的邮件是否是垃圾邮件 我已经研究了几种不同的方法 例如尝试垃圾邮件杀手 但您需要完整的电子邮件 而我稍后才会得到 或者您需要安装
  • 即使文件不存在,为什么 SELECT INTO OUTFILE 也会给出文件存在错误?

    该文件肯定不存在 但我还是收到错误 I do rm tmp records materialized view txt mysql gt SELECT FROM records materialized view INTO OUTFILE
  • AngularJS:如何获取模板的 $location.path

    我需要模板中 url 的当前路径 location path 的内容 但不是通过控制器 因为我有很多控制器 并且我不想重复声明 scope currentUrl location path 感谢您的建议 AngularJS 模板只能看到范围
  • 用于未定方程组的 C++ 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我一直在寻找一个 C 库来解决这样的不确定系统 q 是向量 w x y z 变量和 a b c d 常