%% another acapacity approx
% 2020 0410 
% input: 
%        H    
%        N_t_RF
%        N_r_RF
%        Ns
%        mode 1---> normal 
%        mode 2---> waterfilling
% output: F_BB N_RF*Ns
%         F_RF Nt *N_RF
%         W_BB
%         W_RF

function [Cap_opt, Cap_hyb] = Cap_Approx_pow(H,Nt_RF,Nr_RF,Ns,Nt,Nr,snr,mode)

[U,S,V ] = svd(H);
if mode == 1
    F_opt = V(:,1:Ns);
    W_opt = U(:,1:Ns);
else
    snr_s2 = snr*(diag(S)).^2;
    Pn = 1./snr_s2(1:Ns).';
    Pt = Ns;
    P = waterfill(Pt, Pn);
    F_opt = V(:,1:Ns)*diag(sqrt(P));
    W_opt = U(:,1:Ns);
end
options_pro.func_tolerance = 1e-2;


FRF_enc = exp( 1i*unifrnd(0,2*pi, Nt, Nt_RF) );  
[F_RF, F_BB, ~ ] = fast_hybrid_precoding_NB_wrapper( F_opt, Nt_RF, FRF_enc, options_pro);
F_BB = sqrt(Ns) * F_BB / norm(F_RF * F_BB, 'fro');
F_app = F_RF*F_BB;

WRF_enc = exp( 1i*unifrnd(0,2*pi, Nr, Nr_RF) );  
[W_RF, W_BB, ~] = fast_hybrid_precoding_NB_wrapper( W_opt, Nr_RF, WRF_enc, options_pro);
W_app = W_RF*W_BB;


% Cap_opt = log2(det( eye(Ns) + (snr/Ns)* pinv(W_opt)*H*F_opt*F_opt'*H'*W_opt));
% Cap_hyb = log2(det( eye(Ns) + (snr/Ns)* pinv(W_app)*H*F_app*F_app'*H'*W_app));
% 
Cap_opt = log2(det( eye(Ns) + (snr)* pinv(W_opt)*H*F_opt*F_opt'*H'*W_opt));
Cap_hyb = log2(det( eye(Ns) + (snr)* pinv(W_app)*H*F_app*F_app'*H'*W_app)); % 0308 snr = rho/sigma^2, tongyi le
end

