function [amp, freq, phi] = analyzeSinusoid(sig, fs)
% analyzeSinusoid - determine amplitude, frequency, and phase from samples
%
% Given a signal (sig) sampled at rate fs, determine its amplitude,
% frequency, and phase. The first sample of the signal is taken at time
% t=0, the second at 1/fs, etc.
%
% The objective of this function is to determine parameters amp, freq, and
% phi such that a sinusoid generated from these parameters is as similar as
% possible to the samples in sig. Specifically, the estimated parameters
% will be evaluated as follows (see evalFunc):
%
% % generate a sinusoid from parameters
% tt = (0:length(sig)-1)/fs;        % make a time axis
% xx = amp*cos(2*pi*freq*tt + phi); % construct sinusoid
%
% % measure the power of the difference between xx and sig
% score = var(xx-sig);              % try to make this as small as you can
%
% Your function must have the following inputs and outputs:
%
% Inputs:
%   sig - samples of a (approximately) sinusoidal signal
%   fs  - sampling rate (number of samples per second)
%
% Outputs:
%   amp  - estimated amplitude
%   freq - estimated frequency (in Hz!)
%   phi  - esimated phase (in radians)
%
% Usage:
%   [amp, freq, phi] = analyzeSinusoid(sig, fs)
%
% See also:
%   evalFunc

%%%%%%%%% MAKE NO CHANGES ABOVE THIS LINE %%%%%%%%%%%%%%%%%%
%%%%%%%%% YOU MUST STORE YOUR FILE AS: analyzeSinusoid.m %%%

% Note: this is an example of how you might go about solving this problem.
% This is a reasonable, but not a very good solution. The solution is
% reasonable in the sense that the estimates are based on mathematical
% properties of sinusoids. They are not very good because they don't all
% use all of the available samples.

%% estimate of amplitude
% for the amplitude estimate, find the maximum value amnong all samples.
% The MATLAB function max does this nicely.
amp = max(sig);

%% estimate of phase
% at t=0, a sinusoidal signal has the value x(0) = amp*cos(phi). So, we
% know that cos(phi) = x(0)/amp. MATLAB uses 1-based indexing, so x(t=0) is
% found at sig(1)
cos_phi = sig(1)/amp;
phi = acos(cos_phi);  % acos is the inverse cosine function

% We still have to resolve an ambiguity; For any phase phi, cos(phi) and
% cos(-phi) are always equal. So, we need to figure out if the phase is
% really -phi. We do that by checking if sig is initially increasing (phi <
% 0) or decreasing (phi > 0).
if sig(2) > sig(1)
    % it's increasing -> phase is negative
    phi = -phi;
end

%% estimate of frequency
% for frequency estimation, we use the observation that the slope of the
% sinusoidal signal at a zero crossing from negative to positive equals
% 2*amp*pi*freq.

% find the first such zero crossing - the MATLAB find function is very
% powerful!
ind_zero = find(sig(1:end-1) < 0 & sig(2:end) >= 0, 1, 'first');

% we know that sig(ind_zero) < 0 and sig(ind_zero+1) >=0, use thes two samples
% to estimate the slope (rise/run)
rise = sig(ind_zero+1) - sig(ind_zero);
run  = 1/fs;   % time between two samples 

slope = rise/run;
freq = slope/(2*pi*amp);
