Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

My apologies if this question has been asked before, but for the first 50 or so questions on coefficientlist, I couldn't find a similar topic.

If I've an expression which involves a variable with indices, and I want to collect its coefficients, how can it be achieved? For example, if my expression is

-27 Subscript[u, 1, 1] - 6 Subscript[u, 1, 2] +  9 Subscript[u, 1, 3]
+ 36 Subscript[u, 2, 1] + 8 Subscript[u, 2, 2] - 12 Subscript[u, 2, 3]
- 9 Subscript[u, 3, 1] - 2 Subscript[u, 3, 2] + 3 Subscript[u, 3, 3]

then how can I collect {-27, -6, 9, 36, 8, -12, -9, -2, 3}. The expression can have several other terms, but always of the form of Subscript[u, i, j].

And, if all these terms have a common denominator, how that situation can be handled? So far I was simply taking the numerator part, but if I've to compare the coefficients of many expressions, considering the full expression will further help. In this situation, I found that the answers of Marius and Alexei work straight away.

For example, if my full expression looks like -((27 Subscript[u, 1, 1] + 6 Subscript[u, 1, 2] - 9 Subscript[u, 1, 3] - 36 Subscript[u, 2, 1] - 8 Subscript[u, 2, 2] + 12 Subscript[u, 2, 3] + 9 Subscript[u, 3, 1] + 2 Subscript[u, 3, 2] - 3 Subscript[u, 3, 3])/(16 hx))

then using Marius' and Alexei's suggestion, I get the expected answer {-(27/(16 hx)), -(3/(8 hx)), 9/(16 hx), 9/(4 hx), 1/( 2 hx), -(3/(4 hx)), -(9/(16 hx)), -(1/(8 hx)), 3/(16 hx)}.

share|improve this question
2  
This might be a bit hacky, but instead of using something like CoefficientList you can just extract them yourself: First /@ List @@ expression – Martin Ender Mar 2 at 14:16
    
@MartinBüttner, I don't know about hacky, but that is a more intuitive method than those listed below. I feel really dumb but it took me forever to figure out why First /@ expression was giving 0 as the answer – JasonB Mar 2 at 15:20
    
@JasonB I guess I'll post it then. – Martin Ender Mar 2 at 15:29
    
Thanks to all for your helpful answers, each of them teaching something new (to a newbie of Mathematica). The most elegant and simple answer I found for my purpose is from @MartinBüttner, which I'm selecting as the answer (I can only select one, but honestly appreciating everything). – Saku Mar 2 at 19:50
    
@Saku You might want to reconsider that. See kglr's comment on my answer. It doesn't work reliably if your coefficients could be 1. – Martin Ender Mar 2 at 20:07
up vote 6 down vote accepted

Since all terms have Subscript[something], we can use a pattern:

expr /. Plus -> List /. c_.*Subscript[__] :> c

{-27, -6, 9, 36, 8, -12, -9, -2, 3}

This assumes the expression has been Expanded so that the Head is indeed Plus. This will also give the coefficients in the same order as they appeared in the expression. If you also would like which coefficients belong with which coefficients, do:

expr /. Plus -> List /. c_.*Subscript[x__] :> {c, Subscript[x]}

{{-27, Subscript[u, 1, 1]}, {-6, Subscript[u, 1, 2]}, {9, Subscript[u, 1, 3]}, {36, Subscript[u, 2, 1]}, {8, Subscript[u, 2, 2]}, {-12, Subscript[u, 2, 3]}, {-9, Subscript[u, 3, 1]}, {-2, Subscript[u, 3, 2]}, {3, Subscript[u, 3, 3]}}

EDIT:

Explanation of replacement: First, all terms in expr are put in a list. Then, we replace all instances of expressions in that list that match the pattern c_.*Subscript[__] with just c. This pattern matches expressions where some expression c is multiplied by a Subscript expression with any arguments (at least one). The period in the pattern c_. lets us include the default value in multiplication, which is 1. If we had omitted it, the pattern would not match e.g. the last term in

3 Subscript[u,1,1] + Subscript[u,1,2]

because that term is not strictly "some expression multiplied with Subscript.

As for the ordering, yes, the ordering will be the same as that in expr as long as it is a "flat" sum, i.e. fully expanded.

share|improve this answer
    
Thanks. The second options can be certainly helpful in some situations, and I've noted it. But can you be kind enough to explain the whole idea after Plus -> List (in both the options)? Please note that I'm almost illiterate in Mathematica (coming from structured programming style). It will help to know how this works than just copying for one specific purpose. Also, though you already about it, as some other experts raised the question of ordering, will this construct maintain the order in all situations? – Saku Mar 3 at 9:30
    
Please see my edit :) – Marius Ladegård Meyer Mar 3 at 12:35
    
Thanks a lot. This is indeed helpful, also for comparing your answer with that of Alexei (which might fail if the coefficient is 1). Given all the answers, and the flexibility of having a denominator, I'm selecting your answer as the final one. – Saku Mar 4 at 11:39

Yet another way to do this, using Coefficient

expr = -27 Subscript[u, 1, 1] - 6 Subscript[u, 1, 2] + 
   9 Subscript[u, 1, 3] + 36 Subscript[u, 2, 1] + 
   8 Subscript[u, 2, 2] - 12 Subscript[u, 2, 3] - 
   9 Subscript[u, 3, 1] - 2 Subscript[u, 3, 2] + 
   3 Subscript[u, 3, 3];
Flatten@Array[Coefficient[expr, Subscript[u, #1, #2]] &, {3, 3}]
(* {-27, -6, 9, 36, 8, -12, -9, -2, 3} *)

Edit

Here's a way to get there using CoefficientList,

CoefficientList[expr, Variables[expr]] // Flatten // 
   DeleteDuplicates // Reverse // Most
(* {-27, -6, 9, 36, 8, -12, -9, -2, 3} *)
share|improve this answer
    
You could use Variables[expr] instead of the Table I guess. Anyway, nice one, I could not make sense of the array from CoefficientList so simply, +1. – Marius Ladegård Meyer Mar 2 at 14:47
    
Thanks, I was unaware of Variables :-) – JasonB Mar 2 at 15:08

Turning my comment into an answer. If you know that this is exactly the form of the expression, you can just pick out the coefficients manually with First. It's important though that you first turn the sum into a list, because otherwise the coefficients will be summed up immediately:

First /@ List @@ expression

The List @@ replaces the head Plus with List. Then we simply pick out each coefficient with First, because Mathematica orders products with the coefficient first and the variable second.

Note that this doesn't work reliably if some of the terms have a coefficient of 1 (in that case, the variable itself would be returned). You could fix that with something like:

Replace[First /@ List @@ expression, n_ /; ! NumericQ@n -> 1, {1}]

But at that point it might be simpler to use one of the other answers.

Alternatively, as garej suggested in a comment, if you have a variable a that you know is unused, you could do:

First /@ List @@ Expand[a*expr] /. a -> 1
share|improve this answer
1  
if some coefficients in expression are 1, this approach does not work. E.g. for exp2 used in my answer below, First /@ List @@ exp2 gives {u, -1, u, 36, 8}. – kglr Mar 2 at 20:01
    
@kglr Oh, that's a very good point. – Martin Ender Mar 2 at 20:04
    
@MartinBüttner, that is not as nice but you may use something like First /@ List @@ Expand[2*expr]/2 to avoid problem of 1. – garej Mar 2 at 20:42
    
@garej Then what if you have a coefficient of 1/2? ;) – Martin Ender Mar 2 at 20:42
    
@MartinBüttner, lol!! than may be one has to use First /@ List @@ Expand[a*expr] /. (a :> 1) – garej Mar 2 at 20:46

Using @JasonB's expr, this also works:

expr[[#, 1]] & /@ Range[Length[expr]]
share|improve this answer

A few additional alternatives:

f1 = D[#, {Variables @ #}] &;
f2 = List @@ # /. Subscript -> (1 &) &;
f3 = # /. {Plus -> List, Subscript -> (1 &)} &;
f4 = Block[{Plus = List, Subscript = (1 &)}, #] &;
f5 = Coefficient[#, Variables @ #] &;
☺ = # /. u -> 1 & @@@ {##} & @@ # &;

Examples:

exp1 = -27 Subscript[u, 1, 1] - 6 Subscript[u, 1, 2] + 
 9 Subscript[u, 1, 3] + 36 Subscript[u, 2, 1];

exp2 = Subscript[u, 1, 1] - Subscript[u, 1, 2] + Subscript[u, 1, 3] + 
   36 Subscript[u, 2, 1] ;

f1 /@ {exp1, exp2}

{{-27, -6, 9, 36}, {1, -1, 1, 36}}

Equal@@Through[{f1, f2, f3, f4, f5, ☺} @ exp1]

True

Through[{f1, f2, f3, f4, f5, ☺} @ exp2]

True

share|improve this answer
1  
Wait, can we use emoji as variable names? This changes everything – JasonB Mar 2 at 19:35
    
@JasonB, yes we can ☺. – kglr Mar 2 at 19:43
    
Thanks @kglr. The option f1 is a clever one using mathematical principle. Will the option f5 maintain the ordering, as some other experts have raised this issue? And, yes JasonB, I can confirm that emojis are also working. Hats off to kglr. – Saku Mar 3 at 9:36
    
@kglr, If I've a denominator in the expression, then the options f3, f4 and f5 works, while others do not. While comparing with the answer of Marius, I note that the output here is Matrix-type (2 curly braces), whereas from Marius is of vector-type (1 curly brace). Moreover, the option f5 gives output with the first (additional) element as 0. Could you be kind enough to explain the steps in your answers. From mathematica help, I figured out "#" (argument number) and "&" (pure function), but not very sure about various (including multiple) uses of "@". – Saku Mar 4 at 13:06

Try this:

    expr = -27 Subscript[u, 1, 1] - 6 Subscript[u, 1, 2] + 
   9 Subscript[u, 1, 3] + 36 Subscript[u, 2, 1] + 
   8 Subscript[u, 2, 2] - 12 Subscript[u, 2, 3] - 
   9 Subscript[u, 3, 1] - 2 Subscript[u, 3, 2] + 3 Subscript[u, 3, 3];


expr /. Plus -> List /. a_*Subscript[u, __] -> a

(* {-27, -6, 9, 36, 8, -12, -9, -2, 3}  *)

Have fun!

share|improve this answer
    
Thanks Alexei. I guess this answer is similar to Marius' answer above (perhaps a mix of both of his options?). If I understand correctly, it takes the subscripts of u for the variable a, and then produce a alone without any subscripts? – Saku Mar 3 at 9:53
    
@Saku Yes, it is correct – Alexei Boulbitch Mar 4 at 7:53
    
Thanks @Alexei. The answer proposed by Marius also works for the case when the coefficient could be 1. – Saku Mar 4 at 11:40

A reliable (for linear expressions) and concise way is

Normal@Last@CoefficientArrays[expr]

{-27, -6, 9, 36, 8, -12, -9, -2, 3}

but read also the rest...


I suppose you need the coefficients in some reliable order, the order of variables; maybe you already have the list of variables in the proper order and you expect to get the coefficient in the same order. If not, as already stated, you can get the variables with (Sort is not mandatory):

expr = -27 Subscript[u, 1, 1] - 6 Subscript[u, 1, 2] + 
  9 Subscript[u, 1, 3] + 36 Subscript[u, 2, 1] + 
  8 Subscript[u, 2, 2] - 12 Subscript[u, 2, 3] - 
  9 Subscript[u, 3, 1] - 2 Subscript[u, 3, 2] + 3 Subscript[u, 3, 3]
vars = Sort@Variables[expr]

{Subscript[u, 1, 1], Subscript[u, 1, 2], Subscript[u, 1, 3], Subscript[u, 2, 1], Subscript[u, 2, 2], Subscript[u, 2, 3], Subscript[u, 3, 1], Subscript[u, 3, 2], Subscript[u, 3, 3]}

Now, you can get the coefficients of that expression (or of a list of expression or a list of equations) easily with CoefficientArrays. This return a list of two (or more) SparseArray.

CoefficientArrays[expr]

Mathematica graphics

The first is the constant term (0 in this case), and the second is relative to the first degree terms of the expression. You can then get the cofficient with

Normal@Last@CoefficientArrays[expr, vars]

{-27, -6, 9, 36, 8, -12, -9, -2, 3}

Rest assured that the coefficients are returned in a meaningful and consistent order.

You are not forced to collect the Variables, you can omit the second argument of CoefficientArrays

Normal@Last@CoefficientArrays[expr]

{-27, -6, 9, 36, 8, -12, -9, -2, 3}

You still get the coefficients in the predictable Variables order.

share|improve this answer
    
Thanks a lot for a detailed answer, and addressing the ordering issue. Could you please tell what does the constant term refer here, which results in 0? – Saku Mar 3 at 9:47
    
@Saku Are the terms that doesn't depend on any variable (you pass), for example in 5+x+y, x and y are variables, and 5 is what you get as first element of the returned list. If you pass as second argumen only x as "variable" you get 5+y – unlikely Mar 3 at 18:58
    
Thanks a lot for explaining this. I note that in the presence of a denominator, this construction does not work because the expression is no longer a polynomial. Correct (or any other tuning resolves this case)? – Saku Mar 4 at 13:10
    
@Saku This method still works provide that you pass in, as a second argument, the list of variables $u$ (the variables w.r.t. which the expr is linear), for example: vars = Cases[expr, Subscript[u, _, _], \[Infinity]]; Normal@CoefficientArrays[expr, vars][[2]] – unlikely Mar 7 at 11:22

Another way

(CoefficientRules@expr)[[All, 2]]

{-27, -6, 9, 36, 8, -12, -9, -2, 3}

Using expr as defined in the answer by Alexei Boulbitch

expr = -27 Subscript[u, 1, 1] - 6 Subscript[u, 1, 2] + 
9 Subscript[u, 1, 3] + 36 Subscript[u, 2, 1] + 
8 Subscript[u, 2, 2] - 12 Subscript[u, 2, 3] - 
9 Subscript[u, 3, 1] - 2 Subscript[u, 3, 2] + 3 Subscript[u, 3, 3];

And:

(CoefficientRules@expr)[[All, 2]] == expr /. Plus -> List /. a_*Subscript[u, __] -> a

True

share|improve this answer
    
Thanks TomD. Very concise. But it does not seem to work in the presence of a denominator, right? – Saku Mar 4 at 13:11
    
I didn't consider the denominator part of your question. It would be good if you would post an example, together with the expected outcome. But maybe (CoefficientRules@#)[[All, 2]] & /@ {Numerator@#, Denominator@#} &@expr? – TomD Mar 4 at 17:18
    
Thanks. I just edited my original question to include an example of full expression. Using your updated suggestion, I get {{-27, -6, 9, 36, 8, -12, -9, -2, 3}, {16}}, which is not the expected outcome. With full expression given, I'm sure you can construct a suitable solution :) – Saku Mar 7 at 9:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.