Task: Mertens function





Java: public class MertensFunction {

    public static void main(String[] args) {
        System.out.printf("First 199 terms of the merten function are as follows:%n    ");
        for ( int n = 1 ; n < 200 ; n++ ) {
            System.out.printf("%2d  ", mertenFunction(n));
            if ( (n+1) % 20 == 0 ) {
                System.out.printf("%n");
            }
        }
        
        for ( int exponent = 3 ; exponent<= 8 ; exponent++ ) {
            int zeroCount = 0;
            int zeroCrossingCount = 0;
            int positiveCount = 0;
            int negativeCount = 0;
            int mSum = 0;
            int mMin = Integer.MAX_VALUE;
            int mMinIndex = 0;
            int mMax = Integer.MIN_VALUE;
            int mMaxIndex = 0;
            int nMax = (int) Math.pow(10, exponent);
            for ( int n = 1 ; n <= nMax ; n++ ) {
                int m = mertenFunction(n);
                mSum += m;
                if ( m < mMin ) {
                    mMin = m;
                    mMinIndex = n;
                }
                if ( m > mMax ) {
                    mMax = m;
                    mMaxIndex = n;
                }
                if ( m > 0 ) {
                    positiveCount++;
                }
                if ( m < 0 ) {
                    negativeCount++;
                }
                if ( m == 0 ) {
                    zeroCount++;
                }
                if ( m == 0 && mertenFunction(n - 1) != 0 ) {
                    zeroCrossingCount++;
                }
            }
            System.out.printf("%nFor M(x) with x from 1 to %,d%n", nMax);        
            System.out.printf("The maximum of M(x) is M(%,d) = %,d.%n", mMaxIndex, mMax);
            System.out.printf("The minimum of M(x) is M(%,d) = %,d.%n", mMinIndex, mMin);
            System.out.printf("The sum of M(x) is %,d.%n", mSum);
            System.out.printf("The count of positive M(x) is %,d, count of negative M(x) is %,d.%n", positiveCount, negativeCount);
            System.out.printf("M(x) has %,d zeroes in the interval.%n", zeroCount);
            System.out.printf("M(x) has %,d crossings in the interval.%n", zeroCrossingCount);
        }
    }
    
    private static int MU_MAX = 100_000_000;
    private static int[] MU = null;
    private static int[] MERTEN = null;
        
    
    private static int mertenFunction(int n) {
        if ( MERTEN != null ) {
            return MERTEN[n];
        }
        
        
        MU = new int[MU_MAX+1];
        MERTEN = new int[MU_MAX+1];
        MERTEN[1] = 1;
        int sqrt = (int) Math.sqrt(MU_MAX);
        for ( int i = 0 ; i < MU_MAX ; i++ ) {
            MU[i] = 1;
        }
        
        for ( int i = 2 ; i <= sqrt ; i++ ) {
            if ( MU[i] == 1 ) {
                
                for ( int j = i ; j <= MU_MAX ; j += i ) {
                    MU[j] *= -i;
                }
                
                for ( int j = i*i ; j <= MU_MAX ; j += i*i ) {
                    MU[j] = 0;
                }
            }
        }
        
        int sum = 1;
        for ( int i = 2 ; i <= MU_MAX ; i++ ) {
            if ( MU[i] == i ) {
                MU[i] = 1;
            }
            else if ( MU[i] == -i ) {
                MU[i] = -1;
            }
            else if ( MU[i] < 0 ) {
                MU[i] = 1;               
            }
            else if ( MU[i] > 0 ) {
                MU[i] = -1;
            }
            sum += MU[i];
            MERTEN[i] = sum;
        }
        return MERTEN[n];
    }

}





COBOL:        IDENTIFICATION DIVISION.
       PROGRAM-ID.  MERTENS.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 VARIABLES.
          03 M             PIC S99 OCCURS 1000 TIMES.
          03 N             PIC 9(4).
          03 K             PIC 9(4).
          03 V             PIC 9(4).
          03 IS-ZERO       PIC 99 VALUE 0.
          03 CROSS-ZERO    PIC 99 VALUE 0.

       01 OUTPUT-FORMAT.
          03 OUT-ITEM. 
             05 OUT-NUM    PIC -9.
             05 FILLER     PIC X VALUE SPACE.
          03 OUT-LINE      PIC X(30) VALUE SPACES.
          03 OUT-PTR       PIC 99 VALUE 4.

       PROCEDURE DIVISION.
       BEGIN.
           PERFORM GENERATE-MERTENS.
           PERFORM WRITE-TABLE.
           PERFORM COUNT-ZEROES.
           STOP RUN.

       GENERATE-MERTENS.
           MOVE 1 TO M(1).
           PERFORM MERTENS-OUTER-LOOP VARYING N FROM 2 BY 1
               UNTIL N IS GREATER THAN 1000.
    
       MERTENS-OUTER-LOOP.
           MOVE 1 TO M(N).
           PERFORM MERTENS-INNER-LOOP VARYING K FROM 2 BY 1
               UNTIL K IS GREATER THAN N.

       MERTENS-INNER-LOOP.
           DIVIDE N BY K GIVING V.
           SUBTRACT M(V) FROM M(N).

       WRITE-TABLE.
           DISPLAY "The first 99 Mertens numbers are: "
           PERFORM WRITE-ITEM VARYING N FROM 1 BY 1
               UNTIL N IS GREATER THAN 99.
  
       WRITE-ITEM.
           MOVE M(N) TO OUT-NUM.
           STRING OUT-ITEM DELIMITED BY SIZE INTO OUT-LINE
               WITH POINTER OUT-PTR.
           IF OUT-PTR IS EQUAL TO 31,
               DISPLAY OUT-LINE,
               MOVE 1 TO OUT-PTR.

       COUNT-ZEROES.
           PERFORM TEST-N-ZERO VARYING N FROM 2 BY 1
               UNTIL N IS GREATER THAN 1000.
           DISPLAY "M(N) is zero " IS-ZERO " times.".
           DISPLAY "M(N) crosses zero " CROSS-ZERO " times.".

       TEST-N-ZERO.
           IF M(N) IS EQUAL TO ZERO,
               ADD 1 TO IS-ZERO,
               SUBTRACT 1 FROM N GIVING K,
               IF M(K) IS NOT EQUAL TO ZERO,
                   ADD 1 TO CROSS-ZERO.