MHB Brute force calculation of P(200)

  • Thread starter Thread starter Annoying Twit
  • Start date Start date
  • Tags Tags
    Calculation Force
AI Thread Summary
Major MacMahon calculated the number of partitions of 200 to verify Ramanujan and Hardy's estimates, which would have required extensive calculations. A brute force method initially proposed involved 80,102 calculations, deemed impractical for manual computation. A more efficient approach was later developed, reducing the necessary calculations to 19,900 by utilizing the relationship p(k, n) = p(k + 1, n) + p(k, n - k). This method simplifies the process to basic additions of known values, although it still faces limitations for larger numbers. The discussion highlights the challenges of manual calculation and the evolution of computational techniques in partition theory.
Annoying Twit
Messages
1
Reaction score
0
In the film "The Man Who Knew Infinity" about S. Ramanujan, Major MacMahon calculated the number of partitions of 200, so that the accuracy of Ramanujan & Hardy's estimate could be established.

How would MacMahon have calculated this? I looked into how this number would be calculated by brute force, but my method requires 80,102 calculations to be performed. Which I would think would take one heck of a long time, even with the mental arithmetic skills MacMahon demonstrated.

Is there a more clever way of calculating this number that MacMahon would have used? Otherwise, how long would he have taken to calculate it?

Here's my program, which shows the method I used. I'm not good at describing things in mathematical notation.

Code:
#include <stdio.h>
#include <stdlib.h>

#define MAX_N 500
#define NO_ANSWER -1

long working[MAX_N+1][MAX_N+1];
long solve( int target, int max );

int numCalcs = 0;

int main( int argc, char *argv[] )
{
  int target;
  long answer;
  int i,j;

  if ( argc < 2 )
  {
    fprintf( stderr, "usage partition N\n" );
    exit( -1 );
  }

  target = atoi( argv[1] );

  if ( target < 1 || target > MAX_N )
  {
    fprintf( stderr, "Can only do numbers 1 .. %d\n", MAX_N );
    exit( -1 );
  }

  // Working will be used to store answers.
  // working[target][max] where target is the number we want to add to,
  // and max is the maximum number we can use to add to it.

  for ( i = 0; i <= target; i++ )
  {
    for ( j = 0; j <= target; j++ )
    {
      working[i][j] = NO_ANSWER;
    }
  }

  // No matter what number we're looking for, if we can only use ones, then
  // there is only one partition.

  for ( i = 1; i <= MAX_N; i++ )
  {
    working[i][1] = 1;
  }

  answer = solve( target, target );

  printf( "The answer is %li number of calculations is %d\n", answer, numCalcs );
}

long solve( int target, int max )
{
  int reps;
  int remainder;

  // If we've calculated this answer before, just return it.

  if ( working[target][max] != NO_ANSWER ) return working[target][max];

  // Not found before, calculate it.

  working[target][max] = 0;

  // For every feasible number of uses of the maximum value

  for ( reps = 0; reps * max <= target; reps++ )
  {
    remainder = target - reps * max;

    numCalcs++;

    if ( remainder == 0 ) // exact fit
    {
      working[target][max]++;
    }
    else if ( max > 1 ) // recurse to solve sub-problem of remainder
    {
      working[target][max] += solve( remainder, max-1 );
    }
  }

  // NOW we've calculated it.

  return working[target][max];
}

I did find a better way of doing this. If p( k, n ) means "the number of partitions of n which include a number of at least k", then we have the equality

p( k, n ) = p( k + 1, n ) + p( k, n - k )

The boundary conditions are: p( k, n ) = 0 if k > n, and p( k, n ) = 1 if k = n. Also note that p(n) = p( 1, n ).

That leads to this program:

Code:
#include <stdio.h>
#include <stdlib.h>

#define MAX_N 500
#define NO_ANSWER -1

long working[MAX_N+1][MAX_N+1];
long p( int k, int n );

int numCalc = 0;

int main( int argc, char *argv[] )
{
  int i, j;
  int target;
  long answer;

  target = atoi( argv[1] );

  for ( i = 0; i <= MAX_N; i++ )
  {
    for ( j = 0; j <= MAX_N; j++ )
    {
      working[i][j] = NO_ANSWER;
    }
  }

  answer = p( 1, target );

  printf( "P(%d) is %li number of calculations %d\n", target, answer, numCalc );
}

long p( int k, int n )
{
  if ( k > n ) return 0;
  if ( k == n ) return 1;

  if ( working[k][n] != NO_ANSWER ) return working[k][n];

  numCalc++;

  working[k][n] = p( k + 1, n ) + p( k, n - k );

  return working[k][n];
}

And the number of calculations that actually needs to be performed now reduces to 19,900. They are also much simpler, simple additions of two known values of p( k, n ). The limitation here is only that even using the long data type in C, the program rapidly runs out of digits when problems larger than p( 460 ) are attempted.

Previously I gave my source for this method. But, my posting then disappeared to be moderated, and when it returned the url to my source had disappeared. I'm not sure why, but won't give it here in case my post disappears again.
 
Last edited:
Mathematics news on Phys.org
In that movie they say he calculated it painstakingly by hand. Could be a different movie I'm thinking of, but that is what was stated.
 
Thanks. I guess he did the nearly 20,000 additions then. I can't imagine doing that without making an error.
 
Fermat's Last Theorem has long been one of the most famous mathematical problems, and is now one of the most famous theorems. It simply states that the equation $$ a^n+b^n=c^n $$ has no solutions with positive integers if ##n>2.## It was named after Pierre de Fermat (1607-1665). The problem itself stems from the book Arithmetica by Diophantus of Alexandria. It gained popularity because Fermat noted in his copy "Cubum autem in duos cubos, aut quadratoquadratum in duos quadratoquadratos, et...
Insights auto threads is broken atm, so I'm manually creating these for new Insight articles. In Dirac’s Principles of Quantum Mechanics published in 1930 he introduced a “convenient notation” he referred to as a “delta function” which he treated as a continuum analog to the discrete Kronecker delta. The Kronecker delta is simply the indexed components of the identity operator in matrix algebra Source: https://www.physicsforums.com/insights/what-exactly-is-diracs-delta-function/ by...
Thread 'Imaginary Pythagorus'
I posted this in the Lame Math thread, but it's got me thinking. Is there any validity to this? Or is it really just a mathematical trick? Naively, I see that i2 + plus 12 does equal zero2. But does this have a meaning? I know one can treat the imaginary number line as just another axis like the reals, but does that mean this does represent a triangle in the complex plane with a hypotenuse of length zero? Ibix offered a rendering of the diagram using what I assume is matrix* notation...
Back
Top