是否有一种非黑客方法可以在 SymPy 中使用整数打印连分数而不进行评估?

如何解决是否有一种非黑客方法可以在 SymPy 中使用整数打印连分数而不进行评估?

我想用 SymPy 以那种形式显示带整数的连分数,但我似乎无法让 SymPy 遵守。我发现 this Stack Overflow 问题和答案非常有用(见下文),但在这里无法达到我的目标:

example of continued explicit fraction notation

这是 $\frac{13}{5}$ 的连续分数展开。这种扩展的一个常见符号是只给出框内的术语,如下面的 SymPy,即 SymPy continued_fraction_iterator 中的 $[2,1,2]$:>

Rat_13_5 = list(continued_fraction_iterator(Rational(13,5)))
print( Rat_13_5 )
Rat_13_5 = list(continued_fraction_iterator(Rational(13,5)))
( Rat_13_5 )
print( Rat_13_5 )

输出 [2,2]

Sympy 手册版本 1.5 2019 年 12 月 9 日的第 37 页提供了一个代码片段来打印这样一个扩展的分数列表:

def list_to_frac(l):
    expr = Integer(0)
    for i in reversed(l[1:]):
        expr += i
        expr = 1/expr
    return l[0] + expr

如果您使用 list_to_frac 连分数扩展列表调用 Rat_13_5SymPy 会启动并计算它:

print( list_to_frac( Rat_13_5 ) )

输出 13/5

如果您使用符号列表,则 list_to_frac 打印所需的连分数,例如,

n1,n2,n3,n4,n5,n6,n7,n8,n9 = symbols('n1:10')
cont_frac_list = [n2,n1,n2]
contfrac12201015 = list_to_frac( [n2,n2] )
contfrac122010154

产生所需的结果(我在 JupyterLab 环境中工作,因此实际上我在整个过程中都获得了 typset LaTeX 输出):

n2 + 1/(n1 + 1/(n1 + 1/n2))

我重写了 list_to_frac 以使用 Francesco 在我之前引用的 StackOverflow 问题中提供的 UnevaluatedExpr 工具:

def list_to_frac_noEval(l):
    expr = Integer(0)
    for i in reversed(l[1:]):
        expr = UnevaluatedExpr(expr + i)
        expr = UnevaluatedExpr( 1/expr )
    return l[0] + expr

在 $\frac{13}{5}$ 扩展列表上调用 list_to_frac_noEval

list_to_frac_noEval( [2,2] )

我获得输出

2 + (1 + (1 + 2**(-1))**(-1))**(-1)

有些人使用这种符号(所以我想在任何情况下分享 list_to_frac_noEval,如果你想看到连分数,那比以一个评估的单一有理数结束更好),例如 Roger Penrose in section $\unicode{x00A7}3.2$ The Road to Reality (2004),但我仍然觉得很烦人,当使用整数而不是符号时,我无法获得显式连分数格式。

我尝试用整数代替符号 evaluate=False,同时使用 subs 方法Subs 函数,研究了 sympify 和 {{1 }} 和 sreprparse_expr,,但无法说服 evaluate=False 打印我使用 SymPy 1.4 对符号参数进行操作获得的显式分数形式。有没有办法在不修改 list_to_frac 代码或特殊大小写一组特定数字的情况下实现这一点?

解决方法

您可以将 evaluate=False 显式传递到表达式树的每个部分来构造表达式:

def list_to_frac(l):
    expr = Integer(0)
    for i in reversed(l[1:]):
        expr = Add(i,expr,evaluate=False)
        expr = Pow(expr,-1,evaluate=False)
    return Add(l[0],evaluate=False)

这给出:

In [2]: nums = list(continued_fraction_iterator(Rational(13,5)))

In [3]: nums
Out[3]: [2,1,2]

In [4]: list_to_frac(nums)
Out[4]: 
      1          
───────────── + 2
    1            
───────── + 1    
  1              
───── + 1        
0 + 2  

看起来这是错误的方式,但这只是使用默认设置进行打印的方式:

In [5]: init_printing(order='old')

In [6]: list_to_frac(nums)
Out[6]: 
          1      
2 + ─────────────
            1    
    1 + ─────────
              1  
        1 + ─────
            0 + 2

您可以使用 doit 触发评估:

In [7]: _.doit()
Out[7]: 13/5

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?