SageMath:如何从模块化 pow 中提取数值

问题描述

在 sagemath 命令行中,当我进行这样的操作时

sage: m = pow(2,5,2)
sage: m
0
sage: m = pow(2,3)
....: n = pow (3,4)
....: m
2
sage: n
3
sage: m * n

unsupported operand parent(s) for *: 'Ring of integers modulo 3' and 'Ring of integers modulo 4'

由此看来,每当您调用模数 pow 时,输出就会与模数相关联,而不是本身就是一个数值

这不会发生在本机 python 程序中。

cat a.py

m = pow (2,3)
n = pow (3,4)
print (m*n)

python a.py

6

此外,如果我将数字相乘,即使我没有要求这样做,乘法也会以模数进行

sage: m = pow(2,5)
....: n = pow (3,5)
....: m
2
sage: n
3
sage: m * n
1

所以我的问题是

  1. 如何从此处的 mn提取数值,以便在非模块化操作中使用它们?

  2. 这是 pow 特有的吗?如果没有,还有哪些其他函数表现出这种行为?

  3. 这背后有什么理由吗?我的意思是,python 本身不会这样做

  4. 可以关闭吗?

解决方法

为了避免模幂运算给出“整数模某物”, 使用power_mod

sage: a = power_mod(2,5,3)
sage: b = power_mod(3,4)
sage: a,a.parent(),b,b.parent()
(2,Integer Ring,3,Integer Ring)
sage: p = a * b
sage: p,p.parent()
(6,Integer Ring)

要将“整数模数”拯救为“通常的整数”, 使用 intIntegerZZ

sage: m = pow(2,3)
sage: n = pow(3,4)
sage: m,m.parent(),n,n.parent()
(2,Ring of integers modulo 3,Ring of integers modulo 4)

sage: p = int(m) * int(n)
sage: p,type(p)
(6,<class 'int'>)

sage: p = Integer(m) * Integer(n)
sage: p,Integer Ring)

sage: p = ZZ(m) * ZZ(n)
sage: p,Integer Ring)

要检查 Sage 预解析器在这种情况下的作用:

sage: preparse('m = pow(2,3)')
'm = pow(Integer(2),Integer(5),Integer(3))'

所以 Sage 不是在调整 pow 而是只是转动 输入到 Sage 整数中的任何整数。 然后会发生pow(a,c) 变成 a.__pow__(b,c) 和 Sage 整数 有自己的 __pow__ 方法可以吐出 整数模某物。

要关闭 Sage 预解析器:

sage: preparser(False)
sage: m = pow(2,type(m),type(n)
(2,<class 'int'>,<class 'int'>)
sage: p = m * n
sage: p,<class 'int'>)

为了避免使用 pow 和预解析器时的行为, 将整数标记为原始或使用 int:

sage: preparser(True)

sage: m = pow(2r,5r,3r)
sage: n = pow(3r,4r)
sage: m,<class 'int'>)

sage: m = pow(int(2),int(5),int(3))
sage: n = pow(int(3),int(4))
sage: m,<class 'int'>)

禁用所有 Python 整数到 Sage 整数的转换 同时保持 Sage 预解析器开启:

sage: Integer = int
sage: m = pow(2,<class 'int'>)

恢复 Python 整数到 Sage 整数的转换:

sage: Integer = sage.rings.integer.Integer