function [Out,Par] = JM_CDM(Y, Init, Par)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  This function implements 'Algorithm 1' in our paper
%  Author: Kan Chang, Guangxi University
%  Date: 1/31/2015
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Group_size = Par.Group_size;
Patch_size = Par.Patch_size;
Window_size = Par.Window_size;
Sliding_step = Par.Sliding_step;
Grouping_iter = Par.Grouping_iter;
RL_tol = Par.RL_tol;
Rec = double(Init);

%% Iteratively Grouping
for m = 1:Grouping_iter
    
    fprintf(1, 'Performing Searching and Grouping, number %d \n', m);
   
    % Using the initial demosaicked image to perform block matching
    patch_pos_arr   =  Block_matching_RGB(Rec, Patch_size, Window_size, Group_size, Sliding_step);
    
    % Calculating the parameters 'alpha' and 'beta'
    [Par.alpha, Par.beta] = Cal_alpha_beta(Rec); 
    Par.alpha = Par.alpha*(1 + Par.sigma*2.0);
    Par.beta = Par.beta*(1 + Par.sigma*2.0);  
    
    % Iteration number for iteratively solving 2 sub-problems
    if m == 1
        RL_iter = Par.RL_iter;
    else
        RL_iter = Par.RL_iter + 10;
    end
    
    fprintf(1, 'Iteratively Solving two sub-problems...\n');
    for k = 1:RL_iter
        Rec_prev = Rec;               
        Rec = Low_Rank_denosing_RGB(Rec, Patch_size, patch_pos_arr, Par, size(Init,1), size(Init,2));
        Rec = clip(Rec,0,255);
        Rec = Split_Bregman_demosaicking_solver(Y, Rec, Par.alpha, Par.beta, Par.mu, Par.Mask, Par.SB_tol, Par.SB_iter);
        Rec = clip(Rec,0,255);
        
        if  norm(Rec(:) - Rec_prev(:))/norm(Rec_prev(:)) < RL_tol
            break;
        end
      
    end
end

Out = Rec;