6
$\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$
8
  • 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, 2014 at 16:56
  • $\begingroup$ Oh... thanks a lot. I didn't think about Symbol... $\endgroup$
    – funnyp0ny
    Dec 8, 2014 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, 2014 at 17:02
  • $\begingroup$ In this example this works .. eq /. Cases[ Variables[eq] , v : Except[a | d] :> v -> 1 ] $\endgroup$
    – george2079
    Dec 8, 2014 at 18:13
  • $\begingroup$ as an alternative possibility: Times @@ ToExpression /@ (StringReplace[Map[ToString, List @@ eq], Except[Characters["ab"]] -> "1"]) . Try. $\endgroup$ Dec 9, 2014 at 12:37

4 Answers 4

4
$\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
  • 2
    $\begingroup$ Though Variables[x^a] is {x^a}, not {x,a}. $\endgroup$
    – Szabolcs
    Dec 9, 2014 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, 2014 at 13:44
3
$\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$
1
$\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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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