# Equating coefficients in a non-power-series equation

How can I use Mathematica to equate coefficients in a non-power-series equation?

For example, I would like to take an equation like the following: $$af_x+\frac{b}{2}f_xf_y+chf_x=f_x+e^af_x+3f_xf_y+2bhf_x$$ and produce the following system: $$a=1+e^a$$ $$\frac{b}{2}=3$$ $$c=2b$$ EDIT: This is a rather small example. If possible, I would prefer a solution that requires minimal human inspection of the original equation. The equations I will be working with will have many, perhaps hundreds of partial derivative terms, and it would be unfeasible to do things like individually pick them out. Ideally, I would like to specify only the unknowns I am interested in (in this case, {a, b, c}) and let Mathematica take it from there.

-
You can subtract rhs from lhs, use 'Variables', remove all that are not 'FreeQ' of '{a,b,c}', and then 'SolveAlways[lhs-rhs, remaining variables]'. –  Daniel Lichtblau Dec 29 '13 at 21:22
SolveAlways[ a fx + b fx fy/2 + c h fx - (fx + Exp[a] fx + 3 fx fy + 2 b h fx) == 0, {fx, fy, h}] gives me SolveAlways::tdep: The equations appear to involve the variables to be solved for in an essentially non-algebraic way. –  David Zhang Dec 29 '13 at 22:43
Ah. I was hoping it would handle that a=1+e^a. Another possibility is to find the fx etc. vars progrmatically, mult iply all by a new variable, say t. Now take a Series in t. The coeffs should be the things you want to equate to zero. (Traveling sans Mathematica so cannot test this in detail). –  Daniel Lichtblau Dec 30 '13 at 1:13
Actually, your first method works if I use another similar equation, like SolveAlways[b fx fy + c h fx == 3 c fx fy + (a + b + 2 c) h fx, {fx, fy, h}]. I assume the issue arises from the equation $a=1+e^a$, which Mathematica doesn't seem to like for being non-algebraic. –  David Zhang Dec 30 '13 at 7:37
Is there a way to tell Mathematica not to try to solve the equations produced by SolveAlways, but to simply return them? –  David Zhang Dec 30 '13 at 11:18

Also there is MonomialList.

coefficientRelations[expr_, params_] := Module[
{vars},
vars = DeleteCases[Variables[expr],
vv_ /; InternalDependsOnQ[vv, params]];
MonomialList[expr, vars] /. Thread[vars -> 1]
]


Your example is then as follows.

expr = a fx + b fx fy/2 +
c h fx - (fx + Exp[a] fx + 3 fx fy + 2 b h fx);
parameters = {a, b, c};

coefficientRelations[expr, parameters]

(* ut[104]= {-3 + b/2, -2 b + c, -1 + a - E^a} *)

-
Daniel, would you describe the function of InternalDependsOnQ please? –  Mr.Wizard Jan 5 '14 at 8:50
Interestingly, I cannot find anything about DependsOnQ in the Documentation Center. At first, I thought it might be something like a complement of FreeQ, but there are cases in which they disagree. For example, FreeQ[g[x], g] is False whereas InternalDependsOnQ[g[x], g] is True. –  David Zhang Jan 5 '14 at 9:03
@DavidZhang just explained it. That is to say, it is a more nuanced version of FreeQ, that decides there is no dependency between e.g. x and x[1]. Also the second arg can be a list, rather than an Alternatives construct. The author no longer recalls the reason for this difference. Possibly indifference, at the time. Or maybe just that DependsOnQ is not pattern-based. –  Daniel Lichtblau Jan 5 '14 at 22:48

Probably (ok, most likely) not the most elegant way. But here we go: May be you can let $x=f_x$ and $y=f_y$ and use CoefficientList to help.

ClearAll[x, y, a, b, c, h, r, lhs, rhs]
fx = D[f[x, y], x];
fy = D[f[x, y], y];
expr = a fx + b/2 fx fy + c h fx == fx + Exp[a] fx + 3 fx fy + 2 b h fx


expr = expr /. {fx -> x, fy -> y}


lhs = Last@CoefficientList[expr /. (lhs_ == rhs_) :> lhs, {x, y}];
rhs = Last@CoefficientList[expr /. (lhs_ == rhs_) :> rhs, {x, y}];
(r = MapThread[Equal, {lhs, rhs}]) // TableForm


One small part left

r2 = r[[1]] /. (h any_ + __) :> h any;
r2 /. (any1_ h == any2_ h) :> any1 == any2
Inner[Subtract, r[[1]], r2, Equal]
`

-
Thanks. This does work, but it seems this requires quite a bit of inspection. For what I'm working on, I will need to deal with many partial derivative terms (perhaps hundreds) and picking them out by hand this way would be unfeasible. Is there any more automated solution? –  David Zhang Dec 29 '13 at 18:23
@DavidZhang as I said, it is not the most automated method, but unless some Mathematica parsing expert steps in and can see a more direct way, I thought this might be a start. The transformation you are asking for is not a common one, and I could not think of a more direct way myself..... –  Nasser Dec 29 '13 at 20:06