📄 maxent.m
字号:
function [x_lambda,rho,eta,data,X] = maxent(A,b,lambda,w,x0) %MAXENT Maximum entropy regularization. % % [x_lambda,rho,eta] = maxent(A,b,lambda,w,x0) % % Maximum entropy regularization: % min { || A x - b ||^2 + lambda^2*x'*log(diag(w)*x) } , % where -x'*log(diag(w)*x) is the entropy of the solution x. % If no weights w are specified, unit weights are used. % % If lambda is a vector, then x_lambda is a matrix such that % x_lambda = [x_lambda(1), x_lambda(2), ... ] . % % This routine uses a nonlinear conjugate gradient algorithm with "soft" % line search and a step-length control that insures a positive solution. % If the starting vector x0 is not specified, then the default is % x0 = norm(b)/norm(A,1)*ones(n,1) . % Per Christian Hansen, IMM and Tommy Elfving, Dept. of Mathematics, % Linkoping University, 06/10/92. % Reference: R. Fletcher, "Practical Methods for Optimization", % Second Edition, Wiley, Chichester, 1987. % Set defaults. flat = 1e-3; % Measures a flat minimum. flatrange = 10; % How many iterations before a minimum is considered flat. maxit = 150; % Maximum number of CG iterations; minstep = 1e-12; % Determines the accuracy of x_lambda. sigma = 0.5; % Threshold used in descent test. tau0 = 1e-3; % Initial threshold used in secant root finder. % Initialization. [m,n] = size(A); x_lambda = zeros(n,length(lambda)); F = zeros(maxit,1); if (min(lambda) <= 0) error('Regularization parameter lambda must be positive') end if (nargin ==3), w = ones(n,1); end if (nargin < 5), x0 = ones(n,1); end % Treat each lambda separately. for j=1:length(lambda); % Prepare for nonlinear CG iteration. l2 = lambda(j)^2; x = x0; Ax = A*x; g = 2*A'*(Ax - b) + l2*(1 + log(w.*x)); p = -g; r = Ax - b; % Start the nonlinear CG iteration here. delta_x = x; dF = 1; it = 0; phi0 = p'*g; while (norm(delta_x) > minstep*norm(x) & dF > flat & it < maxit & phi0 < 0) it = it + 1; % Compute some CG quantities. Ap = A*p; gamma = Ap'*Ap; v = A'*Ap; % Determine the steplength alpha by "soft" line search in which % the minimum of phi(alpha) = p'*g(x + alpha*p) is determined to % a certain "soft" tolerance. % First compute initial parameters for the root finder. alpha_left = 0; phi_left = phi0; if (min(p) >= 0) alpha_right = -phi0/(2*gamma); h = 1 + alpha_right*p./x; else % Step-length control to insure a positive x + alpha*p. I = find(p < 0); alpha_right = min(-x(I)./p(I)); h = 1 + alpha_right*p./x; delta = eps; while (min(h) <= 0) alpha_right = alpha_right*(1 - delta); h = 1 + alpha_right*p./x; delta = delta*2; end end z = log(h); phi_right = phi0 + 2*alpha_right*gamma + l2*p'*z; alpha = alpha_right; phi = phi_right; if (phi_right <= 0) % Special treatment of the case when phi(alpha_right) = 0. z = log(1 + alpha*p./x); g_new = g + l2*z + 2*alpha*v; t = g_new'*g_new; beta = (t - g'*g_new)/(phi - phi0); else % The regular case: improve the steplength alpha iteratively % until the new step is a descent step. t = 1; u = 1; tau = tau0; while (u > -sigma*t) % Use the secant method to improve the root of phi(alpha) = 0 % to within an accuracy determined by tau. while (abs(phi/phi0) > tau) alpha = (alpha_left*phi_right - alpha_right*phi_left)/... (phi_right - phi_left); z = log(1 + alpha*p./x); phi = phi0 + 2*alpha*gamma + l2*p'*z; if (phi > 0) alpha_right = alpha; phi_right = phi; else alpha_left = alpha; phi_left = phi; end end % To check the descent step, compute u = p'*g_new and % t = norm(g_new)^2, where g_new is the gradient at x + alpha*p. g_new = g + l2*z + 2*alpha*v; t = g_new'*g_new; beta = (t - g'*g_new)/(phi - phi0); u = -t + beta*phi; tau = tau/10; end % End of improvement iteration. end % End of regular case. % Update the iteration vectors. g = g_new; delta_x = alpha*p; x = x + delta_x; p = -g + beta*p; r = r + alpha*Ap; phi0 = p'*g; % Compute some norms and check for flat minimum. rho(j,1) = norm(r); eta(j,1) = x'*log(w.*x); F(it) = rho(j,1)^2 + l2*eta(j,1); if (it <= flatrange) dF = 1; else dF = abs(F(it) - F(it-flatrange))/abs(F(it)); end data(it,:) = [F(it),norm(delta_x),norm(g)]; X(:,it) = x; end % End of iteration for x_lambda(j). x_lambda(:,j) = x; end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -