function Y = signed_bernoulli2(N,p1,p2,r)
assert (0 < p1) ;
assert (p1 < 1) ;
assert (0 < p2) ;
assert (p2 < 1) ;
assert (-1 < r) ;
assert (r < 1) ;
Y = zeros(2,N) ;
A = [1,1,1,1;0,0,1,1;0,1,0,1;1,-1,-1,1] ;
b = [1;p1;p2;r] ;
p = pinv(A)*b ;
assert(all(p >= 0), sprintf('The given p1=%f and p2=%f cannot result in a correlation r=%f with the given algorithm.\np1=p2=0.5 is a safe value.',p1,p2,r)) ;
% Now that we have the joint pdf in "p" we can draw from this distribution
% as follows (based on conditional pdfs and inverse transform sampling):
% 1. Draw samples of Y_1 from Signed_Bernoulli(p1) in a standard fashion using
% an auxiliary uniformly distributed variable U_1 = U(1,:).
% 2. If the n-th sample of Y_1 is "-1", then draw for Y_2 from the conditional pdf
% p(Y_2|Y_1 = -1) using a second axiliary uniformly distributed
% variable U_2 = U(2,:).
% 2. If the n-th sample of Y_1 is "+1", then draw for Y_2 from the conditional pdf
% p(Y_2|Y_1 = +1) using the second axiliary uniformly distributed
% variable U_2 = U(2,:).
% The conditional pdfs are given as follows:
% p(Y_2|Y_1 = -1) = p(4)/p1 for -1, and 1-(p(4)/p1) for +1.
% p(Y_2|Y_1 = +1) = p(2)/(1-p1) for -1, and 1-(p(2)/(1-p1)) for +1.
%
% Note: for the rather straightforward proofs for the above steps, please contact
% the author.
% Auxiliary variable U
U = rand(2,N) ;
% Draw samples from p(Y_1)
Y(1,:) = (-1).^(U(1,:) < p1) ;
% Indices to help choose the conditional pdf
I1 = Y(1,:) == -1 ;
I2 = Y(1,:) == +1 ;
% Draw samples from the conditional pdfs
Y(2,I1) = (-1).^(U(2,I1) < p(4)/p1) ;
Y(2,I2) = (-1).^(U(2,I2) < p(2)/(1-p1)) ;