Hello,
Suppose that I have an equation such as the following:
|A*x**2 + B*y**2 + C*x*y+ D*x**2 = E*z**2 + F
|
In the above, {A, B, C, D, E, F} are coefficients, and {x, y, z} are
variables. Multiplication is denoted by the * symbol, addition by the +
symbol, and powers by the ** sy
On 11/09/2010 3:46 PM, Aaron S. Meurer wrote:
I think you want the collect() function and the .as_independent
method. The easiest way to manipulate Equalities is to first convert
them into regular expressions. Then, you would call collect on the
expression using x**2. collect collects all p
I think you want the collect() function and the .as_independent
method. The easiest way to manipulate Equalities is to first convert
them into regular expressions. Then, you would call collect on the
expression using x**2. collect collects all powers of the argument
by default, but you can
If the second one had given set([M(i, j) ,M(1 + i, j)]), then you could have
had something to work with (Chris or Oyvind, do you know why it does this?).
Of course, the way I gave again above will still work, if you know what the M's
are in the expression:
In [104]: expr = expr.lhs - expr.rh
On 10-09-16 10:33 PM, Aaron S. Meurer wrote:
.atoms() is the standard way to get all the similar kinds of objects in an
expression, so it is a shame that it isn't working in this case. I opened
issue (2058) for this (see
http://code.google.com/p/sympy/issues/detail?id=2058).
Feel free to le
Exactly, Indexed is very fresh, and will probably change a bit before
the 0.7 release. See issue 2059 for instance. But as smichr figured
out in issue 2058, the .atoms() method works as it should. The
confusion comes from the fact that when an Indexed object recieves
indices, the returned ob
Well, I've written some code in an attempt to re-arrange another example
expression, but for some reason this is not working. What am I doing
wrong here, and how might I collect terms with (n+1) powers and bring
them to the RHS of the equation? Here's what I have done:
# begin code
from symp
expr3 = collect( expr2, M**(n+1), exact=True )
This doesn't work because it is M(2, 1)**(n+1) that is present in expr2,
and not M**(n+1). So you must use:
expr3 = collect( expr2, M(2, 1)**(n+1), exact=True)
Ųyvind
Thank you very much for your response, Ųyvind! That works well f
Playing around with these concepts again, I've written another example
script:
# begin code
from sympy import *
from sympy.tensor import Indexed, Idx, IndexedElement
p = Indexed('p')
i,j,n = symbols('i j n', integer = True)
exprA = Eq(p(1,1)**(n+1) + p(2,1)**(n+1), p(3,3)**(n+1) + p(1,3)**(n+
On 10-09-18 09:30 PM, smichr wrote:
But that only groups together one variety of M**(n+1). If you want
them all together you have to give them a common coefficient that can
be used for collection:
u = Dummy('u')
These are the quantities that may have the n+1 power
expr2.atom
u = Dummy('u')
I can't seem to use the u = Dummy('u') variable, since I now receive the
following error:
Traceback (most recent call last):
File "test.py", line 12, in
u = Dummy('u')
NameError: name 'Dummy' is not defined
Moreover, I think that something like this would be extremel
Thanks Ondrej and Řyvind; that's greatly appreciated!
Ondrej:
As you suggest, I've attempted to use
a = Symbol("x", dummy=True)
In the example code given below, I am still using "from sympy import *" since I
am not certain
exactly what I would have to import. However, I do agree that it is f
Thanks for your response, smichr; that's greatly appreciated.
However, this does not seem to work, since the following error is produced:
Traceback (most recent call last):
File "test-1.py", line 17, in
print collect(expr.subs([(a**(n+1), u*a**(n+1)) for a in _]), u)
NameError: na
That would be cool to have implemented, though. Or maybe some kind of lambda
thing, so you could just say
collect(expr, lambda i: i.is_Indexed, lambda=True)
and it would collect all Indexed terms.
Also, as far as making the Indexed separation work, maybe some kind of lambda
support in as_i
I think you have found a bug with subs. Can you report it in the issues, with
the traceback?
Aaron Meurer
Done, the issue has been reported here
(http://code.google.com/p/sympy/issues/detail?id=2060). I expect that
it will be closed soon, but at least it gets everyone thinking ;-)
Generally it's easiest to convert an Equality into a regular expression and
then convert it back (like I showed in my first email to this thread). If you
only want to manipulate one side of an Equality, you could do
Eq(manipulation(expr.lhs), expr.rhs), i.e., only do it to whatever side and
In the mean time I found an easy way to do the Wild() trick in collect,
and have uploaded to github, the branch is fix_collect. I am trying to
use the pull request feature, without any luck so far...
Ųyvind
That's very exciting, Ųyvind - it will be a neat experience to try your
patch. I'v
sø., 19.09.2010 kl. 17.19 -0600, skrev Nicholas Kinar:
In the mean time I found an easy way to do the Wild() trick in collect,
and have uploaded to github, the branch is fix_collect. I am trying to
use the pull request feature, without any luck so far...
Ųyvind
That's
Working again on this example program, I am now trying to use
as_independent() on expr1 after collect() has been called on expr.
# begin code
from sympy import *
from sympy.tensor import Indexed, Idx, IndexedElement
M = Indexed('M')
var('A B C D E')
i,j,n = symbols('i j n', integer = True)
i =
Working again on this example program, I am now trying to use
as_independent() on expr1 after collect() has been called on expr.
# begin code
from sympy import *
from sympy.tensor import Indexed, Idx, IndexedElement
M = Indexed('M')
var('A B C D E')
i,j,n = symbols('i j n', integer = True)
i
OK, so here is how to do it (with all the work arounds). First off, again I
HIGHLY RECOMMEND that you use M(i, j, n) instead of M(i, j)**n. As a simple
example of how M(i, j)**n can lead to unintended consequences, consider what
will happen if you set n = 0. You will get M(i, j)**0 == 1!
Just a follow up about using subs(wild=True). If Idx is derived from
Expr rather than Basic, then the wild subs shown below (in t2) works:
eq=A*M(i, j)**n + B*M(1 + i, j)**(1 + n)- D*M(i, j)**(1 + n)
Eq(*reversed(collect(eq.subs(w**(1+n), w**(1+n)*u, wild=True),
u).as_independent( u))).subs(
On 10-09-21 01:18 AM, Aaron S. Meurer wrote:
OK, so here is how to do it (with all the work arounds). First off, again I
HIGHLY RECOMMEND that you use M(i, j, n) instead of M(i, j)**n. As a simple
example of how M(i, j)**n can lead to unintended consequences, consider what
will happen if you
Now I believe that as_base_exp() and other related functions can be found in
expr.py, and I've tried copying these functions into the Idx class (indexed.py)
to serve as a template for what I would like to do. I've then attempted to
modify these functions, but based on these very preliminary
I received this same error when manually copying the functions between
the files, which isn't too extraordinary (given that we're subclassing
one class from the other).
Nicholas
My mistake; I was running the wrong Python script! Now by subclassing
Idx from Expr, the following works qu
I am interested in re-arranging equations in this fashion since I
would like to create a function to generate systems for the solution
of finite-difference time domain (FDTD) schemes, which are very useful
in computational physics. I plan to create a function such as
generate_fdtd(expr) that
Another way of handling the lambda functionality would be to piggy
back off of match so that eq.match(lambda) would return True if the
lambda was true for eq. That way routines would gain matching and
lambda capabilities at the same time. Or, like for .has(), routines
already having wild matchin
So given that Idx can subclass from Expr as suggested by smichr, and
Oyvind's fix gets pushed into the trunk, my proposed (extremely
modest) function would become:
def generate_fdtd(expr, nsolve):
w = Wild('w')
expr0 = expr.lhs - expr.rhs
expr1 = collect(expr0, w**nsolve)
r
Try using .args, as in
expr.args
Aaron Meurer
Thanks, Aaron; that's the icing on the cake, and it is exactly what I
needed. Isn't it neat how expr.args can be cascaded?
expr1 = expr0.args[0].args[1].args[1]
Nicholas
--
You received this message because you are subscribed to the Goog
Yep. .args is basically the key to doing advanced stuff in SymPy. You can
access any part of an expression you want by walking the .args tree, and you
can use it to do any kind of manipulation you want. Basically, if you look at
the source for many of these functions like collect() or as_i
I've written another example program :-D
What I would like to do is separate each term into coefficients and
variables.
Is it possible to obtain the coefficients of a term using .coeff without
knowing the indexed variable? The following example program
demonstrates what I would like to achi
Hello,
Given an expression in sympy with indexed variables such as
expr = A*M(i,j) + B*M(i,j) + C
is there a way to iterate through each of the terms in the expression?
I've learned that
i = 0
expr.args[i]
can be used to access parts of the expression, but is there a way to use
this in a
expr.args gives a python tuple of the arguments that can be iterated
through in the normal ways.
for i in (1, 42, 'this'):
... print i
...
1
42
this
expr = 1+x+42/x
for i in expr.args:
... print i
...
1
42/x
x
for i, a in enumerate(expr.args):
Try:
In [166]: expr = 0.5*p(1, 3)**(1 + n)/(x**2*y**2)
In [167]: for n, arg in enumerate(expr.args):
if p(1, 3) in arg:
m = n
break
In [171]: expr.coeff(expr.args[m])
Out[171]: 0.5/(x**2*y**2)
Much appreciated, Andy; thanks for this code snippet. However, what
wo
h[1]>>> from sympy.tensor import *
h[1]>>> M=Indexed('M')
h[1]>>> var('i j k', integer=1)
(i, j, k)
h[2]>>> eq=1+2*M(i,1)+3*j+4*M(i,2); eq
1 + 2*M(i, 1) + 3*j + 4*M(i, 2)
h[3]>>> for a in eq.as_Add():
... ie = []
... co = []
... for m in a.as_Mul():
... if
You should also know about pre/post_order_traversal (both must be imported from
sympy.utilities.iterables), which let you dig all the way down in an expression
tree.
In [109]: from sympy.utilities.iterables import preorder_traversal,
postorder_traversal
In [110]: preorder_traversal(sin(x**2
Hello,
Suppose that I have an expression such as the one given below:
M = Indexed('M')
var('A B C')
i,j,n = symbols('i j n', integer = True)
expr = A*M(1,2)**n + B*M(-2,1)**n + C*M(-1,-1)**n
Is there a way to iterate through this expression and apply the
following sequence of operations?
(1
There's no need to iterate through the expression to do this. Just use subs,
i.e., expr.subs({M(1, 2)**n: Symbol('M_1_2_n'), M(-2, 1)**n:
Symbol('M_neg2_1_n'), …})
Of course, if you want to generate the Symbols automatically, that would
require you to be a little more clever.
Yes, I would
There is (I gave it below :)
Aaron Meurer
Then I think that .subs() could be used to make the substitution.
(2) For every replacement, a list (or similar data structure) is created with
the names of the variables [M_1_2_n, M_neg2_1_n, M_neg1_neg1_n]. The list
contains the names of unique
Hmm. To me, it seems like ccode() should be able to do this on its own. Maybe
you could submit it as a patch to ccode(). Or maybe it really can and neither
of us know about it. Øyvind (or anyone)?
There is a lot of pending patches that will improve the support for
Indexed in ccode. You ca
So it sounds like that is what you want to do. I guess you need to combine the
expr.atoms(IndexedElement) with str() or .args and some regular expression
replacement. Something like '_'.join([str(t) for t in
index.args]).replace('-', 'neg'), where index is a M(1, 2, …) element (again a
ver
(1) What can I do if I have the n expressed as a power (superscript),
and it must remain as a superscript? I've found that a.atoms(
IndexedElement ) will only return the indexed element, and not the
power. Is there a way of having a.atoms( IndexedElement ) return the
superscript as well?
I've attempted to incorporate your suggestions into my example script,
but I don't think I'm doing this correctly. For example, using the
code below, I would like to change
p(3, 1)**(1 + n)
p(1, 1)**(1 + n)
p(2, 1)**(1 + n)
p(-1, -3)**(1 + n)
into
p_3_1_nplus1
p_1_1_nplus1
p_2_1_nplus1
p_n
Hello,
I've been testing my script again to perform algebraic re-arrangement of
equations, and I've found that the sample expression (expr) given below
does not seem to be re-arranged correctly.
As discussed on this mailing list, I would like to set up the
generate_fdtd() function to do the
I am currently using the fix_collect branch of Oyvind's repository, and I've
also changed the code so that Idx is subclassed from Expr.
This has been pushed in, so you can use the official master again.
Aaron Meurer
Thank, Aaron; that's good to know, since now I can write research
Nicholas Kinar wrote:
However, as the output shows below, the term p(1,
2)**n/(deltat**2*deltax**2) is still on the LHS of the expression, to
the immediate left of the == sign. As I understand, the
If you use master it all works. IndexedElement is now called IndexedBase (but
you
Hello,
Testing the example code again with a slightly more complicated
expression, it appears that there is still a p[1, 1]**(-1 + n) term on
the LHS. Essentially what I've been trying to do is group terms so that
there is only one of each p[i , j] on the LHS. For example, there
should only
For example, there should only be one p[1,1]**(-1+n) IndexedBase term
with a coefficient.
Whoops, I mean that there should only be one p[2, 1]**(1 + n)
IndexedBase term with a coefficient on the LHS, since all terms with
(n+1) powers should be on the LHS. The p[1,1]**(-1+n) term should
def generate_fdtd(expr, nsolve):
w = Wild('w')
expr0 = expr.lhs - expr.rhs
expr1 = expr0.expand()
expr2 = collect(expr1, w**nsolve)
expr2 = expr2.expand()
Why are you expanding after you collect? This will undo what you just collected.
Ah, you are right, C
Glad to help. When I started learning python I found the tutor group SO
helpful. With python (and I don't know about other languages) you not only get
a great syntax, but you get a pretty enthusiastic user group that's doing all
kinds of interesting things with python. I'm glad to be able to
I remember when I was working on boudary conditions for a FD method. I started
using a CAS system to see if the conditions were even solvable for a coarse
grid. It helped a lot.
Another little trick I just learned is that many programs (I use Irfanview) can
read a pbm file which is just a fi
Hello,
Working again with the FDTD re-arrangement of terms, I am wondering if
there is any way to run collect() on indices of an IndexedBase object
using the current master sympy git repository. Rather than having (n+1)
expressed as a power, is it possible to run collect() in the manner
show
def generate_fdtd(expr, nsolve):
w = Wild('w')
expr0 = expr.lhs - expr.rhs
expr1 = expr0.expand()
# this doesn't work to collect terms at timestep (n+1)
print collect(expr1, p[w,w,n+1])
Pardon the unintentional indent, so the function should be:
def generate_fdtd
Hello,
Working again with the FDTD re-arrangement of terms, I am wondering if
there is any way to run collect() on indices of an IndexedBase object
using the current master sympy git repository. Rather than having (n+1)
expressed as a power, is it possible to run collect() in the manner
shown
#begin modified sample code
from sympy import *
from sympy.tensor import Indexed, Idx, IndexedBase
from sympy.matrices import *
p = IndexedBase('p')
var('deltax deltay delta deltat A B')
i,j,n = symbols('i j n', integer = True)
def generate_fdtd(expr, nsolve):
w = Wild('w')
expr0 = ex
Hello,
Looking back at a previous thread
(http://groups.google.com/group/sympy/browse_thread/thread/a406176eeb28eb04),
an interesting procedure was discussed to place p[i,j,n+1] terms on the
LHS of the expression. (Thanks again, Aaron!) As shown in another
sample code below, the procedure u
Your problem comes from using atoms(IndexedBase). Here is what that gives:
In [24]: expr.atoms(IndexedBase)
Out[24]: set(p)
But this doesn't have the i, j, n args that you want. I think what you really
want to do is use atoms(Indexed) (Øyvind, correct me if I am wrong here). That
gives:
Yes, this is exactly what I wanted, Aaron; many thanks for pointing me
in the right direction. As shown in the final example code below,
I've done as you've suggested and used atoms(Indexed). I've also
taken a poet's license with the code and called expand() to be able to
distribute through
Here's a short comment: using Idx(n+1) seems to work a little better for me,
since I've noticed that if I use Idx(n) with a very complicated expression,
there is a possibility of terms with (n+1) indices ending up on the same side
as the (n) indices.
That sounds like a bug. Can you gi
Here's a short comment: using Idx(n+1) seems to work a little better
for me, since I've noticed that if I use Idx(n) with a very
complicated expression, there is a possibility of terms with (n+1)
indices ending up on the same side as the (n) indices.
That sounds like a bug. Can you give a spe
I think what you are getting is expected behavior. Remember that when you
switch n and n + 1, you are switching the side of the equation that they will
end up on. So in the first one, you have all terms with n on the right-hand
side, and in the second one, you have all the terms with n + 1
Hello,
I've attempted to calculate the Jacobian of a simple expression with
indexed variables, and it appears that the diff() function cannot
currently work with the IndexedBase class.
Running the sample code below results in the following traceback:
Traceback (most recent call last):
File
Hello,
I've attempted to calculate the Jacobian of a simple expression with
indexed variables, and it appears that the diff() function cannot
currently work with the IndexedBase class.
Running the sample code below results in the following traceback:
Traceback (most recent call last):
Fi
The easiest workaround that I can think of is to use subs() to
substitute variables p_1_1 and p_1_2 into the expressions so that the
Jacobian is not computed using indexed variables p[1,1] and p[1,2].
However, I can't seem to use subs() to substitute the variables
either! What am I doing
I have to admit that the documentation
(http://docs.sympy.org/modules/core.html?highlight=subs#sympy.core.basic.Basic.subs)
misled me into thinking that subs() works directly on the variable itself, and
there is no need to assign the output to another variable.
All expressions in SymP
65 matches
Mail list logo