function [energies,interactions] = enumerate(N)
% ENUMERATE function to enumerate all possible 2^N occupations
% on a 1-D lattice of N sites.
%
% This function returns all of the energies as well as the 
% Hamiltonian matrix. This function depends on (requires)
% the "compute_energy" function. If N is large, this function is 
% very slow. N=14 requires about 10 seconds on an average PC. The
% required time scales as 2^N (for obvious reasons)
%
% Call this function from the command line and then save the variables
% to a file when experimenting with the GA so that the enumerations does 
% not have to be repeated each time one runs the GA.
%

% These two lines define the Hamiltonian--the intersite coupling and
% "on-site" terms. The second line makes the Hamiltonian symmetric---
% not necessary but makes physical sense
interactions = rand(N,N)-.5;
interactions = interactions + interactions';

% This block of codes loops over each possibility and stores the
% corresponding energy.
Nperms = 2^N;
energies = zeros(1,Nperms);  % Initialize the array for energies
for i = 1:Nperms 
   binstr = dec2bin(i-1);           % Convert the number to binary  (0...2^N-1)
   occupation = str2num(binstr');   % Convert it to a string
   occupation = [zeros(N-length(occupation),1); occupation]; % Pad with extra zeroes
   energies(i) = compute_energy(interactions,occupation');
end
