# How Do I Extract Terms Containing Certain Coefficients From A Polynomial?

More specifically, I am trying to do small signal analysis on a power system, and I have some polynomial like this:

-D*I_L*Ron - I_L*Ron*d - D*Ron*i_L - Ron*d*i_L + D*V_g + V_g*d + D*v_g + d*v_g + D*V_C/n + V_C*d/n + D*v_C/n + d*v_C/n - V_C/n - v_C/n


I would like to take out terms including one of i_L, d, v_g, v_C, but not more. How can I do this?

edit retag close merge delete

Sort by » oldest newest most voted

I am not sure how I should interpret your criterion: do you want to allow a variable to appear more than once in the same monomial? Supposing you do, and supposing p is your polynomial expression, here's a fancy solution

[m for m in p.iterator() if sum(m({x:0}).is_zero() for x in (i_L, d, v_g, v_C)) == 1]


There's certainly many other, but I am afraid none is going to be very simple. A word of explanation:

• The first for loops over each monomial.
• For each monomial m, m({x:0}) evaluates the monomial at the point x=0, where x ranges over i_L, d, etc.
• If is_zero() returns True, the variable is obviously in the monomial.
• In a summation, True and False get converted to 0 and 1, thus sum(...) == 1 guarantees that the monomial contains exactly one of the variables i_l, d, etc.

Thanks for this refreshing riddle :)

more

( 2014-07-19 01:26:10 +0200 )edit

Wow, after some careful study, this is indeed a fancy solution which is equivalent to 7 lines of code. What is this syntax called? Is it a standard python feature?

( 2014-07-19 01:36:39 +0200 )edit

Also, after I get the list, what should I do next to convert back to polynomial?

( 2014-07-19 01:37:55 +0200 )edit

I found it, it's called _list comprehension_. Thank you!

( 2014-07-19 01:40:23 +0200 )edit

To convert back to polynomial, just sum() over the list.

( 2014-07-19 02:37:15 +0200 )edit

Thanks for Luca's answer! I am just expanding the code here

p1 = []
for m in p.iterator():
sum = 0
for x in (i_L, d, v_g, v_C):
sum += m({x:0}).is_zero()
if sum == 1:
p1.append(m)
p1

more

Careful: there's an indentation level missing after the second for

( 2014-07-19 02:40:34 +0200 )edit

Thank you! When I copied it, it just disappeared...

( 2014-07-19 02:58:17 +0200 )edit

# Quick Question

...Did you intend I_L and i_L to be distinct? did you intend D and d to be distinct? how about v_C and V_C? In Sage, the capitalization matter, and these would be treated as distinct.

# Solution

Assuming that you wanted them to be distinct, the following will work:

var("D I_L Ron d i_L V_g v_g V_C n v_C")

f = -DI_LRon - I_LRond - DRoni_L - Rondi_L + DV_g + V_gd + Dv_g + dv_g + DV_C/n + V_Cd/n + Dv_C/n + dv_C/n - V_C/n - v_C/n

print "Before:"

print f

print "After:"

print f(i_L=0, d=0, v_g=0, v_C=0)

# Output

Before:

-DI_LRon - I_LRond - DRoni_L - Rondi_L + DV_g + V_gd + Dv_g + dv_g + DV_C/n + V_Cd/n + Dv_C/n + dv_C/n - V_C/n - v_C/n

After:

-DI_LRon + DV_g + DV_C/n - V_C/n

more

Not quite... Yes, i_L and I_L are different. However, it is the lower-case ones that are being preserved: i_L, d, etc. So this is the opposite of what I need... I am reading about pattern match in document, but I have not found useful information yet.

( 2014-07-19 01:22:18 +0200 )edit