# How to rewrite the rules in a list when they satisfy a given condition

I think the best way to state my problem is to illustrate it with an example. Assume I have the following toy-list of rules:

toylist = {a -> 10^12 b + 2 c, d  -> 10^-11 e - 0.5 b, f -> 2 g}


What I am trying to find is a way of "reversing" the rules according to the coefficients present in the righthand side. Namely, if the coefficient of a certain variable in the righthand side is above a certain value, say 10^10, I would like to rewrite the rule so that the variable in question is on the lefthand side. The desired output would be:

toylist = {b -> 10^-12 a - 2*10^-12 c, d -> 10^-11 e - 0.5 b, f -> 2 g}


Note that I do not want anything to happen to the other rules in toylist, they're good as they are because all the coefficient are below the cutoff.

I am sure there's a clever way of doing this, I have tried in a lot of ways but failed miserably. Maybe using associations? I'm not so sure.

• Is the right hand side of the rules always linear in the parameters ? Mar 12, 2015 at 9:45
• Is it true that only one coefficient is to be tested against the condition? Will that coefficient be specified or does it need to be detected? Mar 12, 2015 at 9:57
• @b.gatessucks Yes, it's a linear system Mar 12, 2015 at 10:22
• @m_goldberg In principle, you could have something like a->10^12 b + 2 c + 3*10^15 d. Then you solve for the biggest one of the two above cutoff, in this case d. Mar 12, 2015 at 10:22
• @Kuba give me a sec I want to understand what you're doing :) Mar 12, 2015 at 10:27

Brute force:

toylist /.  Rule[lhs_, rhs_] :> With[{
coeff = Coefficient[rhs, Variables[rhs]]
},
Solve[lhs == rhs, #][[1, 1]] &[
Last[Variables[rhs][[Ordering[coeff]]]]
] /; Max[coeff] > 10^5
]

{b->(a-2 c)/1000000000000,d->-0.5 b+e/100000000000,f->2 g}


You can reverse condition: /; Min[coeff] < 10^-5

{a->1000000000000 b+2 c,e->-1.*10^11 (-0.5 b-d),f->2 g}


That was automatic, if you want less general solution, such as one you've asked for:

rewrite[expr_, var_, limit_] := expr /. Rule[lhs_, rhs_] :>
Solve[lhs == rhs, var][[1, 1]] /; Coefficient[rhs, var] > limit

rewrite[toylist, b, 10^5]

{b->(a-2 c)/1000000000000,d->-0.5 b+e/100000000000,f->2 g}

• Your answer seems to work in this toy model but not with my list. Here's a sample of it. I suspect the problem has to do with the subscripts, unfortunately is that I can't get rid of them in my code. u = {Subscript[c, 15] -> - 1.08*^16 Subscript[c, 24] - 0.14 Subscript[c, 29], Subscript[c, 23] -> 5.83*^-15 Subscript[c, 24] - 0.84 Subscript[c, 29]} Mar 12, 2015 at 10:38
• Actually it was just the minus sign! Just replaced coeff with Abs[coeff] in your code and it works like a charm. Thank you! Mar 12, 2015 at 10:43
• @user50473 Yes it is, -10^15 isn't larger than 10^10. So you have to decide what do you want to check, add Abs to dondition if you want.
– Kuba
Mar 12, 2015 at 10:44
• @user50473 ok, you've got it, great ;)
– Kuba
Mar 12, 2015 at 10:45
• @user50473 Please consider holding on with an accept, better answers may appear, let's do not discourage others :)
– Kuba
Mar 12, 2015 at 10:47
rewriteF[e_, v_, cf_] := If[cf[Coefficient[#[[2]], v]],
Solve[Equal @@ #, v][[1, 1]], #] & /@ e

rewriteF[toylist, b, # > 10^5 &]
(* {b -> (a - 2 c)/1000000000000, d -> -0.5 b + e/100000000000, f -> 2 g} *)

rewriteF[toylist, g, Positive]
(* {a -> 1000000000000 b + 2 c, d -> -0.5 b + e/100000000000, g -> f/2} *)

Fold[rewriteF[#, #2, Positive] &, toylist, {g, b}]
(* {b -> (a - 2 c)/1000000000000, d -> -0.5 b + e/100000000000, g -> f/2} *)
`