5
$\begingroup$

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.

$\endgroup$
  • 1
    $\begingroup$ Replace[x^y + a/h - z + k, Except[a | x, _Symbol] -> 1, {0, Infinity}] ? Heads -> False is the default for Replace. $\endgroup$ – Szabolcs Dec 8 '14 at 16:56
  • $\begingroup$ Oh... thanks a lot. I didn't think about Symbol... $\endgroup$ – funnyp0ny Dec 8 '14 at 17:00
  • $\begingroup$ 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 ... $\endgroup$ – Szabolcs Dec 8 '14 at 17:02
  • $\begingroup$ In this example this works .. eq /. Cases[ Variables[eq] , v : Except[a | d] :> v -> 1 ] $\endgroup$ – george2079 Dec 8 '14 at 18:13
  • $\begingroup$ as an alternative possibility: Times @@ ToExpression /@ (StringReplace[Map[ToString, List @@ eq], Except[Characters["ab"]] -> "1"]) . Try. $\endgroup$ – Alexei Boulbitch Dec 9 '14 at 12:37
3
$\begingroup$

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 π *)
$\endgroup$
  • 2
    $\begingroup$ Though Variables[x^a] is {x^a}, not {x,a}. $\endgroup$ – Szabolcs Dec 9 '14 at 12:11
  • 2
    $\begingroup$ Already to be found somewhere on the site as a substitute for Variables: DeleteDuplicates[Cases[eq, _Symbol, -1]] $\endgroup$ – Yves Klett Dec 9 '14 at 13:44
2
$\begingroup$

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

$\endgroup$
1
$\begingroup$

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 *)
$\endgroup$
0
$\begingroup$

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^π π *)
$\endgroup$

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.