https://github.com/Data2Dynamics/d2d
Raw File
Tip revision: 4c697ee160f4d91719a65cfcfe3e3b50395b6656 authored by Helge Hass on 29 July 2015, 07:45:33 UTC
new C code version
Tip revision: 4c697ee
arNLSstep.m
% generate trial steps within box bounds
%
% [dp, solver_calls, qred, dpmem, grad_dir_frac, llh_expect, normdpmu_type] = ...
%     arNLSstep(llh, g, H, sres, mu, p, lb, ub, solver_calls, dpmem, useInertia, method)
%
% llh:  likelihood
% g:    gradient
% H:    Hessian matrix
% mu:   trust region size (for LM: lambda = 10/mu)
% p:    current parameters
% lb:   lower bounds
% ub:   upper bounds
%
% method:   
%  0 = trust region (based on modified trust.m)
%  1 = Levenberg-Marquardt
%  2 = Newton (with maximal step length mu)
%  3 = gradient descent (with steplength mu)
%  4 = gradient descent (to cauchy point with steplength mu)
%  5 = dogleg
%  6 = generalized trust region (based on modified trust.m)
%  7 = MATLABs trdog
%  8 = Newton pcgr (with maximal step length mu)
%  9 = trdog pcgr (with maximal step length mu)
% 10 = dogleg Newton pcgr
% 11 = dogleg trdog pcgr
% 12 = trdog pcgr (no DM)
% 13 = trdog pcgr (no DG)
% 14 = trdog pcgr Levenberg-Marquardt
% 15 = trdog pcgr 2D subspace 
% 16 = trdog pcgr (no DM) 2D subspace 
% 17 = trdog pcgr (no DM) 3D subspace 
% 18 = trust region (with DG, based on modified trust.m)
% 19 = trust region solution (with EV)

function [dp, solver_calls, qred, grad_dir_frac, llh_expect, normdpmu_type] = ...
    arNLSstep(llh, g, H, sres, mu, p, lb, ub, solver_calls, dpmem, method)

if(nargin==0)
    dp = {};
    dp{1} = 'trustregion';
    dp{2} = 'Levenberg-Marquardt';
    dp{3} = 'Newton';
    dp{4} = 'gradient-descent';
    dp{5} = 'gradient-descent';
    dp{6} = 'dogleg';
    dp{7} = 'generalized-trustregion';
    dp{8} = 'MATLAB-trdog';
    dp{9} = 'Newton-pcgr';
    dp{10} = 'trdog-pcgr';
    dp{11} = 'dogleg-Newton-pcgr';
    dp{12} = 'dogleg-trdog-pcgr';
    dp{13} = 'trdog-pcgr-noDM';
    dp{14} = 'trdog-pcgr-noDG';
    dp{15} = 'trdog-pcgr-Levenberg-Marquardt';
    dp{16} = 'trdog-pcgr-2D-subspace';
    dp{17} = 'trdog-pcgr-noDM-2D-subspace';
    dp{18} = 'trdog-pcgr-noDM-3D-subspace';
    dp{19} = 'trustregion-withDG';
    dp{20} = 'trustregion-withEV';
    return;
end

qred = false(size(p));
% qred = sum(abs(sres),1)<1e-3;

if(isscalar(mu) && mu==0)
    dp = zeros(size(g));
    grad_dir_frac = 0;
    llh_expect = llh;
    normdpmu_type = nan;
    return
end

if(method==7) % use MATLABs trdog
    g_trdog = -0.5*g';
    [v, dv] = definev(g_trdog',p,lb,ub);
    dd = sqrt(abs(v)); 
    D = sparse(diag(dd));
    pcoptions = Inf;
    pcgtol = 0.1;
    kmax = max(1,floor(length(p)/2));
    gopt = v.*g_trdog;
    optnrm = norm(gopt,inf);
    theta = max(.95,1-optnrm);  
    
    dp = trdog(p',g_trdog,sres,D,mu,dv,@atamult,@aprecon,...
        pcoptions,pcgtol,kmax,theta,lb',ub',[],[],'jacobprecon')';
    
    solver_calls = solver_calls + 1;
    normdpmu_type = nan;
    
else % own step implementation
    % solve subproblem
    [dp, normdpmu_type, solver_calls_tmp] = getDP(p, lb, ub, g, H, sres, mu, dpmem, method, qred);
    solver_calls = solver_calls + solver_calls_tmp;
    
    distp = -[p-ub; -(p - lb)]; % distance to bounds (should be always positive)
    onbound = distp==0; % which parameter is exactly on the bound ?
    exbounds = [p+dp-ub; -(p+dp - lb)] > 0; % dp bejond bound ?
    
    % if p on bounds and dp pointing bejond bound, reduce problem
    qred = qred | sum(onbound & exbounds,1)>0;
    if(sum(~qred)==0)
        error('solution outside bounds, no further step possible');
    end
    qred_tmp = qred;
    while(sum(qred_tmp)>0)
        gred = g(~qred);
        Hred = H(~qred,~qred);
        sresred = sres(:,~qred);
        
        % solve reduced subproblem
        [dp_red, normdpmu_type, solver_calls_tmp] = getDP(p(~qred), lb(~qred), ub(~qred), ...
            gred, Hred, sresred, mu, dpmem, method, qred);
        solver_calls = solver_calls + solver_calls_tmp;
        
        dp(:) = 0;
        dp(~qred) = dp_red;
        
        exbounds = [p+dp-ub; -(p+dp - lb)] > 0; % dp bejond bound ?
        qred_tmp = sum(onbound & exbounds,1)>0;
        qred = qred_tmp | qred;
        
        if(sum(~qred)==0)
            error('solution in the conner, dp pointing outside, no further step possible');
        end
    end
    
    % if dp too long cut to bounds
    dptmp = [dp; dp];
    dpredfac = abs(min(distp(exbounds)./dptmp(exbounds)));
    if(~isempty(dpredfac))
        if(dpredfac==0)
            error('zero step size error');
        end
        dp = dp * dpredfac;
    end
end

% proportion of step in direction of gradient
grad_dir_frac = dp(~qred)*g(~qred)'/norm(dp(~qred))/norm(g(~qred));

% expected likelihood
llh_expect = llh - g*dp' + 0.5*dp*H*dp';



% generate trial steps within ball of size mu (for LM: lambda = 10/mu)
% normdpmu = 
%       norm(dp) in units of mu
%       nan if trust region scaling based on normdpmu not applicable
function [dp, normdpmu_type, solver_calls_tmp] = getDP(p, lb, ub, g, H, sres, mu, dpmem, method, qred)

if(mu==0)
    dp = zeros(size(g));
    normdpmu_type = nan;
    solver_calls_tmp = 0;
    return;
else
    solver_calls_tmp = 1;
end

if(~isempty(dpmem))
    dpmem = dpmem(~qred);
end
    

switch method
    case 0 % trust region solution       
        dp = trust(-g',H,mu)';
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp)/mu > 1.01)
            % fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp)/mu, lambda);
            dp = trust(-g',H+lambda*eye(size(H)),mu)';
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        normdpmu_type = -1;
        
    case 1 % levenberg-marquardt
        lambda = 1/mu;
        dp = transpose(pinv(H + lambda*eye(size(H)))*g');
        normdpmu_type = nan;
        
    case 2 % newton with maximum steplength mu
        dp = transpose(pinv(H)*g');
        if(norm(dp)>mu)
            dp = mu*dp/norm(dp);
        end
        normdpmu_type = -1;
        
    case 3 % gradient with steplength mu
        dp = mu*g/norm(g);
        normdpmu_type = -1;
       
    case 4 % gradient to cauchy point with steplength mu
        dp = norm(g)^2/(g*H*g') * g;
        if(norm(dp)>mu)
            dp = mu*dp/norm(dp);
        end
        normdpmu_type = -1;
        
    case 5 % dogleg
        dpC = norm(g)^2/(g*H*g') * g;
        if(norm(dpC)>mu)
            % truncated gradient
            dp = mu*g/norm(g);
%             fprintf('truncated gradient - ');
        else
            dpN = transpose(pinv(H)*g');
            if(norm(dpN)<=mu)
                % full newton
                dp = dpN;
%                 fprintf('full newton - ');
            else
                % dogleg
                a = sum((dpN - dpC).^2);
                b = 2*sum(dpC.*(dpN - dpC));
                c = sum(dpC.^2) - mu^2;
                t = (-b + sqrt(b^2 - 4 * a * c))/(2*a);
                dp = dpC + t*(dpN - dpC);
%                 fprintf('dogleg (%4.2f) - ', norm(dpC)/mu);
            end
        end
        normdpmu_type = -1;
        
    case 6 % generalized trust region
        mut = mu(~qred,~qred);
        gt = g*mut;
        Ht = mut'*H*mut;
        Ht = 0.5*(Ht + Ht');
        
        dp = trust(-gt',Ht,1)';
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp) > 1.01)
%             fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp), lambda);
            dp = trust(-gt',Ht+lambda*eye(size(Ht)),1)';
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        dp = dp * mut;
        normdpmu_type = norm(dp) / sqrt((dp/mut)*(dp/mut)');
        
    case 8 % Newton pcgr
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        DM = eye(length(g));
        DG = DM;
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        dp = pcgr(DM,DG,g_pcgr,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions)';
        if(norm(dp)>mu)
            dp = mu*dp/norm(dp);
        end
        normdpmu_type = -1;
        
    case 9 % trdog pcgr
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
%         DM = sparse(eye(size(DM)));
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
%         DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        dp = pcgr(DM,DG,DM*g_pcgr,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);
        dp = transpose(DM*dp);
        if(norm(dp)>mu)
            dp = mu*dp/norm(dp);
        end
        normdpmu_type = -1;
   
    case 10 % dogleg Newton pcgr
        dpC = norm(g)^2/(g*H*g') * g;
        if(norm(dpC)>mu)
            % truncated gradient
            dp = mu*g/norm(g);
            fprintf('truncated gradient - ');
        else
            g_pcgr = -0.5*g';
            pcoptions = Inf;
            pcgtol = 0.1;
            kmax = max(1,floor(length(g)/2));
            DM = eye(length(g));
            DG = DM;
            [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
            dpN = pcgr(DM,DG,g_pcgr,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions)';
            
            if(norm(dpN)<=mu)
                % full newton
                dp = dpN;
                fprintf('full newton - ');
            else
                % dogleg
                a = sum((dpN - dpC).^2);
                b = 2*sum(dpC.*(dpN - dpC));
                c = sum(dpC.^2) - mu^2;
                t = (-b + sqrt(b^2 - 4 * a * c))/(2*a);
                dp = dpC + t*(dpN - dpC);
                fprintf('dogleg (%4.2f) - ', norm(dpC)/mu);
            end
        end
        normdpmu_type = -1;
        
    case 11 % dogleg trdog pcgr
        dpC = norm(g)^2/(g*H*g') * g;
        if(norm(dpC)>mu)
            % truncated gradient
            dp = mu*g/norm(g);
            fprintf('truncated gradient - ');
        else
            g_pcgr = -0.5*g';
            pcoptions = Inf;
            pcgtol = 0.1;
            kmax = max(1,floor(length(g)/2));
            [v, dv] = definev(g_pcgr',p,lb,ub);
            dd = sqrt(abs(v));
            DM = sparse(diag(dd));
%             DM = sparse(eye(size(DM)));
            DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
%             DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
            [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
            dpN = pcgr(DM,DG,DM*g_pcgr,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);
            dpN = transpose(DM*dpN);
            
            if(norm(dpN)<=mu)
                % full newton
                dp = dpN;
                fprintf('full newton - ');
            else
                % dogleg
                a = sum((dpN - dpC).^2);
                b = 2*sum(dpC.*(dpN - dpC));
                c = sum(dpC.^2) - mu^2;
                t = (-b + sqrt(b^2 - 4 * a * c))/(2*a);
                dp = dpC + t*(dpN - dpC);
                fprintf('dogleg (%4.2f) - ', norm(dpC)/mu);
            end
        end
        normdpmu_type = -1;
        
    case 12 % trdog pcgr no DM
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
        DM = sparse(eye(size(DM)));
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        dp = pcgr(DM,DG,DM*g_pcgr,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);
        dp = transpose(DM*dp);
        if(norm(dp)>mu)
            dp = mu*dp/norm(dp);
        end
        normdpmu_type = -1;
        
    case 13 % trdog pcgr no DG
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
        DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        dp = pcgr(DM,DG,DM*g_pcgr,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);
        dp = transpose(DM*dp);
        if(norm(dp)>mu)
            dp = mu*dp/norm(dp);
        end
        normdpmu_type = -1;
        
    case 14 % trdog pcgr Levenberg-Marquardt
        lambda = 1/mu;
        sresLM = [sres;sqrt(lambda)*eye(size(sres,2))];
        
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
%         DM = sparse(eye(size(DM)));
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
%         DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
        [R,permR] = feval(@aprecon,sresLM,pcoptions,DM,DG);
        dp = pcgr(DM,DG,DM*g_pcgr,kmax,pcgtol,@atamult,sresLM,R,permR,'jacobprecon',pcoptions);
        dp = transpose(DM*dp);
        
        normdpmu_type = nan;
        
    case 15 % trdog pcgr 2D subspace
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
%         DM = sparse(eye(size(DM)));
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
%         DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
        grad = DM*g_pcgr;
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        [dp, posdef] = pcgr(DM,DG,grad,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);
        
        % calculate subspace Z
        tol2 = sqrt(eps);
        if norm(dp) > 0
            v1 = dp/norm(dp);
        else
            v1 = dp;
        end
        Z(:,1) = v1;
        if length(p) > 1
            if (posdef < 1)
                v2 = D*sign(g_pcgr);
                if norm(v2) > 0
                    v2 = v2/norm(v2);
                end
            else
                if norm(g_pcgr) > 0
                    v2 = g_pcgr/norm(g_pcgr);
                else
                    v2 = g_pcgr;
                end
                
            end
            v2 = v2 - v1*(v1'*v2);
            nrmv2 = norm(v2);
            if nrmv2 > tol2
                v2 = v2/nrmv2;
                Z(:,2) = v2;
            end
        end
        
        % reduce to subspace
        W = DM*Z;        
        WW = feval(@atamult,sres,W,0);
        
        W = DM*WW;
        MM = full(Z'*W + Z'*DG*Z);
        rhs = full(Z'*grad);
        
        % determine 2D trust solution
        dp = trust(rhs,MM,mu);
        normdpmu_type = norm(dp)/mu;
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp)/mu > 1.01)
%             fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp)/mu, lambda);
            dp = trust(rhs,MM+lambda*eye(size(MM)),mu);
            normdpmu_type = norm(dp)/mu;
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        
        % got back to original space
        dp = Z*dp;
        dp = transpose(DM*dp);
        
    case 16 % trdog pcgr no DM 2D subspace
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
        DM = sparse(eye(size(DM)));
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
%         DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
        grad = DM*g_pcgr;
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        [dp, posdef] = pcgr(DM,DG,grad,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);

%         posdef = 1;
%         dp = (DM*H*DM + DG)\g';
        
        % calculate subspace Z
        tol2 = sqrt(eps);
        if norm(dp) > 0
            v1 = dp/norm(dp);
        else
            v1 = dp;
        end
        Z(:,1) = v1;
        if length(p) > 1
            if (posdef < 1)
                v2 = D*sign(g_pcgr);
                if norm(v2) > 0
                    v2 = v2/norm(v2);
                end
            else
                if norm(g_pcgr) > 0
                    v2 = g_pcgr/norm(g_pcgr);
                else
                    v2 = g_pcgr;
                end
                
            end
            v2 = v2 - v1*(v1'*v2);
            nrmv2 = norm(v2);
            if nrmv2 > tol2
                v2 = v2/nrmv2;
                Z(:,2) = v2;
            end
        end
        
        % reduce to subspace
        W = DM*Z;        
        WW = feval(@atamult,sres,W,0);
        
        W = DM*WW;
        MM = full(Z'*W + Z'*DG*Z);
        rhs = full(Z'*grad);
        
        % determine 2D trust solution
        dp = trust(rhs,MM,mu);
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp)/mu > 1.01)
%             fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp)/mu, lambda);
            dp = trust(rhs,MM+lambda*eye(size(MM)),mu);
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        
        % got back to original space
        dp = Z*dp;
        dp = transpose(DM*dp);
        normdpmu_type = -1;
        
    case 17 % trdog pcgr (no DM) 3D subspace 
        g_pcgr = -0.5*g';
        pcoptions = Inf;
        pcgtol = 0.1;
        kmax = max(1,floor(length(g)/2));
        [v, dv] = definev(g_pcgr',p,lb,ub);
        dd = sqrt(abs(v));
        DM = sparse(diag(dd));
        DM = sparse(eye(size(DM)));
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
%         DG = sparse(1:length(g),1:length(g),full(ones(size(g_pcgr)).*dv));
        grad = DM*g_pcgr;
        [R,permR] = feval(@aprecon,sres,pcoptions,DM,DG);
        [dp, posdef] = pcgr(DM,DG,grad,kmax,pcgtol,@atamult,sres,R,permR,'jacobprecon',pcoptions);
        
        % calculate subspace Z
        tol2 = sqrt(eps);
        if norm(dp) > 0
            v1 = dp/norm(dp);
        else
            v1 = dp;
        end
        Z(:,1) = v1;
        if length(p) > 1
            if (posdef < 1)
                v2 = D*sign(g_pcgr);
                if norm(v2) > 0
                    v2 = v2/norm(v2);
                end
            else
                if norm(g_pcgr) > 0
                    v2 = g_pcgr/norm(g_pcgr);
                else
                    v2 = g_pcgr;
                end
                
            end
            v2 = v2 - v1*(v1'*v2);
            nrmv2 = norm(v2);
            if nrmv2 > tol2
                v2 = v2/nrmv2;
                Z(:,2) = v2;
            end
        end
        
        % additional directions
%         tmpp = randn(1,length(v1));
%         Z(:,end+1) = tmpp/norm(tmpp);
        if(~isempty(dpmem))
            tmpp = DM*dpmem';
            Z(:,end+1) = tmpp/norm(tmpp);
        end
%         tmpp = transpose(pinv(H)*g');
%         Z(:,end+1) = tmpp/norm(tmpp);
        Z = mgrscho(Z);
        
        % reduce to subspace
        W = DM*Z;        
        WW = feval(@atamult,sres,W,0);
        
        W = DM*WW;
        MM = full(Z'*W + Z'*DG*Z);
        rhs = full(Z'*grad);
        
        % determine 2D trust solution
        dp = trust(rhs,MM,mu);
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp)/mu > 1.01)
%             fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp)/mu, lambda);
            dp = trust(rhs,MM+lambda*eye(size(MM)),mu);
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        
        % got back to original space
        dp = Z*dp;
        dp = transpose(DM*dp);
        normdpmu_type = -1;
        
    case 18 % trust region solution (with DG)
        g_pcgr = -0.5*g';
        [~, dv] = definev(g_pcgr',p,lb,ub);
        DG = sparse(1:length(g),1:length(g),full(abs(g_pcgr).*dv));
        
        dp = trust(-g',H+DG,mu)';
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp)/mu > 1.01)
            %             fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp)/mu, lambda);
            dp = trust(-g',H+DG+lambda*eye(size(H)),mu)';
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        normdpmu_type = -1;
        
    case 19 % trust region solution (with EV)
%         [U,S,V] = svd(H);
%         Q = S/max(S(:));
%         S2 = S;
%         S2(Q<1e-6) = 0;
%         H2 = U*S2*V';

        [V,D] = eig(H);
        q = diag(D/max(D(:))) > 0;
        
        Z = V(:,q);
        g = transpose(Z'*g');
        H = Z'*H*Z;

        dp = trust(-g',H,mu)';
        
        % the function trust has a bug, therefore, in some cases
        % the problem has to be regularized
        lambda = 1e-6;
        while(norm(dp)/mu > 1.01)
            fprintf('trust.m problem %g, regularizing with new lambda=%g\n', norm(dp)/mu, lambda);
            dp = trust(-g',H+lambda*eye(size(H)),mu)';
            solver_calls_tmp = solver_calls_tmp + 1;
            lambda = lambda * 10;
        end
        
        dp = transpose(Z*dp');
        normdpmu_type = -1;
end



% Scaling vector and derivative
function [v,dv]= definev(g,x,l,u)
n = length(x); 
v = zeros(n,1); 
dv=zeros(n,1);
arg1 = (g < 0)  & (u <  inf ); 
arg2 = (g >= 0) & (l > -inf);
arg3 = (g < 0)  & (u == inf); 
arg4 = (g >= 0) & (l == -inf);
v(arg1)  = (x(arg1) - u(arg1)); 
dv(arg1) = 1;
v(arg2)  = (x(arg2) - l(arg2)); 
dv(arg2) = 1;
v(arg3)  = -1;
dv(arg3) = 0;
v(arg4)  = 1;
dv(arg4) = 0;



function A = mgrscho(A)
%MGRSHO Modified Gram-Schmidt orthogonalization procedure. 
% -For a basis of fundamentals on classical Gram-Schmidt process, procedure
% and its origin. Please see the text of the m-file cgrsho you can download
% from www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=12465
% The classical Gram-Scmidt algorithm is numerically unstable, mainly 
% because of all the successive subtractions in the order they appear. When
% this process is implemented on a computer, then the vectors s_n are not
% quite orthogonal because of rounding errors. This loss of orthogonality
% is particularly bad; therefore, it is said that the (naive) classical 
% Gram–Schmidt process is numerically unstable. If we write an algorithm
% based on the way we developed the Gram-Schmidt iteration (in terms of 
% projections), we get a better algorithm.
% The Gram–Schmidt process can be stabilized by a small modification. 
% Instead of computing the vector u_n as,
%
%     u_n = v_k - proj_u_1 v_n - proj_u_2 v_n -...- proj_u_n-1 v_n
%
% it is computed as,
%
%     u_n = u_n ^n-2 - proj_u_n-1 u_n ^n-2
%
% This series of computations gives the same result as the original formula
% in exact arithmetic, but it introduces smaller errors in finite-precision
% arithmetic. A stable algorithm is one which does not suffer drastically 
% from perturbations due to roundoff errors. This is called as the modified
% Gram-Schmidt orthogonalization process. 
% There are several different variations of the Gram-Schmidt process 
% including classical Gram-Schmidt (CGS), modified Gram-Schmidt (MGS) and 
% modified Gram-Schmidt with pivoting (MGSP). MGS economizes storage and is
% generally more stable than CGS.
% The Gram-Schmidt process can be used in calculating Legendre polynomials,
% Chebyshev polynomials, curve fitting of empirical data, smoothing, and
% calculating least square methods and other functional equations.
% 
% Syntax: function mgrscho(A)
%
% Input:
%    A - matrix of n linearly independent vectors of equal size. Here, them
%        must be arranged as columns.
% Output:
%    Matrix of n orthogonalized vectors.
%
% Example: Taken the problem 18, S6.3, p308, from the Mathematics 206 Solutions
% for HWK 24b. Course of Math 206 Linear Algebra by Prof. Alexia Sontag at
% Wellesley Collage, Wellesley, MA, USA. URL address:
% http://www.wellesley.edu/Math/Webpage%20Math/Old%20Math%20Site/Math206sontag/
% Homework/Pdf/hwk24b_s02_solns.pdf
%           
% We are interested to orthogonalize the vectors,
%
%    v1 = [0 2 1 0], v2 = [1 -1 0 0], v3 = [1 2 0 -1] and v4 = [1 0 0 1]
%
% by the modified Gram-Schmidt process.
%
% Vector matrix must be:
%    A = [0 1 1 1;2 -1 2 0;1 0 0 0;0 0 -1 1];
%
% Calling on Matlab the function: 
%    mgrscho(A)
%
% Answer is:
%
% ans =
%         0    0.9129    0.3162    0.2582
%    0.8944   -0.1826    0.3162    0.2582
%    0.4472    0.3651   -0.6325   -0.5164
%         0         0   -0.6325    0.7746
%
% NOTE.- Comparing the orthogonality of resulting vectors by both classical
%    Gram-Schmidt and modified Gram-Schmidt processes, using floating point
%    format with 15 digits for double and 7 digits for single. We found that
%    during the process, with the modified one there exists smaller errors. 
%
%                                  Gram-Schmidt Process
%                  --------------------------------------------------------
%        Vectors         Classical                         Modified
%       -------------------------------------------------------------------
%         A1-A2   -8.326672684688674e-017          -8.326672684688674e-017
%         A1-A3    1.665334536937735e-016           1.110223024625157e-016
%         A1-A4    1.110223024625157e-016           1.110223024625157e-016
%         A2-A3    5.551115123125783e-017          -1.110223024625157e-016
%         A2-A4   -5.551115123125783e-017          -5.551115123125783e-017
%         A3-A4              0                                 0
%       -------------------------------------------------------------------
%
%
% Created by A. Trujillo-Ortiz, R. Hernandez-Walls, A. Castro-Perez
%            and K. Barba-Rojo
%            Facultad de Ciencias Marinas
%            Universidad Autonoma de Baja California
%            Apdo. Postal 453
%            Ensenada, Baja California
%            Mexico.
%            atrujo@uabc.mx
%
% Copyright. September 30, 2006.
%
% To cite this file, this would be an appropriate format:
% Trujillo-Ortiz, A., R. Hernandez-Walls, A. Castro-Perez and K. Barba-Rojo. (2006). 
%   mgrscho:Modified Gram-Schmidt orthogonalization procedure. A MATLAB file.
%   [WWW document]. URL http://www.mathworks.com/matlabcentral/fileexchange/
%   loadFile.do?objectId=12495
%
% References:
% Gerber, H. (1990), Elementary Linear Algebra. Brooks/Cole Pub. Co. Pacific
%     Grove, CA. 
% Wong, Y.K. (1935), An Application of Orthogonalization Process to the 
%     Theory of Least Squares. Annals of Mathematical Statistics, 6:53-75.
%

if nargin ~= 1,
    error('You need to imput only one argument.');
end

[~, n]=size(A);

for j= 1:n
    R(j,j)=norm(A(:,j)); %#ok<AGROW>
    A(:,j)=A(:,j)/R(j,j);
    R(j,j+1:n)=A(:,j)'*A(:,j+1:n); %#ok<AGROW>
    A(:,j+1:n)=A(:,j+1:n)-A(:,j)*R(j,j+1:n);
end
back to top