You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Sympy支持含自定义函数的表达式的模运算求值?

如何在SymPy中实现支持模运算的自定义超大整数函数?

你需要定义一个能处理模运算的自定义函数,且希望SymPy能自动拆解表达式(如Foo(n)+1)计算整体模值,而非返回未化简的Mod对象。以下是问题重现及解决方案:

问题重现

你的初始代码仅能处理单独的Foo(n) % mod,但组合表达式无法自动化简:

from sympy import Function

class Foo(Function):
    @classmethod
    def eval(cls, n):
        pass
    
    def __mod__(self, modulus: int) -> int:
        n, = self.args
        return (n + 1) % modulus

print(Foo(7) % 3)
# 2
print((Foo(7) + 1) % 3)
# Mod(Foo(7) + 1, 3)
print((Foo(7) + 1) % 3 == 0)
# False

解决方案

1. 适配SymPy的模运算钩子

SymPy为自定义函数提供了_eval_mod标准方法,替代直接重载__mod__,更适配SymPy的表达式系统:

from sympy import Function, Integer

class Foo(Function):
    @classmethod
    def eval(cls, n):
        pass
    
    def _eval_mod(self, modulus):
        # 定义Foo(n)的模运算逻辑
        n, = self.args
        return (n + 1) % modulus

2. 递归化简表达式模运算

实现一个递归函数,遍历表达式树,利用模运算的分配律(如(a+b)%m = [(a%m)+(b%m)]%m)自动拆解计算:

def simplify_mod(expr, modulus):
    if isinstance(expr, Integer):
        return expr % modulus
    elif isinstance(expr, Foo):
        return expr._eval_mod(modulus)
    elif expr.is_Add:
        total = 0
        for term in expr.args:
            total += simplify_mod(term, modulus)
        return total % modulus
    elif expr.is_Mul:
        product = 1
        for factor in expr.args:
            product *= simplify_mod(factor, modulus)
        return product % modulus
    elif expr.is_Mod:
        return simplify_mod(expr.args[0], expr.args[1])
    else:
        return expr % modulus

3. 测试验证

print(Foo(7) % 3)
# 输出: 2

expr = Foo(7) + 1
print(simplify_mod(expr, 3))
# 输出: 0

print(simplify_mod(expr, 3) == 0)
# 输出: True

原理说明

  • _eval_mod是SymPy官方提供的自定义函数模运算接口,当SymPy处理Mod(Foo(n), m)时会自动调用该方法。
  • simplify_mod递归遍历表达式的每个节点,对加法、乘法等运算应用模运算的分配规则,避免直接计算超大整数,完美适配你无法存储超大值的场景。

内容的提问来源于stack exchange,提问作者sligocki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:45:08