Package sympycore :: Package basealgebra :: Module ring
[hide private]
[frames] | no frames]

Source Code for Module sympycore.basealgebra.ring

  1  """ Provides CommutativeRing class. 
  2  """ 
  3   
  4  __docformat__ = "restructuredtext" 
  5  __all__ = ['CommutativeRing'] 
  6   
  7  from .algebra import Algebra 
  8   
9 -class CommutativeRing(Algebra):
10 """ Base class to commutative rings. 11 12 Derived classes may redefine the following methods:: 13 14 Symbol(cls, obj) 15 Number(cls, obj) 16 Add(cls, *seq) 17 Mul(cls, *seq), 18 Pow(cls, base, exponent) 19 Terms(cls, *seq) 20 Factors(cls, *seq) 21 as_Add_args(self) 22 as_Mul_args(self) 23 as_Pow_args(self), 24 as_Terms_args(self) 25 as_Factors_args(self) 26 """ 27 __slots__ = ['_symbols'] 28 _symbols = None 29 30 @classmethod
31 - def Add(cls, *seq):
32 """ Compute sum over seq containing algebra elements. 33 """ 34 raise NotImplementedError('%s must define classmethod Add' #pragma NO COVER 35 % (cls.__name__)) #pragma NO COVER
36 37 @classmethod
38 - def Sub(cls, *seq):
39 """ Compute ``seq[0] - Add(*seq[0])``. 40 """ 41 if seq: 42 return seq[0] - cls.Add(*seq[1:]) 43 return cls.zero
44 45 @classmethod
46 - def Mul(cls, *seq):
47 """ Compute product over seq containing algebra elements. 48 """ 49 raise NotImplementedError('%s must define classmethod Mul' #pragma NO COVER 50 % (cls.__name__)) #pragma NO COVER
51 52 @classmethod
53 - def Div(cls, *seq):
54 """ Compute ``seq[0] / Mul(*seq[0])``. 55 """ 56 if seq: 57 return seq[0] / cls.Mul(*seq[1:]) 58 return cls.one
59 60 @classmethod
61 - def Pow(cls, base, exponent):
62 """ Compute power from base and exponent. 63 64 Argument base must be an algebra element and exponent must be 65 an element of exponent algebra. 66 """ 67 raise NotImplementedError('%s must define classmethod Pow' #pragma NO COVER 68 % (cls.__name__)) #pragma NO COVER
69 70 @classmethod
71 - def Log(cls, arg, base=None):
72 """ Compute logarithm of arg in base. 73 74 Argument arg must be an element of exponent algebra and base 75 is an element of an algebra. 76 """ 77 raise NotImplementedError('%s must define classmethod Pow' #pragma NO COVER 78 % (cls.__name__)) #pragma NO COVER
79 80 @classmethod
81 - def Terms(cls, *seq):
82 """ Compute sum over seq containing pairs ``(element, coefficient)``. 83 84 ``element``-s must belong to algebra, ``coefficient``-s must 85 belong to the coefficient algebra. 86 """ 87 raise NotImplementedError('%s must define classmethod Terms' #pragma NO COVER 88 % (cls.__name__)) #pragma NO COVER
89 90 @classmethod
91 - def Factors(cls, *seq):
92 """ Compute product over seq containing pairs ``(element, exponent)``. 93 94 ``element``-s must belong to algebra, ``exponent``-s must belong 95 to the exponent algebra. 96 """ 97 raise NotImplementedError('%s must define classmethod Factors' #pragma NO COVER 98 % (self.__class__.__name__)) #pragma NO COVER
99
100 - def as_Add_args(self):
101 """ Return a sequence such that ``Add(*self.as_Add_args()) == self`` 102 """ 103 raise NotImplementedError('%s must define method as_Add_args' #pragma NO COVER 104 % (self.__class__.__name__)) #pragma NO COVER
105
106 - def as_Mul_args(self):
107 """ Return a sequence such that ``Mul(*self.as_Mul_args()) == self`` 108 """ 109 raise NotImplementedError('%s must define method as_Mul_args' #pragma NO COVER 110 % (self.__class__.__name__)) #pragma NO COVER
111
112 - def as_Pow_args(self):
113 """ Return a 2-tuple such that ``Pow(*self.as_Pow_args()) == self`` 114 """ 115 raise NotImplementedError('%s must define method as_Pow_args' #pragma NO COVER 116 % (self.__class__.__name__)) #pragma NO COVER
117
118 - def as_Log_args(self):
119 """ Return a 2-tuple such that ``Log(*self.as_Log_args()) == self`` 120 """ 121 raise NotImplementedError('%s must define method as_Log_args' #pragma NO COVER 122 % (self.__class__.__name__)) #pragma NO COVER
123
124 - def as_Terms_args(self):
125 """ Return a sequence such that ``Terms(*self.as_Terms_args()) == self`` 126 """ 127 raise NotImplementedError('%s must define method as_Terms_args' #pragma NO COVER 128 % (self.__class__.__name__)) #pragma NO COVER
129
130 - def as_Factors_args(self):
131 """ Return a sequence such that ``Factors(*self.as_Factors_args()) == self`` 132 """ 133 raise NotImplementedError('%s must define method as_Factors_args' #pragma NO COVER 134 % (self.__class__.__name__)) #pragma NO COVER
135
136 - def __pos__(self):
137 return self
138
139 - def __neg__(self):
140 return self.Mul(self, self.convert(-1))
141
142 - def __add__(self, other):
143 other = self.convert(other, False) 144 if other is NotImplemented: 145 return NotImplemented 146 return self.Add(self, other)
147
148 - def __radd__(self, other):
149 other = self.convert(other, False) 150 if other is NotImplemented: 151 return NotImplemented 152 return self.Add(other, self)
153
154 - def __sub__(self, other):
155 other = self.convert(other, False) 156 if other is NotImplemented: 157 return NotImplemented 158 return self + (-other)
159
160 - def __rsub__(self, other):
161 other = self.convert(other, False) 162 if other is NotImplemented: 163 return NotImplemented 164 return other + (-self)
165
166 - def __mul__(self, other):
167 other = self.convert(other, False) 168 if other is NotImplemented: 169 return NotImplemented 170 return self.Mul(self, other)
171
172 - def __rmul__(self, other):
173 other = self.convert(other, False) 174 if other is NotImplemented: 175 return NotImplemented 176 return self.Mul(other, self)
177
178 - def __div__(self, other):
179 other = self.convert(other, False) 180 if other is NotImplemented: 181 return NotImplemented 182 if isinstance(other, (int, long)): 183 other = self.Number(other) 184 return self * other ** (-1)
185
186 - def __rdiv__(self, other):
187 other = self.convert(other, False) 188 if other is NotImplemented: 189 return NotImplemented 190 return other * self ** (-1)
191
192 - def __truediv__(self, other):
193 other = self.convert(other, False) 194 if other is NotImplemented: 195 return NotImplemented 196 return self * other ** (-1)
197
198 - def __rtruediv__(self, other):
199 other = self.convert(other, False) 200 if other is NotImplemented: 201 return NotImplemented 202 return other * self ** (-1)
203
204 - def __pow__(self, other):
205 other = self.convert_exponent(other, False) 206 if other is NotImplemented: 207 return NotImplemented 208 return self.Pow(self, other)
209
210 - def __rpow__(self, other):
211 other = self.convert(other, False) 212 if other is NotImplemented: 213 return NotImplemented 214 return self.Pow(other, self.convert_exponent(self))
215
216 - def _matches(pattern, expr, repl_dict, wild_info):
217 pfunc = pattern.func 218 efunc = expr.func 219 Add = pattern.Add 220 Mul = pattern.Mul 221 if pfunc==Add: 222 wild_part = [] 223 exact_part = [] 224 for a in pattern.args: 225 if a.symbols.intersection(wild_info[0]): 226 if a.head is SYMBOL: 227 wild_part.append(a) 228 else: 229 wild_part.insert(0, a) 230 else: 231 exact_part.append(a) 232 if exact_part: 233 expr = expr - Add(*exact_part) 234 if len(wild_part)==1: 235 return wild_part[0].matches(expr, repl_dict, wild_info) 236 expr_args = expr.as_Add_args() + [pattern.zero] 237 for i in range(len(wild_part)): 238 w = wild_part[i] 239 w_rest = Add(*(wild_part[:i]+wild_part[i+1:])) 240 for e in expr_args: 241 r = w.matches(e, repl_dict, wild_info) 242 if r is not None: 243 r1 = w_rest.subs(r.items()).matches(expr-e, r, wild_info) 244 if r1 is not None: 245 return r1 246 elif pfunc==Mul: 247 wild_part = [] 248 exact_part = [] 249 for a in pattern.args: 250 if a.symbols.intersection(wild_info[0]): 251 if a.head is SYMBOL: 252 wild_part.append(a) 253 else: 254 wild_part.insert(0, a) 255 else: 256 exact_part.append(a) 257 if exact_part: 258 expr = expr / Mul(*exact_part) 259 if len(wild_part)==1: 260 return wild_part[0].matches(expr, repl_dict, wild_info) 261 expr_args = expr.as_Mul_args() + [pattern.one] 262 for i in range(len(wild_part)): 263 w = wild_part[i] 264 w_rest = Mul(*(wild_part[:i]+wild_part[i+1:])) 265 for e in expr_args: 266 r = w.matches(e, repl_dict, wild_info) 267 if r is not None: 268 r1 = w_rest.subs(r.items()).matches(expr/e, r, wild_info) 269 if r1 is not None: 270 return r1 271 elif pfunc == efunc: 272 return pattern._matches_seq(pattern.args, expr.args, repl_dict, wild_info) 273 return
274 275 from ..utils import NUMBER, SYMBOL 276