2016-01-27 13 views
9

आज मैंने पाया इससिम्पी कक्षाएं शून्य, एक और नकारात्मक, वे क्यों मौजूद हैं?

>>> type(1) 
<class 'sympy.core.numbers.One'> 
>>> type(0) 
<class 'sympy.core.numbers.Zero'> 
>>> type(-1) 
<class 'sympy.core.numbers.NegativeOne'> 
>>> type(2) 
<class 'sympy.core.numbers.Integer'> 

मैं उन प्रकारों के बारे में documentation from sympy देखा, लेकिन इसके बारे में क्यों वे मौजूद कुछ नहीं कहा। क्या -1, 0 और 1 के लिए 3 विशेष सिंगलटन कक्षाएं हैं?

संपादित करें: मैं SymPy में हर संख्या the class Number का एक उदाहरण का प्रतिनिधित्व करती है SymPy online shell

+0

क्या बिल्ली तुम के लिए क्या किया 'int' के अलावा कुछ भी होने के लिए 'टाइप (1) 'प्राप्त करें? – user2357112

+0

@ user2357112 बस आयातित सिम्पी मॉड्यूल –

+0

आयात करना सिम्पी इस तरह के पार्सर के साथ पेंच नहीं करेगा। 'टाइप (1) 'हमेशा एक वास्तविक पायथन पूर्णांक का निर्माण करेगा और इसका प्रकार लेगा, जो' int' होगा। – user2357112

उत्तर

5

पर देखा। Float एस, Integer एस और Rational एस Number के उप-वर्ग हैं। ZeroInteger का उप-वर्ग है।

आप अपने वर्ग के mro (विधि संकल्प क्रम) विधि को फोन करके एक वस्तु का पूरा वर्ग वंश का निरीक्षण कर सकते हैं:

In [34]: from sympy import S 
In [38]: type(S.Zero).mro() 
Out[38]: 
[sympy.core.numbers.Zero, 
sympy.core.numbers.IntegerConstant, 
sympy.core.numbers.Integer,   <-- Zero is a kind of Integer 
sympy.core.numbers.Rational, 
sympy.core.numbers.Number, 
sympy.core.expr.AtomicExpr, 
sympy.core.basic.Atom, 
sympy.core.expr.Expr, 
sympy.core.basic.Basic, 
sympy.core.evalf.EvalfMixin, 
object] 

ये उपवर्गों "सिखाने" SymPy कैसे हेरफेर और भाव प्रतीकात्मक आसान बनाने के लिए। एक उदाहरण के रूप में, वाजिब वर्ग के उदाहरण negated this way हैं:

def __neg__(self): 
    return Rational(-self.p, self.q) 

, कहने के लिए है, तो xRational का एक उदाहरण है है, तो -x का कारण बनता है x.__neg__() कहा जाता है।

@staticmethod 
def __neg__(): 
    return S.Zero # the negation of Zero is still Zero 

Zero, One और MinusOne: इस बीच, Integer वर्ग के उदाहरण, negated by

def __neg__(self): 
    return Integer(-self.p) 

हैं और वस्तु, Zero का एक उदाहरण विशेष रूप से, है, तो its negation है द्वारा परिभाषित किया गया _eval_power विधि को भी लागू करें जो इन वस्तुओं को "सिखाता है" x को एक शक्ति में कैसे बढ़ाया जाए (जहां x है Zero, One या MinusOne)। उदाहरण के लिए, Zero raised to a positive expression ही बराबर है:

def _eval_power(self, expt): 
    if expt.is_positive: 
     return self 
    ... 

One raised to anything ही बराबर है:

def _eval_power(self, expt): 
    return self 

आप sympy.core.numbers मॉड्यूल के लिए the source code अवलोकन हैं, तो आप करने के लिए जो प्रभाव में हैं परिभाषाओं की भार SymPy शिक्षण कैसे मिल जाएगा प्रतीकात्मक अंकगणित करें। यह गणित वर्ग में बच्चों को सिखाए जाने से बहुत अलग नहीं है, सिवाय इसके कि यह कंप्यूटर-ese में व्यक्त किया गया है।

आप सोच रहे होंगे कि प्रत्येक पूर्णांक के लिए एक विशेष कक्षा क्यों नहीं है। IntegersZero, One और MinusOne सामान्य Integer कक्षा के उदाहरणों के रूप में माना जाता है। उनके नियम और गुणा के नियम और इतने पर रखा गया है।विपरीत Zero, One और MinusOne जो जब मॉड्यूल लोड किया जाता है instantated कर रहे हैं, अन्य पूर्णांकों only as needed कैश नहीं किया जाता:

def __new__(cls, i): 
    ... 
    try: 
     return _intcache[ival] # <-- return the cached Integer if seen before 
    except KeyError:   
     obj = Expr.__new__(cls) # <-- create a new Integer if ival not in _intcache 
     obj.p = ival 

     _intcache[ival] = obj 
     return obj 
+0

वाह, उत्कृष्ट उत्तर। सिर्फ एक और सवाल, तथ्य यह है कि 'शून्य', 'वन' और 'नकारात्मक' के बगल में अन्य पूर्णांक मांग पर कैश किए गए हैं, यही कारण है कि यह हमेशा एक ही स्मृति पता ('id' फ़ंक्शन के साथ) देता है? यह प्रत्येक इंटीजर उदाहरण "सिंगलटनिंग" का कुछ भाग्य है? –

+1

हां। '_intcache' एक (निजी) 'dict' है जो सिमपी' इंटीजर की पाइथन पूर्णांक को मैप करता है। जब भी 'इंटीजर' तत्काल होता है, तो पहले '_intcache' की जांच की जाती है। यदि पूर्णांक पहले से ही '_intcache' में एक कुंजी के रूप में मौजूद है, तो वह 'इंटीजर' वापस आ गया है। – unutbu

3

सबसे पहले, ध्यान दें कि type(1) आप type(Integer(1)) दिया क्योंकि SymPy लाइव Integer() स्वचालित रूप में पूर्णांक शाब्दिक लपेटता (इस से बचने के लिए है gotcha जहां 1/2 के बजाय 0.5 का मूल्यांकन करता है)। लेकिन ध्यान दें कि एक नियमित पायथन सत्र में type(1)int है।

सिम्पी में कई वस्तुएं हैं जिन्हें सिंगलेट्स के रूप में लागू किया गया है, जिसका अर्थ है कि केवल एक उदाहरण मौजूद होगा। आप सभी S वस्तु

In [13]: dir(S) 
Out[13]: 
['Catalan', 
'ComplexInfinity', 
'Complexes', 
'EulerGamma', 
'Exp1', 
'GoldenRatio', 
'Half', 
'IdentityFunction', 
'ImaginaryUnit', 
'Infinity', 
'NaN', 
'Naturals0', 
'NegativeInfinity', 
'NegativeOne', 
'One', 
'Pi', 
'Reals', 
'Zero', 
'__call__', 
'__class__', 
'__delattr__', 
'__doc__', 
'__format__', 
'__getattr__', 
'__getattribute__', 
'__hash__', 
'__init__', 
'__module__', 
'__new__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__setattr__', 
'__sizeof__', 
'__slots__', 
'__str__', 
'__subclasshook__', 
'_classes_to_install', 
'false', 
'register', 
'true'] 

पर इन देख सकते हैं (जो कि _ के साथ शुरू की उपेक्षा, उन अजगर आंतरिक तरीके हैं)

कारण यह किया जाता है कि इन वस्तुओं एक बहुत उपयोग किया जाता है। 0, 1, और -1 बहुत आम वस्तुएं हैं। हर बार जब आप 1/x लिखते हैं तो इसे आंतरिक रूप से Pow(x, -1) के रूप में दर्शाया जाता है। x - y को Add(x, Mul(-1, y)) के रूप में दर्शाया गया है। 0 के लिए, यह प्रतीकात्मक गणना के सभी प्रकार में अक्सर दिखाई देता है। 1 भी आम है। एक उदाहरण होने के कारण, SymPy दो अनुकूलन सक्षम करता है। सबसे पहले, यह स्मृति बचाता है। दूसरा, आप is तुलना का उपयोग करके इन वस्तुओं के विरुद्ध तुलना कर सकते हैं, जैसे x is S.One। क्योंकि केवल एक उदाहरण मौजूद हो सकता है Integer(1) हमेशा S.One जैसा ही होता है।

(भी, मैं नोट करना चाहिए कि S में वस्तुओं में से कुछ, वास्तव में उस आम नहीं हैं Catalan और EulerGamma की तरह। मुझे लगता है कि वे कुछ भी की तुलना में सुविधा के लिए अधिक जोड़े गए)

+0

इंट ऑटो-रैपिंग सुनिश्चित करता है कि उस विशेष गॉचा के लिए बहुत ही मूर्खतापूर्ण "सिम्पी लाइव में कोड कोड ब्लॉक" लिंक बनाता है। SymPy लाइव व्यवहार के विपरीत करता है जो दस्तावेज समझाए जाने की कोशिश कर रहा है। – user2357112

+0

हा अच्छा बिंदु। मैंने https://github.com/sympy/sympy/issues/10484 खोला। – asmeurer

संबंधित मुद्दे