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.

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