You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: grabcut.m
    path of file: ./repos/grabcut
    
    the code of the file until where you have to start completion: function im_out = grabcut(im_in, gamma)
%GRABCUT Foreground extraction with GrabCut
%
% Inputs:
%   - im_in: input image, e.g., a 100x100x3 matrix
%   - gamma: gamma parameter
%
% Output:
%   - im_out: the extracted foreground
%
% Author:
%   Xiuming Zhang
%   GitHub: xiumingzhang
%   Dept. of ECE, National University of Singapore
%   April 2015
%

% Convergence criterion
E_CHANGE_THRES = 0.0001;

%%% Get image dimensions
[im_h, ~, ~] = size(im_in);

%--------------------------- I. Initialization

%%% User indicates background
[im_1d, alpha, im_sub] = select_back(im_in);

pix_U = alpha==1;
T_U = im_1d(pix_U, :);
pix_B = ~pix_U;
T_B = im_1d(pix_B, :);

%%% Initialize GMM
no_gauss = 5; % 5 Gaussians in each GMM
% Background
k_B = kmeans(T_B, no_gauss, 'Distance', 'cityblock', 'Replicates', 5);
gmm_B = fit_gmm(T_B, k_B);
% Foreground
k_U = kmeans(T_U, no_gauss, 'Distance', 'cityblock', 'Replicates', 5);
gmm_U = fit_gmm(T_U, k_U);

%--------------------------- II. Iterative Minimization

%%% Compute pairwise in one shot
pairwise = compute_pairwise(im_sub, gamma);
fprintf('Pairwise terms computed in one shot\n');

isConverged = 0;
E_prev = +Inf;
iter = 0;
while ~isConverged
    
    %------- 1. Assign GMM components to pixels
    
    [k_U, k_B] = assign_gauss(im_1d, pix_U, gmm_U, pix_B, gmm_B);
    
    %------- 2. Learn GMM parameters from data
    

    
function im_out = grabcut(im_in, gamma)
%GRABCUT Foreground extraction with GrabCut
%
% Inputs:
%   - im_in: input image, e.g., a 100x100x3 matrix
%   - gamma: gamma parameter
%
% Output:
%   - im_out: the extracted foreground
%
% Author:
%   Xiuming Zhang
%   GitHub: xiumingzhang
%   Dept. of ECE, National University of Singapore
%   April 2015
%

% Convergence criterion
E_CHANGE_THRES = 0.0001;

%%% Get image dimensions
[im_h, ~, ~] = size(im_in);

%--------------------------- I. Initialization

%%% User indicates background
[im_1d, alpha, im_sub] = select_back(im_in);

pix_U = alpha==1;
T_U = im_1d(pix_U, :);
pix_B = ~pix_U;
T_B = im_1d(pix_B, :);

%%% Initialize GMM
no_gauss = 5; % 5 Gaussians in each GMM
% Background
k_B = kmeans(T_B, no_gauss, 'Distance', 'cityblock', 'Replicates', 5);
gmm_B = fit_gmm(T_B, k_B);
% Foreground
k_U = kmeans(T_U, no_gauss, 'Distance', 'cityblock', 'Replicates', 5);
gmm_U = fit_gmm(T_U, k_U);

%--------------------------- II. Iterative Minimization

%%% Compute pairwise in one shot
pairwise = compute_pairwise(im_sub, gamma);
fprintf('Pairwise terms computed in one shot\n');

isConverged = 0;
E_prev = +Inf;
iter = 0;
while ~isConverged
    
    %------- 1. Assign GMM components to pixels
    
    [k_U, k_B] = assign_gauss(im_1d, pix_U, gmm_U, pix_B, gmm_B);
    
    %------- 2. Learn GMM parameters from data
    
    [gmm_U, gmm_B] = update_gmm(im_1d, pix_U, k_U, pix_B, k_B);
    
    %------- 3. Estimate segmentation: use min cut to solve
    
    [pix_U, E] = cut_Tu(pix_U, im_sub, alpha, gmm_U, gmm_B, pairwise);
    
    %%% Report progress
    E_change = (E_prev-E)/E_prev;
    iter = iter+1;
    fprintf('\n');
    fprintf('Iter %i done, E drops by %.3f%% (converged when < %.3f%%)\n', iter, E_change*100, E_CHANGE_THRES*100);
    
    %%% Check convergence
    if E_change < E_CHANGE_THRES
        isConverged = 1;
    end