# Solve equations for all values of variables, rejecting certain types of solution

I have an expression, expr, containing 3 variables, 4 coefficients and 2 non-zero generic constants. I want to solve for the 4 coefficients such that the equation holds for all values of the variables and for all non-zero values of the constants. It is possible to solve either expr == 0 or expr == 1. Acceptable solutions should not assign a specific value to the constants. Also, I do not want solutions that set all 4 coefficients simultaneously to zero.

Example:

Let x,y,z be the variables, a1,a2,a3,a4 be the coefficients and b1,b2 be the generic non-zero constants.

expr =
-2*a3*b1 + a1*x + a2*x + a3*x + a4*x + (a3*b1*y)/b2 - (a4*b1*y)/b2 +
2*a1*z - 2*a1*b2*z - 4*a2*b2*z - 2*a3*b2*z - 2*a4*b2*z;

SolveAlways[{b1 != 0, b2 != 0, expr == 0}, {x, y, z}]
(* {{a2 -> -a1, a4 -> 0, a3 -> 0, b2 -> -1}, {a2 -> 0, a4 -> 0, a1 -> 0,
a3 -> 0}} *)

SolveAlways[{b1 != 0, b2 != 0, expr == 1}, {x, y, z}]
(* {{a2 -> -((2 a3)/(1 + b2)), a4 -> a3, a1 -> -((2 a3 b2)/(1 + b2)),
b1 -> -(1/(2 a3))}} *)


Here I would want to automatically select only the last solution, all the others do not meet my criteria. Also, it should be rearranged so as to assign a value to a3 dependent on b1, not the other way around.

Is there a way to do this?

-

Regarding getting as in terms of bs and not vice versa: just treat the output as another system of equations:

In[2]:= SolveAlways[{b1 != 0, b2 != 0, expr == 1}, {x, y, z}]
Out[2]= {{a2 -> -((2 a3)/(1 + b2)), a4 -> a3, a1 -> -((2 a3 b2)/(1 + b2)), b1 -> -(1/(2 a3))}}

In[3]:= Equal @@@ First[%]
Out[3]= {a2 == -((2 a3)/(1 + b2)), a4 == a3, a1 == -((2 a3 b2)/(1 + b2)), b1 == -(1/(2 a3))}

In[4]:= Solve[%, {a1, a2, a3, a4}]
Out[4]= {{a1 -> b2/(b1 (1 + b2)), a2 -> 1/(b1 (1 + b2)), a3 -> -(1/(2 b1)), a4 -> -(1/(2 b1))}}


The trivial a1==a2==a3==a4==0 solution can be filtered using DeleteCases after you have Sorted each solution to put the as in order and therefore directly comparable with {a1 -> 0, a2 -> 0, a3 -> 0, a4 -> 0}.

-
This nearly answers my question, perhaps I can use DeleteCases also to remove unwanted solutions that assign values to b1 and b2. – spj Feb 10 '14 at 1:31
The following seems to do the trick: DeleteCases[DeleteCases[Solve[#, {a1, a2, a3, a4}] & @@ {Apply[Equal, #, {1}]} & /@ SolveAlways[{b1 != 0, b2 != 0, expr == 0}, {x, y, z}], {{a1 -> 0, a2 -> 0, a3 -> 0, a4 -> 0}}], {}]. Not exactly pretty. I'm not sure it will always eliminate solutions that assign values to b1 and b2. It does in this particular case. It also produces quite deeply nested lists, presumably because both Solve and SolveAlways produce lists of lists. – spj Feb 10 '14 at 2:34
Sorry, above should read: Sort @@ DeleteCases[Solve[#, {a1, a2, a3, a4}] & @@ {Apply[Equal, #, {1}]} & /@ SolveAlways[{b1 != 0, b2 != 0, expr == 0}, {x, y, z}], {{a1 -> 0, a2 -> 0, a3 -> 0, a4 -> 0}}]. Forgot to Sort which also seems to remove empty lists from lists. – spj Feb 10 '14 at 2:43