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: minf_ncg.m
    path of file: ./repos/imtsl/libs/tensorlab
    
    the code of the file until where you have to start completion: function [z,output] = minf_ncg(f,g,z0,options)
%MINF_NCG Minimize a function by nonlinear conjugate gradient.
%   [z,output] = minf_ncg(f,g,z0) starts at z0 and attempts to find a local
%   minimizer of the real-valued function f(z). The input variables z may
%   be a scalar, vector, matrix, tensor or even a (nested) cell array of
%   tensors and its contents may be real or complex.
%
%   If f(x) is a function of real variables x, the function g(x) should
%   compute the partial derivatives of f with respect to the real variables
%   x, i.e. g(xk) := df(xk)/dx. If f(z) is a function of complex variables
%   z, the function g(z) should compute two times the partial derivative
%   of f with respect to conj(z) (treating z as constant), i.e. g(zk) :=
%   2*df(zk)/d(conj(z)) = 2*conj(df(zk)/dz). If g is the empty matrix [],
%   the real gradient or scaled conjugate cogradient is approximated with
%   finite differences. The output of the function g(z) may have the same
%   structure as z (although this is not necessary). The structure output
%   returns additional information:
%
%      output.alpha      - The line search step length in every iteration.
%      output.fevals     - The total number of function/gradient calls.
%      output.fval       - The value of the objective function f in every
%                          iteration.
%      output.info       - The circumstances under which the procedure
%                          terminated:
%                             1: Objective function tolerance reached.
%                             2: Step size tolerance reached.
%                             3: Maximum number of iterations reached.
%      output.infols     - The circumstances under which the line search
%                          terminated in every iteration.
%      output.iterations - The number of iterations.
%      output.relfval    - The difference in objective function value
%                          between every two successive iterates, relative
%                          to its initial value.
%      output.relstep    - The step size relative to the norm of the 
%                          current iterate in every iteration.
%
%   minf_ncg(f,g,z0,options) may be used to set the following options:
%
%      options.Beta =            - The conjugate gradient update parameter.
%      ['HS',{'HSm'},'PR',...      Options are 'HS' (Hestenes-Stiefel),
%       'PRm','FR,'SD']            'HSm' (modified Hestenes-Stiefel), 'PR'
%                                  (Polak-Ribiere), 'PRm' (modified Polak-
%                                  Ribiere), 'FR' (Fletcher-Reeves) and
%                                  'SD' (steepest descent).
%      options.Display = 10      - Displays the objective function value,
%                                  its difference with the previous iterate
%                                  relative to the first iterate and the
%                                  relative step size each options.Display
%                                  iterations. Set to 0 to disable.
%      options.LineSearch        - The line search used to minimize the
%      = @ls_mt                    objective function in the quasi-Newton
%                                  descent direction.
%      options.LineSearchOptions - The options structure passed to the line
%                                  search routine.

    
function [z,output] = minf_ncg(f,g,z0,options)
%MINF_NCG Minimize a function by nonlinear conjugate gradient.
%   [z,output] = minf_ncg(f,g,z0) starts at z0 and attempts to find a local
%   minimizer of the real-valued function f(z). The input variables z may
%   be a scalar, vector, matrix, tensor or even a (nested) cell array of
%   tensors and its contents may be real or complex.
%
%   If f(x) is a function of real variables x, the function g(x) should
%   compute the partial derivatives of f with respect to the real variables
%   x, i.e. g(xk) := df(xk)/dx. If f(z) is a function of complex variables
%   z, the function g(z) should compute two times the partial derivative
%   of f with respect to conj(z) (treating z as constant), i.e. g(zk) :=
%   2*df(zk)/d(conj(z)) = 2*conj(df(zk)/dz). If g is the empty matrix [],
%   the real gradient or scaled conjugate cogradient is approximated with
%   finite differences. The output of the function g(z) may have the same
%   structure as z (although this is not necessary). The structure output
%   returns additional information:
%
%      output.alpha      - The line search step length in every iteration.
%      output.fevals     - The total number of function/gradient calls.
%      output.fval       - The value of the objective function f in every
%                          iteration.
%      output.info       - The circumstances under which the procedure
%                          terminated:
%                             1: Objective function tolerance reached.
%                             2: Step size tolerance reached.
%                             3: Maximum number of iterations reached.
%      output.infols     - The circumstances under which the line search
%                          terminated in every iteration.
%      output.iterations - The number of iterations.
%      output.relfval    - The difference in objective function value
%                          between every two successive iterates, relative
%                          to its initial value.
%      output.relstep    - The step size relative to the norm of the 
%                          current iterate in every iteration.
%
%   minf_ncg(f,g,z0,options) may be used to set the following options:
%
%      options.Beta =            - The conjugate gradient update parameter.
%      ['HS',{'HSm'},'PR',...      Options are 'HS' (Hestenes-Stiefel),
%       'PRm','FR,'SD']            'HSm' (modified Hestenes-Stiefel), 'PR'
%                                  (Polak-Ribiere), 'PRm' (modified Polak-
%                                  Ribiere), 'FR' (Fletcher-Reeves) and
%                                  'SD' (steepest descent).
%      options.Display = 10      - Displays the objective function value,
%                                  its difference with the previous iterate
%                                  relative to the first iterate and the
%                                  relative step size each options.Display
%                                  iterations. Set to 0 to disable.
%      options.LineSearch        - The line search used to minimize the
%      = @ls_mt                    objective function in the quasi-Newton
%                                  descent direction.
%      options.LineSearchOptions - The options structure passed to the line
%                                  search routine.
%      options.MaxIter = 500     - The maximum number of iterations.
%      options.TolFun = 1e-6     - The tolerance for output.relfval.
%      options.TolX = 1e-8       - The tolerance for output.relstep.

%   Authors: Laurent Sorber (Laurent.Sorber@cs.kuleuven.be)
%            Marc Van Barel (Marc.VanBarel@cs.kuleuven.be)
%            Lieven De Lathauwer (Lieven.DeLathauwer@kuleuven-kulak.be)
%
%   References:
%   [1] L. Sorber, M. Van Barel, L. De Lathauwer, "Unconstrained
%       optimization of real functions in complex variables", SIAM J. Opt.,
%       Vol. 22, No. 3, 2012, pp. 879-898.

% Evaluate the objective function and gradient.
dim = structure(z0);
fval = f(z0);
if ~isa(g,'function_handle') && isempty(g)
    grad = serialize(deriv(f,z0,fval));
else
    grad = serialize(g(z0));
end