Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question
add comment

4 Answers 4

up vote 24 down vote accepted

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]))}

share|improve this answer
    
Thanks! This combined with FullSimplify seemed to do exactly what I wanted. –  Echows Apr 2 '12 at 9:34
3  
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. –  Sjoerd C. de Vries Apr 2 '12 at 15:16
    
@Sjoerd in "normal" circumstances I always start with lower case letter, but for functions in my "helper-functions-package" I like Capitalize. –  Peter Breitfeld Apr 2 '12 at 15:21
add comment

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]) *)
share|improve this answer
add comment

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

share|improve this answer
    
wow! An "answer" linking to other answers on the same question? You definitely are taking this to new heights :O –  rm -rf Dec 25 '13 at 17:36
    
@rm-rf New heights? The post is from two years ago. ;-p This information needs to be somewhere; do you have a better idea? –  Mr.Wizard Dec 25 '13 at 17:37
    
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! –  rm -rf Dec 25 '13 at 17:48
    
@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. –  Mr.Wizard Dec 25 '13 at 18:20
    
@rm-rf And I ran out of character space, but Merry Christmas! –  Mr.Wizard Dec 25 '13 at 18:21
show 1 more comment

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)
    
share|improve this answer
    
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. –  A.G. Dec 23 '13 at 2:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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