classdef CloseIn < rfprop.PropagationModel
%CloseIn   Close-In propagation model
%   PM = propagationModel('close-in') creates a close-in propagation model.
%
%   PM = propagationModel('close-in',Name,Value) creates a close-in
%   propagation model with properties specified by one or more Name-Value
%   pairs. Properties you do not specify retain their default values, which
%   correspond to an urban macro-cell scenario in a non-line-of-sight
%   (NLOS) environment.
%
%   The Close-In model is valid for distances greater than or equal to
%   ReferenceDistance. If a distance less than ReferenceDistance is used,
%   path loss is 0.
%
%   CloseIn properties:
%
%      ReferenceDistance - Free-space reference distance (m)
%      PathLossExponent  - Path loss exponent
%      Sigma             - Standard deviation (dB)
%      NumDataPoints     - Number of data points
%
%   CloseIn methods:
%
%      add      - Add propagation models
%      pathloss - Path loss of radio wave propagation
%      range    - Range of radio wave propagation 

%   Copyright 2017-2019 The MathWorks, Inc. 

% Reference: S. Sun, T.S. Rappaport, T. Thomas, A. Ghosh, H. Nguyen, I.
% Kovacs, I. Rodriguez, O. Koymen, A. Partyka, "Investigation of prediction
% accuracy, sensitivity, and parameter stability of large-scale propagation
% path loss models for 5G wireless communications," IEEE Transactions on
% Vehicular Technology, vol. 65, no. 5, pp. 2843 - 2860, May 2016.

% Default property values obtained from Table III ibid.
    properties
        %ReferenceDistance   Free-space reference distance (m)
        %  Free-space reference distance in meters, specified as double
        %  scalar. Default value is 1.
        ReferenceDistance(1,1) double {mustBeFinite, mustBeReal, mustBePositive, mustBeNonsparse} = 1
        %PathLossExponent   Path loss exponent
        %   Path loss exponent, specified as double scalar. Default value
        %   is 2.9.
        PathLossExponent(1,1) double {mustBeFinite, mustBeReal, mustBeNonsparse} = 2.9
        %Sigma   Standard deviation (dB)
        %   Standard deviation of zero-mean Gaussian random variable in dB,
        %   specified as double scalar. Default value is 5.7.
        Sigma(1,1) double {mustBeFinite, mustBeReal, mustBePositive, mustBeNonsparse} = 5.7
        %NumDataPoints   Number of data points
        %   Number of data points of zero-mean Gaussian random variable,
        %   specified as integer value double scalar. Default value is
        %   1869.
        NumDataPoints(1,1) double {mustBeFinite, mustBeReal, mustBePositive, mustBeInteger, mustBeNonsparse} = 1869
    end
    
    methods(Access = protected)
        function pl = pathlossOverDistance(pm, ~, tx, d, ~)
            
            % Get CI model parameters
            fq = tx.TransmitterFrequency;
            d0 = pm.ReferenceDistance;
            n = pm.PathLossExponent;
            sigma = pm.Sigma;
            N = pm.NumDataPoints;
            
            % Compute path loss
            if d < d0
                pl = 0;
            else
                pl = cipl(fq,d0,d,n,sigma,N);
            end
        end
    end
end

function PL = cipl(f, d0, d, n, sigma, N)

c = rfprop.Constants.LightSpeed;
lambda = c/f;

% The terms
term1 = fspl(d0,lambda);
term2 = 10*n*log10(d./d0);

% Gaussian RV - sigma is voltage, var is power
sigma_lin = 10^(sigma/20);
Xi = sigma_lin.*randn(N,1);
Xi = Xi.^2;

PL_rv = term1 +term2 + 10*log10(Xi);
PL = mean(PL_rv);
end



