ASKSAGE: Sage Q&A Forum - Individual question feedhttp://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 05 Dec 2013 06:29:59 -0600Symbolic functions without named variableshttp://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/Is there a way to define a symbolic function that can (e.g.) be differentiated, but doesn't remember the name of its input variable(s)? For instance, consider:
sage: f(x) = x^2
sage: g(x) = x^2
sage: h(t) = t^2
Mathematically, f, g, and h, should all be the same function. However, Sage doesn't think so:
sage: f+g
x |--> 2*x^2
sage: f+h
(t, x) |--> t^2 + x^2
I guess that this is happening because a "function" defined with `f(x)=x^2` is actually just a symbolic expression equipped with an ordering on its variables, rather than what a mathematician would call a "function". Is there a way to define an actual mathematical function?
Wed, 27 Nov 2013 08:33:17 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/Answer by tmonteil for <p>Is there a way to define a symbolic function that can (e.g.) be differentiated, but doesn't remember the name of its input variable(s)? For instance, consider:</p>
<pre><code>sage: f(x) = x^2
sage: g(x) = x^2
sage: h(t) = t^2
</code></pre>
<p>Mathematically, f, g, and h, should all be the same function. However, Sage doesn't think so:</p>
<pre><code>sage: f+g
x |--> 2*x^2
sage: f+h
(t, x) |--> t^2 + x^2
</code></pre>
<p>I guess that this is happening because a "function" defined with <code>f(x)=x^2</code> is actually just a symbolic expression equipped with an ordering on its variables, rather than what a mathematician would call a "function". Is there a way to define an actual mathematical function?</p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?answer=15733#post-id-15733You are right, you defined a symbolic expression, which includes the name of the variable:
sage: type(f)
<type 'sage.symbolic.expression.Expression'>
sage: f.parent()
Callable function ring with arguments (x,)
You can survive by noticing that:
sage: i(t) = f(t) + g(t)
sage: i
t |--> 2*t^2
Unfortunately, it is currently not possible to add more semantics to such objects, therefore approaching mathematical functions. Typically, it would be very nice to be able to define a function, including its domain and codomain (this is currently imitated with assumptions on the variables).
Wed, 27 Nov 2013 10:21:13 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?answer=15733#post-id-15733Comment by Mike Shulman for <p>You are right, you defined a symbolic expression, which includes the name of the variable:</p>
<pre><code>sage: type(f)
<type 'sage.symbolic.expression.Expression'>
sage: f.parent()
Callable function ring with arguments (x,)
</code></pre>
<p>You can survive by noticing that: </p>
<pre><code>sage: i(t) = f(t) + g(t)
sage: i
t |--> 2*t^2
</code></pre>
<p>Unfortunately, it is currently not possible to add more semantics to such objects, therefore approaching mathematical functions. Typically, it would be very nice to be able to define a function, including its domain and codomain (this is currently imitated with assumptions on the variables).</p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16587#post-id-16587Thanks! Why do you refer to defining mathematical functions as "adding more semantics"?Mon, 02 Dec 2013 16:31:29 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16587#post-id-16587Comment by nbruin for <p>You are right, you defined a symbolic expression, which includes the name of the variable:</p>
<pre><code>sage: type(f)
<type 'sage.symbolic.expression.Expression'>
sage: f.parent()
Callable function ring with arguments (x,)
</code></pre>
<p>You can survive by noticing that: </p>
<pre><code>sage: i(t) = f(t) + g(t)
sage: i
t |--> 2*t^2
</code></pre>
<p>Unfortunately, it is currently not possible to add more semantics to such objects, therefore approaching mathematical functions. Typically, it would be very nice to be able to define a function, including its domain and codomain (this is currently imitated with assumptions on the variables).</p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16603#post-id-16603This has a side-effect (the string returned by preparse is what is actually executed):
sage: preparse("i(t)=f(t)+g(t)")
'__tmp__=var("t"); i = symbolic_expression(f(t)+g(t)).function(t)'
In addition to defining `i` as the required symbolic function, the symbol `t`
also gets re-defined as a symbolic variable. That's a side-effect you may not
always expect:
sage: t=1
sage: f(t)=t+1
sage: f
t |--> t + 1
sage: t # t has been redefined too
t
Thu, 28 Nov 2013 06:56:56 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16603#post-id-16603Answer by niles for <p>Is there a way to define a symbolic function that can (e.g.) be differentiated, but doesn't remember the name of its input variable(s)? For instance, consider:</p>
<pre><code>sage: f(x) = x^2
sage: g(x) = x^2
sage: h(t) = t^2
</code></pre>
<p>Mathematically, f, g, and h, should all be the same function. However, Sage doesn't think so:</p>
<pre><code>sage: f+g
x |--> 2*x^2
sage: f+h
(t, x) |--> t^2 + x^2
</code></pre>
<p>I guess that this is happening because a "function" defined with <code>f(x)=x^2</code> is actually just a symbolic expression equipped with an ordering on its variables, rather than what a mathematician would call a "function". Is there a way to define an actual mathematical function?</p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?answer=15740#post-id-15740Depending on what you want, the underlying tree for a symbolic expression might also be useful. A naive function that takes a symbolic expression as input and returns an expression tree is demonstrated [here](http://ask.sagemath.org/question/2063/getting-a-rooted-graph-from-a-nested-list-of-lists).
Sage has more sophisticated ways of building expression trees for the purposes of creating fast callable functions (for, e.g., plotting graphs or computing numerical integrals). I find them a bit confusing, but they might prove useful. The relevant classes are `Expression` and `ExpressionTreeBuilder`, both defined in [sage.ext.fast_callable](https://github.com/sagemath/sage/blob/master/src/sage/ext/fast_callable.pyx)
Here is a demonstration of how they might be used, and also a "variable free" version of the naive tree:
from sage.ext.fast_callable import ExpressionTreeBuilder
class AbstractFunction(SageObject):
"""
A class to compute and store information for abstract (variable-free) functions
"""
def __init__(self,f):
self._vars = f.variables()
# an ExpressionTreeBuilder instance must know
# the names and ordering of variables
self.etb = ExpressionTreeBuilder(vars=self._vars)
# store the symbolic expression, since we don't
# know how to rebuild it
self.symbolic_expr = f
# the Expression object
self.expr = self.etb(f)
# the fast callable version of this Expression
# useful for computing values of the function
self.callable_expr = fast_callable(self.expr)
# a naive expression tree, stored as a list of lists
self.naive_tree = self.extract_naive_tree(f)
def vars(self,i=None):
if i is not None:
return lambda V: V[i]
return self._vars
def reset_vars(self,new_vars):
"""
Change the variable names for the underlying symbolic expression
"""
sub_dict = dict(zip(self._vars,new_vars))
self.symbolic_expr = self.symbolic_expr.subs(sub_dict)
self._vars = new_vars
return self.symbolic_expr
def extract_naive_tree(self,expr):
"""
A nested list of operators and operands.
Variables are replaced by coordinate functions which
extract ith value from list of inputs.
"""
if expr.operator() is None:
try:
v0 = expr.variables()[0] # test whether we have non-trivial tuple of variables
return [self.vars,self._vars.index(expr)]
except IndexError:
return expr
else:
return [expr.operator()]+map(self.extract_naive_tree,expr.operands())
def diff(self,*args,**kwds):
"""
Differentiate the symbolic expression and
convert the result to an AbstractFunction
"""
df = self.symbolic_expr.diff(*args,**kwds)
return AbstractFunction(df)
----
Even though this is getting too long, here are some examples of using this class:
sage: var('x,y,z')
(x, y, z)
Create `AbstractFunction` from symbolic expression
sage: f = AbstractFunction(x^2 + 1)
sage: f.symbolic_expr # original symbolic expression
x^2 + 1
sage: f.expr # Expression object
add(ipow(v_0, 2), 1)
sage: f.naive_tree # naive expression tree
[<function operator.add>,
[<function operator.pow>,
[<bound method AbstractFunction.vars of <class '__main__.AbstractFunction'>>,
0],
2],
1]
sage: f.callable_expr(3) # calling the callable version of the expression
10
sage: f.callable_expr(z+x) # calling with symbolic expressions as inputs
(x + z)^2 + 1
Operating on the symbolic expression and converting the result to an `AbstractFunction`:
sage: df = f.diff()
sage: df.symbolic_expr
2*x
sage: df.expr
mul(v_0, 2)
Change variable names for the original symbolic expression:
sage: f.reset_vars((z,))
z^2 + 1
sage: f.diff().symbolic_expr
2*z
A multivariable example:
sage: h = AbstractFunction(sin(x + z) + y^2)
sage: h.expr
add(ipow(v_1, 2), sin(add(v_0, v_2)))
sage: h.diff(y).expr
mul(v_0, 2)
The naive tree replaces the variables with coordinate functions. Evaluating `AbstractFunction.vars` on an index *i* returns a function whose output is the *i*th item in a given list:
sage: h.naive_tree
[<function operator.add>,
[<function operator.pow>,
[<bound method AbstractFunction.vars of <class '__main__.AbstractFunction'>>,
1],
2],
[sin,
[<function operator.add>,
[<bound method AbstractFunction.vars of <class '__main__.AbstractFunction'>>,
0],
[<bound method AbstractFunction.vars of <class '__main__.AbstractFunction'>>,
2]]]]
sage: h.naive_tree[1][1][0](1)(h._vars)
y
Fri, 29 Nov 2013 05:00:11 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?answer=15740#post-id-15740Comment by Mike Shulman for <div class="snippet"><p>Depending on what you want, the underlying tree for a symbolic expression might also be useful. A naive function that takes a symbolic expression as input and returns an expression tree is demonstrated <a href="http://ask.sagemath.org/question/2063/getting-a-rooted-graph-from-a-nested-list-of-lists">here</a>.</p>
<p>Sage has more sophisticated ways of building expression trees for the purposes of creating fast callable functions (for, e.g., plotting graphs or computing numerical integrals). I find them a bit confusing, but they might prove useful. The relevant classes are <code>Expression</code> and <code>ExpressionTreeBuilder</code>, both defined in <a href="https://github.com/sagemath/sage/blob/master/src/sage/ext/fast_callable.pyx">sage.ext.fast_callable</a></p>
<p>Here is a demonstration of how they might be used, and also a "variable free" version of the naive tree:</p>
<pre><code>from sage.ext.fast_callable import ExpressionTreeBuilder
class AbstractFunction(SageObject):
"""
A class to compute and store information for abstract (variable-free) functions
"""
def __init__(self,f):
self._vars = f.variables()
# an ExpressionTreeBuilder instance must know
# the names and ordering of variables
self.etb = ExpressionTreeBuilder(vars=self._vars)
# store the symbolic expression, since we don't
# know how to rebuild it
self.symbolic_expr = f
# the Expression object
self.expr = self.etb(f)
# the fast callable version of this Expression
# useful for computing values of the function
self.callable_expr = fast_callable(self.expr)
# a naive expression tree, stored as a list of lists
self.naive_tree = self.extract_naive_tree(f)
def vars(self,i=None):
if i is not None:
return lambda V: V[i]
return self._vars
def reset_vars(self,new_vars):
"""
Change the variable names for the underlying symbolic expression
"""
sub_dict = dict(zip(self._vars,new_vars))
self.symbolic_expr = self.symbolic_expr.subs(sub_dict)
self._vars = new_vars
return self.symbolic_expr
def extract_naive_tree(self,expr):
"""
A nested list of operators and operands.
Variables are replaced by coordinate functions which
extract ith value from list of inputs.
"""
if expr.operator() is None:
try:
v0 = expr.variables()[0] # test whether we have non-trivial tuple of variables
return [self.vars,self._vars.index(expr)]
except IndexError:
return expr
else:
return [expr.operator()]+map(self.extract_naive_tree,expr.operands())
def diff(self,*args,**kwds):
"""
Differentiate the symbolic expression and
convert the result to an AbstractFunction
"""
df = self.symbolic_expr.diff(*args,**kwds)
return AbstractFunction(df)
</code></pre>
<hr/>
<p>Even though this is getting too long, here are some examples of using this class:</p>
<pre><code>sage: var('x,y,z')
(x, y, z)
</code></pre>
<p>Create <code>AbstractFunction</code> from symbolic expression</p>
<pre><code>sage: f = AbstractFunction(x^2 + 1)
sage: f.symbolic_expr # original symbolic expression
x^2 + 1
sage: f.expr # Expression object
add(ipow(v_0, 2), 1)
sage: f.naive_tree # naive expression tree
[<function operator.add>,
[<function operator.pow>,
[<bound method AbstractFunction.vars of <class '__main__.AbstractFunction'>>,
0],
2],
1]
sage: f.callable_expr(3) # calling the callable version of the expression
10
sage: f.callable_expr(z+x) # calling with symbolic expressions as inputs
(x + z)^2 + 1
</code></pre>
<p>Operating on the symbolic expression and converting the result to an <code>AbstractFunction</code>:</p>
<pre><code>sage: df = f.diff()
sage: df.symbolic_expr
2*x
sage: df.expr
mul(v_0, 2)
</code></pre>
<p>Change variable names for the original symbolic expression:</p>
<pre><code>sage: f.reset_vars((z,))
z^2 + 1
sage: f.diff().symbolic_expr
2*z
</code></pre>
<p>A multivariable example:</p>
<pre><code>sage: h ...</code></pre></hr/><span class="expander"> <a>(more)</a></span></div>http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16585#post-id-16585I'm trying to understand this. Is the expression tree really necessary? It seems like a wrapper around a callable symbolic expression that knows how to reset the variables as needed might be sufficient for what I want. For instance, could you also overload function application, addition, etc.?Mon, 02 Dec 2013 16:49:58 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16585#post-id-16585Comment by niles for <div class="snippet"><p>Depending on what you want, the underlying tree for a symbolic expression might also be useful. A naive function that takes a symbolic expression as input and returns an expression tree is demonstrated <a href="http://ask.sagemath.org/question/2063/getting-a-rooted-graph-from-a-nested-list-of-lists">here</a>.</p>
<p>Sage has more sophisticated ways of building expression trees for the purposes of creating fast callable functions (for, e.g., plotting graphs or computing numerical integrals). I find them a bit confusing, but they might prove useful. The relevant classes are <code>Expression</code> and <code>ExpressionTreeBuilder</code>, both defined in <a href="https://github.com/sagemath/sage/blob/master/src/sage/ext/fast_callable.pyx">sage.ext.fast_callable</a></p>
<p>Here is a demonstration of how they might be used, and also a "variable free" version of the naive tree:</p>
<pre><code>from sage.ext.fast_callable import ExpressionTreeBuilder
class AbstractFunction(SageObject):
"""
A class to compute and store information for abstract (variable-free) functions
"""
def __init__(self,f):
self._vars = f.variables()
# an ExpressionTreeBuilder instance must know
# the names and ordering of variables
self.etb = ExpressionTreeBuilder(vars=self._vars)
# store the symbolic expression, since we don't
# know how to rebuild it
self.symbolic_expr = f
# the Expression object
self.expr = self.etb(f)
# the fast callable version of this Expression
# useful for computing values of the function
self.callable_expr = fast_callable(self.expr)
# a naive expression tree, stored as a list of lists
self.naive_tree = self.extract_naive_tree(f)
def vars(self,i=None):
if i is not None:
return lambda V: V[i]
return self._vars
def reset_vars(self,new_vars):
"""
Change the variable names for the underlying symbolic expression
"""
sub_dict = dict(zip(self._vars,new_vars))
self.symbolic_expr = self.symbolic_expr.subs(sub_dict)
self._vars = new_vars
return self.symbolic_expr
def extract_naive_tree(self,expr):
"""
A nested list of operators and operands.
Variables are replaced by coordinate functions which
extract ith value from list of inputs.
"""
if expr.operator() is None:
try:
v0 = expr.variables()[0] # test whether we have non-trivial tuple of variables
return [self.vars,self._vars.index(expr)]
except IndexError:
return expr
else:
return [expr.operator()]+map(self.extract_naive_tree,expr.operands())
def diff(self,*args,**kwds):
"""
Differentiate the symbolic expression and
convert the result to an AbstractFunction
"""
df = self.symbolic_expr.diff(*args,**kwds)
return AbstractFunction(df)
</code></pre>
<hr/>
<p>Even though this is getting too long, here are some examples of using this class:</p>
<pre><code>sage: var('x,y,z')
(x, y, z)
</code></pre>
<p>Create <code>AbstractFunction</code> from symbolic expression</p>
<pre><code>sage: f = AbstractFunction(x^2 + 1)
sage: f.symbolic_expr # original symbolic expression
x^2 + 1
sage: f.expr # Expression object
add(ipow(v_0, 2), 1)
sage: f.naive_tree # naive expression tree
[<function operator.add>,
[<function operator.pow>,
[<bound method AbstractFunction.vars of <class '__main__.AbstractFunction'>>,
0],
2],
1]
sage: f.callable_expr(3) # calling the callable version of the expression
10
sage: f.callable_expr(z+x) # calling with symbolic expressions as inputs
(x + z)^2 + 1
</code></pre>
<p>Operating on the symbolic expression and converting the result to an <code>AbstractFunction</code>:</p>
<pre><code>sage: df = f.diff()
sage: df.symbolic_expr
2*x
sage: df.expr
mul(v_0, 2)
</code></pre>
<p>Change variable names for the original symbolic expression:</p>
<pre><code>sage: f.reset_vars((z,))
z^2 + 1
sage: f.diff().symbolic_expr
2*z
</code></pre>
<p>A multivariable example:</p>
<pre><code>sage: h ...</code></pre></hr/><span class="expander"> <a>(more)</a></span></div>http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16583#post-id-16583Sorry for the complexity -- I was learning as I wrote this, and I think it contains at least two independent solutions. But I'm also not sure what you want. A wrapper which changes variables in a symbolic expression seems reasonable too. The expression tree gives a presentation of a symbolic expression as a composite of elementary functions -- that may or may not be useful depending on how you want to work with abstract functions.Tue, 03 Dec 2013 00:42:31 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16583#post-id-16583Answer by nbruin for <p>Is there a way to define a symbolic function that can (e.g.) be differentiated, but doesn't remember the name of its input variable(s)? For instance, consider:</p>
<pre><code>sage: f(x) = x^2
sage: g(x) = x^2
sage: h(t) = t^2
</code></pre>
<p>Mathematically, f, g, and h, should all be the same function. However, Sage doesn't think so:</p>
<pre><code>sage: f+g
x |--> 2*x^2
sage: f+h
(t, x) |--> t^2 + x^2
</code></pre>
<p>I guess that this is happening because a "function" defined with <code>f(x)=x^2</code> is actually just a symbolic expression equipped with an ordering on its variables, rather than what a mathematician would call a "function". Is there a way to define an actual mathematical function?</p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?answer=15734#post-id-15734It's a peculiarity of sage that object "(print)names" have significance. For instance, `QQ['x']` and `QQ['t']` are both rings of univariate polynomials over `QQ`. They are of course isomorphic but in the eyes of sage not canonically so (there are many relations possible between x and t that could establish an isomorphism), and hence sage declines to choose any by default. The same here:
sage: parent(f)
Callable function ring with arguments (x,)
sage: parent(h)
Callable function ring with arguments (t,)
Going from one to the other can be done:
sage: Ct = parent(h)
sage: ft = Ct(f(t))
sage: ft
t |--> t^2
sage: parent(ft)
Callable function ring with arguments (t,)
sage: ft+h
t |--> 2*t^2
sage: parent(ft+h)
Callable function ring with arguments (t,)
Doing it like this might give you a bit of a glimpse "under the hood" into why it works this way. Wed, 27 Nov 2013 11:35:04 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?answer=15734#post-id-15734Comment by Mike Shulman for <p>It's a peculiarity of sage that object "(print)names" have significance. For instance, <code>QQ['x']</code> and <code>QQ['t']</code> are both rings of univariate polynomials over <code>QQ</code>. They are of course isomorphic but in the eyes of sage not canonically so (there are many relations possible between x and t that could establish an isomorphism), and hence sage declines to choose any by default. The same here:</p>
<pre><code>sage: parent(f)
Callable function ring with arguments (x,)
sage: parent(h)
Callable function ring with arguments (t,)
</code></pre>
<p>Going from one to the other can be done:</p>
<pre><code>sage: Ct = parent(h)
sage: ft = Ct(f(t))
sage: ft
t |--> t^2
sage: parent(ft)
Callable function ring with arguments (t,)
sage: ft+h
t |--> 2*t^2
sage: parent(ft+h)
Callable function ring with arguments (t,)
</code></pre>
<p>Doing it like this might give you a bit of a glimpse "under the hood" into why it works this way. </p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16586#post-id-16586Hmm... if it were really consistent about behaving this way, then I would expect `f+h` to be a type error, since you can't add elements of different rings.Mon, 02 Dec 2013 16:34:28 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16586#post-id-16586Comment by Mike Shulman for <p>It's a peculiarity of sage that object "(print)names" have significance. For instance, <code>QQ['x']</code> and <code>QQ['t']</code> are both rings of univariate polynomials over <code>QQ</code>. They are of course isomorphic but in the eyes of sage not canonically so (there are many relations possible between x and t that could establish an isomorphism), and hence sage declines to choose any by default. The same here:</p>
<pre><code>sage: parent(f)
Callable function ring with arguments (x,)
sage: parent(h)
Callable function ring with arguments (t,)
</code></pre>
<p>Going from one to the other can be done:</p>
<pre><code>sage: Ct = parent(h)
sage: ft = Ct(f(t))
sage: ft
t |--> t^2
sage: parent(ft)
Callable function ring with arguments (t,)
sage: ft+h
t |--> 2*t^2
sage: parent(ft+h)
Callable function ring with arguments (t,)
</code></pre>
<p>Doing it like this might give you a bit of a glimpse "under the hood" into why it works this way. </p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16568#post-id-16568Okay, I guess I see what the developers were thinking, even if I don't agree with it. (Wouldn't "coproduct" be a more appropriate term?)Thu, 05 Dec 2013 06:29:59 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16568#post-id-16568Comment by nbruin for <p>It's a peculiarity of sage that object "(print)names" have significance. For instance, <code>QQ['x']</code> and <code>QQ['t']</code> are both rings of univariate polynomials over <code>QQ</code>. They are of course isomorphic but in the eyes of sage not canonically so (there are many relations possible between x and t that could establish an isomorphism), and hence sage declines to choose any by default. The same here:</p>
<pre><code>sage: parent(f)
Callable function ring with arguments (x,)
sage: parent(h)
Callable function ring with arguments (t,)
</code></pre>
<p>Going from one to the other can be done:</p>
<pre><code>sage: Ct = parent(h)
sage: ft = Ct(f(t))
sage: ft
t |--> t^2
sage: parent(ft)
Callable function ring with arguments (t,)
sage: ft+h
t |--> 2*t^2
sage: parent(ft+h)
Callable function ring with arguments (t,)
</code></pre>
<p>Doing it like this might give you a bit of a glimpse "under the hood" into why it works this way. </p>
http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16575#post-id-16575You can if you consider the two rings as subrings of a bigger ring, and in this case there is an (almost) natural candidate: the Callable function ring with arguments (x,t), since a function in either x or t can be considered as a function in both. The fact that the order of the arguments isn't well-defined is problematic, though. Finding a common "covering structure" in which the result of an operation on two elements from distinct structures lives is referred to as a "pushout" in sage.Wed, 04 Dec 2013 03:19:01 -0600http://ask.sagemath.org/question/10782/symbolic-functions-without-named-variables/?comment=16575#post-id-16575