Mathematica 9 is now available
Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2007
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Problem with base 2 logs and Floor

  • To: mathgroup at smc.vnet.net
  • Subject: [mg73017] Re: Problem with base 2 logs and Floor
  • From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
  • Date: Mon, 29 Jan 2007 04:23:35 -0500 (EST)
  • Organization: The Open University, Milton Keynes, UK
  • References: <ephdk1$s2c$1@smc.vnet.net>

neillclift at msn.com wrote:
> Hi,
> 
> When I use an expression like this:
> 
> r - Floor[Log[2, r]] - 1 /. r -> 4
> 
> I get precision errors in Mathematica 5.2. If I use an expression like 
> this:
> 
> N[r - Floor[Log[2, r]] - 1] /. r -> 4
> 
> I get a correct result of 1 and no errors. If I use an expression like 
> this I get the same result:
> 
> N[r - Ceiling[Log[2, r]] - 1] /. r -> 4
> 
> This is to be expected as Floor[Log[2, r]]  = Ceiling[Log[2, r]]  when 
> r is a power of two.
> Unfortunatly the expessions diverge for r=8:
> 
> N[r - Floor[Log[2, r]] - 1] /. r -> 8 gives 5
> N[r - Ceiling[Log[2, r]] - 1] /. r -> 8 gives 4
> 
> How can I get exacts results for expessions like this?
> Thanks.
> Neill.
> 

Neill,

Most of your troubles come from evaluation order of the components of 
the expressions. We will investigate first the evaluation order of the 
transformation rules and how to fix it, then an alternative solution, 
shorter and using SetDelayed, will be giving at the bottom of this mail.

Note that using machine size numbers in the transformation rule yields 
the same result than using the N[] function. (Floor does not attempt any 
symbolic simplification.)

In[1]:=
r - Floor[Log[2, r]] - 1 /. r -> 4.

Out[1]=
1.

Now, if you compute directly log_2(4), Mathematica returns the 
simplified answer 2.

In[2]:=
Log[2, 4]

Out[2]=
2

In this case, Floor has no problem to determine the correct ans exact 
result.

In[3]:=
Floor[Log[2, 4]]

Out[3]=
2

However, things behave differently when you apply some transformation rules.

In[4]:=
Log[2, r] /. r -> 4

Out[4]=
Log[4]
------
Log[2]

The above expression is returned because Mathematica standardizes the 
logarithm first.

In[5]:=
Trace[Log[2, r] /. r -> 4]

Out[5]=
              Log[r]  Log[r]   Log[r]            Log[4]
{{Log[2, r], ------, ------}, ------ /. r -> 4, ------}
              Log[2]  Log[2]   Log[2]            Log[2]

After the rule has been applied, no other transformations or 
simplifications are used.

One way to force Mathematica to simplify the ration of logarithms is to 
use FullSimplify.

In[6]:=
FullSimplify[Log[4]/Log[2], ComplexityFunction ->
    (Count[{#1}, _Log, Infinity] & )]

Out[6]=
2

However, if we plug directly the above expression into our original 
expression, no simplification seems to happen anymore!

In[7]:=
r - Floor[FullSimplify[Log[2, r], ComplexityFunction ->
       (Count[{#1}, _Log, Infinity] & )]] - 1 /. r -> 8

Floor::"meprec" : "Internal precision limit $MaxExtraPrecision = 
49.99999999999999` reached while evaluating Floor[Log[8]\Log[2]]."

Out[7]=
           Log[8]
7 - Floor[------]
           Log[2]

The issue is, again, a matter of precedence: if we use Hold and 
ReleaseHold, we get the correct answer.

In[8]:=
ReleaseHold[
   r - Floor[Hold[FullSimplify[Log[2, r], ComplexityFunction ->
         (Count[{#1}, _Log, Infinity] & )]]] - 1 /. r -> 8]

Out[8]=
4

In[9]:=
ReleaseHold[
   r - Ceiling[Hold[FullSimplify[Log[2, r], ComplexityFunction ->
         (Count[{#1}, _Log, Infinity] & )]]] - 1 /. r -> 8]

Out[9]=
4

Indeed, we can get ride of FullSimplify, and and wrap Hold around the 
original expression (not including the transformation rule) and 
ReleaseHold around the whole thing.

In[10]:=
ReleaseHold[Hold[r - Floor[Log[2, r]] - 1] /. r -> 8]

Out[10]=
4

In[11]:=
ReleaseHold[Hold[r - Ceiling[Log[2, r]] - 1] /. r -> 8]

Out[11]=
4

Finally, an easier way is to define a new function with SetDelayed. In 
doing so, the internal expression is kept as it is written until the 
function is called. Then, the argument is first replace within the body 
of the function, then the resulting expression is simplified and evaluated.

In[12]:=
floorlog[r_] := r - Floor[Log[2, r]] - 1
ceilinglog[r_] := r - Ceiling[Log[2, r]] - 1

In[14]:=
floorlog[8]

Out[14]=
4

In[15]:=
ceilinglog[8]

Out[15]=
4

Regards,
Jean-Marc


  • Prev by Date: Re: Re: Sequence of Bernoulli RVs
  • Next by Date: Re: Re: Sequence of Bernoulli RVs
  • Previous by thread: Re: Problem with base 2 logs and Floor
  • Next by thread: Correction to "Sequence of Bernoulli RVs"