function nEffi = calcNEffi(obj)

[N nx] = size(obj.xRegressor);
M      = sum(obj.leafModels);
X      = obj.xRegressor;
phi    = obj.phi;
lmIdx  = find(obj.leafModels);
SiiAll = zeros(N,M);
for k = 1:sum(obj.leafModels)
    
    pseudoInv = obj.localModels(lmIdx(k)).pseudoInv;
    r2        = phi(:,lmIdx(k)).^(3/2);
    XW        = X.*r2(:,ones(1,nx));
    for m = 1:nx
        SiiAll(:,k) = SiiAll(:,k) + XW(:,m).*pseudoInv(m,:)';
    end
    
    % Equivalent alternative 1:
    %
    %     for k2=1:N
    %         SiiAll(k2,lmIdx(k)) = phi(k2,lmIdx(k))*X(k2,:)*pseudoInv(:,k2)*sqrt(phi(k2,lmIdx(k)));
    %     end
    
    % Equivalent alternative 2:
    %
    % Q = diag(obj.phi(:,lmIdx(k)));
    % S = S+Q*X*pinv(X'*Q*X)*X'*Q;
    % Sii(:,lmIdx(k)) = diag(S);
    
end

% Number of effective parameters:
% Caution: Usually, for local model networks nEff is calculated as nEff = trace(S*S) [see e.g.
% Murray-Smith et al.]. However, this is computationally very expensive. Therefore, it will be
% calculated as nEff = trace(S). Consider: trace(S) >= trace(S*S) [Hastie et al.]. This leads
% to an overestimated amount of parameters which is more secure in terms of complexity
% considerations.
nEffi = sum(SiiAll,1)';

end