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 1
s 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.