function [xycov,lags] = xcov(x,y,varargin)
%MATLAB Code Generation Library File

%   Copyright 1988-2020 The MathWorks, Inc.
%#codegen

narginchk(1,4);
coder.internal.prefer_const(varargin);
xc = center(x);
if nargin == 1
    [xycov,lags] = xcorr(xc);
    return
end
% Note that SCALEOPT is only valid as the last input, so for y to be
% SCALEOPT, nargin must be 2.
yIsScaleOpt = coder.const(nargin == 2 && ischar(y));
% Unless nargin == 4, a fixed-size, scalar y will be interpreted as MAXLAG.
yIsMaxLag = coder.const(nargin <= 3 && ...
    coder.internal.isConstTrue(isscalar(y)));
if coder.const(yIsScaleOpt || yIsMaxLag)
    coder.internal.prefer_const(y);
    yc = y;
else
    % Note that variable-size y that become run-time scalars will never
    % be interpreted as MAXLAG for code generation.
    coder.internal.errorIf(isscalar(y), ...
        'MATLAB:xcov:MaxLagNotFixedSize');
    yc = center(y);
end
[xycov,lags] = xcorr(xc,yc,varargin{:});

%--------------------------------------------------------------------------

function xc = center(x)
% xc = bsxfun(@minus,x,mean(x)) but without the complication of needing to
% allocate mean(x) based on the first non-singleton dimension.
if islogical(x)
    xc = coder.nullcopy(zeros(size(x)));
else
    xc = coder.nullcopy(zeros(size(x),'like',x));
end
dim = coder.internal.nonSingletonDim(x);
m = coder.internal.indexInt(size(x,dim));
n = coder.internal.prodsize(x,'above',dim);
if m < 1
    vlen = 1;
else
    vlen = size(x,dim);
end
for j = 1:n
    offset = (j - 1)*n;
    s = zeros('like',xc);
    for i = 1:m
        s = s + x(offset + i);
    end
    s = s/vlen;
    for i = 1:m
        xc(offset + i) = x(offset + i) - s;
    end
end

%--------------------------------------------------------------------------
