如何在 SymPy 中加速缓慢的矩阵乘法?

2023-12-04

我正在编写一个工具来使用 SymPy 求解特定的递推方程,并发现涉及矩阵乘法的步骤之一花费了非常长的时间。例如,如果我在 iPython 控制台中尝试以下操作,

In [1]: from sympy import *

In [2]: A = Matrix(500, 500, lambda i,j: 2 + abs(i-j) if i-j in [-1, 0, 1] else 0)

In [3]: A[0:7, 0:7]
Out[3]: 
Matrix([
[2, 3, 0, 0, 0, 0, 0],
[3, 2, 3, 0, 0, 0, 0],
[0, 3, 2, 3, 0, 0, 0],
[0, 0, 3, 2, 3, 0, 0],
[0, 0, 0, 3, 2, 3, 0],
[0, 0, 0, 0, 3, 2, 3],
[0, 0, 0, 0, 0, 3, 2]])

In [4]: A * A
...

我从来没有等待足够长的时间来完成它。

我很欣赏符号操作比数值计算慢得多,但这看起来很荒谬。使用 Octave 或其他线性代数包可以在几分之一秒内完成此计算。

有人有使用 SymPy 的矩阵类(行和列 ~ 1000)以及 Rational 条目的经验吗?


任意精度是必须的,速度是可有可无的

有一些用于此目的的 pythonic 类,可能会让您对任意精度计算感兴趣

  • decimal.Decimal()

  • fractions.Fraction( numerator = 0, denominator = 1 )

这些对于精确计算是必不可少的,无论是大规模天文学、DEP 模拟还是其他领域,在这些领域中,精度不得随着长时间/事件/递归的计算策略的进展而降低,以及对标准数字表示的类似威胁。

就我个人而言,我曾与decimal.Decimal()(在密码序列随机性分析中达到 5,000,000 位精度)但并不专注于将它们放在“内部”numpy matrix.

Numpy 可以在其矩阵数据结构中承载这些类型(dtype = decimal.Decimal语法等),但是需要进行测试,以验证其向量化函数操作以及处理这些可爱的 pythonic 类实例后的整体速度。

表现

作为对标准上 numpy 速度的初步观察(“dense“这个规模听起来很有趣)2x2decimal.Decimal-s:

>>> aClk.start();m*m;aClk.stop()
array([[Decimal('0.01524157875323883675019051999'),
        Decimal('5.502209507697009702374335655')],
       [Decimal('1.524157875323883675019051999'),
        Decimal('11.94939027587381419881628113')]], dtype=object)
5732L # 5.7 msec_______________________________________________________________

虽然同样在dtype = numpy.float96 took

>>> aClk.start();f*f;aClk.stop()
array([[ 0.042788046,  0.74206772],
       [ 0.10081096,  0.46544855]], dtype=float96)
2979L # 2.9 msec_______________________________________________________________

对于 500 x 500 完全填充的dtype = fractions.Fraction

>>> aClk.start();M*M;aClk.stop()
array([[Fraction(9, 64), Fraction(1, 4), Fraction(64, 25), ...,
        Fraction(64, 81), Fraction(16, 81), Fraction(36, 1)],
        ..,
       [Fraction(1, 1), Fraction(9, 4), Fraction(4, 1), ...,
        Fraction(1, 4), Fraction(25, 36), Fraction(1, 1)]], dtype=object)
2692088L # 2.7 sec_<<<_Fraction_______________________________vs. 19 msec float96

对于 500 x 500 完全填充的密集区域dtype = decimal.Decimal

>>> aClk.start();D*D;aClk.stop()
array([[Decimal('0.140625'), Decimal('0.25'), Decimal('2.56'), ...,
        Decimal('0.7901234567901234567901234568'),
        Decimal('0.1975308641975308641975308642'), Decimal('36')],
       [Decimal('3.24'), Decimal('0.25'), Decimal('0.25'), ...,
        Decimal('0.02040816326530612244897959185'), Decimal('0.04'),
        Decimal('0.1111111111111111111111111111')],
       [Decimal('0.1111111111111111111111111111'), Decimal('0.25'),
        Decimal('2.25'), ..., Decimal('0.5102040816326530612244897959'),
        Decimal('0.25'), Decimal('0.0625')],
       ...,
       [Decimal('0'), Decimal('5.444444444444444444444444443'),
        Decimal('16'), ..., Decimal('25'), Decimal('0.81'), Decimal('0.04')],
       [Decimal('1'), Decimal('7.111111111111111111111111113'),
        Decimal('1'), ..., Decimal('0'), Decimal('81'), Decimal('2.25')],
       [Decimal('1'), Decimal('2.25'), Decimal('4'), ..., Decimal('0.25'),
        Decimal('0.6944444444444444444444444444'), Decimal('1')]], dtype=object)
4789338L # 4.8 sec_<<<_Decimal_______________________________vs. 19 msec float96
2692088L # 2.7 sec_<<<_Fraction______________________________vs. 19 msec float96

对三对角矩阵 1000x1000 的期望是否可以低于 50 毫秒?

由于有 3,000 个非零(稀疏表示)元素,而不是上面测试的完全填充的 500x500 矩阵中的 250,000 个单元,因此使用这些 Pythonic 类进行任意精度计算会带来巨大的性能飞跃。一旦发动机可以利用分数的优势,分数就有更多的空间numerator/denominator在 Decimal 上构建 MUL/DIV 运算,但是应根据您的计算方法使用的实际情况在体内测试确切的性能范围。

Sympy 语法为SparseMatrix& 在 1000x1000 三对角线上进行测试

1000x1000 的真实测试SparseMatrix然而,正如 @tmyklebu 所提议的那样,由于安装问题,需要更长的时间才能详细说明可能会让您进一步了解现实世界的实施项目:

>>> F = sympy.SparseMatrix( 1000, 1000, { (0,0): 1} )        # .Fraction()
>>> D = sympy.SparseMatrix( 1000, 1000, { (0,0): 1} )        # .Decimal()

>>> for i in range( 1000 ):                                  # GEN to have F & D hold
...     for j in range( 1000 ):                              #     SAME values,
...         if i-j in [-1,0,1]:                              # but DIFF representations
...            num = int( 100 * numpy.random.random() )      #     
...            den = int( 100 * numpy.random.random() ) + 1  # + 1 to avoid DIV!0
...            F[i,j] = fractions.Fraction( numerator = num, denominator = den )
...            D[i,j] = decimal.Decimal( str( num ) ) / decimal.Decimal( str( den ) )

# called in Zig-Zag(F*F/D*D/F*F/D*D/...) order to avoid memory-access cache artifacts

>>> aClk.start();VOID=F*F;aClk.stop()
770353L                                      # notice the 1st eval took  TRIPLE LONGER
205585L                                      # notice the 2nd+
205364L # 0.205 sec_<<<_Fraction()____________________________vs. 0.331 sec Decimal()


>>> aClk.start();VOID=D*D;aClk.stop()
383137L # 0.383 sec_<<<_Decimal()____________________________vs. 0.770 sec 1st Fraction()
390164L # 0.390 sec_<<<_Decimal()____________________________vs. 0.205 sec 2nd Fraction()
331291L # 0.331 sec_<<<_Decimal()____________________________vs. 0.205 sec 3rd Fraction()

>>> F[0:4,0:4]
Matrix([
[ 1/52,  6/23,     0,     0],
[42/29, 29/12,     1,     0],
[    0, 57/88, 39/62, 13/57],
[    0,     0, 34/83, 26/95]])
>>> D[0:4,0:4]
Matrix([
[0.0192307692307692, 0.260869565217391,                 0,                 0],
[  1.44827586206897,  2.41666666666667,               1.0,                 0],
[                 0, 0.647727272727273, 0.629032258064516, 0.228070175438596],
[                 0,                 0, 0.409638554216867, 0.273684210526316]])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 SymPy 中加速缓慢的矩阵乘法? 的相关文章

  • 增量SQL查询

    我的应用程序有一组固定的 SQL 查询 这些查询以轮询模式运行 每 10 秒一次 由于数据库的大小 gt 100 GB 和设计 超级规范化 我遇到了性能问题 每当数据库上发生更改查询结果的 CRUD 事件时 是否可以对给定查询进行增量更改
  • 是否存在比 SVN 更快的集中版本控制?

    我已经使用 SVN 很长时间了 现在我们正在尝试使用 Git 我在这里谈论的不是中心化 去中心化的争论 我唯一关心的是速度 后一个工具要快得多 但有时 我需要使用一种集中式方法 这种方法比分散式方法更简单 更简单 学习曲线非常快 这节省了大
  • 在 C# 中存储矩阵值的快速且有用的方法

    我需要用 C 为 3D 引擎创建一个 4x4 矩阵类 我见过一些其他引擎将矩阵值存储在单个浮点成员变量 字段中 如下所示 float m11 m12 m13 m14 float m21 m22 m23 m24 float m31 m32 m
  • 加快写入文件的速度

    我已经分析了一些我用 cProfile 继承的遗留代码 我已经做了很多有帮助的更改 例如使用 simplejson 的 C 扩展 基本上 该脚本将数据从一个系统导出到 ASCII 固定宽度文件 每一行都是一条记录 并且有许多值 每行有 71
  • 性能计数器的性能影响是什么

    当考虑使用性能计数器作为我公司的基于 NET 的站点时 我想知道使用它们的开销有多大 我是否想让我的网站不断更新其计数器 或者我最好只在测量时更新 设置性能计数器的开销通常不够高 无需担心 设置共享内存区域和一些 NET 对象 以及 CLR
  • 哪个更快:堆栈分配或堆分配

    这个问题听起来可能相当简单 但这是我与另一位合作的开发人员进行的辩论 我小心翼翼地在可能的地方进行堆栈分配 而不是堆分配它们 他一边跟我说话 一边看着我 并评论说没有必要 因为他们的表现是一样的 我总是有这样的印象 堆栈的增长是恒定的时间
  • Xcode“使用性能工具运行”被禁用?

    我正在尝试从我的 Xcode 项目中查找内存泄漏 我不知道发生了什么 我无法选择任何内容Run gt Run with performance tool 事物列表被禁用 请帮助我 我是初学者 问题是我已经删除了构建文件夹并尝试使用性能工具运
  • Array.indexOf 如何比 Array.some 更高效

    这个问题的灵感来自于这个问题的竞争答案 具有多个参数的indexOf https stackoverflow com questions 39000151 indexof with multiple arguments 用户想知道一种有效的
  • sympy 任意函数范围

    我想定义任意函数f 我知道 f 总是返回一个正数 我希望 sympy 在运行简化时能够使用这些知识 特别是简化文档中提到的三个幂规则 有没有办法做到这一点 我正在寻找类似下面的东西 f Function f positive True g
  • 存储 PHP 数组的首选方法(json_encode 与序列化)

    我需要将多维关联数据数组存储在平面文件中以进行缓存 我偶尔可能会遇到需要将其转换为 JSON 以便在我的 Web 应用程序中使用的情况 但绝大多数时候我会直接在 PHP 中使用该数组 在此文本文件中将数组存储为 JSON 或 PHP 序列化
  • 为什么 pandas 在简单的数学运算上比 numpy 更快?

    最近 我观察到 pandas 的乘法速度更快 我在下面的例子中向您展示了这一点 如此简单的操作怎么可能做到这一点 这怎么可能呢 pandas 数据帧中的底层数据容器是 numpy 数组 测量 我使用形状为 10k 10k 的数组 数据框 i
  • 获取所有矩阵列逐元素乘积对的快速方法

    假设我有一个数字matrix set seed 1 mat lt matrix rnorm 1000 ncol 100 我想生成所有向量 它们是中所有唯一向量对的逐元素乘积的结果mat 我们如何改进下面的代码 all pairs lt t
  • 通过增加索引之和来生成排序组合的有效方法

    对于启发式算法 我需要一个接一个地评估特定集合的组合 直到达到停止标准 由于它们很多 目前我正在使用以下内存高效迭代器块生成它们 受到 python 的启发 itertools combinations http docs python o
  • 将数据从一个线程传递到另一个线程的最快可能方法

    我正在使用增强spsc queue将我的东西从一个线程移动到另一个线程 这是我的软件中的关键位置之一 所以我想尽快完成它 我写了这个测试程序 include
  • 为什么对于小数组,for-of 循​​环比标准 for 循环快,而对于大数组则慢?

    在 JavaScript 中 我注意到 ES6for of循环的性能与传统的有很大不同for start stop step loop 基准 const n 10000 const arr Array n fill map e i gt i
  • 组和平均 NumPy 矩阵

    假设我有一个任意的 numpy 矩阵 如下所示 arr 6 0 12 0 1 0 7 0 9 0 1 0 8 0 7 0 1 0 4 0 3 0 2 0 6 0 1 0 2 0 2 0 5 0 2 0 9 0 4 0 3 0 2 0 1 0
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 优化 LATERAL join 中的慢速聚合

    在我的 PostgreSQL 9 6 2 数据库中 我有一个查询 该查询根据一些股票数据构建计算字段表 它为表中的每一行计算 1 到 10 年的移动平均窗口 并将其用于周期性调整 具体来说 CAPE CAPB CAPC CAPS 和 CAP
  • 当我使用可变参数而不是常量参数时,为什么我的内联表 UDF 慢得多?

    我有一个表值内联 UDF 我想过滤该 UDF 的结果以获得一个特定值 当我使用常量参数指定过滤器时 一切都很好 并且性能几乎是瞬时的 当我使用可变参数指定过滤器时 它会花费明显更大的时间块 大约是逻辑读取的 500 倍和持续时间的 20 倍
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式

随机推荐

  • 如何使用 urllib 跟踪重定向?

    我正在 Python 3 中创建一个脚本 该脚本访问如下页面 example com daora zz asp x qqrzzt 使用 urllib request urlopen example com daora zz asp x qq
  • 如何在 Google Apps 脚本中使用 AngularJS

    是否可以使用 Angular js 作为使用 Google Apps 脚本中的 HtmlService 提供服务的 Web 应用程序的一部分 我也改变了Code gs文件如下链接所述 如何在 Google Apps 脚本提供的 HTML 网
  • .NET 框架中最安全的哈希算法是什么?

    生成的哈希值的大小和算法的速度并不重要 我真的只对它是最安全的选择感兴趣 我也不想使用任何第三方库 我使用的 NET 框架版本是 3 5 如果这有什么区别的话 我会想SHA512将是内置哈希算法的最佳选择 它是非常安全的算法的最大哈希形式
  • Python 彗星服务器

    我正在构建一个具有实时提要 类似于 Facebook 的新闻提要 的 Web 应用程序 我想通过长轮询机制对其进行更新 据我所知 对于 Python 我的选择几乎是使用 Stackless 从他们的 Comet wsgi 示例构建 或 Co
  • Openpyxl:将背景颜色设置为行和列属性错误

    看了这里的几个例子后 我尝试将背景颜色设置为整行和整列 我已经做好了 import openpyxl from openpyxl styles import PatternFill wb openpyxl load workbook sel
  • 如何在 Go Web-Server 和 Vue.js 前端之间交换数据? http 帖子:404

    我试图了解如何在非常精简的 golang Web 服务器和 vue js 前端之间交换数据 这是 server gorillamux go 文件 package main import encoding json github com go
  • 如何使用反射调用 IDBSet.FirstOrDefault(predicate)?

    给定一个 IDbSet 其中 Person 包含 Id 属性 我通常如何执行以下命令 var p PersonDbSet FirstOrDefault i gt i Id 3 我可以构建谓词 并获取对 FirstOrDefault 扩展方法
  • 使用 Oracle Wallet 从 PHP 连接到 Oracle DB

    是否可以将 PHP 配置为使用安全的外部密码存储 如中所述http download oracle com docs cd B19306 01 network 102 b14266 cnctslsh htm 是的 这是可能的 您需要 1 创
  • ActiveRecord 中的浮点型与小数型

    有时 Activerecord 数据类型让我感到困惑 呃 经常 我永恒的问题之一是 对于特定情况 我应该使用 decimal or float 我经常看到这个链接ActiveRecord 十进制与 浮点 但答案还不够明确 无法让我确定 我见
  • 无法使用命名空间从动态类中获取常量

    我无法从使用字符串变量和 PHP 5 3 定义的类中获取常量 命名空间 例子 use Some Foo Bar class Bar echo class LOCATION 其中 LOCATION 是一个正确定义的常量 我收到的错误表明 Ba
  • 如何以印地语语言以 unicode 形式存储数据

    我在用PHP and MySQL申请 问题是 如何将数据存储在MySQL 可读格式或 format 当用户在文本框中输入数据并单击提交时 我们会获得不同格式的数据 我们需要做什么来转换并存储在MySQL以可读的格式 选择utf8字符集并ut
  • 具有重复标签的ggplot轴自定义顺序

    set seed 357 x lt data frame name sample letters 10 val runif 10 stringsAsFactors F x c 2 6 name lt c k k ggplot x aes x
  • 主要 C/C++ 编译器生成的代码中的寄存器分配规则

    我记得以前 32 位 Intel 处理器之前 的一些规则 当时 至少对我来说 非常频繁地必须分析 C C 编译器 在我的例子中 当时是 Borland Turbo 生成的汇编输出查找性能瓶颈 并将汇编例程与 C C 代码安全地混合 诸如使用
  • 代码签名错误,如何将 Xcode 项目切换到另一台 Mac?

    我知道如何使用 Xcode 和一切 但这是一个初学者问题 我刚刚买了一台新的 MacBook Pro 我专门用它来开发 iPhone 我将主要应用程序项目从 Mac Mini 转移到了 MacBook Pro 这样我就可以在两台设备上工作
  • 如何重新启动一个线程

    我尝试编写一个文件监视器 如果附加了新行 它将检查文件 该监视器实际上是一个线程 它将始终通过随机访问文件读取该行 这是监控核心代码 public class Monitor public static Logger log Logger
  • 如何在 idl 中声明 IStream,以便 Visual Studio 将其映射到 s.w.interop.comtypes?

    我有一个 COM 对象 需要从 C 客户端获取流并对其进行处理 看来我应该使用 IStream 所以我像下面这样写我的idl 然后我使用 MIDL 编译为 tlb 编译我的解决方案 注册它 然后将对我的库的引用添加到 C 项目 Visual
  • C++ 字符串转二进制代码 / 二进制代码转字符串

    我需要将一个字符串转换为带有第一个字符串的二进制代码的字符串 对于第一部分 我使用了这个 将字符串转换为二进制的最快方法 工作完美 但我无法找到将其写入新字符串的方法 这是我到目前为止使用的代码 for size t i 0 i lt ou
  • Python循环遍历字符串并将其与通配符模式匹配

    string1 abc string2 abdabcdfg 我想知道 string1 是否是 string2 的子串 但是 也有通配符 例如 可以是任何字母 y can be a or d x can be b or c 因此 yx 将是子
  • SQL - WHERE 条件的顺序重要吗?

    假使 假设category id是表的索引键 不是主键 books 下面两条SQL语句有什么区别吗 SELECT FROM books WHERE author Bill AND category id 1 SELECT FROM book
  • 如何在 SymPy 中加速缓慢的矩阵乘法?

    我正在编写一个工具来使用 SymPy 求解特定的递推方程 并发现涉及矩阵乘法的步骤之一花费了非常长的时间 例如 如果我在 iPython 控制台中尝试以下操作 In 1 from sympy import In 2 A Matrix 500