2 __all__
= ['Ring', 'CommutativeRing']
4 from ..basealgebra
import Algebra
5 from .interface
import RingInterface
7 from ..core
import init_module
, classes
8 init_module
.import_heads()
9 init_module
.import_numbers()
13 from ..arithmetic
import mpq
14 Ring
.coefftypes
= (int, long, mpq
)
16 class Ring(Algebra
, RingInterface
):
18 Ring represents algebraic ring (R, +, *) where (R, +) is abelian
19 group, (R,*) is monoid, with distributivity.
23 def get_function_algebra(cls
):
24 return classes
.FunctionRing
28 return h
.data_to_str_and_precedence(type(self
), d
)[0]
34 return self
.head
.neg(type(self
), self
)
36 def __add__(self
, other
):
40 if tother
in numbertypes_set
:
41 return self
.head
.add_number(cls
, self
, other
)
42 other
= cls
.convert(other
, typeerror
=False)
43 if other
is NotImplemented: return NotImplemented
44 return self
.head
.add(cls
, self
, other
)
48 def __iadd__(self
, other
):
50 if type(other
) is not cls
:
51 other
= cls
.convert(other
, typeerror
=False)
52 if other
is NotImplemented: return NotImplemented
53 return self
.head
.inplace_add(cls
, self
, other
)
55 def __sub__(self
, other
):
59 if tother
in numbertypes_set
:
60 return self
.head
.sub_number(cls
, self
, other
)
61 other
= cls
.convert(other
, typeerror
=False)
62 if other
is NotImplemented: return NotImplemented
63 return self
.head
.sub(cls
, self
, other
)
65 def __rsub__(self
, other
):
66 return other
+ (-self
)
68 def __isub__(self
, other
):
70 if type(other
) is not cls
:
71 other
= cls
.convert(other
, typeerror
=False)
72 if other
is NotImplemented: return NotImplemented
73 return self
.head
.inplace_add(cls
, self
, -other
)
75 def __mul__(self
, other
):
79 if tother
in numbertypes_set
:
80 return self
.head
.non_commutative_mul_number(cls
, self
, other
)
81 other
= cls
.convert(other
, typeerror
=False)
82 if other
is NotImplemented: return NotImplemented
83 return self
.head
.non_commutative_mul(cls
, self
, other
)
85 def __rmul__(self
, other
):
89 if tother
in numbertypes_set
:
90 return self
.head
.non_commutative_rmul_number(cls
, self
, other
)
91 other
= cls
.convert(other
, typeerror
=False)
92 if other
is NotImplemented: return NotImplemented
93 return other
.head
.non_commutative_mul(cls
, other
, self
)
95 def __pow__(self
, other
):
99 if tother
in numbertypes_set
:
100 return self
.head
.pow_number(cls
, self
, other
)
101 other
= cls
.convert(other
, typeerror
=False)
102 if other
is NotImplemented: return NotImplemented
103 return self
.head
.pow(cls
, self
, other
)
105 def __rpow__(self
, other
):
108 if cls
is not tother
:
109 other
= cls
.convert(other
, typeerror
=False)
110 if other
is NotImplemented: return NotImplemented
111 return other
.head
.pow(cls
, other
, self
)
113 def __div__(self
, other
):
116 if tother
is not cls
:
117 if tother
in numbertypes_set
:
118 return self
.head
.non_commutative_div_number(cls
, self
, other
)
119 other
= cls
.convert(other
, typeerror
=False)
120 if other
is NotImplemented: return NotImplemented
121 return self
* other
**-1
123 def __rdiv__(self
, other
):
126 if cls
is not tother
:
127 other
= cls
.convert(other
, typeerror
=False)
128 if other
is NotImplemented: return NotImplemented
129 return other
* self
**-1
131 __truediv__
= __div__
134 return self
.head
.expand(type(self
), self
)
136 def evalf(self
, n
=None):
137 return self
.head
.evalf(type(self
), self
, n
)
139 class CommutativeRing(Ring
):
141 def __mul__(self
, other
):
144 if tother
is not cls
:
145 if tother
in numbertypes_set
:
146 return self
.head
.commutative_mul_number(cls
, self
, other
)
147 other
= cls
.convert(other
, typeerror
=False)
148 if other
is NotImplemented:
149 return NotImplemented
150 return self
.head
.commutative_mul(cls
, self
, other
)
154 def __imul__(self
, other
):
156 if type(other
) is not cls
:
157 other
= cls
.convert(other
, typeerror
=False)
158 if other
is NotImplemented:
159 return NotImplemented
160 return self
.head
.inplace_commutative_mul(cls
, self
, other
)
162 def __div__(self
, other
):
165 if tother
is not cls
:
166 if tother
in numbertypes_set
:
167 return self
.head
.commutative_div_number(cls
, self
, other
)
168 other
= cls
.convert(other
, typeerror
=False)
169 if other
is NotImplemented:
170 return NotImplemented
171 return self
.head
.commutative_div(cls
, self
, other
)
173 def __rdiv__(self
, other
):
176 if tother
is not cls
:
177 if tother
in numbertypes_set
:
178 return self
.head
.commutative_rdiv_number(cls
, self
, other
)
179 other
= cls
.convert(other
, typeerror
=False)
180 if other
is NotImplemented:
181 return NotImplemented
182 return other
* self
**-1
184 def to(self
, target
, *args
):
185 """ Convert expression to target representation.
187 The following targets are recognized:
189 EXP_COEFF_DICT - convert expression to exponents-coefficient
190 representation, additional arguments are variables. When
191 no arguments are specified, variables will be all symbols
192 and non-power expressions used in the expression.
194 TERM_COEFF_DICT - convert expression to term-coefficient
195 representation. Note that the returned result may have
196 actual head NUMBER, SYMBOL, TERM_COEFF, POW, or
197 BASE_EXP_DICT instead of TERM_COEFF_DICT.
199 head
, data
= self
.pair
202 if target
is EXP_COEFF_DICT
:
203 return head
.to_EXP_COEFF_DICT(type(self
), data
, self
, args
or None)
204 if target
is TERM_COEFF_DICT
:
205 return head
.to_TERM_COEFF_DICT(type(self
), data
, self
)
206 raise NotImplementedError('%s.to(target=%r)' % (type(self
), target
))
208 def diff(self
, symbol
, order
=1):
212 if type(symbol
) is cls
:
213 assert symbol
.head
is SYMBOL
,`symbol
.pair`
215 elif isinstance(symbol
, str):
218 raise TypeError('diff(symbol, order) first argument must be str or %s instance but got %s instance' % (cls
.__name
__, type(symbol
).__name
__))
221 result
= self
.head
.diff(cls
, self
.data
, self
, symbol
, order
, cache
=cache
)
226 def integrate(self
, x
):
237 assert x
.head
is SYMBOL
,`x
.pair`
242 raise TypeError('integrate(x,..), x must be str or %s instance but got %s instance' % (cls
.__name
__, type(symbol
).__name
__))
245 return self
.head
.integrate_indefinite(cls
, self
.data
, self
, x
)
246 if type(a
) is not cls
:
248 if type(b
) is not cls
:
250 return self
.head
.integrate_definite(cls
, self
.data
, self
, x
, a
, b
)
253 classes
.CommutativeRing
= CommutativeRing