Re(2): Re: Rationalizing the denominator (better solution!)
- To: mathgroup at smc.vnet.net
- Subject: [mg18809] Re(2): [mg18697] Re: [mg18633] Rationalizing the denominator (better solution!)
- From: Andrzej Kozlowski <andrzej at tuins.ac.jp>
- Date: Thu, 22 Jul 1999 08:19:27 -0400
- Sender: owner-wri-mathgroup at wolfram.com
This is still somwhat imperfect. For example: In[2]:= RationalizeDenominator[4/(3*(Sqrt[2] - 5^(1/4)))] Out[2]= 2 4 6 Root[65536 - 294912 #1 + 290304 #1 - 1772928 #1 + 8 6561 #1 & , 1] In[7]:= ToRadicals[%] Out[7]= 608 272 Sqrt[5] 1 327680 1318912 Sqrt[5] -Sqrt[--- + ----------- + - Sqrt[------ + ---------------]] 9 9 2 9 81 which is not quite what one would like to get. One can do a little better by modifying the complexity function to penalize the presence of Root: In[3]:= RationalizeDenominator1[expr_] := FullSimplify[expr, ComplexityFunction -> ( Count[#, _? (MatchQ[Denominator[#], Power[_, _Rational] _. + _.] &), {0, Infinity} ] + If[FreeQ[#, Root], 0, 1] & ) ] In[4]:= RationalizeDenominator1[4/(3*(Sqrt[2] - 5^(1/4)))] Out[4]= 4 -(-) Sqrt[38 + 17 Sqrt[5] + 2 Sqrt[2 (360 + 161 Sqrt[5])]] 3 All these functions will fail however if roots of order higher than 4 are involved: In[5]:= RationalizeDenominator1[f = (2 + 5^(1/6))/(1 - 5^(1/6))] Out[5]= 1 -1 + -------- 1/6 1 5 - - ---- 3 3 In such cases one needs to use some mathematics. First we load in the package In[6]:= << Algebra`PolynomialExtendedGCD` we set In[7]:= p = Denominator[f] /. {5^(1/6) -> t} Out[7]= 1 - t In[8]:= q = RootReduce[5^(1/6)][[1]][t] Out[8]= 6 -5 + t The answer then is given by: In[9]:= Numerator[f]*PolynomialExtendedGCD[p, q][[2, 1]] /. t -> 5^(1/6) // Expand Out[9]= 1/6 1/3 2/3 5/6 7 3 5 3 5 3 Sqrt[5] 3 5 3 5 -(-) - ------ - ------ - --------- - ------ - ------ 4 4 4 4 4 4 We can try to see if Mathematica can verify this by itself. Not surprisingly it is forced to use numerical methods: In[12]:= FullSimplify[ f == -(7/4) - (3*5^(1/6))/4 - (3*5^(1/3))/4 - (3*Sqrt[5])/4 - (3*5^(2/3))/ 4 - (3*5^(5/6))/4] \!\($MaxExtraPrecision::"meprec" \(\(:\)\(\ \)\) "In increasing internal precision while attempting to evaluate \!\(7\/4 + \ \(3\\ 5\^\(1/6\)\)\/4 + \(3\\ 5\^\(1/3\)\)\/4 + \(3 \(\(\[LeftSkeleton] 1 \ \[RightSkeleton]\)\) \(\(\[LeftSkeleton] 1 \[RightSkeleton]\)\)\)\/4 + \(3\\ \ 5\^\(\[LeftSkeleton] 1 \[RightSkeleton]\)\)\/4 + \(3\\ 5\^\(5/6\)\)\/4 + \(2 \ + 5\^\(1/6\)\)\/\(1 - 5\^\(1/6\)\)\), the limit $MaxExtraPrecision = \!\(50.`\ \) was reached. Increasing the value of $MaxExtraPrecision may help resolve \ the uncertainty."\) Out[12]= True On Mon, Jul 19, 1999, Ersek, Ted R <ErsekTR at navair.navy.mil> wrote: >Andrzej Kozlowski wrote: >---------------------------- > >A short time after sending my reply to this message I noticed that a far >better way to rationalize the denominator of most expressions is already >almost built in into Mathematica! What one has to do is to make use of the >ComplexityFunction option in FullSimplify, which enables you to decide which >of two altrnative forms of an expression Mathematica considers to be >simpler. First we defince a complexity function which makes expressions with >radicals in the denominator more complex than those without: > >In[1]:= >rat[p_] := If[FreeQ[Denominator[p], Power[_, Rational[_, _]]], 0, 1] > > >Now we can use FullSimplify with ComplexityFunction set to rat. We can now >rationalize denominators in expressions which we could not deal with before: > ><snip> > >In[3]:= >FullSimplify[1/(5 - 2*Sqrt[3]), ComplexityFunction -> rat] >Out[3]= >1 >-- (5 + 2 Sqrt[3]) >13 > >---------------------------- > >The solution from Andrzej Kozlowski doesn't rationalize denominators deep >down inside an expression. I wrote RationalizeDenominator below which does. > > >In[1]:= >RationalizeDenominator[expr_]:= > FullSimplify[expr,ComplexityFunction-> > ( > Count[#,_? > (MatchQ[Denominator[#],Power[_,_Rational] _.+_.]&), > {0,Infinity} > ]& > ) > ]/.x_Root? > (LeafCount[ToRadicals[#]]<=LeafCount[#]&):>ToRadicals[x] > > >--------------------- > >In[2]:= >tst=2*(E^(Sqrt[2] +Sqrt[3])^(-1) + x)^2; > > >In[3]:= >RationalizeDenominator[tst] >Out[3]= >2*(E^Sqrt[5 - 2*Sqrt[6]] + x)^2 > > >In the example above a denominator deep inside the expression is >rationalized. >This version also converts Root objects to radicals when it makes sense to >do so. > >---------------------------------- >Of course my function doesn't rationalize the denominator in the following >example. To do that the expression returned would need the head (HoldForm). > > >In[4]:= >RationalizeDenominator[1/Sqrt[8]] > >Out[4]= >1/(2*Sqrt[2]) > >---------------------------------- > >I think WRI could make a built-in function that would do this much faster, >and I hope they give us one in a future release. > > >Regards, >Ted Ersek > Andrzej Kozlowski Toyama International University JAPAN http://sigma.tuins.ac.jp/ http://eri2.tuins.ac.jp/