gusucode.com > elmat工具箱matlab源码程序 > elmat/private/randsvd.m
function A = randsvd(n, kappa, mode, kl, ku, method, classname) %RANDSVD Random matrix with pre-assigned singular values. % A = GALLERY('RANDSVD', N, KAPPA, MODE, KL, KU) is a banded random % matrix of order N with COND(A) = KAPPA and singular values from the % distribution MODE. If N is a two-element vector, A is N(1)-by-N(2). % % MODE may be one of the following values: % 1: one large singular value, % 2: one small singular value, % 3: geometrically distributed singular values, % 4: arithmetically distributed singular values, % 5: random singular values with uniformly distributed logarithm. % If omitted, MODE defaults to 3, and KAPPA defaults to SQRT(1/EPS). % If MODE < 0 then the effect is as for ABS(MODE) except that in the % original matrix of singular values the order of the diagonal % entries is reversed: small to large instead of large to small. % % KL and KU are the number of lower and upper off-diagonals % respectively. If they are omitted, a full matrix is produced. % If only KL is present, KU defaults to KL. % % Special case: KAPPA < 0 % A is a random full symmetric positive definite matrix with % COND(A) = -KAPPA and eigenvalues distributed according to % MODE. KL and KU, if present, are ignored. % % A = GALLERY('RANDSVD', N, KAPPA, MODE, KL, KU, METHOD) specifies % how the computations are carried out. % METHOD = 0 is the default, while METHOD = 1 uses an alternative % method that is much faster for large dimensions, even though it uses % more flops. % Acknowledgement: % This routine is similar to the more comprehensive Fortran routine % xLATMS in the following reference: % % Reference: % J. W. Demmel and A. McKenney, A test matrix generation suite, % LAPACK Working Note #9, Courant Institute of Mathematical % Sciences, New York, 1989. % % Nicholas J. Higham % Copyright 1984-2005 The MathWorks, Inc. if isempty(kappa), kappa = sqrt(1/eps(classname)); end if isempty(mode), mode = 3; end if isempty(kl), kl = n-1; end % Full matrix. if isempty(ku), ku = kl; end % Same upper and lower bandwidths. if isempty(method) method = 0; end if abs(kappa) < 1 error(message('MATLAB:randsvd:KappaLTOne')) end posdef = 0; if kappa < 0, posdef = 1; kappa = -kappa; end % Special case. p = min(n); m = n(1); % Parameter n specifies dimension: m-by-n. n = n(length(n)); if p == 1 % Handle case where A is a vector. A = cast(randn(m, n),classname); A = A/norm(A); return end % Set up vector sigma of singular values. switch abs(mode) case 1 sigma = ones(p,1)./kappa; sigma(1) = 1; case 2 sigma = ones(p,1); sigma(p) = 1/kappa; case 3 factor = kappa^(-1/(p-1)); sigma = factor.^(0:p-1); case 4 sigma = ones(p,1) - (0:p-1)'/(p-1)*(1-1/kappa); case 5 % In this case cond(A) <= kappa. sigma = exp( -rand(p,1)*log(kappa) ); otherwise error(message('MATLAB:randsvd:invalidMode')); end % Convert to diagonal matrix of singular values. if mode < 0 sigma = sigma(p:-1:1); end sigma = diag(cast(sigma,classname)); if posdef % Handle special case. Q = qmult(p,method,classname); A = Q'*sigma*Q; A = (A + A')/2; % Ensure matrix is symmetric. return end if m ~= n sigma(m, n) = 0; % Expand to m-by-n diagonal matrix. end if kl == 0 & ku == 0 % Diagonal matrix requested - nothing more to do. A = sigma; return end % A = U*sigma*V, where U, V are random orthogonal matrices from the % Haar distribution. A = qmult(sigma',method,classname); A = qmult(A',method,classname); if kl < n-1 | ku < n-1 % Bandwidth reduction. A = bandred(A, kl, ku); end