6

I'm doing some heavy symbolic calculations and for preliminary simple tests I need to replace all coefficients except chosen with 1, e.g.:

eq = a b c d e f g ...
Replace[eq, Except[a | b] -> 1]

a b ...

Surely that's not working, just illustration. How can I do this?

A little remark: eq/.(c|d|e|f|g|...)->1 will give what I want, but the point is there could be too many coefficients with different names, so it's much easier to write down only the those I want to keep.

funnyp0ny
  • 1,905
  • 14
  • 21
  • 1
    Replace[x^y + a/h - z + k, Except[a | x, _Symbol] -> 1, {0, Infinity}] ? Heads -> False is the default for Replace. – Szabolcs Dec 08 '14 at 16:56
  • Oh... thanks a lot. I didn't think about Symbol... – funnyp0ny Dec 08 '14 at 17:00
  • But I'm not very happy about this solution. For example, Pi is a symbol too and you probably wouldn't want to replace it ... I'd rather make a list of all relevant symbols first and work with that. Just to make sure nothing is included that shouldn't be ... – Szabolcs Dec 08 '14 at 17:02
  • In this example this works .. eq /. Cases[ Variables[eq] , v : Except[a | d] :> v -> 1 ] – george2079 Dec 08 '14 at 18:13
  • as an alternative possibility: Times @@ ToExpression /@ (StringReplace[Map[ToString, List @@ eq], Except[Characters["ab"]] -> "1"]). Try. – Alexei Boulbitch Dec 09 '14 at 12:37
  • @AlexeiBoulbitch it won't go for heavier expression as previously mentioned a^b c d.. or like c d e f g astroboy1. I guess complete symbolic parser is not the simplest solution. – funnyp0ny Dec 09 '14 at 12:56
  • @funnypony, why don't you then place the expression you have in mind? – Alexei Boulbitch Dec 09 '14 at 13:32
  • @AlexeiBoulbitch I believe it's not necessary as the problem is clear. Moreover, I mentioned that equations are quite heavy - they occupy about several pages in Mathematica. – funnyp0ny Dec 09 '14 at 13:45

4 Answers4

4

A useful function is Variables[], which returns a list of variables in eq.

eq = a b c d e f g π;

eq /. (Rule[# , 1] & /@ Complement[Variables[eq], {a, b}])

(* a b π *)
gpap
  • 9,707
  • 3
  • 24
  • 66
David G. Stork
  • 41,180
  • 3
  • 34
  • 96
3

I dare to post as an answer a very slightly enchanced Szabolcs' comment, which doesn't touch Pi or E and deprived of problems with Variables:

eq = a^(b + b1) c d e Pi E^Pi;
Replace[eq, Except[a | b | _?NumericQ, x_Symbol] -> 1, All]

a^(1 + b) E^Pi Pi

funnyp0ny
  • 1,905
  • 14
  • 21
1

Another way to implement this is as follows:

Create a List of Rules to ReplaceAll Variables with 1:

rules1 = # -> 1 & /@ Variables[eq]
    (* {a -> 1, b -> 1, c -> 1, d -> 1, e -> 1, f -> 1, g -> 1, h -> 1, i -> 1, j -> 1, k -> 1, l -> 1, m -> 1, n -> 1, o -> 1, p -> 1, q -> 1, r -> 1, s -> 1, t -> 1, u -> 1, v -> 1, w -> 1, x -> 1, y -> 1, z -> 1} *)

Join to the front of this list of rules a new list with the variables you don't want replaced with 1:

rules2 = Join[{a -> a, b -> b}, # -> 1 & /@ Variables[eq]]
    (* {a -> a, b -> b, a -> 1, b -> 1, c -> 1, d -> 1, e -> 1, f -> 1, g -> 1, h -> 1, i -> 1, j -> 1,  k -> 1, l -> 1, m -> 1, n -> 1, o -> 1, p -> 1, q -> 1, r -> 1, s -> 1, t -> 1, u -> 1, v -> 1, w -> 1, x -> 1, y -> 1, z -> 1} *)

Then use ReplaceAll with the new, second list of rules:

eq /. rules2
    (* a b *)

You can combine these steps in a single expression, which avoids the creation of unnecessary symbols ("rules1" and "rules2" here):

eq /. Join[{a -> a, b -> b}, # -> 1 & /@ Variables[eq]]
    (* a b *)
TransferOrbit
  • 3,547
  • 13
  • 26
1

The following, more robust code works both for the expression eq of the OP as well as for more complicated expressions, such as:

eq2 = a^(b + b1) c d e Pi E^Pi

As one-line code, one can use the following:

eq2 /. Join[{a -> a, b -> b}, # -> 1 & /@ Intersection@Flatten[Cases[#, _?AtomQ, {0, Infinity}] & /@ Variables[eq2]]]
    (* a^(1 + b) E^π π *)

This is built up as follows. First, Variables is used, but only on Atoms in the expression. Nested lists are then Flattened and duplicates are removed with Intersection.

varslist = Intersection@Flatten[Cases[#, _?AtomQ, {0, Infinity}] & /@ Variables[eq2]]
    (* {a, b, b1, c, d, e} *)

Second, a List of Rules is created to replace all variables in varslist with 1. Then Join to the front of this list of rules a new list with the variables you don't want replaced with 1. Finally, ReplaceAll is used on the expression eq2:

eq2 /. Join[{a -> a, b -> b}, # -> 1 & /@ varslist]
    (* a^(1 + b) E^π π *)
TransferOrbit
  • 3,547
  • 13
  • 26