function [s_hat, opt_obj] = psk_detector(H, y, cnstll_size, noise_level, nPerturbation, mTry) 
% =========================================================================
% Implementation of PSK Detector. 
% Purpose: approximation algorithm for solving maximum-likelihood detection 
% problem given by:       
%                          min   || y - H * s ||
%                          s.t.  s(i) in C^n,
% where C^n is a Phase-Shift-Keying constellation.
% =========================================================================
%
% [s_hat, opt_obj] = psk_detector(H, y, cnstll_size, noise_level, nPerturbation, mTry) 
%
% -------------------------------------------------------------------------
% PSK Detector
%   CHANNEL MODEL:                 y = H * s + v
%            where 
%                           - s is a data vector, 
%                           - H is square or tall mixing matrix,
%                           - v is the AWGN. 
%   GOAL:                   find s which achieves min || y - H * s ||, given H and y.
%   REQUIRED PARAMETERS:
%            H              - a mixing matrix
%            y              - an observation vector
%            cnstll_size    - the size of the constellation that each s(i) entry is drawn from
%                             [For BPSK]
%                                cnstll_size = 2;
%                             [For QPSK]
%                                cnstll_size = 4;
%                             [For 8-PSK]
%                                cnstll_size = 8;
%            noise_level    - quality-speed tradeoff parameter, recommended settings:
%                             [For BPSK] 
%                                noise_level = chi2inv(.972, size(H,2));
%                             [For QPSK or 8-PSK] 
%                                noise_level = chi2inv(.972, size(H,2)) / 1.5;
%                             [For 16-QAM converted to BPSK] 
%                                noise_level = chi2inv(.972, 4*size(H,2)) / 4.0;
%   OPTIONAL PARAMETERS: 
%            nPerturbation  - number of perturbed restarts per try >= 0
%                             [DEFAULT] nPerturbation = 3
%            mTry           - total number of tries >= 1
%                             [DEFAULT] mTry = 8
%    OUTPUT: 
%            s_hat          - phases of the estimate of s
%            opt_obj        - the squared norm of the vector y - H * s_hat
% =========================================================================
% Developed by      :       Xiaodong Luo
% Modified by       :       Nick Kisialiou 
% Release date      :       September 09, 2002 
% Last update       :       November 15, 2006
% Contacts          :       xdluo@attbi.dom, kisi0004@umn.edu
% Affiliations      :       Prof. Tom Luo's research laboratory,
%                           Department of Electrical and Computer Engineering,
%                           University of Minnesota, MN, United States
% Version           :       0.9
% License           :       Please, see the website
%                           http://www.ece.umn.edu/users/luozq/software/sw_about.html
% Compatibility     :       Windows(R) 2000, XP+ platform, Matlab(R) 6.0+ versions.
% =========================================================================

Z = H' * y;
Hp = H' * H;

if (nargin>=5)
	nPerturbation_ = nPerturbation;
else
	nPerturbation_ = 3;
end

if (nargin>=6)
	mTry_ = mTry;
else
	mTry_ = 8;
end
adjustment_ = sum(conj(y).*y);

[s_hat, opt_obj] = psk(real(Hp), imag(Hp), real(Z), imag(Z), cnstll_size, nPerturbation_, mTry_, adjustment_, noise_level);

% Round the remaining symbols
s_hat = mod( (2*pi/cnstll_size) * round(s_hat/(2*pi/cnstll_size)), 2*pi );

% =========================================================================
% End of psk_detector.m
% =========================================================================
