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.

  • 1
    $\begingroup$ 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]'. $\endgroup$ – Daniel Lichtblau Dec 29 '13 at 21:22
  • $\begingroup$ 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. $\endgroup$ – David Zhang Dec 29 '13 at 22:43
  • $\begingroup$ 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). $\endgroup$ – Daniel Lichtblau Dec 30 '13 at 1:13
  • $\begingroup$ 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. $\endgroup$ – David Zhang Dec 30 '13 at 7:37
  • $\begingroup$ Is there a way to tell Mathematica not to try to solve the equations produced by SolveAlways, but to simply return them? $\endgroup$ – David Zhang Dec 30 '13 at 11:18

Also there is MonomialList.

coefficientRelations[expr_, params_] := Module[
  vars = DeleteCases[Variables[expr], 
    vv_ /; Internal`DependsOnQ[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} *)
  • $\begingroup$ Daniel, would you describe the function of Internal`DependsOnQ please? $\endgroup$ – Mr.Wizard Jan 5 '14 at 8:50
  • $\begingroup$ 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 Internal`DependsOnQ[g[x], g] is True. $\endgroup$ – David Zhang Jan 5 '14 at 9:03
  • 1
    $\begingroup$ @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. $\endgroup$ – 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

Mathematica graphics

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

Mathematica graphics

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

Mathematica graphics

One small part left

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

Mathematica graphics

  • $\begingroup$ 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? $\endgroup$ – David Zhang Dec 29 '13 at 18:23
  • $\begingroup$ @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..... $\endgroup$ – Nasser Dec 29 '13 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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