Python接口到GAP
项目描述
gappy — Python到GAP的接口
gappy通过链接到其库接口,为GAP计算机代数系统提供Python接口。
它允许从Python直接调用GAP中的函数,并将支持的Python对象传递回GAP。
gappy基于SageMath的LibGAP接口到GAP,最初由Volker Braun开发,但完全独立于Sage - 它不需要或使用Sage,可以在任何Python代码中使用。如果足够有兴趣,它也可能通过一个用于在GAP内与Python交互的补充GAP包进行增强。
快速入门
要从Python开始使用GAP函数,只需运行
>>> from gappy import gap
然后GAP中的任何全局变量,包括函数,都可以作为gap上的属性访问,如
>>> gap.Cite()
Please use one of the following samples
to cite GAP version from this installation
Text:
[GAP] GAP – Groups, Algorithms, and Programming, Version 4.dev, The GAP Group, https://www.gap-system.org.
...
所有在GAP会话中可用的全局变量都可以以此方式访问
>>> GAPInfo.Version
"4.dev"
大多数基本的Python类型在GAP中都有直接等效,可以直接传递给GAP函数,而无需显式转换为它们的等效GAP类型
>>> S4 = gap.SymmetricGroup(4)
>>> S4
Sym( [ 1 .. 4 ] )
您还可以在GapObj对象上调用“方法”。这只是在函数支持将对象绑定到方法的情况下,以该对象作为第一个参数调用GAP函数的语法糖。例如
>>> S4.GeneratorsOfGroup()
[ (1,2,3,4), (1,2) ]
GAP函数返回的值是包裹在名为GapObj的Python类中的GAP对象
>>> type(S4)
<class 'gappy.gapobj.GapObj'>
还有许多类型的GAP对象的专门子类。要显式地将Python对象直接转换为它的GAP等价物,您可以像下面这样调用gap
>>> one = gap(1)
>>> type(one)
<class 'gappy.gapobj.GapInteger'>
当在REPL中显示对象或在对象上调用GAP的Print()函数时,GAP对象将(使用repr)或字符串化(使用str)以与GAP中相同的方式进行显示
>>> one
1
>>> s = gap("Hello GAP!")
>>> s
"Hello GAP!"
>>> print(s)
Hello GAP!
并非所有GAP对象在基本Python类型中都有等价物,因此从GAP到Python没有隐式转换。但是,所有可以转换为GAP对象的Python类型都可以以对称的方式转换回它们等价的Python类型
>>> int(one)
1
>>> type(int(one))
<class 'int'>
>>> str(s)
'Hello GAP!'
>>> type(str(s))
<class 'str'>
类似地,对于浮点数、列表、字典等其他类型也是如此。
如果您要转换为其等效Python类型的对象,也可以调用obj.python()
>>> type(one.python())
<class 'int'>
有关为GAP对象注册自己的转换为自定义Python类型的转换器,请参阅gap.convert_to装饰器。
最后,您可以直接使用gap.eval执行任意GAP代码。这通常是构造更复杂GAP对象的简单方法,尤其是如果您更熟悉GAP语法。span class="docutils literal">gap.eval的返回值是在GAP中评估相同语句的结果(当评估单个语句时,分号是可选的)
>>> rec = gap.eval('rec(a:=123, b:=456, Sym3:=SymmetricGroup(3))')
>>> rec['Sym3']
Sym( [ 1 .. 3 ] )
这也是从gappy声明新GAP函数的简单方法
>>> sign = gap.eval("""sign := function(n)
... if n < 0 then
... return -1;
... elif n = 0 then
... return 0;
... else
... return 1;
... fi;
... end;""")
>>> sign
<GAP function "sign">
>>> sign(0)
0
>>> sign(-99)
-1
有关如何使用gap对象以及内置的GapObj类型的大量其他示例,请参阅完整的API文档。
安装
先决条件
支持的平台:Linux、MacOS、Cygwin。
可能适用于大多数其他*BSD版本,但尚未经过测试。
Python 3.6或更高版本,并已安装开发头文件。在基于Debian的系统上,这意味着
$ sudo apt-get install python3.7-dev
GAP 4.10.2或更高版本
可以从PyPI安装(注意分布名称为gappy-system,不要安装名为“gappy”的包,它是一个无关的已弃用包)
$ pip install gappy-system
或从源代码安装
$ git clone https://github.com/embray/gappy.git
$ cd gappy/
$ pip install .
但是,根据GAP的安装方式,可能需要一些额外的步骤。特别是,如果您按照GAP网站上的典型说明从源代码安装GAP,您需要确保通过在GAP源目录中运行以下命令来构建libgap共享库
$ make install-libgap
在GAP源目录中。
您还需要通过设置环境变量GAP_ROOT来指向您的GAP安装位置,例如
$ GAP_ROOT=<path/to/gap/root> pip install .
如果您需要在安装时提供GAP_ROOT,则通常还需要在使用gappy之前设置此环境变量,以便它可以找到您的GAP安装路径。有关更多信息,请参阅Gap类的文档。
但是,如果您使用APT在Debian/Ubuntu或Conda等发行版中从GAP安装,则GAP库(libgap)通常安装在标准系统位置,并且可能不需要提供GAP_ROOT。下一节将提供示例。
Conda安装
以下是一个示例,说明如何安装Conda环境中的gappy
$ conda create -n gap
$ conda activate gap
$ conda install -c conda-forge gap-defaults==4.11 python==3.8
$ pip install .
或者,您可以使用提供的 environment.yml 文件创建 conda 环境
$ conda env create
Cygwin安装
Cygwin 安装时的附加说明
依赖项 psutil 不支持 Cygwin。然而,有一个非官方分支支持 Cygwin,地址为: https://github.com/embray/psutil/tree/cygwin/v3。您可以通过运行以下命令来安装它:
$ pip install git+https://github.com/embray/psutil.git@cygwin/v3
libgap DLL(文件名 cyggap-0.dll)的路径需要位于您的 PATH 环境变量中,以便 gappy 可以导入。为此,您可以从 GAP 安装中将其复制到标准位置,例如
$ cp /path/to/gap_root/.libs/cyggap-0.dll /usr/local/bin
或者您可以将环境修改为指向 GAP 放置构建 DLL 的位置
$ export PATH="/path/to/gap_root/.libs:$PATH"
并将此添加到您的 .profile 中。
变更日志
v0.1.0a3 (2021-02-15)
增强功能
根据 https://trac.sagemath.org/ticket/31297#comment:23 上的讨论,将特殊方法 _gap_(用于将任意 Python 对象转换为 GAP 对象)重命名为 __gap__。
同样,特殊方法 _gap_init_ 现在命名为 __gap_eval__,以强调它返回一个字符串,该字符串将传递给 Gap.eval()。它仍然不接受任何参数。
添加了 GapObj.python() 方法,用于将 GapObj 转换为其等效类型(如果存在)。它并不总是这样做,但在存在内置于 Python 的等效类型的案例中这样做。
GapList.python() 和 GapRecord.python() 也递归地将它们包含的值转换为等效的 Python 类型(如果可能)。
注册转换器到/从 GAP 对象类型的新接口
Gap.register_converter 被替换为 Gap.convert_from 装饰器。
可以使用 GapObj.convert_to 装饰器在 GapObj 或其特定子类上注册新的转换方法。
在 GapInteger 上添加了一些 C 级别的实用方法,以帮助转换为不同的整数类型(根据 int 的大小,是 C long int 还是 mpz_t)。这有助于更有效地转换为 Sage 整数,而无需通过中间的 Python int。
为 GapObj 实现了 __invert__ 和 __neg__ 魔法方法。
为所有 GapObj 实现了默认的 __bool__,如果其值等于零则返回 False。
安装 .pyx 源文件,以便 Cython 跟踪回溯可以更好地工作。
错误修复
当使用 dict(rec) 将 GapRecord 转换为字典时,键保持为 GapString 而不是 str。这与值没有被转换为 Python 等效的事实更一致。
如果在使用 Gap.__getattr__ 查找全局变量时发生任意 GAP 错误,则会处理它并将其重新抛出为 AttributeError。
Gap.__repr__ 方法正确显示子类的名称。
v0.1.0a2 (2021-02-03)
错误修复
对 MacOS 和 Cygwin 支持进行了修复。
v0.1.0a1 (2021-02-03)
增强功能
为使用 gap.gap_functions 定义的函数添加了 LRU 缓存,恢复了 Sage 的 Gap.function_factory 的一些缓存功能。
错误修复
修复了嵌套列表的多索引错误。
修复了在索引单个列表与索引嵌套列表时 IndexError 消息中的轻微格式差异。
修复了在调用之前将使用 gap.gap_function 定义的函数作为另一个 GAP 函数的参数时出现的错误。
v0.1.0a0 (2021-01-26)
SageMath 测试的初始 alpha 版本。
项目详情
gappy-system-0.1.0a3.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 90a2c9b6c4fd07ef3b9197303a929c00806e6c397b383895ffae1044864b0e5b |
|
MD5 | cb4f31f5a89bf806f7f5c68c9241dd04 |
|
BLAKE2b-256 | 5a4fa3b8001054faab5459105c5f9343f8d09747bd7a9e52e5152dcaf65e7076 |