    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: The Model Student: A Primal Skyline (Part 1)</title>
        <link>https://members.accu.org/index.php/articles/1574</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Design of applications and programs + Overload Journal #92 - August 2009</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c67/">Design</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c255/">92</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c67-255/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c67+255/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;The Model Student: A Primal Skyline (Part 1)</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 09 August 2009 09:56:00 +01:00 or Sun, 09 August 2009 09:56:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Prime numbers are the 'building blocks' of the integers. Richard Harris investigates how they're combined.</p>
<p><strong>Body:</strong>&nbsp;<p>The prime numbers, those positive integers wholly divisible by only themselves or by one, are perhaps the most studied numbers in all of history. Evidently a breed apart from their more mundane neighbours on the number line they are, depending upon how much number theory you have been subjected to, their noble elite, their rugged individualists, or their psychopathic loners.
  </p><p> 
    Every integer can be represented as the product of a set of primes, known as the prime factors. For example the number 42 has the prime factors 2, 3, and 7 since 42 = 2 &times; 3 &times; 7.
  </p><p> 
    Numbers with more than one prime factor (i.e. non-primes) are known as composite numbers and the number 1 is technically known as the identity and is neither prime nor composite.
  </p><p> 
    Now, in general, the prime factors of a number may contain multiple copies of each given prime. We can capture this by raising each factor to a power representing how many times it shows up in the factorisation. For example
  </p>
  <p class="indented">
  252 = 2 &times; 2 &times; 3 &times; 3 &times; 7 = 2<sup>2</sup> &times; 3<sup>2</sup> &times; 7<sup>1</sup>
  </p>
    Noting that raising a number to the power of 0 results in 1, we can propose an alternative notation for the integers. Identifying the first, second, third and so on entries in a list as the powers to which the first, second and third and so on primes should be raised in the product, and in much the same way as we truncate trailing zeros in decimal notation, truncating trailing zeros in our list of prime powers, we have a unique representation for every integer. For example
  </p>
  <p class"indented">
  252 = 2<sup>2</sup> &times; 3<sup>2</sup> &times; 5<sup>0</sup> &times; 7<sup>1</sup> &rarr; 2,2,0,1
  </p>
    since 2, 3, 5 and 7 are the 1st, 2nd, 3rd and 4th primes.
  </p><p> 
    Whilst this happens to be a supremely convenient notation in which to perform multiplication, it is an atrocious notation for addition, which perhaps explains why we don't use it.
  </p><p> 
    Compounding the lack of usefulness of this notation is the fact that it is actually rather difficult to identify the <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>'th prime. Generally, the prime numbers are notoriously difficult to find, which is unfortunate since they lie at the heart of many of the great unanswered mathematical questions of the 21st century. Such as, for example, whether the Riemann Hypothesis is true [<a href="#duSautoy04">duSautoy04</a>], or whether it is possible to efficiently decompose numbers into their constituent prime factors [<a href="#Menezes97">Menezes97</a>].
  </p><h2>
    Euclid's proof of the infinity of the primes
  </h2><p> 
    It was Euclid who took the first timid steps towards subjugating these aristocrats cum robber barons of the integers by demonstrating, over two thousand years ago, that there are infinitely many of them.
  </p><p> 
    His proof is elegant and simple, and as such is a rare and precious gem of number theory. It is an example of proof by contradiction in which we assume that there are only a finite number of primes and then demonstrate that this leads to a contradiction.
  </p><p> 
    So, assuming there are only <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> primes for some undetermined value of <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>, we can write the product of all of them as follows:
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-05.gif"/><p> 
    where <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">p</span><span style="  font-style: italic; font-weight: normal; vertical-align: sub">i</span> is the <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">i</span>'th prime and the capital pi means the result of multiplying together all of the values from <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">p</span><span style="  font-style: normal; font-weight: normal; vertical-align: sub">1</span> to <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">p</span><span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span>. In this sense it is much like the capital sigma we use to represent the sum of a set of numbers.
  </p><p> 
    Now, this number is trivially composite since it can be divided by <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">every</span> prime. However, consider the result of adding 1 to it:
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-06.gif"/><p> 
    Now, dividing this number by any of the primes leaves a remainder of 1, since the product is divisible by all of them and the 1 by none of them.
  </p><p> 
    It is, by definition, greater than any of the primes in our set and hence cannot be one of them. Furthermore, since it is not wholly divisible by any of them it must either be a prime itself or have a prime factor that is not in our set. Hence our set is incomplete, no matter what value <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> takes and there must therefore be an infinite number of primes.
  </p><p> 
    Sweet.
  </p><p> 
    Having concluded that the primes are infinite in number, the next obvious question to ask is how densely packed they are amongst the integers; how many primes are there less than or equal to any given integer <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>?
  </p><h2>
    The prime number theorem
  </h2><p> 
    We have an approximate answer to this question, at least for large <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>, first guessed at by the mathematical giants Legendre and Gauss in the late 18th century:
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-07.gif"/><p> 
    The drunkenly scribed equals sign means approximately equal to, the lower case pi is the function that returns the number of primes less than or equal to its argument <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> and the ln is the natural logarithm; the number to which we need to raise the mathematical constant <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">e</span> (approximately 2.718) to recover the argument.
  </p><p> 
    It took about 100 years to raise the status of this formula from conjecture to theorem, when it was tortuously proven by both Vall&eacute;e-Poussin and Hadamard [<a href="#Daintith89">Daintith89</a>].
  </p><p> 
    Technically, the theorem states that the ratio between the number of primes and this formula tends to 1 as <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> grows larger.
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-08.gif"/><p> 
    The lim term here indicates that we are describing the limit of the expression that follows it as <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> grows larger and larger, or tends to infinity.
  </p><p> 
    Figure 1 plots the function counting the primes as the solid line in the graph on the left, the approximation as the dotted line and the ratio between them in the graph on the right.</p>
<table class="sidebartable"><tr><td><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-09.gif"/></td></tr><tr><td class="title">Figure 1</td></tr></table>
<p> 
    Clearly, the approximation isn't particularly accurate in this range. Which is a shame since it could easily be used to determine the distribution of the primes amongst the positive integers, which is one of the most fundamental puzzles in number theory.
  </p><p> 
    Those of you who have been following this, as it turns out rather formulaic, series of articles will not be in the least bit surprised when I abandon all attempt to address the question at hand and introduce a simpler one which I, with my limited mathematical arsenal, may actually be capable of shedding some light upon.
  </p><p> 
    Ready.
  </p><p> 
    Get set.
  </p><h2>
    The X factors
  </h2><p> 
    Rather than attempt to investigate the distribution of the primes, I shall instead propose that we consider looking for a pattern in the prime factorisations of the integers. As mentioned at the start of this article, every positive integer can be represented by the product of a set of primes, with 1 being the special case of multiplying together no primes.
  </p><p> 
    The simplest method of factorising integers, known as trial division, is to iterate through all of the prime numbers less than a given integer, increasing the powers of each whilst they leave no remainder upon dividing it.
  </p><p> 
    Listing 1 illustrates a function that prints out the prime factors of its argument using this algorithm.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    void  
    print_factors(unsigned long x)  
    {  
      unsigned long n = 0;  
      while(nth_prime(n)&lt;=x)  
      {  
        unsigned long power  = 0;  
        unsigned long factor = nth_prime(n);  
        while(x%factor==0)  
        {  
          ++power;  
          factor *= nth_prime(n);  
        }  
        if(power!=0) std::cout &lt;&lt; nth_prime(n) &lt;&lt;  
           &quot;^&quot; &lt;&lt; power &lt;&lt; &quot; &quot;;  
        ++n;  
      }  
    }  
</pre></td></tr><tr><td class="title">Listing 1</td></tr></table>
<p> 
    Note that if <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> is sufficiently large then repeated multiplication of the <tt class="code">factor</tt> variable by the <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>'th prime might exceed the maximum representable value of an <tt class="code">unsigned long</tt>.
  </p><p> 
    Fortunately, this is not technically an overflow and hence does not invoke the dreaded undefined behaviour. This is because the C++ standard defines arithmetic with <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> bit unsigned integer types as being modulo 2<span style="  font-style: italic; font-weight: normal; vertical-align: super">n</span>, effectively throwing away any unrepresentable bits in the result of an arithmetic expression and wrapping round into the range of representable values [<a href="#ANSI">ANSI</a>].
  </p><p> 
    Unfortunately, this doesn't really help us all that much. For example, if <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x </span>is equal to 2<span style="  font-style: italic; font-weight: normal; vertical-align: super">n</span><span style="  font-style: normal; font-weight: normal; vertical-align: super">-1</span>, the <tt class="code">result</tt> variable will eventually wrap around to 0 and the next step of the loop will involve a divide by 0 error during the modulus calculation.
  </p><p> 
    Leaving this problem and the definition of the <tt class="code">nth_prime</tt> function aside for now, we shall instead focus on some performance improvements that we can make to this approach.
  </p><p> 
    The first thing we should note is that the largest repeated factor of a compound number must be no larger than the square root of that number. Indeed, if this were not so, then the product of the least possible number of repeated factors, 2, would exceed our compound number and could clearly not be equal to it.
  </p><p> 
    In exploiting this fact, we must be careful that we identify any single prime factor that may be larger than the square root of the number. We can do this by keeping track of the product of the factors so far identified; if this is not equal to the original number then there must be one more unrepeated prime factor equal to the original number divided by the product of the identified factors.
  </p><p> 
    Listing 2 illustrates the changes we need to make to the <tt class="code">print_factors</tt> function to implement this improvement.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    void  
    print_factors(unsigned long x)  
    {  
      unsigned long n = 0;  
      unsigned long factors = 1;  
 
      while(nth_prime(n)*nth_prime(n)&lt;=x)  
      {  
        unsigned long power  = 0;  
        unsigned long factor = nth_prime(n);  
 
        while(x%factor==0)  
        {  
          ++power;  
          factor  *= nth_prime(n);  
          factors *= nth_prime(n);  
        }  
 
        if(power!=0)  std::cout &lt;&lt; nth_prime(n)   
           &lt;&lt; &quot;^&quot; &lt;&lt; power &lt;&lt; &quot; &quot;;  
        ++n;  
      }  
 
      if(x!=0 &amp;&amp; factors!=x) std::cout &lt;&lt; x/factors   
         &lt;&lt; &quot;^1 &quot;;  
    }
</pre></td></tr><tr><td class="title">Listing 2</td></tr></table>
<p><p> 
    Unfortunately, we have introduced another sensitivity to integer wrap around. If <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> is sufficiently large then the square of the smallest prime strictly greater than it could wrap around. This means that we may very well enter into an infinite loop, never finding a prime whose square, modulo 2 to the power of the number of bits in an <tt class="code">unsigned long</tt>, is greater than <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span>.
  </p><p> 
    Ignoring this potential problem too, we finally note that even if we have found all of the factors of the number we will still keep looking until we reach the last prime less than or equal to its square root.
  </p><p> 
    A further improvement is therefore to divide the number by each factor we discover, allowing us to stop when we reach a prime larger than the square root of the product of the remaining factors, if any.
  </p><p> 
    If this remaining product is anything other than 1, it must be a single non-repeated prime factor. To prove this, recall that every compound number must have at least one factor no greater than its square root and since we have already removed all such factors it cannot therefore be a compound number.
  </p><p> 
    This final change to the trial division algorithm is illustrated in listing 3.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    void  
    print_factors(unsigned long x)  
    {  
      unsigned long n = 0;  
 
      while(nth_prime(n)*nth_prime(n)&lt;=x)  
      {  
        unsigned long power = 0;  
 
        while(x%nth_prime(n)==0)  
        {  
          ++power;  
          x /= nth_prime(n);  
        }  
 
        if(power!=0)  std::cout &lt;&lt; nth_prime(n)   
           &lt;&lt; &quot;^&quot; &lt;&lt; power &lt;&lt; &quot; &quot;;  
        ++n;  
      }  
 
      if(x&gt;1)  std::cout &lt;&lt; x &lt;&lt; &quot;^1 &quot;;  
    }  
</pre></td></tr><tr><td class="title">Listing 3</td></tr></table>
<p> 
    The performance improvement from this change is significantly less dramatic than that of the first, as illustrated in figure 2, which gives the time each version of the algorithm takes to factor (but not print) the integers from 2 to 100 using the machine with which I happen to be writing this article 10,000 times each.
  </p>
<table class="sidebartable"><tr><td>
<p>
<table class="journaltable" border="1" cellspacing="0" cellpadding="5">
<tr><td>First Attempt</td><td>0.53s</td></tr>
<tr><td>Second Attempt</td><td>0.14s</td></tr>
<tr><td>Third Attempt</td><td>0.12s</td></tr>
</table>
</p>
</td></tr><tr><td class="title">Figure 2</td></tr></table>
<p>
    That said, it does neatly side step the possible wrap around issue whilst multiplying the <tt class="code">factor</tt> variable by the <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>'th prime, although it does not address that of squaring the <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>'th prime.
  </p><h2>
    The n'th prime
  </h2><p> 
    So, given that we don't have an exact formula for the <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>'th prime, how are we to go about implementing the <tt class="code">nth_prime</tt> function?
  </p><p> 
    To be perfectly honest, we can't; the function I used to test the various implementations of the <tt class="code">print_factors</tt> function used a look up table of the primes between 0 and 100, which I'm sure you'll agree isn't particularly scalable.
  </p><p> 
    However, if we are interested in the factorisations of all numbers up to a given upper bound, which I can assure you we shall be, we can build the table of primes as we go.
  </p><p> 
    Instead of providing a function to calculate the primes, we will provide a pair of iterators that range from the first prime, 2, to a prime guaranteed to be no smaller than the square root of the number we seek to factor. Furthermore we change the function to return a <tt class="code">bool</tt> to indicate whether or not the number in question remained unchanged throughout the trial division and is itself therefore a prime
  </p><p> 
    Listing 4 illustrates the changes we need to make to the <tt class="code">print_factors</tt> function.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    template&lt;class FwdIt&gt;  
    bool  
    print_factors(unsigned long x, FwdIt first_prime,  
       FwdIt last_prime)  
    {  
      const unsigned long x0 = x;  
 
      while(first_prime!=last_prime &amp;&amp;  
         (*first_prime)*(*first_prime)&lt;=x)  
      {  
        unsigned long power = 0;  
 
        while(x%*first_prime==0)  
        {  
          ++power;  
          x /= *first_prime;  
        }  
 
        if(power!=0)  std::cout &lt;&lt; *first_prime   
           &lt;&lt; &quot;^&quot; &lt;&lt; power &lt;&lt; &quot; &quot;;  
        ++first_prime;  
      }  
 
      if(x&gt;1)  std::cout &lt;&lt; x &lt;&lt; &quot;^1 &quot;;  
      return x0&gt;1 &amp;&amp; x==x0;  
    }  
</pre></td></tr><tr><td class="title">Listing 4</td></tr></table>
<p> 
    We can now supplement this with a second function that iterates from 0 (or strictly speaking a non-negative number less than or equal to 2) up to some upper bound printing the factorisation of each of them.
  </p><p> 
    This second function can use the result of <tt class="code">print_factors</tt> to add new primes, up to the square root of the upper bound, to the back of the sequence that the iterators range over.
  </p><p> 
    Note that we can use the prime number theorem to get an estimate of how large the sequence of primes might be. By multiplying this estimate by some constant factor sufficiently greater than 1, we can ensure that it will exceed the number of primes in almost all cases. This, in turn, ensures that in almost all cases we can reserve enough space for all of the primes we'll need in a <tt class="code">std::vector</tt>. Of course, this is a ridiculous micro-optimisation, but we shall eventually be desperate for simple ways to squeeze out those last few wasted cycles.
  </p><p> 
    Moving on from that rather vague justification for my apparent performance anxiety, we shall implement this as an overload of the <tt class="code">print_factors</tt> function as illustrated in listing 5.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    void  
    print_factors(unsigned long upper_bound)  
    {  
      std::vector&lt;unsigned long&gt; primes;  
 
      const double pi_upper_bound =  
         sqrt(double(upper_bound)) /   
         log(sqrt(double(upper_bound)));  
 
      const unsigned long n(1.5*pi_upper_bound);  
      primes.reserve(n);  
 
      unsigned long x = 1;  
      while(x&lt;upper_bound)  
      {  
        std::cout &lt;&lt; x &lt;&lt; &quot;: &quot;;  
        bool is_prime =  
           print_factors(x,primes.begin(),  
           primes.end());  
        std::cout &lt;&lt; std::endl;  
 
        if(is_prime &amp;&amp; x*x&lt;=upper_bound)  
           primes.push_back(x);  
        ++x;  
      }  
    }  
</pre></td></tr><tr><td class="title">Listing 5</td></tr></table>
<p> 
    Note that this function too suffers from potential integer wrap around whilst squaring prime numbers when we're checking whether to add them to our list.
  </p><p> 
    The output of this function for the integers from 1 to 20 is given in figure 3. Note that since 1 is neither prime nor compound, it has no factors.</p>
    <table class="sidebartable"><tr><td><pre class="programlisting">
    1:
    2: 2^1
    3: 3^1
    4: 2^2
    5: 5^1
    6: 2^1 3^1  
    7: 7^1
    8: 2^3
    9: 3^2
    10: 2^1 5^1  
    11: 11^1
    12: 2^2 3^1  
    13: 13^1
    14: 2^1 7^1  
    15: 3^1 5^1  
    16: 2^4  
    17: 17^1  
    18: 2^1 3^2  
    19: 19^1
    20: 2^2 5^1  
</pre></td></tr><tr><td class="title">Figure 3</td></tr></table>
    <h2>
    Omega? Feh!
  </h2><p> 
    Now, analysing the complete factorisations of ranges of integers is something of a tall order, so instead I suggest we simply count how many prime factors each integer has. A cousin of the prime counting function <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">P</span>, the function that returns the number of prime factors (including repeated factors) of its argument is denoted by <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span>.
  </p><p> 
    Using the factorisations we calculated in figure 3, and noting that 0 is the result of dividing 1 by infinitely many factors, we can derive the values of <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span> for the integers from 0 to 20, as illustrated in figure 4.</p>

<table class="sidebartable"><tr><td>
<p>
<table border="0" cellspacing="0" cellpadding="5">
<tr><td>

  <table border="1" cellspacing="0" cellpadding="5">
  <tr><th>n</th><th>&Omega;(n)</th></tr>
  <tr><td>0</td><td>-&#8734;</td></tr>
  <tr><td>1</td><td>0</td></tr>
  <tr><td>2</td><td>1</td></tr>
  <tr><td>3</td><td>1</td></tr>
  <tr><td>4</td><td>2</td></tr>
  <tr><td>5</td><td>1</td></tr>
  <tr><td>6</td><td>2</td></tr>
  </table>

</td><td>

  <table border="1" cellspacing="0" cellpadding="5">
  <tr><th>n</th><th>&Omega;(n)</th></tr>
  <tr><td>7</td><td>1</td></tr>
  <tr><td>8</td><td>3</td></tr>
  <tr><td>9</td><td>2</td></tr>
  <tr><td>10</td><td>2</td></tr>
  <tr><td>11</td><td>1</td></tr>
  <tr><td>12</td><td>3</td></tr>
  <tr><td>13</td><td>1</td></tr>
  </table>

</td><td>

  <table border="1" cellspacing="0" cellpadding="5">
  <tr><th>n</th><th>&Omega;(n)</th></tr>
  <tr><td>14</td><td>2</td></tr>
  <tr><td>15</td><td>2</td></tr>
  <tr><td>16</td><td>4</td></tr>
  <tr><td>17</td><td>1</td></tr>
  <tr><td>18</td><td>3</td></tr>
  <tr><td>19</td><td>1</td></tr>
  <tr><td>20</td><td>3</td></tr>
  </table>

</td></tr>
</table>
</p>
</td></tr><tr><td class="title">Figure 4</td></tr></table>

    
    <p> 
    This function has some useful properties, not least of which is that it maps non-negative integers to integers, assuming we're happy to count negative infinity as an integer. Furthermore, every number for which this function evaluates to 1 is, by definition, a prime; it has, after all only 1 prime factor.
  </p><p> 
    It would be extremely tedious to work out the values of <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span> from the factorisations we can currently produce. Fortunately, we can simply adapt the functions to count the factors instead. Listing 6 illustrates the function to count the factors of a single integer.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    template&lt;class FwdIt&gt;  
    unsigned long  
    count_factors(unsigned long x, FwdIt first_prime,  
       FwdIt last_prime)  
    {  
      unsigned long count = 0;  
 
      while(first_prime!=last_prime &amp;&amp;  
         (*first_prime)*(*first_prime)&lt;=x)  
      {  
        while(x%*first_prime==0)  
        {  
          ++count;  
          x /= *first_prime;  
        }  
 
        ++first_prime;  
      }  
 
      if(x&gt;1)  ++count;  
      return count;  
    }  
</pre></td></tr><tr><td class="title">Listing 6</td></tr></table>
<p> 
    We shall overload this to count the factors of every positive integer up to some upper bound, in much the same way as we did for <tt class="code">print_factors</tt>. The single integer function no longer returns a <tt class="code">bool</tt> to indicate that the argument is a prime, but as noted above if a number has precisely 1 factor it must be prime and we can use this fact as the indication that we should add the number to the back of our sequence of primes. This second function is given in listing 7.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
    void  
    count_factors(unsigned long upper_bound)  
    {  
      std::vector&lt;unsigned long&gt; primes;  
 
      const double pi_upper_bound =  
         sqrt(double(upper_bound)) /   
         log(sqrt(double(upper_bound)));  
      const unsigned long n(1.5*pi_upper_bound);  
      primes.reserve(n);  
      unsigned long x = 1;  
      while(x&lt;upper_bound)  
      {  
        const unsigned long count = count_factors(  
           x, primes.begin(),primes.end());  
        std::cout &lt;&lt; x &lt;&lt; &quot;: &quot; &lt;&lt; count &lt;&lt; std::endl;  
        if(count==1 &amp;&amp; x*x&lt;=upper_bound)  
           primes.push_back(x);  
        ++x;  
      }  
    }  
</pre></td></tr><tr><td class="title">Listing 7</td></tr></table>
<p> 
    The output of this function for the integers from 1 to 20 is given in figure 5, which you can see is in agreement with our hand derived values for <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span>.
  </p>
<table class="sidebartable"><tr><td><pre class="programlisting">
  1: 0
  2: 1
  3: 1
  4: 2
  5: 1
  6: 2
  7: 1
  8: 3
  9: 2
  10: 2   
  11: 1
  12: 3
  13: 1
  14: 2
  15: 2
  16: 4
  17: 1
  18: 3
  19: 1
  20: 3   
</pre></td></tr><tr><td class="title">Figure 5</td></tr></table>

  <p> 
    The graphs of <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span> for the integers from 1 to 20 and from 1 to 100 are given in figure 6. We extend this from the integers to the real numbers by plotting the value of <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span> for the integer part of each real number.</p>
<table class="sidebartable"><tr><td>
<img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-14.gif"/>
</td></tr><tr><td class="title">Figure 6</td></tr></table>
    <p> 
    It is tempting to look for patterns in these graphs and there is, in fact, a particularly striking one. To see it we need to look at an exponential function of <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span>; specifically raising 2 to its power.
  </p><p> 
    In keeping with the time honoured tradition of naming mathematical functions with single letters from non-Latin alphabets, I christen this function &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span>.
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-16.gif"/><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-17.gif"/><p> 
    You may recall from previous articles that the odd square brackets surrounding the 2<span style="  font-style: italic; font-weight: normal; vertical-align: super">n</span><span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> terms means the largest integer less than or equal to the value between them and that the expression on the right with the rounded E means that <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> must be in the range 0 to 1. Figure 7 illustrates the graphs of &#1507;<sub><i>&#x200E;5</i></sub> and &#1507;<sub><i>&#x200E;7</i></sub>.</p>
<table class="sidebartable"><tr><td>
<img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-20.gif"/>
</td></tr><tr><td class="title">Figure 7</td></tr></table>
    <h2>
    The properties of &#1507;<sub><i>n</i></sub></h2><p> 
    For any <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span>, &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> is defined for arguments between 0 and 1. Moreover, at 0 it returns a value of 0 and at 1 it returns a value of 1.
  </p><p> 
    To demonstrate this, we note firstly that for <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> equal to 0, <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span> receives an argument of 0 and returns negative infinity. Since any number greater than 1 raised to negative infinity yields 0, &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> returns 0 for an argument of 0.
  </p><p> 
    Secondly, the integer between 0 and 2<span style="  font-style: italic; font-weight: normal; vertical-align: super">n</span> with the most factors is 2<span style="  font-style: italic; font-weight: normal; vertical-align: super">n</span>, since 2 is the smallest prime. This has <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> factors and hence the top and bottom of the fraction defining &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> are equal when <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> equals 1, yielding a result of 1.
  </p><p> 
    In fact, the entire graph must never rise above the line from (0,0) to (1,1) as proven in derivation 1.
  </p>
  <table class="sidebartable"><tr><td>
<p> 
    First we assume that the graph <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">can</span> rise above the line 
 and show that this leads to a contradiction. This assumption means that for some <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span></p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-26.gif"/><p> 
    implying that
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-27.gif"/><p> 
    Now, since the left hand side of the inequality is an integer and 
is greater than or equal to 0, we have
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-29.gif"/><p> 
    Of course, this is impossible since 2 is the smallest prime number and hence 
 must be less than or equal to 2<sup>&Omega;(<i>i</i>)</sup> and consequently &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span>(<span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span>) must be less than or equal to <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span>.
  </p>
  </td></tr><tr><td class="title">Derivation 1</td></tr></table>
  
<p> 
    Another statement that we can make about these curves is that for all <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> greater than 0, &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> must coincide with &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span><span style="  font-style: normal; font-weight: normal; vertical-align: sub">-1</span> for half of the values of <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span>; specifically, those where the integer part of 2<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span><span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> is even, as demonstrated in derivation 2.
  </p>
<table class="sidebartable"><tr><td>
<p> 
    Noting that &lfloor;<i>a</i>&rfloor; = 2 &times; &lfloor;&frac12;<i>a</i>&rfloor; for even &lfloor;<i>a</i>&rfloor;, for even &lfloor;2<sub><i>n</i></sub><i>x</i>&rfloor; we have
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-37.gif"/>
</td></tr><tr><td class="title">Derivation 2</td></tr></table>
<p> 
    The curves &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> and &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span><span style="  font-style: normal; font-weight: normal; vertical-align: sub">-1</span> are further related by the equation
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-40.gif"/><p> 
    as shown in derivation 3.
  </p>
<table class="sidebartable"><tr><td>
<img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-41.gif"/><p> 
    Note that since we haven't exploited the properties of <span style=" font-style: normal; font-weight: normal; vertical-align: baseline">&Omega;</span>, this would hold if we replaced it with any other function.
  </p>
</td></tr><tr><td class="title">Derivation 3</td></tr></table>
<p> 
    If we combine these two properties then we recover the striking pattern that I alluded to above; specifically that, when the integer part of 2<span style="  font-style: italic; font-weight: normal; vertical-align: super">n</span><span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span> is even, we have
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-42.gif"/><p> 
    Now this may not strike you as being especially striking, but it is strikingly similar to a property exhibited by many of a very well known class of curves; the fractals.
  </p><p> 
    Many fractals are defined in terms of a sequence of curves which serve as closer and closer approximations to the fractal itself. These curves can themselves be approximated by zooming in on sub-sections of them, in much the same way as we can for &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span>. The major difference is that for the iterative approximations of fractals we can zoom in on many parts of the curve rather than just one specific region.
  </p><p> 
    We can uncover further hints at the relationship between fractals and &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> by considering the limit as <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">n</span> tends to infinity. Waving our hands somewhat vigorously we can take the result that
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-45.gif"/><p> 
    and infer that
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-46.gif"/><p> 
    since &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span><span style="  font-style: normal; font-weight: normal; vertical-align: sub">-1</span> is approximately equal to &#1507;<span style="  font-style: italic; font-weight: normal; vertical-align: sub">n</span> for arbitrarily accurate interpretations of approximately.
  </p><p> 
    Now, instead of recovering an approximation of the curve by zooming in on a sub-section of it, we can entirely reconstruct it. Specifically, for all values of <span style="  font-style: italic; font-weight: normal; vertical-align: baseline">x</span>, we have
  </p><img src="/content/images/journals/ol92//Overload%20WW%20XML%20and%20CSS-6-1-49.gif"/><p> 
    This is suspiciously similar to the self-similarity property of many fractals; the ability to reconstruct the entire curve by zooming in on sub-sections of it.
  </p><p> 
    So is &#1507;<span style=" font-style: normal; font-weight: normal; vertical-align: sub">&#8734;</span> itself a fractal?
  </p><p> 
    Well, that happens to be a very interesting question and we shall pursue its answer in the next article.
  </p><p> 
    Until then, dear reader, fare well.</p><h2>
    Acknowledgements
  </h2><p> 
    With thanks John Paul Barjaktarevic and Lee Jackson for proof reading this article.
  </p><h2>
    References and further reading
  </h2><p class="bibliomixed"><a name="ANSI"></a> 
    [ANSI]  The C++ Standard, American National Standards Institute
  </p><p class="bibliomixed"><a name="Daintith89"></a> 
    [Daintith89]  Daintith, J. &amp; Nelson, R. (ed), The Penguin Dictionary of Mathematics, Penguin, 1989
  </p><p class="bibliomixed"><a name="duSautoy04"></a> 
    [duSautoy04]  du Sautoy, M., The Music of the Primes, Harper Perennial, 2004.
  </p><p class="bibliomixed"><a name="Menezes97"></a> 
    [Menezes97]  Menezes, A. et al, Handbook of Applied Cryptography, CRC Press, 1997
  </p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
