% function [S1, S2, b1, b2] = optimize_l2(Hmag_sq, No, E2, theta, ...
%     lambda_1, mask, gap, bitcap,cb)
%
% OSB finds weight w2 for USER 2
% A. Chowdhery ~2010 ; Updated by J. Cioffi in 2024.  It presently handles
% only 2 users, so U=2.  E(2) is held constant, while E(1) varies.
%
% Inputs 
%
% Hmag_sq is a N x 2 x 2 where N is FFT size. N inferred from this.
% No      is a 1 x U white-noise power spectra density matrix.
%    If Hmag_sq is complex BB, then No should be the one-sided PSD.
% E2      is user 2's energy.
% theta   is a 1 x U user-rate weighting vector.
% w_1     is user 1's energy weight.
% mask    is an N x U PSD maximum allowed.
% gap     is the (non-dB) linear gap (so 1 if 0 dB gap).
% bitcap  is a 1 x U maximum number of bits allowed per tone.
% cb      is 2 for real baseband and 1 for cplex bband
%
% Outputs
%
% S1      is user 1's Nx1 PSD
% S2      is user 2's Nx1 PSD
% b1      is user 1's Nx1 bit distribution
% b2      is user 2's Nx1 bit distribution
%
% --------------------------------------------------------------

function [S1, S2, b1, b2] = optimize_l2(Hmag_sq, No, E2, theta, lambda_1, mask, gap, bitcap,cb)

N = size(Hmag_sq,1);

b1 = zeros(N,1); b2 = zeros(N,1);
S1 = zeros(N,1); S2 = zeros(N,1);

w_2_l = 0; % lower limit on Lagrange for energy constraint
w_2_u = 1e1; % upper limit on Lagrange for energy constraint

[S1, S2, b1, b2] = optimize_s(Hmag_sq, No, theta, lambda_1, w_2_u, mask, gap, bitcap,cb);

while sum(S2) > E2 % too much energy on user 2
    w_2_u = 2 * w_2_u;
    [S1, S2, b1, b2] = optimize_s(Hmag_sq, No, theta, lambda_1, w_2_u, mask, gap, bitcap,cb);
end
    
err = 1e-1;
while (w_2_u - w_2_l)>err | sum(S2)>E2
    lambda_2 = (w_2_u + w_2_l)/2;

    [S1, S2, b1, b2] = optimize_s(Hmag_sq, No, theta, lambda_1, lambda_2, mask, gap, bitcap, cb);
    
    if (sum(S2) - E2) >= 0
         w_2_l = lambda_2; % increase lower limit
    else
         w_2_u = lambda_2; % decrease upper limit
    end
end

        