to., 16.09.2010 kl. 22.10 -0600, skrev Aaron S. Meurer:
> Hi again.
> 
> On Sep 16, 2010, at 9:51 PM, Nicholas Kinar 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 powers of the argument by default, but 
> >>> you can use the exact=False flag to turn this off (see the docstring of 
> >>> collect).  Actually, collect is optional, and is only if you want (A + 
> >>> D)*x**2 instead of A*x**2 + D*x**2.
> >>> 
> >>> Then, you can gather the independent and dependent parts using 
> >>> as_independent.  Here is an example of how you would do it with your 
> >>> expression:
> >>> 
> >>> In [1]: var('A B C D E F')
> >>> Out[1]: (A, B, C, D, E, F)
> >>> 
> >>> In [2]: expr = Eq(A*x**2 + B*y**2 + C*x*y + D*x**2, E*z**2 + F)
> >>> 
> >>> In [3]: expr
> >>> Out[3]:
> >>>           2      2      2          2
> >>> C⋅x⋅y + A⋅x  + B⋅y  + D⋅x  = F + E⋅z
> >>> 
> >>> In [4]: expr = expr.lhs - expr.rhs
> >>> 
> >>> In [5]: expr
> >>> Out[5]:
> >>>                2      2      2      2
> >>> -F + C⋅x⋅y + A⋅x  + B⋅y  + D⋅x  - E⋅z
> >>> 
> >>> In [6]: expr = collect(expr, x**2, exact=True)
> >>> 
> >>> In [7]: expr
> >>> Out[7]:
> >>>      2                      2      2
> >>> -F + x ⋅(A + D) + C⋅x⋅y + B⋅y  - E⋅z
> >>> 
> >>> In [8]: expr.as_independent(x**2, y**2)
> >>> Out[8]:
> >>> ⎛                2   2              2⎞
> >>> ⎝-F + C⋅x⋅y - E⋅z , x ⋅(A + D) + B⋅y ⎠
> >>> 
> >>> In [9]: expr = Eq(*reversed(expr.as_independent(x**2, y**2)))
> >>> 
> >>> In [10]: expr
> >>> Out[10]:
> >>> 2              2                   2
> >>> x ⋅(A + D) + B⋅y  = -F + C⋅x⋅y - E⋅z
> >>> 
> >>> It shouldn't be too hard to write a simple function that is passed an 
> >>> Equality and some variables and returns the result like in [10].
> >>> 
> >>> Aaron Meurer
> >>> 
> >> 
> >> Thanks, Aaron; that's exactly what I wanted and it is very exciting to 
> >> realize that this can be done.   I've just started playing with sympy and 
> >> exploring its possibilities, so thank you very much for helping to guide 
> >> me and for your response!
> >> 
> > 
> > I've been playing around with the algebraic rearrangement being discussed 
> > in this post, and I am wondering if it is possible to do the same operation 
> > with variables that are indexed.  Let me perhaps demonstrate what I would 
> > like to achieve.
> > 
> > In [1]: from sympy import *
> > In [2]: from sympy.tensor import Indexed, Idx
> > In [3]: var('A B C D')
> > In [4]: i, j, n, m = symbols('i j n m', integer=True)
> > In [5]: M = Indexed('M')
> > In [6]: expr = Eq(A*M(i,j)**(n+1) + B*M(i+1,j)**(n+1), C*M(i+1,j)**(n+1) + 
> > D*M(i,j)**n)
> > 
> > In [7]: expr
> > Out[7]: A*M(i, j)**(1 + n) + B*M(1 + i, j)**(1 + n) == D*M(i, j)**n + C*M(1 
> > + i, j)**(1 + n) + D*M(i, j)**(1 + n)
> 
> I'm not sure if exponentiation is the correct way to do superscripts.  I 
> guess you could use it, as an abstraction, but remember that SymPy is going 
> to want to treat M(i, j)**(1 + n) as M(i, j)*M(i, j)**n.  Probably a better 
> idea would be to just put the "superscript" as another element of the index, 
> such as M(i, j, 1 + n).  The only disadvantage is that It won't print the 
> same.  Maybe we should implement special handling for super/subscripts in 
> Indexed with printing support (feel free to send in a patch to do this).  
> 
> Also, the things I say below will work much better if you make n an index of 
> M. 
> 
> > 
> > So essentially what I've done is created an equation with a variable M.  
> > The variable M has superscripts (either 1+n or n), and subscripts (i,j).  I 
> > would now like to do the following:
> > 
> > (1) Set i = 1 and j = 1.  These are just example integers, but i and j 
> > could be set to other numbers.  So then the expr should become:
> 
> Use .subs().
> 
> > 
> > A*M(1, 1)**(1 + n) + B*M(1 + 1, 1)**(1 + n) == D*M(1, 1)**n + C*M(1 + 1, 
> > 1)**(1 + n) + D*M(1, 1)**(1 + n)
> > A*M(1, 1)**(1 + n) + B*M(2, 1)**(1 + n) == D*M(1, 1)**n + C*M(2, 1)**(1 + 
> > n) + D*M(1, 1)**(1 + n)
> > 
> > (2) Group all terms with similar subscripts and move all terms with (1 + n) 
> > superscripts to the LHS of the equation:
> 
> So the same thing I said before would work, except collect() and 
> .as_independent aren't so smart to handle more complex things like this.  One 
> idea I had was to use .atoms(), but it seems that it doesn't work as expected 
> for Indexed:
> 
> In [98]: expr = Eq(A*M(i,j)**(n+1) + B*M(i+1,j)**(n+1), C*M(i+1,j)**(n+1) + 
> D*M(i,j)**n)
> 
> In [100]: expr.atoms()
> Out[100]: set(1, A, B, C, D, M, i, j, n)
> 
> In [101]: expr.atoms(Indexed)
> Out[101]: set(M)
> 
> 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.rhs
> 
> In [105]: expr.subs({i:1}).as_independent(M)
> Out[105]: 
> ⎛              n            1 + n            1 + n            1 + n⎞
> ⎝0, - D⋅M(1, j)  + A⋅M(1, j)      + B⋅M(2, j)      - C⋅M(2, j)     ⎠
> 
> In [106]: expr.subs({i:1}).as_independent(M(1, j))
> Out[106]: 
> ⎛         1 + n            1 + n             n            1 + n⎞
> ⎝B⋅M(2, j)      - C⋅M(2, j)     , - D⋅M(1, j)  + A⋅M(1, j)     ⎠
> 
> The problem is knowing that M(1, j) and M(2, j) are the indexed objects in 
> the expression (that is where I would have liked to use atoms).
> 
> > 
> > (A - D)*M(1, 1)**(1 + n) + (B - C)*M(2, 1)**(1 + n) == D*M(1, 1)**n
> > 
> > (3) Print this new expression out in a "nice" format suitable for reading.
> 
> You can use the same collect() idea that I gave above, but again, you have to 
> give each full indexed object at this point in time.
> 
> > 
> > If anyone could point me in the right direction, I would be extremely 
> > grateful.  Could these operations be done using sympy?
> > 
> > Nicholas
> 
> Indexed() is kind of new, so most functions don't know about it.  But I think 
> if we fix the atoms bug above, what you want to do should be possible.
> 

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 object is of type IndexedElement.  So you need to
use .atoms(IndexedElement)

It is very cool that you have started to use the tensor module,
Nicholas! And even cooler that you communicate the issues you have, so
that we can fix it before the next release :-)

Øyvind

> Aaron Meurer
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to 
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to