2013-05-05 2 views
1

Использование 64-битную Python 3.3.1 и 32 Гб оперативной памяти и эту функцию для генерации целевого выражения 1+1/(2+1/(2+1/...)):ошибка памяти Python в sympy.simplify

def sqrt2Expansion(limit): 
    term = "1+1/2" 
    for _ in range(limit): 
     i = term.rfind('2') 
     term = term[:i] + '(2+1/2)' + term[i+1:] 
    return term 

я получаю MemoryError при вызове:

simplify(sqrt2Expansion(100)) 

короткие выражения работают отлично, например:

simplify(sqrt2Expansion(50)) 

есть ли способ Conf настроить SymPy для завершения этого расчета? Ниже приводится сообщение об ошибке:

MemoryError        Traceback (most recent call last) 
<ipython-input-90-07c1e2de29d1> in <module>() 
----> 1 simplify(sqrt2Expansion(100)) 

C:\Python33\lib\site-packages\sympy\simplify\simplify.py in simplify(expr, ratio, measure) 
    2878  from sympy.functions.special.bessel import BesselBase 
    2879 
-> 2880  original_expr = expr = sympify(expr) 
    2881 
    2882  expr = signsimp(expr) 

C:\Python33\lib\site-packages\sympy\core\sympify.py in sympify(a, locals, convert_xor, strict, rational) 
    176  try: 
    177   a = a.replace('\n', '') 
--> 178   expr = parse_expr(a, locals or {}, rational, convert_xor) 
    179  except (TokenError, SyntaxError): 
    180   raise SympifyError('could not parse %r' % a) 

C:\Python33\lib\site-packages\sympy\parsing\sympy_parser.py in parse_expr(s, local_dict, rationalize, convert_xor) 
    161 
    162  code = _transform(s.strip(), local_dict, global_dict, rationalize, convert_xor) 
--> 163  expr = eval(code, global_dict, local_dict) # take local objects in preference 
    164 
    165  if not hit: 

MemoryError: 

EDIT:

Я написал версию, используя SymPy выражения вместо строк:

def sqrt2Expansion(limit): 
    x = Symbol('x') 
    term = 1+1/x 
    for _ in range(limit): 
     term = term.subs({x: (2+1/x)}) 
    return term.subs({x: 2}) 

Он работает лучше: sqrt2Expansion(100) возвращает правильный результат, но sqrt2Expansion(200) производит RuntimeError со многими страницами трассировки и вешает IPython-интерпретатор с большим количеством системной памяти, оставшейся неиспользованной. Я создал новый вопрос Long expression crashes SymPy с этой проблемой.

+0

вы можете вставить вывод ошибки? – donfede

+3

Вы __really__ не должны использовать строки, когда можете написать это непосредственно с помощью математических выражений. – Krastanov

+0

@ Krastanov Я попробую, спасибо. –

ответ

2

SymPy использует eval по пути, чтобы превратить вашу строку в объект SymPy, а eval использует встроенный синтаксический анализатор Python с максимальным лимитом. Это не проблема SymPy.

Например, для меня:

>>> eval("("*100+'3'+")"*100) 
s_push: parser stack overflow 
Traceback (most recent call last): 
    File "<ipython-input-46-1ce3bf24ce9d>", line 1, in <module> 
    eval("("*100+'3'+")"*100) 
MemoryError 

Коротких модификаций MAXSTACK в Parser.h и перекомпиляции Python с другим пределом, вероятно, лучшим способом, чтобы попасть туда, куда вы направляетесь, чтобы избежать использования строк в первом место. [Я должен упомянуть, что интерпретатор PyPy может сделать это до ~ 1100 для меня.]

+0

ОК, я собираюсь узнать, как использовать выражение вместо строки. –

+0

+1 для дайвинга в коде C. – Krastanov

+0

Я создал новый вопрос: [Длинное выражение вызывает SymPy] (http://stackoverflow.com/questions/16390875/long-expression-crashes-sympy) –

Смежные вопросы