5
$\begingroup$

Given an arbitrary Mathematica expression, how can I choose a random part of the expression and replace it with another symbol of my choosing?

For example, given $a x^3 +2y\cos(x)- \tanh(x^{y+3})/(x^4-\sqrt{b})$, I want to select a single randomly chosen part of the expression that involves an $x$ term and replace it with $\mathbf{u}$. This part could be any sub-expression with an $x$ such as $x^3,a x^3, 2y\cos(x),\cos(x),x, x^{y+3},\tanh(x^{y+3}),x^4,(x^4-\sqrt{b})$, or even the whole expression. Examples:

$$ \mathbf{u}\\ \mathbf{u} +2y\cos(x)- \tanh(x^{y+3})/(x^4-\sqrt{b})\\ a x^3 +2y\cos(x)- \tanh(x^{y+3})/\mathbf{u}\\ a x^3 +2y\cos(x)- \tanh(\mathbf{u})/(x^4-\sqrt{b})\\ a x^3 +\mathbf{u}- \tanh(x^{y+3})/(x^4-\sqrt{b})\\ a x^3 +2y\cos(x)- \mathbf{u}/(x^4-\sqrt{b})\\ \mathbf{u} - \tanh(x^{y+3})/(x^4-\sqrt{b})\\ a x^3 + 2y\cos(x) - \mathbf{u}\\ a x^3 + \mathbf{u} $$

Also I'd like to know which subexpression was chosen for replacement with $\mathbf{u}$. So far I've been able to generate random replacements like this:

expr = a x^3 + 2 y Cos[x] - Tanh[x^(y + 3)]/(x^4 - Sqrt[b]);
Table[ReplacePart[expr, 
 RandomChoice[Position[expr, _, Heads -> False]] -> u], 
 1000] // DeleteDuplicates

...but I have not been able to 1) only select expressions involving $x$, and 2) record which subexpression was chosen.

For clarification, the following image shows the expression tree for the example I gave above. Green nodes are eligible for replacement with $\mathbf{u}$ because they contain $x$ or some sub-expression involving $x$. Red nodes do not contain any $x$ and are not eligible for replacement:

expression tree

$\endgroup$
  • 1
    $\begingroup$ Is this in relation to (223870)? $\endgroup$ – MarcoB Jun 12 at 21:00
  • 1
    $\begingroup$ @MarcoB yes, but I think it's a useful question in its own right, and applies to other things like fuzzing and genetic algorithms - it would be a bit hidden if I explored it in that question. $\endgroup$ – flinty Jun 12 at 21:02
  • $\begingroup$ Wouldn't you need to break all the terms of a power, like $x^3 = x x x$ in the expression first, because it is possible to only replace one $x$ and keep the others in the power also? For example, you could replace $x^3$ as $u x^2$. $\endgroup$ – Moo Jun 12 at 22:43
  • $\begingroup$ @Moo Good point. That would be interesting to see if you know how to implement it, but it's probably quite tricky. $\endgroup$ – flinty Jun 12 at 23:04
7
$\begingroup$

Here's one way:

expr = a x^3 + 2 y Cos[x] - Tanh[x^(y + 3)]/(x^4 - Sqrt[b]);
pos = Position[expr, x];
thisPos = RandomChoice[pos]; 
ReplacePart[expr, Drop[thisPos, -RandomInteger[{0, Length[thisPos] - 1}]] -> u]

Each time you execute it, you select a random term containing x from the expression and replace it with u.

| improve this answer | |
$\endgroup$
  • $\begingroup$ This will not select parts like Cos[x] or Tanh[x^(y+3)] - it will just replace the 'leaf' terms x. I want to replace any part of the expression tree provided it involves an x term at some leaf. $\endgroup$ – flinty Jun 12 at 21:05
  • $\begingroup$ I don't understand the requirement... every possible combination of symbols in the expression "involve x" in some way. If you can replace a x^2 with u then why not replace Co[x]+a x^2 with u? $\endgroup$ – bill s Jun 12 at 21:08
  • $\begingroup$ When I execute your code many times it just replaces a random $x$ with $u$. every possible combination of symbols in the expression "involve x" in some way - take $(y+3)$ and $2y$, they do not involve $x$. If you take the TreeForm of the expression, I want to replace a random node with $u$ provided that node is $x$ or it has some descendent node $x$. So that also covers things like replacing Tanh[x^(y+3)], x^(y+3), x by itself, or even the whole expression since it trivially involves $x$. $\endgroup$ – flinty Jun 12 at 21:14
  • $\begingroup$ Thanks, your edit mostly works. The only slight problem is it sometimes chooses sub-expressions like this one for example 2 a x^3 + 2 y Cos[x], which doesn't appear in the expression and replaces nothing. I'm not sure why as I tried a similar approach moments ago and it happened to me also. $\endgroup$ – flinty Jun 12 at 21:54
  • $\begingroup$ OK.. but the expression 2 a x^3 + 2 y Cos[x] certainly "involves x" in a nontrivial way. $\endgroup$ – bill s Jun 12 at 21:56
4
$\begingroup$

Depending on your definition of random the method from bill s might have a problem in that some elements can be selected in more than one way. For example in your expr the element at position {3} can be selected from either {3, 2, 1, 2, 1} or {3, 3, 1, 1}. If we use Position to find all elements directly (rather than Dropping afterward) we avoid this.

expr = a x^3 + 2 y Cos[x] - Tanh[x^(y + 3)]/(x^4 - Sqrt[b]);

pos = Most @ Position[expr, s_ /; ! FreeQ[s, x]]

ReplacePart[expr, RandomChoice[pos] -> u]

This never seems to replace the whole expression with $u$, even if I run it 100,000 times. Shouldn't that happen, as the Plus in the top of the TreeForm is eligible for replacement too?

I did not consider the whole expression to be a part. The term {} in the return of Position represents the whole expression, but I dropped it using Most because ReplacePart cannot use this specification.

If you want to include that as a possibility I propose this instead:

pos = Position[expr, s_ /; ! FreeQ[s, x]]

Module[{x = expr}, x[[## & @@ RandomChoice @ pos]] = u; x]
| improve this answer | |
$\endgroup$
  • $\begingroup$ This is exactly why they tell you not to accept answers too quickly! $\endgroup$ – bill s Jun 12 at 23:46
  • $\begingroup$ This never seems to replace the whole expression with $u$, even if I run it 100,000 times. Shouldn't that happen, as the Plus in the top of the TreeForm is eligible for replacement too? $\endgroup$ – flinty Jun 12 at 23:50
  • $\begingroup$ @flinty See the update. $\endgroup$ – Mr.Wizard Jun 13 at 0:50

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.