60
$\begingroup$

This seems like a simple thing to do, but I couldn't find anything relevant from Mathematica documentation.

So suppose I have an expression:

a*b/(a + a*Cos[a/b])

And I have defined:

k=a/b

Now I want to simplify the expression above so that the simplify would use my definition of k in place of a/b in as many places as possible so that the final expression would look something like:

a/(k+k*Cos[k])

This was just a simple example I made up to demonstrate what I'd like to do, but I have encountered a similar situations many times every now and then.

$\endgroup$
0

4 Answers 4

48
$\begingroup$

Daniel Lichtblau and Andrzej Koslowski posted a solution in mathgroup, which I adjusted marginally. (I like to use german identifiers, because they will never clash with Mma builtins). That's the code:

SetAttributes[termErsetzung,Listable];
termErsetzung[expr_, rep_, vars_] := 
Module[{num = Numerator[expr], den = Denominator[expr],
        hed = Head[expr], base, expon},
  If[PolynomialQ[num, vars] && PolynomialQ[den, vars] && ! NumberQ[den], 
    termErsetzung[num, rep, vars]/termErsetzung[den, rep, vars], (*else*)
    If[hed === Power && Length[expr] === 2,        
       base  = termErsetzung[expr[[1]], rep, vars];
       expon = termErsetzung[expr[[2]], rep, vars];
       PolynomialReduce[base^expon, rep, vars][[2]],        (*else*)
      If[Head[Evaluate[hed]] === Symbol && 
        MemberQ[Attributes[Evaluate[hed]], NumericFunction], 
        Map[termErsetzung[#, rep, vars] &, expr],    (*else*)
       PolynomialReduce[expr, rep, vars][[2]] ]]]
];

TermErsetzung[rep_Equal,vars_][expr_]:=
  termErsetzung[expr,Evaluate[Subtract@@rep],vars]//Union;

Usage is like this:

a*b/(a + a*Cos[a/b]) // TermErsetzung[k b == a, b]

a/(k (1 + Cos[k]))

The first parameter is the "replacement equation", the second the variable (or list of variables) to be eliminated:

a*b/(a + a*Cos[a/b]) // TermErsetzung[k b == a, {a, b}] 

{b/(1 + Cos[k]), a/(k (1 + Cos[k]))}

$\endgroup$
3
  • $\begingroup$ Thanks! This combined with FullSimplify seemed to do exactly what I wanted. $\endgroup$
    – Echows
    Commented Apr 2, 2012 at 9:34
  • 12
    $\begingroup$ If you want to prevent name conflicts with built-in names the canonic method is to start your variable names with a lowercase letter. German names are no guarantee, they may still conflict with built-in ones (EigenSystem and GröbnerBasis are examples) and are less convenient for the majority of people here that do not speak German. $\endgroup$ Commented Apr 2, 2012 at 15:16
  • $\begingroup$ @Sjoerd in "normal" circumstances I always start with lower case letter, but for functions in my "helper-functions-package" I like Capitalize. $\endgroup$ Commented Apr 2, 2012 at 15:21
21
$\begingroup$

This general question has been raised on the main StackOverflow site. The answers to these questions may be helpful:

How to reduce the number of independent variables in mathematica

Question on “smart” replacing in mathematica

How to perform a complicated change of variables for a polynomial (in Mathematica)

Get mathematica to simplify expression with another equation

Look specifically at the answers by Daniel Lichtblau.


More questions on the topic here on Mathematica.SE:

Can I simplify an expression into form which uses my own definitions? (this question)

How do I replace a variable in a polynomial?

Replacing composite variables by a single variable

Replace expressions with symbols

Reduce an equation by putting a new variable

Find subexpression to minimize leafcount after replacment with temporary variable

Common subexpression from two expressions

Rewriting one expression using a variable representing another expression

Replacing a sum of expressions

$\endgroup$
6
  • $\begingroup$ wow! An "answer" linking to other answers on the same question? You definitely are taking this to new heights :O $\endgroup$
    – rm -rf
    Commented Dec 25, 2013 at 17:36
  • $\begingroup$ @rm-rf New heights? The post is from two years ago. ;-p This information needs to be somewhere; do you have a better idea? $\endgroup$
    – Mr.Wizard
    Commented Dec 25, 2013 at 17:37
  • 1
    $\begingroup$ Yes, I know that (see deleted comments) :) My only suggestion before was to not merge them, but I see that's now useless as well :P The merge made a link self-referential, hence my comment. In any case, I try to tell folks not to post "link only" answers so I don't see why this answer should be treated differently. (Or should we start posting answers with only cross-links to other answers on related questions as well?) But I don't really care... the weather today is just too magnificent to not go outside! $\endgroup$
    – rm -rf
    Commented Dec 25, 2013 at 17:48
  • $\begingroup$ @rm-rf Sorry, I didn't remember the full history of this. I needed to refer to this answer and I found you had deleted the question it was attached to some time ago (which I don't disagree with). Since the question was already deleted I didn't (and don't) see the harm in merging, so I popped my answer over here with a merge. Regarding link-only answers I think occasionally they are OK, especially if the links are numerous and all to SE resources that wont go dead. Nevertheless it was for that concern that I merged an old answer rather than posting a new one. $\endgroup$
    – Mr.Wizard
    Commented Dec 25, 2013 at 18:20
  • $\begingroup$ @rm-rf And I ran out of character space, but Merry Christmas! $\endgroup$
    – Mr.Wizard
    Commented Dec 25, 2013 at 18:21
11
$\begingroup$

In this simple example you can just use a rule. In more complex cases it might not be straighforward to generalize.

Simplify[a*b/(a + a*Cos[a/b]) /. a -> k b]

(* b/(1 + Cos[k]) *)
$\endgroup$
8
$\begingroup$

Rephrasing your question, what you want is to eliminate a given variable by introducing another one. There are two ways to go about it:

  • The first (and easiest) is simply to express you change in variable in a rule, such as b -> a/k, and use it in a call to ReplaceAll (aka /.). This gives the following code:

    In[1]:= a*b/(a + a*Cos[a/b]) /. b -> a/k
    Out[1]= a^2/(k (a + a Cos[k]))
    
  • The second way, it is covered in this Mathematica tutorial. You can use Eliminate to that aim, but it might not do exactly what you intend. For example, in your example, it will actually go further than you intended:

    In[4]:= Eliminate[{U == a*b/(a + a*Cos[a/b]) && k == a/b}, a]
    Out[4]= (-ArcCos[(b - U)/U] == k && b != 0) || (ArcCos[(b - U)/U] == k && b != 0)
    
$\endgroup$
1
  • $\begingroup$ Actually you could follow that with U /. First@Solve[%, U, Reals]. I don't know if there are situations where that would be preferred to b.gatessucks's answer. $\endgroup$
    – A.G.
    Commented Dec 23, 2013 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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