MathGroup Archive 2005

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

Search the Archive

Re: Reducing binary representation

  • To: mathgroup at smc.vnet.net
  • Subject: [mg57204] Re: Reducing binary representation
  • From: Maxim <ab_def at prontomail.com>
  • Date: Fri, 20 May 2005 04:44:26 -0400 (EDT)
  • References: <d6heg9$d24$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

On Thu, 19 May 2005 07:16:25 +0000 (UTC), Torsten Coym  
<torsten.coym at eas.iis.fraunhofer.de> wrote:

> Hi MathGroup,
>
> I want to reduce the number of coefficients in the binary representation
> of arbitrary integer numbers. I managed to convert an integer number
> into a sum of powers of two in the following way:
>
> In[7]:=
> ToBinary[x_, n_] := Plus @@
>     Sequence[MapThread[Times,
>       {Table[(HoldForm[2^#1] & )[i], {i, n - 1, 0, -1}],
>        IntegerDigits[x, 2, n]}]]
>
> In[8]:=
> ToBinary[121, 10]
>
> Out[8]=
> HoldForm[2^0] + HoldForm[2^3] + HoldForm[2^4] +
>    HoldForm[2^5] + HoldForm[2^6]
>
> The sum of adjacent powers of two can be reduced as follows:
>
> In[9]:=
> Sum[2^i, {i, k, j}]
>
> Out[9]=
> 2^(1 + j) - 2^k
>
> I now want to apply that to the binary number representation, so that
> 121 will become
>
> 2^7-2^3+2^0
>
> but I cannont figure out how to do this. If I release the Hold[]
> Mathematica just evaluates all the terms containing "2" to get "121",
> which is not what I want ;)
>
> Unfortunately I have no idea how to tackle this kind of problem. Any
> suggestion would be appreciated.
> Thank you.
>
> Torsten
>

In[1]:=
f[n_] := Append[Reverse@ IntegerDigits[n, 2], 0] //.
     {s___, 1, s1: (1).., 0, s2___} :>
       Join[{s, -1}, 0*{s1}, {1, s2}] //
   #.Array[HoldForm[2^#]&, Length@ #, 0]&

In[2]:= f[121]

Out[2]= HoldForm[2^0] - HoldForm[2^3] + HoldForm[2^7]

In[3]:= ReleaseHold[%]

Out[3]= 121

This uses the fact that ReplaceAll starts by trying the shortest matches  
for BlankSequence/BlankNullSequence and Repeated/RepeatedNull, so

{0, 1, 1} /. {s___, 1, ___} -> rhs

first sets s to Sequence[0].

Things gets more complicated if there are several patterns; if we define  
f2 like this (certainly a very inefficient way):

f2[n_] := Append[Reverse@ IntegerDigits[n, 2], 0] //.
     {s___, 1, s1: (1).., s2___} /;
         (Print[Length /@ {{s}, {s1}, {s2}}]; {s2}[[1]] == 0) :>
       Join[{s, -1}, 0*{s1}, {1, s2}] //
   #.Array[HoldForm[2^#]&, Length@ #, 0]&

then f2[2^5 - 1] will give the following output:

{0, 1, 4}
{0, 2, 3}
{1, 1, 3}
{0, 3, 2}
{1, 2, 2}
{2, 1, 2}
{0, 4, 1}

which shows that Mathematica tries to minimize the total length of {s, s1}  
-- 0+1, then 0+2, 1+1, 0+3, 1+2, 2+1, 0+4. From what section 2.3.8 of The  
Book says ("In general, Mathematica tries first those matches that assign  
the shortest sequences of arguments to the first multiple blanks that  
appear in the pattern.") I would expect the pattern matcher to search  
through all combinations with {s} === {} first.

Maxim Rytin
m.r at inbox.ru


  • Prev by Date: Re: Re: Crossing of 3D functions
  • Next by Date: Re: Best way to maximize over a discrete space?
  • Previous by thread: Re: Reducing binary representation
  • Next by thread: Re: Modifying displayed form of an expression?