function y = mls(n)
    // Generates a maximum length sequence (MLS) of order n, i.e., 
    // with a total length 2^n - 1
    //
    // Usage: 
    //       y = mls(n)
    // where
    //       n:  order of the sequence, a positive integer up to 25
    //       y:  mls sequence
    //
    // NOTE: The MLS is a periodic pseudo random sequence whose 
    //       autoorrelation is an impulse and hence its spectrum 
    //       is flat. Is period is 2^n - 1. An MLS can be generated
    //       using a recursive structure derived from primitive
    //       polynomials on a finite field over the set {0,1} where
    //       multiplication and addition are inherited from the 
    //       field of real numbers modulo 2. The simplest structures
    //       can be obtained from trinomials, i.e., polynomials of
    //       degree n with only one non-zero coefficient appart from
    //       the 0 and n powers.
    // Reference: 
    // Živković, Miodrag (1994) A Table of Primitive Binary Polynomials. 
    // Mathematics of Computation, Vol. 62, No. 205, pp. 385-386
    //
    // ----------------------------
    // Author: Federico Miyara
    // Date:   2019-08-29
    //         2020-02-11

    // Prevent memory issues if taking a very large size.
    // n = 25 provides a 12.68 min long signal at a sample
    // rate of 44100 Hz
    // NOTE: Included data allow up to n=30. If necessary 
    // (and if memory is not an issue), change this limit. 
    // However, generation can take quite long 
    if n>25 then
        n = 25;
    end

    // Position of the non-zero coefficient of the primitive
    // trinomials. If zero, there is no primitive trinomial and
    // a pentanomial must be used
    pp3 = [1 1 1 2 1 1 0 4 3 2 0 0 0 1 0 3 7 0 3 2 1 5 0 3 0 0 ...
           3 2 0 3];

    // Position of the non-zero coefficients of the primitive
    // pentanomials for those ordere for which there is no 
    // primitive trinomial. First column contains the order 
    pp5 = [ 1  0  0  0
            2  0  0  0
            3  0  0  0
            4  1  2  3
            5  1  4  5
            6  2  3  4
            7  1  2  7
            8  3  5  6
            9  2  3  8
            10  1  8 10
            11  1  2 10
            12  3  5  8
            13  1 11 12
            14  3  4 12
            15 10 12 15
            16  4 12 16
            17  4 11 16
            18  3  9 10
            19  2  7 13
            20  3  4  9
            21  3  7 12
            22  4  8 15
            23  2  5 11
            24  7 12 13
            25 13 15 23
            26 17 22 23
            27  5  8 24
            28  2  6 16
            29  9 10 27
            30  8 23 25]; 

    // Allocate memory for output variable
    tic
    y = zeros(1,2^n-1) == 1;
    toc

    // Generate MLS
    select pp3(n-1)
    case 0
        // There is no primitive trinomial of this order
        // Use a primitive pentanomial instead
        // Detect which row of pp5 to use
        tic
        A = ones(1,n) & %t;
        m = n - 1;
        n1 = n - pp5(m,2); 
        n2 = n - pp5(m,3);
        n3 = n - pp5(m,4); 
        for k=1:2^n -1
            y(k) = A(n);
            A = [xor(xor(xor(A(n), A(n1)), A(n2)), A(n3)), A(1:n-1)];
        end
        toc    
    else
        tic
        A = ones(1,n) & %t;
        no = n - pp3(n-1);
        for k=1:2^n -1
            y(k) = A(n);

            A = [xor(A(n),A(no)), A(1:n-1)];
        end
        toc
    end
    // Convert T/F to +1/-1  
    y = 2*y-1;    
endfunction

// Defining exclusive or, xor
function u = xor(v,w)
    u = ((~v)&w) | (v&(~w));
endfunction
