% script to run against submitted entries

%% parameters
DEBUG = false;

nTest = 5;

A = 1:nTest;
phi = linspace(-6*pi/7, pi/11, nTest);

fs = 44100*ones(size(A));

ff = logspace(log10(2/3), log10(44100/5), nTest);

sigma = [0 A(5)/sqrt(20) 0 A(4)/sqrt(80) 0];
exponent = [1 1 3 3 1];

dur = ones(1,nTest);

%% space for results
results(1:nTest) = struct( ...
    'amp', 0, ...
    'freq', 0, ...
    'phase', 0, ...
    'score', 1000, ...
    'run_time', 0, ...
    'error_msg', '' ...
    );

%% evaluation loop
for nn = 1:nTest
    % make the signal
    tt = 0:1/fs(nn):dur(nn);
    
    sig = A(nn)*(cos(2*pi*ff(nn)*tt + phi(nn))).^exponent(nn) + ...
        sigma(nn)*randn(size(tt));
    
    try
       % invoke estimation function
       tic
       [amp, freq, phase] = analyzeSinusoid(sig, fs(nn)); 
       elapsed = toc;
       
       % looks like we made it!
       results(nn).amp = amp;
       results(nn).freq = freq;
       results(nn).phase = phase;
       
       results(nn).run_time = elapsed;
       
    catch ME
        % oh, oh, trouble!
        results(nn).error_msg = sprintf('Your code failed on line %d! Matlab says: ''%s''', ...
            ME.stack(1).line, ME.message);
        
        % bail out - skip evaluation
        continue
    end
    
    % let's try to evaluate this
    try
       % first check the estimates for sanity - they must be scalar, and
       % can't be infinite, NaN, or complex
       assert(numel(amp) == 1 && ~isinf(amp) && ~isnan(amp) && isreal(amp), ...
           'Your amplitude estimate does not make sense (amp = %6.2g).', amp);
       assert(numel(freq) == 1 && ~isinf(freq) && ~isnan(freq) && isreal(freq), ...
           'Your frequency estimate does not make sense (freq = %6.2g).', freq);
       assert(numel(phase) == 1 && ~isinf(phase) && ~isnan(phase) && isreal(phase), ...
           'Your phase estimate does not make sense (phase = %6.2g).', phase);
       
       % run through evalFunc
       score = evalFunc(sig, fs(nn), amp, freq, phase);
       
       results(nn).score = score;
    catch ME       
        results(nn).error_msg = sprintf('Your estimates caused a problem: %s', ME.message);
        
        continue
    end
    
    if DEBUG
       plot(tt, sig, tt, amp*cos(2*pi*freq*tt + phase));
       xlabel('Time(s)')
       grid on
       
       fprintf('\nTest %d\n', nn);
       fprintf('Amplitude: true: %6.2g, estimated: %6.2g\n', A(nn), amp);
       fprintf('Phase: true: %6.2g, estimated: %6.2g\n', phi(nn), phase);
       fprintf('Frequency: true: %6.2g, estimated: %6.2g\n', ff(nn), freq);
       fprintf('Score: %6.2g, run time: %6.2g ms\n', score, elapsed*1000);
       pause
    end
end

%% Output
fid = fopen('results.txt', 'w+');
fprintf(fid, 'score: %12.6g\nrun_time: %12.6g', ...
    sum([results.score]), sum([results.run_time])*1000);
fclose(fid);

fid = fopen('details.txt', 'w+');
for nn = 1:nTest
    fprintf(fid, '\nTest %d\n', nn);
    fprintf(fid, 'Est. Amplitude: %6.2g\n', results(nn).amp);
    fprintf(fid, 'Est. Phase: %6.2g\n', results(nn).phase);
    fprintf(fid, 'Est. Frequency: %6.2g\n', results(nn).freq);
    fprintf(fid, 'Score: %6.2g\nrun time: %6.2g ms\n', results(nn).score, ...
            results(nn).run_time*1000);
    if ~strcmp(results(nn).error_msg, '')
        fprintf(fid, 'Error Message: %s\n', ...
                results(nn).error_msg);
    end
end
fclose(fid);


