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

SageMath: How to extract the numerical value from a Modular pow

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

sage: m = pow(2, 5, 2)
sage: m
0
sage: m = pow(2, 5, 3)
....: n = pow (3, 5, 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 程序不会发生这种情况。

猫a.py

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

python a.py

6

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

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

所以我的问题是

  1. 如何从这里的m & n中提取一个数值,以便我可以在非模块化操作中使用它们?

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

  3. 这背后是否有任何理由 - 我的意思是,python 本身不会这样做

  4. 可以关掉吗?

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

sage: a = power_mod(2, 5, 3)
sage: b = power_mod(3, 5, 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, 5, 3)
sage: n = pow(3, 5, 4)
sage: m, m.parent(), n, n.parent()
(2, Ring of integers modulo 3, 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, p.parent()
(6, Integer Ring)

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

检查 Sage 预解析器在这种情况下做了什么:

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

所以 Sage 不是在调整 pow,而只是转向 将输入中的任何整数转换为 Sage 整数。 然后发生的是 pow(a, b, c) 变成 a.__pow__(b, c) 和 Sage 整数 有自己的__pow__方法吐出来 整数模数。

要关闭 Sage 预解析器:

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

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

sage: preparser(True)

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

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

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

sage: Integer = int
sage: m = pow(2, 5, 3)
sage: n = pow(3, 5, 4)
sage: m, type(m), n, type(n)
(2, <class 'int'>, 3, <class 'int'>)
sage: p = m * n
sage: p, type(p)
(6, <class 'int'>)

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

sage: Integer = sage.rings.integer.Integer