Fwd: [sage-support] Is there an efficient method of producing indexed variables?

7 views
Skip to first unread message

Franco Saliola

unread,
Apr 2, 2010, 1:47:13 PM4/2/10
to sage-...@googlegroups.com
I forgot to more the conversation below from sage-support to sage-devel.

---------- Forwarded message ----------
From: Franco Saliola <sal...@gmail.com>
Date: Fri, Apr 2, 2010 at 1:45 PM
Subject: Re: [sage-support] Is there an efficient method of producing
indexed variables?
To: sage-s...@googlegroups.com


On Thu, Apr 1, 2010 at 10:50 PM, Minh Nguyen <nguye...@gmail.com> wrote:
> Hi,
>
> On Fri, Apr 2, 2010 at 12:36 PM, scott.h <scott...@gmail.com> wrote:
>
> <SNIP>
>
>> It seems like this should be simple but for the life of me I can't
>> figure out how to do it.
>
> Here I'm taking a guess at what you really want to do. See the
> following Sage session:
>
> [mvngu@sage ~]$ sage
> ----------------------------------------------------------------------
> | Sage Version 4.3.5, Release Date: 2010-03-28                       |
> | Type notebook() for the GUI, and license() for information.        |
> ----------------------------------------------------------------------
> sage: n = 3
> sage: M = random_matrix(ZZ, nrows=n); M
> [ 2  2 -2]
> [ 4  2 -7]
> [ 2 -1  1]
> sage: # create a list of unknown constants; these are actually
> symbolic variables
> sage: C = [var("C_%s" % i) for i in range(n)]; C
> [C_0, C_1, C_2]
> sage: X = [randint(1, 10) for i in range(n)]; X
> [2, 3, 2]
> sage: F = [C[i] * exp(M[i,i] * x) for i in range(n)]; F
> [C_0*e^(2*x), C_1*e^(2*x), C_2*e^x]
> sage: [F[i].substitute(x=X[i]) for i in range(n)]
> [C_0*e^4, C_1*e^6, C_2*e^2]

It might be useful to have a constructor to simplify this.
One would be able to do something like this:

   sage: a = SymbolicVariables('a')
   sage: sum(a[i]*x^i for i in range(3))
   a2*x^2 + a1*x + a0

and Minh's session above would become:

   sage: n = 3
   sage: M = random_matrix(ZZ, nrows=n)
   sage: c = SymbolicVariables('c')
   sage: [c[i] * exp(M[i,i] * x) for i in range(n)]
   [c0*e^(-x), c1*e^(-5*x), c2*e^(13*x)]

Here is a very simple implementation of SymbolicVariables.

   class SymbolicVariables(SageObject):
       def __init__(self, prefix='x'):
           self._prefix = prefix
       def __getitem__(self, i):
           return var("%s%s"%(self._prefix, i))

Thoughts?

Franco

--

Jason Grout

unread,
Apr 2, 2010, 2:14:39 PM4/2/10
to sage-...@googlegroups.com


This has come up several times before on sage-devel, and I've always
liked it. For example, Nathann Cohen brought this up when he was first
integrating the linear programming stuff. I believe Robert Bradshaw
suggested this "indexing creates a variable" approach a while ago too.

When/if we wrap pynac vectors/matrices, though, or have "symbolic vector
variables", we might have to be careful about how we treat the
__getitem__ function. I think in your case, where you explicitly are
creating x with the understanding that indexing x creates new variables,
things would be fine, though.

Thanks,

Jason

Robert Dodier

unread,
Apr 3, 2010, 1:54:52 PM4/3/10
to sage-devel
On Apr 2, 12:14 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
> On 04/02/2010 12:47 PM, Franco Saliola wrote:

> > Here is a very simple implementation of SymbolicVariables.
>
> >     class SymbolicVariables(SageObject):
> >         def __init__(self, prefix='x'):
> >             self._prefix = prefix
> >         def __getitem__(self, i):
> >             return var("%s%s"%(self._prefix, i))

> This has come up several times before on sage-devel, and I've always


> liked it.  For example, Nathann Cohen brought this up when he was first
> integrating the linear programming stuff.  I believe Robert Bradshaw
> suggested this "indexing creates a variable" approach a while ago too.
>
> When/if we wrap pynac vectors/matrices, though, or have "symbolic vector
> variables", we might have to be careful about how we treat the
> __getitem__ function.  I think in your case, where you explicitly are
> creating x with the understanding that indexing x creates new variables,
> things would be fine, though.

Not that it matters, but creating new symbols for indexed
variables seems to have some potential for unexpected behavior,
aside from cluttering the namespace.

Another approach is to represent an indexed variable as a
symbolic expression the same as an unevaluated function call,
but with an extra flag which essentially just shows it's
a subscripted expression instead of a function call.
(There isn't any real conceptual difference, right?
A subscripted variable is just a function on some countable
set.) That representation has the advantage that properties
of a collection of variables (e.g. x[1], x[2], ..., x[i])
can be associated with just the indexed symbol (x here).

There is an existing program which uses this scheme,
although it doesn't matter which one it is, so I won't
bother to mention it.

FWIW

Robert Dodier

Nicolas M. Thiery

unread,
Apr 9, 2010, 11:39:20 AM4/9/10
to sage-...@googlegroups.com

+1

Just: why countable? Well, yeah, there are only countably objects that
can be represented on a computer. I guess all I want to point out is
that such subscripted variables would be useful with all sorts of
subscripts (trees, graphs, groups, ...), and not just integers.

> There is an existing program which uses this scheme,
> although it doesn't matter which one it is, so I won't
> bother to mention it.

More than one :-)

Cheers,
Nicolas
--
Nicolas M. Thi�ry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/

Reply all
Reply to author
Forward
0 new messages