Есть ли способ без взлома печатать непрерывные дроби в SymPy с целыми числами без оценки?

Я хотел бы, чтобы непрерывные дроби с целыми числами отображались в этой форме с помощью SymPy, но я не могу заставить SymPy соответствовать. Я нашел этот вопрос и ответ Stack Overflow очень полезным (см. Ниже), но не могу достичь своей цели здесь:

Это разложение $\frac{13}{5}$ на непрерывные дроби. Обычное обозначение для этого расширения состоит в том, чтобы давать только термины в рамке, как SymPy ниже, то есть $[2,1,1,2]$ из SymPycontinued_fraction_iterator:

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, 1, 1, 2].

На стр. 37 руководства Sympy версии 1.5 от 9 декабря 2019 г. приведен фрагмент кода для печати такого расширенного списка фракций:

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_5 непрерывных дробей, SymPy взлетает и оценивает его:

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, n1, n2]
contfrac12201015 = list_to_frac( [n2,n1,n1,n2] )
contfrac122010154

Что дает желаемое (я работаю в среде JupyterLab, поэтому фактически получаю вывод LaTeX с набором):

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

Я переписал list_to_frac, чтобы использовать средство UnevaluatedExpr, представленное Франческо в вопросе StackOverflow, который я цитировал ранее:

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

Вызов list_to_frac_noEval в списке расширения $\frac{13}{5}$:

list_to_frac_noEval( [2,1,1,2] )

я получаю вывод

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

Некоторые люди используют эту нотацию (поэтому я хотел поделиться list_to_frac_noEval в любом случае, это лучше, чем получить оцененное единственное рациональное число, если вы хотите увидеть непрерывную дробь), например Роджер Пенроуз в разделе $\unicode{x00A7}3.2 $ из «Дороги к реальности» (2004), но меня все еще раздражает, что я не могу получить явный формат непрерывной дроби при использовании целых чисел вместо символов.

Я экспериментировал с заменой целых чисел на символы с evaluate=False, используя как метод subs, так и функцию Subs, просмотрел различные комбинации sympify и srepr и parse_expr с evaluate=False, , но не смог убедить SymPy 1.4 напечатать явную форму дроби, которую я получаю с list_to_frac работа с символьными аргументами. Есть ли способ выполнить это, за исключением изменения кода SymPy или специального оформления определенного набора чисел?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
345
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете создать выражение, явно передавая 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], expr, evaluate=False)

Это дает:

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

In [3]: nums
Out[3]: [2, 1, 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

Хорошее решение. Мой SymPy 1.4 в Jupyter Lab не меняет отображение с иврита на обычное с помощью init_printing(order='old'), но это незначительно. Кроме того, моя версия печатает не 0 + 2, а правильную дробь 1/2, поэтому я не буду жаловаться. Интересно посмотреть на дерево операций в действии. Спасибо.

Dalton Bentley 21.12.2020 22:40

Вывод, который я показал выше, относится к мастеру sympy, который близок к недавно выпущенному sympy 1.7.1.

Oscar Benjamin 22.12.2020 11:40

Полезно знать (разница в поведении init_printing связана с изменением в новой версии, т. е. улучшением). Я буду "стоять при себе" (не брать больше карт и играть с той рукой, которая у меня есть).

Dalton Bentley 22.12.2020 16:50

Другие вопросы по теме