Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

(I am affraid that this is a duplicate, but I read several already asked questions and non of them helped me. If it's already answered, please tell me)

I have expressions like this

expr1=F1[0]*F2[3]*F3[2]+4I*F1[1]*F2[2]*F3[1]-2*F1[0]*F2[-2]*F3[2]
expr2=4*F1[0]*F2[2]*F3[1]-I*F1[1]*F2[0]*F3[-1]-1*F1[1]*F2[0]*F3[2]+2*F1[6]*F2[1]*F3[1]

in general the expression is always of this form

expr= c1*F1[z1]*F2[z2]*F3[z3]+c2*F1[z4]*F2[z5]*F3[z6]+c3*F1[z7]*F2[z8]*F3[z9] + ...

with c1,c2,c3 complex, and z1-z9 integers, and there can be arbitrary many F1*F2*F3-terms.

Now I want to find the coefficients of this expressions.

I tried

CoefficientList[expr, F2[__]*F3[__]*F4[__]]

but it didnt give any result.

Now I found a semi-solutions (which works if all z>=0; by mapping each function call to a prime-power thus they are unambiguous):

exprnew = expr /. {F2[v2_] -> x^(2*v2), F3[v3_] -> x^(3*v3), F4[v4_] -> x^(5*v4)}
CoefficientList[exprnew, x]

Best-Case:

I want

CoefList[expr] -> {c1,c2,c3}
CoefList[expr1] -> {1,4I,-2}
CoefList[expr2] -> {4,-I,-1,+2}

Thanks for help!!

share|improve this question

3 Answers 3

up vote 2 down vote accepted

Or like this:

List @@ expr1 /. {F1[a_] -> 1, F2[b_] -> 1, F3[c_] -> 1}

(*   {4 I, -2, 1}  *)

List @@ expr2 /. {F1[a_] -> 1, F2[b_] -> 1, F3[c_] -> 1}

(*    {-I, 2, 4, -1}   *)

Later Edit: Concerning your comment below: you are right. Try the following:

coeffts[expr_] := ({expr /. Plus -> List}) /. {F1[a_] -> 1, 
F2[b_] -> 1, F3[c_] -> 1} // Flatten;

working as follows:

coeffts[expr1]

(*   {4 I, -2, 1}   *)

Let us look at expressions with a single term:

exprSingle1 = F1[0]*F2[3]*F3[2];
exprSingle2 = 2 I F1[0]*F2[3]*F3[2];

and test the function:

coeffts[exprSingle1]
coeffts[exprSingle2]

(*  {1}   *)

(*  {2 I}  *)
share|improve this answer
    
Thanks for this one. I was trying to get this idea working (making expression to List, but failed). And its by far the simplest one, even through I had to read about "Apply". –  NicoDean Jul 23 at 17:24
    
Just realized that there is a problem if you use an expression that only consists of one element, like expr3=F1[0]*F2[0]*F3[0]. It returns more than one element. –  NicoDean Jul 31 at 16:05
1  
@NicoDean You are right. Have a look at the edit to my answer –  Alexei Boulbitch Aug 1 at 7:24

Solution


If the equations always use this pattern we can simply use pattern matching:

findCoefficients[expr_] := PadLeft[Cases[
   expr,
   coeff : Except[F1[_] | F2[_] | F3[_]] :> coeff,
   {2}
   ], Length@expr, 1]

findCoefficients[expr1]
(* Out: {1, 4 I, -2} *)

I wonder, though, how you intend to use these coefficients. I'm padding with ones to the left, so the coefficients may not be in the same order as in the original equation.

Explanation


Let's take a look at how a pattern can be worked out.

expr1 // FullForm
(* Out: Plus[Times[Complex[0,4],F1[1],F2[2],F3[1]],Times[-2,F1[0],F2[-2],F3[2]],Times[F1[0],F2[3],F3[2]]] *)

FullForm is the internal representation of expr1. When we do pattern matching, this is the expression we're trying to match. Cases will by default try to find any matches inside the expression and collects all these matches, but as you can see I have as the third argument {2} which means it will only look at level 2. Let's see what the expression's second level looks like:

Level[expr1, {2}] // FullForm
(* Out: {4 I,F1[1],F2[2],F3[1],-2,F1[0],F2[-2],F3[2],F1[0],F2[3],F3[2]} *)

As you can see, by specifying that we're only interested in matches on the second level of the expression we have weeded out most of the irrelevant information. The only thing left to do is to remove F1, F2 and F3 since these are not coefficients. This is exactly what the pattern does, because Except[F1[_] | F2[_] | F3[_]] will match (select) any expression in the list except for those three.

1 does not show up as a coefficient in the expression, because Mathematica realizes it can do without it:

Clear[a, b]
1 a b // FullForm
(* Times[a, b] *)

So any coefficient that is 1 will never be found by pattern matching. But we know that there should be as many coefficients as there are terms, so we can assume that if we found only three coefficient and the expression has four terms then there is one term with the coefficient 1. And that's why we pad the left with 1s until we have the same number of coefficients as we have terms.

To understand the code you also need to know that Length@expr gives the number of terms. It does that, because the head of expr is Plus and Length@Plus[...] is the number of arguments that Plus has. The number of arguments that Plus has is the number of terms.

share|improve this answer
    
Thanks for this solution (ordering doesnt matter for me). It works for me too, but I dont understand the logic. Could you please explain what your "Pattern" in "Cases" does, I cant follow that part. And why do you need "PadLeft" with 1s? Black Magic :) –  NicoDean Jul 23 at 17:30
1  
@NicoDean Please see update. –  Pickett Jul 23 at 17:55
    
Oh wow, thats a really nice solution. Pretty tricky. Thanks alot for the explanation. I knew "FullForm", but didnt know the "Level" instruction, so now i'm able to go through such expressions much better. Thx! –  NicoDean Jul 23 at 20:56
    
Just realized that there is a problem if you use an expression that only consists of one element, like expr3=F1[0]*F2[0]*F3[0]. It returns more than one element. –  NicoDean Jul 31 at 16:07

I am not sure if this help or not but if you have coefficient for each term, this cloud help:

((expr /. Plus -> List) /. Times -> List)[[;; , 1]]

As mentioned by Pickett, the Times and Plus are Odorless. In this case I would suggest the following:

expr1 = HoldForm[
   F1[0]*F2[3]*F3[2] + 4 I*F1[1]*F2[2]*F3[1] - 2*F1[0]*F2[-2]*F3[2]];
expr2 = HoldForm[
   4*F1[0]*F2[2]*F3[1] - I*F1[1]*F2[0]*F3[-1] - 1*F1[1]*F2[0]*F3[2] + 
    2*F1[6]*F2[1]*F3[1]];

list = (ReleaseHold[expr2/. Plus -> List]) /. F_[_] -> F[x];
Coefficient[#, F1[x] F2[x] F3[x]] & /@ list

(*{4, -I, -1, 2}*)
share|improve this answer
    
1) He doesn't have coefficients for all terms and 2) Times has the attribute Orderless so we can't assume that the coefficient has a specific position (i.e. first as in this case.) –  Pickett Jul 22 at 23:29
    
Thanks for this solution! This is also one thing I tried yesterday (see above, using coefficients of F1[]*F2[]*F3[_]) and failed. Interesting to see how it works. –  NicoDean Jul 23 at 17:41

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.