function A = adde( A , pn )
%ADDE randomly add egdes to graph
%
%   ADDE(A,pn)  adds edges to the network (given by its
%      adjacency matrix A). The no. of added edges depends on
%      - if 0 < pn < 1  it is the probability for adding an 
%        edge in each potential location
%      - if pn >= 1  it is the actual number of edges to be added
%
%  Last change:  10/2/2005 - Florian Knorn

if nargin < 2
	error('Please provide adjacency matrix A and probability p !');
else
	n = size(A,1);
	if n ~= size(A,2)
		error('Please input SQUARE matrix !');
	end
	if ~islogical(A)
		error('A must be of type LOGICAL');
	end
	errmsg = 'Cannot add more edges then there are pot. locations for';
	if pn < 0 || (pn >= 1 && round(pn) ~= pn)
		error(errmsg);
	end
end

if pn >= 1 && pn <= 50
	for k = 1:pn
		if any(diag(A)) || nnz(A) >= n^2-n;
			error([errmsg ' or other problem']);
		end
		i = ceil(rand*n^2); [i,j] = ind2sub([n,n],i);
		while A(i,j) || i==j
			i = ceil(rand*n^2);
			[i,j] = ind2sub([n,n],i);
		end

		A(i,j) = true; A(j,i) = true;
	end

else

	A = logical(sparse(triu(A,1))); % only keep upper triang part

	ind = find(A);              % get 1D-indexes of edges
	allind = find(triu(ones(n,n),1)); % get all 1D indexes of upper triang
	nind = setdiff(allind,ind); % get 1D-indexes for potential edge locations
	lnind = length(nind);

	if pn < 1 % we're dealing with probabilities
		pn = binornd(lnind,pn);
	end
	if pn > lnind
		error(errmsg);
	end

	nind = nind(randperm(lnind)); % randomly "reorder" pot. locations

	A(nind(1:pn)) = true; % add edges to the first pn pot. locations

	A = A | A';

end