ASKSAGE: Sage Q&A Forum - Individual question feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 06 Nov 2013 00:46:53 -0600[style] Choose between multiple inheritancehttps://ask.sagemath.org/question/10692/style-choose-between-multiple-inheritance/Dear Sage people,
I want to create a new (mathematical) object that sometimes is an Expression and sometimes a SymbolicFunction, depending on the arguments. You can think of this for example like $f(a, b, t) = \int_0^t a^b e^{-x^2} dx$. For special values of $t$ I would like to see it as an Expression ($t=0$ or $t=\infty$), but in all other cases I want it to be a BuiltinFunction (or something alike).
In Sage I can do something like:
class MyObjectExpression(Expression):
def __init__(self, a, b, t):
Expression.__init__(self, integral(a**b*e**(-x**2), x, 0, t))
# More (override) stuff below
class MyObjectFunction(BuiltinFunction):
def __init__(self, a, b, t):
BuiltinFunction.__init__(self, 'f(a,b,t)', nargs=1)
# More (override) stuff below
def MyObject(a, b, t):
if t == 0 or t == infty:
return MyObjectExpression(a, b, t)
else:
return MyObjectFunction(a, b, t)
Is it possible to combine these three things into one class? So I want to create a class which is sometimes an Expression and sometimes an much more abstract class, is this possible?
Best,
Noud
**Edit:**
What I actually want to do is programming Askey-Wilson polynomials and give them extra options, like a three term recurrence relation. But this depends on $n$. I already programmed this.
class Askey_Wilson(SageObject):
def __init__(self, SR, n, z, a, b, c, d, q):
self.n = n
self.z = z
self.q = q
self.a = a
self.b = b
self.c = c
self.d = d
self.param = [a, b, c, d]
if self.n in ZZ:
self.I = self.evaluate()
else:
self.I = var('askey_wilson')
def __repr__(self):
return 'p_%i(%s;%s,%s,%s,%s|%s)' % (
self.n, self.z, self.a, self.b, self.c, self.d, self.q
)
def evaluate(self):
n, q, z, a, b, c, d = [self.n, self.q, self.z] + self.param
lc = qPochhammerSymbol(SR, [a*b, a*c, a*d], q, n) / a**n
poly = BasicHypergeometricSeries(SR,
[q**(-n), a*b*c*d*q**(n-1), a*z, a*z**(-1)],
[a*b, a*c, a*d], q, q)
return lc*poly
def three_term_recurrence(self):
A, B, C = 0, 0, 0
# compute three term recurrence relation
return A, B, C
But now every time I want to know the explicit value of the Askey-Wilson polynomials I have to call askey_wilson.I. I want to get rid of the I.Sun, 03 Nov 2013 07:22:42 -0600https://ask.sagemath.org/question/10692/style-choose-between-multiple-inheritance/Answer by tmonteil for <p>Dear Sage people,</p>
<p>I want to create a new (mathematical) object that sometimes is an Expression and sometimes a SymbolicFunction, depending on the arguments. You can think of this for example like $f(a, b, t) = \int_0^t a^b e^{-x^2} dx$. For special values of $t$ I would like to see it as an Expression ($t=0$ or $t=\infty$), but in all other cases I want it to be a BuiltinFunction (or something alike).</p>
<p>In Sage I can do something like:</p>
<pre><code>class MyObjectExpression(Expression):
def __init__(self, a, b, t):
Expression.__init__(self, integral(a**b*e**(-x**2), x, 0, t))
# More (override) stuff below
class MyObjectFunction(BuiltinFunction):
def __init__(self, a, b, t):
BuiltinFunction.__init__(self, 'f(a,b,t)', nargs=1)
# More (override) stuff below
def MyObject(a, b, t):
if t == 0 or t == infty:
return MyObjectExpression(a, b, t)
else:
return MyObjectFunction(a, b, t)
</code></pre>
<p>Is it possible to combine these three things into one class? So I want to create a class which is sometimes an Expression and sometimes an much more abstract class, is this possible?</p>
<p>Best,
Noud</p>
<p><strong>Edit:</strong>
What I actually want to do is programming Askey-Wilson polynomials and give them extra options, like a three term recurrence relation. But this depends on $n$. I already programmed this.</p>
<pre><code>class Askey_Wilson(SageObject):
def __init__(self, SR, n, z, a, b, c, d, q):
self.n = n
self.z = z
self.q = q
self.a = a
self.b = b
self.c = c
self.d = d
self.param = [a, b, c, d]
if self.n in ZZ:
self.I = self.evaluate()
else:
self.I = var('askey_wilson')
def __repr__(self):
return 'p_%i(%s;%s,%s,%s,%s|%s)' % (
self.n, self.z, self.a, self.b, self.c, self.d, self.q
)
def evaluate(self):
n, q, z, a, b, c, d = [self.n, self.q, self.z] + self.param
lc = qPochhammerSymbol(SR, [a*b, a*c, a*d], q, n) / a**n
poly = BasicHypergeometricSeries(SR,
[q**(-n), a*b*c*d*q**(n-1), a*z, a*z**(-1)],
[a*b, a*c, a*d], q, q)
return lc*poly
def three_term_recurrence(self):
A, B, C = 0, 0, 0
# compute three term recurrence relation
return A, B, C
</code></pre>
<p>But now every time I want to know the explicit value of the Askey-Wilson polynomials I have to call askey_wilson.I. I want to get rid of the I.</p>
https://ask.sagemath.org/question/10692/style-choose-between-multiple-inheritance/?answer=15649#post-id-15649Inheritance is used when you want to build a class that is a particular case of an existing class (by adding some features). In your case, this looks more like a "mix", hence inheritance seems not very appropriate.
I am not sure i understand your wish clearly, does something along this way makes sense for you ?
class MyObject(SageObject):
def __init__(self, a, b, t):
self.a = a
self.b = b
self.t = t
if t == 0 or t == infinity:
self.I = var('t') == t # self.I takes the value one of the expressions "(t == 0)" or "(t == infinity)"
else:
self.I = integral(a**b*e**(-x**2), x, 0, t)
Perhaps could you describe the behaviour you want to see as an example of creation and interaction with the object, so we can help you more.
Sun, 03 Nov 2013 09:48:34 -0600https://ask.sagemath.org/question/10692/style-choose-between-multiple-inheritance/?answer=15649#post-id-15649Comment by Noud for <p>Inheritance is used when you want to build a class that is a particular case of an existing class (by adding some features). In your case, this looks more like a "mix", hence inheritance seems not very appropriate.</p>
<p>I am not sure i understand your wish clearly, does something along this way makes sense for you ?</p>
<pre><code>class MyObject(SageObject):
def __init__(self, a, b, t):
self.a = a
self.b = b
self.t = t
if t == 0 or t == infinity:
self.I = var('t') == t # self.I takes the value one of the expressions "(t == 0)" or "(t == infinity)"
else:
self.I = integral(a**b*e**(-x**2), x, 0, t)
</code></pre>
<p>Perhaps could you describe the behaviour you want to see as an example of creation and interaction with the object, so we can help you more.</p>
https://ask.sagemath.org/question/10692/style-choose-between-multiple-inheritance/?comment=16782#post-id-16782I actually want to implement Askey-Wilson polynomials (http://en.wikipedia.org/wiki/Askey%E2%80%93Wilson_polynomials), but I want to give the polynomials some extra functions so that you can do something like: Askey_Wilson(n, z, a, b, c, d, q).three_term() and you get a triple with the three term recurrence relation. So if n is an integer I can use Expression, but if n is a variable I want to use an other object. Your answer does work, except that I don't want to call askey_wilson.I all the time, but just without the I.Wed, 06 Nov 2013 00:46:53 -0600https://ask.sagemath.org/question/10692/style-choose-between-multiple-inheritance/?comment=16782#post-id-16782