等效源法(ESM,也称波叠加法)Matlab序分享

等效源法(ESM,也称波叠加法)Matlab程序分享

等效源法简介:

所谓等效源法(Equivalent Source Method),属于近场声全息(Near-field Acoustic Holography)算法的一种,类似声辐射模态(Acoustic Radiation Modes)法、快速傅里叶变换法(Fast Fourier Transform),边界元法(Boundary Element Method)等。可用于声场还原,噪声源识别定位,在振动与噪声控制、汽车、船舶、航空等领域等工程领域都有广泛应用等等。

基本理论代码部分

这部分主要用两种声源作为案例进行分析:单极子声源和简支板声源

ESM-主程序

tic
clear all
global k f
f_vec = 1000;%分析频率
% f_vec = 100:100:3000;
for nn = 1:length(f_vec)
    f = f_vec(nn)% 激振频率
    c = 343;
    w = 2*pi*f;
    k = w/c;
    rho = 1.21;
    F = 1;% 激振力
    Lx = 0.5;
    Ly = 0.5;
    xy0 = [Lx/2,Ly/2];% 激振点位置
    h = 0.001;%板厚度
    z0 = 0;% 板子在z轴上的位置
    PlateSize = [Lx,Ly];% 板子的尺寸
    Ne = [121,121];% x轴、y轴方向上的板子划分成的单元格数量
    %% 测量面
    dxyh = 0.025;
    dxyr = 0.025;
    dxys = 0.025;
    [XH,YH,ZH] = XYz_function(dxyh,0,Lx,0,Lx,0.1);
    %XYz_function()是自定义的坐标位置网格函数,详见:函数一
    [XR,YR,ZR] = XYz_function(dxyr,0,Lx,0,Lx,0.05);
    [XS,YS,ZS] = XYz_function(dxys,0,Lx,0,Lx,-0.01);
    Rs = [XS,YS,ZS];
    Rr = [XR,YR,ZR];
    Rh = [XH,YH,ZH];
    %% 单极子(四个)
    %     rs11 = [-0.06 0 0];rs12 = [0.06 0 0];
    %     [Ph11,~] = ESM_point_source(Rh,rs11);
    %ESM_point_source()单极子声源,详见:函数二
    %     [Ph12,~]= ESM_point_source(Rh,rs12);
    %     [Pth11,~]= ESM_point_source(Rr,rs11);
    %     [Pth12,~]= ESM_point_source(Rr,rs12);
    %     Prth = Pth11+Pth12;
    %     PH = Ph11+Ph12;
    %% 简支板
    [PH,~] = SimplySupportedPlate(f,F,xy0,PlateSize,h,Ne,Rh,z0);
    %ESM_point_source()简支板声源,详见:函数三
    [Prth,~] = SimplySupportedPlate(f,F,xy0,PlateSize,h,Ne,Rr,z0);
    PH = awgn(PH,30,'measured');%添加高斯白噪声
    %% 格林函数(传递函数)
    Gpsh = CreatTM_p(Rh,Rs);
    %CreatTM_p()格林函数/传递函数,详见:函数四
    Gpsr = CreatTM_p(Rr,Rs);
    [u,s,v] = csvd(Gpsh);
    %csvd()奇异值分解(在这里处理对象为复数对,因此是csvd,而非svd)
    lambda = gcv(u,s,PH);
    %lambda = l_curve(u,s,PH);%L-曲线法
    %gcv()广义交叉验证,与L-曲线法功能相同,仿真与实验各有所长,详见:函数五
    Qreg = tikhonov(u,s,v,PH,lambda);
    %tikhonov()基霍诺夫正则化,稳定求解过程,解决方程求逆时噪声放大问题,详见:函数六
    %     Qreg = Gpsh\PH;
    Pr = Gpsr*Qreg;
    %% 误差计算
    Error_p(nn) = norm(abs(Pr)-abs(reshape(Prth,[],1)))...
        /norm(abs(reshape(Prth,[],1)))*100
end
    %% 误差绘图
figure(1)
plot(f_vec,Error_p,'ko-');
xlabel(' 频率(Hz)','Fontname','宋体','Fontsize',14);
ylabel('误差(%)','Fontname','宋体','Fontsize',14);
title('声压值误差曲线','Fontname','宋体','Fontsize',14);
box off;
%% 全息面(测量面)、重建面、重建面理论值声压值画图
figure(2)
subplot 131
contourf(abs(reshape(Prth,Lx/dxyh+1,Ly/dxyh+1)));
title('(a)理论值')
xlabel('x轴(测点数)');ylabel('y轴(测点数)');
hco = colorbar ;t = get(hco,'YTickLabel');t = strcat(t,'Pa');set(hco,'YTickLabel',t);
subplot 132
contourf(abs(reshape(PH,Lx/dxyr+1,Ly/dxyr+1)));
title('(b)测量值')
xlabel('x轴(测点数)');ylabel('y轴(测点数)');
hco = colorbar ;t = get(hco,'YTickLabel');t = strcat(t,'Pa');set(hco,'YTickLabel',t);
subplot 133
contourf(abs(reshape(Pr,Lx/dxyh+1,Ly/dxyh+1)));
title('(c)重建值')
xlabel('x轴(测点数)');ylabel('y轴(测点数)');
hco = colorbar ;t = get(hco,'YTickLabel');t = strcat(t,'Pa');set(hco,'YTickLabel',t);

函数一:绘制三维坐标系网格

说明:这里仅仅是笛卡尔坐标系下的三维坐标系,仅仅是研究的平面声全息,当然也可以把分析面设计成球体面、圆柱体面、锥形面等等,理论上,等效源法适用于任意形状面的声源所产生的声场。

function [X,Y,z]=XYz_function(dx,A,B,C,D,E)
x = A:dx:B;
y = C:dx:D;
[X,Y] = meshgrid(x,y); 
X=reshape(X,[],1);
Y=reshape(Y,[],1);
z=reshape(E*ones(length(x),length(y)),[],1);

函数二:单极子声源声压值振速值

说明:在这部分,要说明单极子声源是理想的点声源,与脉动求声源的区别在于,单极子声源没有半径。

 %%模拟单极子源所产生的声场(声压值和空气粒子振速值)
    function [P,V] = ESM_point_source(Rm,rs)
    %%基本参数
    global f
    c = 343;
    rho = 1.21;
    w = 2*pi*f;
    k = w/c;
    Q0 = 1*10^(-5);%仿真中单极子声源的强度系数
    xs = rs(1);
    ys = rs(2);
    zs = rs(3);
    Xh = Rm(:,1);
    Yh = Rm(:,2);
    Zh = Rm(:,3);
    r1=sqrt((Xh-xs).^2+(Yh-ys).^2+(Zh-zs).^2);
    P = (-1i*rho*w*Q0)./(4*pi*r1).*exp(1i*k*r1);%点声源声压公式频域
    cosz = (Zh-zs)./r1;
    V1 = (-1i*k*Q0)./(4*pi*r1);
    V2 = 1-1./(1i*k*r1);
    V3 = V1.*V2;
    V4 = V3.*exp(1i*k*r1);
    V = V4.*cosz; %点声源声压公式频域
    % surf(abs(P));

函数三:简支板声源声压值、振速值

说明:简支板声源函数。包括声源的长宽厚尺寸、仿真种板子的划分单元数,板子密度(材料)、激励(激振器激励)位置、等都可以自己进行定义

function [p,v] = SimplySupportedPlate(f,F,xy0,PlateSize,h,Ne,Rm,z0)
%%%%% Simply Suported Aluminum Plate, point excited , origin is located at
%%%%% the left lower corner of plate.
%% excitation force
% f -- frequency of excitation force 激振频率
% F -- excitation force 激振力
% xy0 = (x,y,0) -- position of the excitation force 激振点位置
% h -- thickness of the plate 板厚度
% z0 -- 板子在z轴上的位置
% PlateSize = [size_x,size_y] -- 板子的尺寸
% Ne = [N_x,N_y] -- x轴、y轴方向上的板子划分成的单元格数量
% Rm = [XH;YH;ZH] -- 全息面位置向量
%% basic acoustic parameters
c = 343;
rho = 1.21;
w = 2*pi*f;
k = w/c;
%% basic parameters of the plate (Aluminum) 铝
% E = 7.1*10^10; %%%% Young's modulus 杨氏模量
% nju = 0.33; %%%% Possion's ratio 泊松比
% rhos = 2.7*10^3;  %%%% density of the plate 板子密度
% D = E*h^3/(12*(1-nju^2)); %%% flexural rigidity of the plate 板的抗弯刚度
% alpha = (D/rhos/h)^(1/4);
%% basic parameters of the plate (Steel) 钢
E = 2.1*10^11; %%%% Young's modulus
nju = 0.28; %%%% Possion's ratio
rhos = 7.85*10^3;  %%%% density of the plate
D = E*h^3/(12*(1-nju^2)); %%% flexural rigidity of the plate
alpha = (D/rhos/h)^(1/4);
%% 
Lx = PlateSize(1);% x方向长度
Ly = PlateSize(2);% y方向长度
Nx = Ne(1);% x方向点数
Ny = Ne(2);% y方向点数
XH = Rm(:,1);% 测点x轴位置
YH = Rm(:,2);% 测点y轴位置
ZH = Rm(:,3);% 测点z轴位置
M = length(XH);
%% details of the measuring plane
if min(ZH-z0) > 0  %%% Rayleigh's Intergral
    dx = Lx/(Nx-1);
    dy = Ly/(Ny-1);
    x = 0:dx:Lx;
    y = 0:dy:Ly;
    [X,Y] = meshgrid(x,y);
    X = reshape(X,[],1);
    Y = reshape(Y,[],1);
    Wmn = zeros(length(x)*length(y),1);
    for m = 1:20
        for n = 1:20
            PSImn0 = 2/sqrt(Lx*Ly)*sin(m*pi*xy0(1)/Lx).*sin(n*pi*xy0(2)/Ly);
            PSImn = 2/sqrt(Lx*Ly)*sin(m*pi*X/Lx).*sin(n*pi*Y/Ly);
            wmn = alpha^2*((m*pi/Lx)^2+(n*pi/Ly)^2);
            Wmn = Wmn+(-F/(rhos*h))*PSImn0*PSImn/(w^2-wmn^2);
        end
    end
    p = zeros(M,1);
    v = zeros(M,1);
    for ii = 1:M
        r = sqrt((XH(ii)-X).^2+(YH(ii)-Y).^2+(ZH(ii)-z0)^2);
        p(ii) = -w^2*rho/(2*pi)*sum(Wmn.*exp(1i*k*r)./r*dx*dy);
        v(ii) = -1i*w/(2*pi)*sum(Wmn.*(1i*k*r-1)./r.^2.*exp(1i*k*r)*(ZH(ii)-z0)./r*dx*dy);
    end
else   %%% on the surface of the plate, only velocy is derived from displacement
    Wmn = zeros(M,1);
    for m = 1:20
        for n = 1:20
            PSImn0 = 2/sqrt(Lx*Ly)*sin(m*pi*xy0(1)/Lx).*sin(n*pi*xy0(2)/Ly);
            PSImn = 2/sqrt(Lx*Ly)*sin(m*pi*XH/Lx).*sin(n*pi*YH/Ly);
            wmn = alpha^2*((m*pi/Lx)^2+(n*pi/Ly)^2);
            Wmn = Wmn+(-F/(rhos*h))*PSImn0*PSImn/(w^2-wmn^2);
        end
    end
    v = -1i*w*Wmn;
    p = NaN;
end

% p = reshape(p,length(xh),length(yh));
% v = reshape(v,length(xh),length(yh));
%  pcolor(xh,yh,abs(p));;shading interp;
% figure(2); pcolor(xh,yh,abs(v));;shading interp;

函数四:传递函数

说明:这部分是针对传递函数这里也称格林函数,进行代码实现部分,没啥好说的,应该不难理解

function Gp = CreatTM_p(Rh,Rs)
% Rh为全息面位置向量,共三列,每行 【x,y,z】
global k 
Xh = Rh(:,1);
Yh = Rh(:,2);
Zh = Rh(:,3);
Xs = Rs(:,1);
Ys = Rs(:,2);
Zs = Rs(:,3);
[XS,XH] = meshgrid(Xs,Xh);
[YS,YH] = meshgrid(Ys,Yh);
[ZS,ZH] = meshgrid(Zs,Zh);
R_hs = sqrt((XH-XS).^2+(YH-YS).^2+(ZH-ZS).^2);
Gp = exp(1i*k*R_hs)./(4*pi*R_hs);

函数五:正则化参数选取

说明:GCV广义交叉验证法,功能:在对方程进行正则化求解过程中,选取正则化参数的一种方法,与L-曲线法类似,但是GCV方法有时候更适用于实验室实验的计算,而L-曲线法在数值仿真中的计算效果更好。关于为什么要使用正则化这个问题,简单地说是为了抑制噪声,详细的请自行参阅相关文献,资源很多,不再累述。
另外:这段函数还有另外一个小函数模块,会在这段代码后面补上。

function [reg_min,G,reg_param] = gcv(U,s,b,method) 
%GCV Plot the GCV function and find its minimum. 
% 
% [reg_min,G,reg_param] = gcv(U,s,b,method) 
% [reg_min,G,reg_param] = gcv(U,sm,b,method)  ,  sm = [sigma,mu] 
% 
% Plots the GCV-function 
%          || A*x - b ||^2 
%    G = ------------------- 
%        (trace(I - A*A_I)^2 
% as a function of the regularization parameter reg_param. 
% Here, A_I is a matrix which produces the regularized solution. 
% 
% The following methods are allowed: 
%    method = 'Tikh' : Tikhonov regularization   (solid line ) 
%    method = 'tsvd' : truncated SVD or GSVD     (o markers  ) 
%    method = 'dsvd' : damped SVD or GSVD        (dotted line) 
% If method is not specified, 'Tikh' is default. 
% 
% If any output arguments are specified, then the minimum of G is 
% identified and the corresponding reg. parameter reg_min is returned. 
 
% Per Christian Hansen, IMM, Dec. 16, 2003. 
 
% Reference: G. Wahba, "Spline Models for Observational Data", 
% SIAM, 1990. 
 
% Set defaults. 
if (nargin==3), method='Tikh'; end  % Default method. 
npoints = 200;                      % Number of points on the curve. 
smin_ratio = 16*eps;                % Smallest regularization parameter. 
 
% Initialization. 
[m,n] = size(U); [p,ps] = size(s); 
beta = U'*b; beta2 = norm(b)^2 - norm(beta)^2; 
if (ps==2) 
  s = s(p:-1:1,1)./s(p:-1:1,2); beta = beta(p:-1:1); 
end 
if (nargout > 0), find_min = 1; else find_min = 0; end 
 
if (strncmp(method,'Tikh',4) | strncmp(method,'tikh',4)) 
    
  % Vector of regularization parameters. 
  reg_param = zeros(npoints,1); G = reg_param; s2 = s.^2; 
  reg_param(npoints) = max([s(p),s(1)*smin_ratio]); 
  ratio = (s(1)/reg_param(npoints))^(1/(npoints-1)); 
  for i=npoints-1:-1:1, reg_param(i) = ratio*reg_param(i+1); end 
   
  % Intrinsic residual. 
  delta0 = 0; 
  if (m > n & beta2 > 0), delta0 = beta2; end 
   
  % Vector of GCV-function values. 
  for i=1:npoints 
    G(i) = gcvfun(reg_param(i),s2,beta(1:p),delta0,m-n); 
  end  
   
  % Plot GCV function. 
  loglog(reg_param,G,'-'), xlabel('\lambda'), ylabel('G(\lambda)') 
  title('GCV function') 
   
  % Find minimum, if requested. 
  if (find_min) 
    [minG,minGi] = min(G); % Initial guess. 
    reg_min = fminbnd('gcvfun',... 
      reg_param(min(minGi+1,npoints)),reg_param(max(minGi-1,1)),... 
      optimset('Display','off'),s2,beta(1:p),delta0,m-n); % Minimizer. 
    minG = gcvfun(reg_min,s2,beta(1:p),delta0,m-n); % Minimum of GCV function. 
    ax = axis; 
    HoldState = ishold; hold on; 
    loglog(reg_min,minG,'*r',[reg_min,reg_min],[minG/1000,minG],':r') 
    title(['GCV function, minimum at \lambda = ',num2str(reg_min)]) 
    axis(ax) 
    if (~HoldState), hold off; end 
  end 
 
elseif (strncmp(method,'tsvd',4) | strncmp(method,'tgsv',4)) 
    
  % Vector of GCV-function values. 
  rho2(p-1) = abs(beta(p))^2; 
  if (m > n & beta2 > 0), rho2(p-1) = rho2(p-1) + beta2; end 
  for k=p-2:-1:1, rho2(k) = rho2(k+1) + abs(beta(k+1))^2; end 
  for k=1:p-1 
    G(k) = rho2(k)/(m - k + (n - p))^2; 
  end 
  reg_param = [1:p-1]'; 
   
  % Plot GCV function. 
  semilogy(reg_param,G,'o'), xlabel('k'), ylabel('G(k)') 
  title('GCV function') 
   
  % Find minimum, if requested. 
  if (find_min) 
    [minG,reg_min] = min(G); 
    ax = axis; 
    HoldState = ishold; hold on; 
    semilogy(reg_min,minG,'*r',[reg_min,reg_min],[minG/1000,minG],':r') 
    title(['GCV function, minimum at k = ',num2str(reg_min)]) 
    axis(ax); 
    if (~HoldState), hold off; end 
  end 
 
elseif (strncmp(method,'dsvd',4) | strncmp(method,'dgsv',4)) 
 
  % Vector of regularization parameters. 
  reg_param = zeros(npoints,1); G = reg_param; 
  reg_param(npoints) = max([s(p),s(1)*smin_ratio]); 
  ratio = (s(1)/reg_param(npoints))^(1/(npoints-1)); 
  for i=npoints-1:-1:1, reg_param(i) = ratio*reg_param(i+1); end 
   
  % Intrinsic residual. 
  delta0 = 0; 
  if (m > n & beta2 > 0), delta0 = beta2; end 
   
  % Vector of GCV-function values. 
  for i=1:npoints 
    G(i) = gcvfun(reg_param(i),s,beta(1:p),delta0,m-n,1); 
  end 
  
  % Plot GCV function. 
  loglog(reg_param,G,':'), xlabel('\lambda'), ylabel('G(\lambda)') 
  title('GCV function') 
   
  % Find minimum, if requested. 
  if (find_min) 
    [minG,minGi] = min(G); % Initial guess. 
    reg_min = fminbnd('gcvfun',... 
      reg_param(min(minGi+1,npoints)),reg_param(max(minGi-1,1)),... 
      optimset('Display','off'),s,beta(1:p),delta0,m-n,1); % Minimizer. 
    minG = gcvfun(reg_min,s,beta(1:p),delta0,m-n,1); % Minimum of GCV function. 
    ax = axis; 
    HoldState = ishold; hold on; 
    loglog(reg_min,minG,'*r',[reg_min,reg_min],[minG/1000,minG],':r') 
    title(['GCV function, minimum at \lambda = ',num2str(reg_min)]) 
    axis(ax) 
    if (~HoldState), hold off; end 
  end 
 
elseif (strncmp(method,'mtsv',4) | strncmp(method,'ttls',4)) 
 
  error('The MTSVD and TTLS methods are not supported') 
 
else, error('Illegal method'), end

gcvfun

说明:函数五:gcv的内置函数

function G = gcvfun(lambda,s2,beta,delta0,mn,dsvd)
% Auxiliary routine for gcv.  PCH, IMM, 12/29/97.
if (nargin==5)
   f = (lambda^2)./(s2 + lambda^2);
else
   f = lambda./(s2 + lambda);
end
G = (norm(f.*beta)^2 + delta0)/(mn + sum(f))^2;

L-曲线法:选取正则化参数

说明:在正则化参数选取过程中的另外一总算法,这些,我只是拿过来用,里面的很多东西我也不懂,其程序以及内置函数如下:

function [reg_corner,rho,eta,reg_param] = l_curve(U,sm,b,method,L,V) 
%L_CURVE Plot the L-curve and find its "corner". 
% 
% [reg_corner,rho,eta,reg_param] = 
%                  l_curve(U,s,b,method) 
%                  l_curve(U,sm,b,method)  ,  sm = [sigma,mu] 
%                  l_curve(U,s,b,method,L,V) 
% 
% Plots the L-shaped curve of eta, the solution norm || x || or 
% semi-norm || L x ||, as a function of rho, the residual norm 
% || A x - b ||, for the following methods: 
%    method = 'Tikh'  : Tikhonov regularization   (solid line ) 
%    method = 'tsvd'  : truncated SVD or GSVD     (o markers  ) 
%    method = 'dsvd'  : damped SVD or GSVD        (dotted line) 
%    method = 'mtsvd' : modified TSVD             (x markers  ) 
% The corresponding reg. parameters are returned in reg_param.  If no
% method is specified then 'Tikh' is default.  For other methods use plot_lc.
%
% Note that 'Tikh', 'tsvd' and 'dsvd' require either U and s (standard-
% form regularization) or U and sm (general-form regularization), while
% 'mtvsd' requires U and s as well as L and V.
% 
% If any output arguments are specified, then the corner of the L-curve 
% is identified and the corresponding reg. parameter reg_corner is 
% returned.  Use routine l_corner if an upper bound on eta is required. 
% 
% If the Spline Toolbox is not available and reg_corner is requested, 
% then the routine returns reg_corner = NaN for 'tsvd' and 'mtsvd'. 
 
% Reference: P. C. Hansen & D. P. O'Leary, "The use of the L-curve in 
% the regularization of discrete ill-posed problems",  SIAM J. Sci. 
% Comput. 14 (1993), pp. 1487-1503. 
 
% Per Christian Hansen, IMM, Sep. 13, 2001.
 
% Set defaults. 
if (nargin==3), method='Tikh'; end  % Tikhonov reg. is default. 
npoints = 200;  % Number of points on the L-curve for Tikh and dsvd. 
smin_ratio = 16*eps;  % Smallest regularization parameter. 
 
% Initialization. 
[m,n] = size(U); [p,ps] = size(sm); 
if (nargout > 0), locate = 1; else locate = 0; end 
beta = U'*b; beta2 = norm(b)^2 - norm(beta)^2; 
if (ps==1) 
  s = sm; beta = beta(1:p); 
else 
  s = sm(p:-1:1,1)./sm(p:-1:1,2); beta = beta(p:-1:1); 
end 
xi = beta(1:p)./s; 
 
if (strncmp(method,'Tikh',4) | strncmp(method,'tikh',4)) 
 
  eta = zeros(npoints,1); rho = eta; reg_param = eta; s2 = s.^2; 
  reg_param(npoints) = max([s(p),s(1)*smin_ratio]); 
  ratio = (s(1)/reg_param(npoints))^(1/(npoints-1)); 
  ratio = (s(1)/reg_param(npoints))^(1/(npoints-1)); 
  for i=npoints-1:-1:1, reg_param(i) = ratio*reg_param(i+1); end 
  for i=1:npoints 
    f = s2./(s2 + reg_param(i)^2); 
    eta(i) = norm(f.*xi); 
    rho(i) = norm((1-f).*beta(1:p)); 
  end 
  if (m > n & beta2 > 0), rho = sqrt(rho.^2 + beta2); end 
  marker = '-'; pos = .8; txt = 'Tikh.'; 
 
elseif (strncmp(method,'tsvd',4) | strncmp(method,'tgsv',4)) 
 
  eta = zeros(p,1); rho = eta; 
  eta(1) = abs(xi(1))^2; 
  for k=2:p, eta(k) = eta(k-1) + abs(xi(k))^2; end 
  eta = sqrt(eta); 
  if (m > n) 
    if (beta2 > 0), rho(p) = beta2; else rho(p) = eps^2; end 
  else 
    rho(p) = eps^2; 
  end 
  for k=p-1:-1:1, rho(k) = rho(k+1) + abs(beta(k+1))^2; end 
  rho = sqrt(rho); 
  reg_param = [1:p]'; marker = 'o'; pos = .75; 
  if (ps==1) 
    U = U(:,1:p); txt = 'TSVD'; 
  else 
    U = U(:,1:p); txt = 'TGSVD'; 
  end 
 
elseif (strncmp(method,'dsvd',4) | strncmp(method,'dgsv',4)) 
 
  eta = zeros(npoints,1); rho = eta; reg_param = eta; 
  reg_param(npoints) = max([s(p),s(1)*smin_ratio]); 
  ratio = (s(1)/reg_param(npoints))^(1/(npoints-1)); 
  for i=npoints-1:-1:1, reg_param(i) = ratio*reg_param(i+1); end 
  for i=1:npoints 
    f = s./(s + reg_param(i)); 
    eta(i) = norm(f.*xi); 
    rho(i) = norm((1-f).*beta(1:p)); 
  end 
  if (m > n & beta2 > 0), rho = sqrt(rho.^2 + beta2); end 
  marker = ':'; pos = .85; 
  if (ps==1), txt = 'DSVD'; else txt = 'DGSVD'; end 
 
elseif (strncmp(method,'mtsv',4)) 
 
  if (nargin~=6) 
    error('The matrices L and V must also be specified') 
  end 
  [p,n] = size(L); rho = zeros(p,1); eta = rho; 
  [Q,R] = qr(L*V(:,n:-1:n-p),0); 
  for i=1:p 
    k = n-p+i; 
    Lxk = L*V(:,1:k)*xi(1:k); 
    zk = R(1:n-k,1:n-k)\(Q(:,1:n-k)'*Lxk); zk = zk(n-k:-1:1); 
    eta(i) = norm(Q(:,n-k+1:p)'*Lxk); 
    if (i < p) 
      rho(i) = norm(beta(k+1:n) + s(k+1:n).*zk); 
    else 
      rho(i) = eps; 
    end 
  end 
  if (m > n & beta2 > 0), rho = sqrt(rho.^2 + beta2); end 
  reg_param = [n-p+1:n]'; txt = 'MTSVD'; 
  U = U(:,reg_param); sm = sm(reg_param); 
  marker = 'x'; pos = .7; ps = 2;  % General form regularization. 
  
else, error('Illegal method'), end 
 
% Locate the "corner" of the L-curve, if required.  If the Spline 
% Toolbox is not available, return NaN for reg_corner. 
if (locate) 
  SkipCorner = ( (strncmp(method,'tsvd',4) | strncmp(method,'tgsv',4) | ... 
                  strncmp(method,'mtsv',4)) & exist('splines')~=7 ); 
  if (SkipCorner) 
    reg_corner = NaN; 
  else 
    [reg_corner,rho_c,eta_c] = l_corner(rho,eta,reg_param,U,sm,b,method); 
  end 
end 
 
% Make plot. 
plot_lc(rho,eta,marker,ps,reg_param); 
if (locate & ~SkipCorner) 
  ax = axis; 
  HoldState = ishold; hold on; 
  loglog([min(rho)/100,rho_c],[eta_c,eta_c],':r',... 
         [rho_c,rho_c],[min(eta)/100,eta_c],':r') 
  title(['L-curve, ',txt,' corner at ',num2str(reg_corner)]); 
  axis(ax) 
  if (~HoldState), hold off; end 
end 

l_corner

function [reg_c,rho_c,eta_c] = l_corner(rho,eta,reg_param,U,s,b,method,M) 
%L_CORNER Locate the "corner" of the L-curve. 
% 
% [reg_c,rho_c,eta_c] = 
%        l_corner(rho,eta,reg_param) 
%        l_corner(rho,eta,reg_param,U,s,b,method,M) 
%        l_corner(rho,eta,reg_param,U,sm,b,method,M) ,  sm = [sigma,mu] 
% 
% Locates the "corner" of the L-curve in log-log scale. 
% 
% It is assumed that corresponding values of || A x - b ||, || L x ||, 
% and the regularization parameter are stored in the arrays rho, eta, 
% and reg_param, respectively (such as the output from routine l_curve). 
% 
% If nargin = 3, then no particular method is assumed, and if 
% nargin = 2 then it is issumed that reg_param = 1:length(rho). 
% 
% If nargin >= 6, then the following methods are allowed: 
%    method = 'Tikh'  : Tikhonov regularization 
%    method = 'tsvd'  : truncated SVD or GSVD 
%    method = 'dsvd'  : damped SVD or GSVD 
%    method = 'mtsvd' : modified TSVD, 
% and if no method is specified, 'Tikh' is default.  If the Spline Toolbox 
% is not available, then only 'Tikh' and 'dsvd' can be used. 
% 
% An eighth argument M specifies an upper bound for eta, below which 
% the corner should be found. 
 
% The following functions from the Spline Toolbox are needed if 
% method differs from 'Tikh' or 'dsvd': 
% fnder, ppbrk, ppmak, ppual, sp2pp, sorted, spbrk, spmak, sprpp. 
 
% Per Christian Hansen, IMM, Dec. 12, 2002. 
 
% Set default regularization method. 
if (nargin <= 3) 
  method = 'none'; 
  if (nargin==2), reg_param = [1:length(rho)]'; end 
else 
  if (nargin==6), method = 'Tikh'; end 
end 
 
% Set threshold for skipping very small singular values in the 
% analysis of a discrete L-curve. 
s_thr = eps;  % Neglect singular values less than s_thr. 
 
% Set default parameters for treatment of discrete L-curve. 
deg   = 2;  % Degree of local smooting polynomial. 
q     = 2;  % Half-width of local smoothing interval. orig = 2
order = 4;  % Order of fitting 2-D spline curve. 
 
% Initialization. 
if (length(rho) < order) 
  error('Too few data points for L-curve analysis') 
end 
if (nargin > 3) 
  [p,ps] = size(s); [m,n] = size(U);
  beta = U'*b;
  if (m>n), b0 = b - U*beta; end
  if (ps==2)
    s = s(p:-1:1,1)./s(p:-1:1,2);
    U = U(:,p:-1:1);
    beta = beta(p:-1:1);
  end
  xi = beta./s; 
end 
 
% Restrict the analysis of the L-curve according to M (if specified). 
if (nargin==8) 
  index = find(eta < M); 
  rho = rho(index); eta = eta(index); reg_param = reg_param(index); 
end 
 
if (strncmp(method,'Tikh',4) | strncmp(method,'tikh',4)) 
 
  % The L-curve is differentiable; computation of curvature in 
  % log-log scale is easy. 
   
  % Compute g = - curvature of L-curve. 
  g = lcfun(reg_param,s,beta,xi); 
   
  % Locate the corner.  If the curvature is negative everywhere, 
  % then define the leftmost point of the L-curve as the corner. 
  [gmin,gi] = min(g);
  reg_c = fminbnd('lcfun',... 
    reg_param(min(gi+1,length(g))),reg_param(max(gi-1,1)),... 
    optimset('Display','off'),s,beta,xi); % Minimizer. 
  kappa_max = - lcfun(reg_c,s,beta,xi); % Maximum curvature. 
 
  if (kappa_max < 0) 
    lr = length(rho); 
    reg_c = reg_param(lr); rho_c = rho(lr); eta_c = eta(lr); 
  else 
    f = (s.^2)./(s.^2 + reg_c^2); 
    eta_c = norm(f.*xi); 
    rho_c = norm((1-f).*beta); 
    if (m>n), rho_c = sqrt(rho_c^2 + norm(b0)^2); end 
  end
 
elseif (strncmp(method,'tsvd',4) | strncmp(method,'tgsv',4) | ... 
        strncmp(method,'mtsv',4) | strncmp(method,'none',4)) 

  % The L-curve is discrete and may include unwanted fine-grained 
  % corners.  Use local smoothing, followed by fitting a 2-D spline 
  % curve to the smoothed discrete L-curve. 
 
  % Check if the Spline Toolbox exists, otherwise return. 
  if (exist('splines')~=7) 
    error('The Spline Toolbox in not available so l_corner cannot be used') 
  end 
 
  % For TSVD, TGSVD, and MTSVD, restrict the analysis of the L-curve 
  % according to s_thr. 
  if (nargin > 3) 
    if (nargin==8)       % In case the bound M is in action. 
      s    = s(index,:); 
      beta = beta(index); 
      xi   = xi(index); 
    end 
    index = find(s > s_thr); 
    rho = rho(index); eta = eta(index); reg_param = reg_param(index); 
    s = s(index); beta = beta(index); xi = xi(index); 
  end 
 
  % Convert to logarithms. 
  lr = length(rho); 
  lrho = log(rho); leta = log(eta); slrho = lrho; sleta = leta; 
 
  % For all interior points k = q+1:length(rho)-q-1 on the discrete 
  % L-curve, perform local smoothing with a polynomial of degree deg 
  % to the points k-q:k+q. 
  v = [-q:q]'; A = zeros(2*q+1,deg+1); A(:,1) = ones(length(v),1); 
  for j = 2:deg+1, A(:,j) = A(:,j-1).*v; end 
  for k = q+1:lr-q-1 
    cr = A\lrho(k+v); slrho(k) = cr(1); 
    ce = A\leta(k+v); sleta(k) = ce(1); 
  end 
 
  % Fit a 2-D spline curve to the smoothed discrete L-curve. 
  sp = spmak([1:lr+order],[slrho';sleta']); 
  pp = ppbrk(sp2pp(sp),[4,lr+1]); 
 
  % Extract abscissa and ordinate splines and differentiate them. 
  % Compute as many function values as default in spleval. 
  P     = spleval(pp);  dpp   = fnder(pp); 
  D     = spleval(dpp); ddpp  = fnder(pp,2); 
  DD    = spleval(ddpp); 
  ppx   = P(1,:);       ppy   = P(2,:); 
  dppx  = D(1,:);       dppy  = D(2,:); 
  ddppx = DD(1,:);      ddppy = DD(2,:); 
 
  % Compute the corner of the discretized .spline curve via max. curvature. 
  % No need to refine this corner, since the final regularization 
  % parameter is discrete anyway. 
  % Define curvature = 0 where both dppx and dppy are zero. 
  k1    = dppx.*ddppy - ddppx.*dppy; 
  k2    = (dppx.^2 + dppy.^2).^(1.5); 
  I_nz  = find(k2 ~= 0); 
  kappa = zeros(1,length(dppx)); 
  kappa(I_nz) = -k1(I_nz)./k2(I_nz); 
  [kmax,ikmax] = max(kappa); 
  x_corner = ppx(ikmax); y_corner = ppy(ikmax); 
 
  % Locate the point on the discrete L-curve which is closest to the 
  % corner of the spline curve.  Prefer a point below and to the 
  % left of the corner.  If the curvature is negative everywhere, 
  % then define the leftmost point of the L-curve as the corner. 
  if (kmax < 0) 
    reg_c = reg_param(lr); rho_c = rho(lr); eta_c = eta(lr); 
  else 
    index = find(lrho < x_corner & leta < y_corner); 
    if (length(index) > 0) 
      [dummy,rpi] = min((lrho(index)-x_corner).^2 + (leta(index)-y_corner).^2); 
      rpi = index(rpi); 
    else 
      [dummy,rpi] = min((lrho-x_corner).^2 + (leta-y_corner).^2); 
    end 
    reg_c = reg_param(rpi); rho_c = rho(rpi); eta_c = eta(rpi); 
  end 
 
elseif (strncmp(method,'dsvd',4) | strncmp(method,'dgsv',4)) 
 
  % The L-curve is differentiable; computation of curvature in 
  % log-log scale is easy. 
 
  % Compute g = - curvature of L-curve. 
  g = lcfun(reg_param,s,beta,xi,1); 
 
  % Locate the corner.  If the curvature is negative everywhere, 
  % then define the leftmost point of the L-curve as the corner. 
  [gmin,gi] = min(g); 
  reg_c = fminbnd('lcfun',... 
    reg_param(min(gi+1,length(g))),reg_param(max(gi-1,1)),... 
    optimset('Display','off'),s,beta,xi,1); % Minimizer. 
  kappa_max = - lcfun(reg_c,s,beta,xi,1); % Maximum curvature. 
 
  if (kappa_max < 0) 
    lr = length(rho); 
    reg_c = reg_param(lr); rho_c = rho(lr); eta_c = eta(lr); 
  else 
    f = s./(s + reg_c); 
    eta_c = norm(f.*xi); 
    rho_c = norm((1-f).*beta); 
    if (m>n), rho_c = sqrt(rho_c^2 + norm(b0)^2); end 
  end 
 
else, error('Illegal method'), end 

lsolve

function x = lsolve(L,y,W,T) 
%LSOLVE Utility routine for "preconditioned" iterative methods. 
% x = lsolve(L,y,W,T) 
% Computes the vector 
%    x = L_p*y 
% where L_p is the A-weighted generalized inverse of L. 
% Here, L is a p-by-n matrix, W holds a basis for the null space of L, 
% and T is a utility matrix which should be computed by routine pinit. 
% Alternatively, L is square, and W and T are not needed. 
% Notice that x and y may be matrices, in which case 
%    x(:,i) = L_p*y(:,i) . 
% Reference: P. C. Hansen, "Rank-Deficient and Discrete Ill-Posed Problems. 
% Numerical Aspects of Linear Inversion", SIAM, Philadelphia, 1997. 
% Per Christian Hansen, IMM, 07/29/97. 
% Initialization. 
[p,n] = size(L); nu = n-p; ly = size(y,2);    
% Special treatment of square L. 
if (nu==0), x = L\y; return; end   
% The general case. 
x = L(:,1:p)\y; 
x = [x;zeros(nu,ly)] - W*(T(:,1:p)*x); 

函数六:正则化稳定求解过曾

说明:基霍诺夫正则化

function [x_lambda,rho,eta] = tikhonov(U,s,V,b,lambda,x_0) 
%TIKHONOV Tikhonov regularization. 
% 
% [x_lambda,rho,eta] = tikhonov(U,s,V,b,lambda,x_0) 
% [x_lambda,rho,eta] = tikhonov(U,sm,X,b,lambda,x_0) ,  sm = [sigma,mu] 
% 
% Computes the Tikhonov regularized solution x_lambda.  If the SVD 
% is used, i.e. if U, s, and V are specified, then standard-form 
% regularization is applied: 
%    min { || A x - b ||^2 + lambda^2 || x - x_0 ||^2 } . 
% If, on the other hand, the GSVD is used, i.e. if U, sm, and X are 
% specified, then general-form regularization is applied: 
%    min { || A x - b ||^2 + lambda^2 || L (x - x_0) ||^2 } . 
% 
% If x_0 is not specified, then x_0 = 0 is used.
%
% Note that x_0 cannot be used if A is underdetermined and L ~= I.
% 
% If lambda is a vector, then x_lambda is a matrix such that 
%    x_lambda = [ x_lambda(1), x_lambda(2), ... ] . 
% 
% The solution norm(standard-form case) or seminorm (general-form
% case) and the residual norm are returned in eta and rho. 
 
% Per Christian Hansen, IMM, April 14, 2003. 
 
% Reference: A. N. Tikhonov & V. Y. Arsenin, "Solutions of 
% Ill-Posed Problems", Wiley, 1977. 
 
% Initialization. 
if (min(lambda)<0) 
  error('Illegal regularization parameter lambda') 
end 
m = size(U,1);
n = size(V,1);
[p,ps] = size(s); 
beta = U(:,1:p)'*b; 
zeta = s(:,1).*beta; 
ll = length(lambda); x_lambda = zeros(n,ll); 
rho = zeros(ll,1); eta = zeros(ll,1); 

% Treat each lambda separately. 
if (ps==1) 
    % The standard-form case.
  if (nargin==6), omega = V'*x_0; end 
  for i=1:ll 
    if (nargin==5) 
      x_lambda(:,i) = V(:,1:p)*(zeta./(s.^2 + lambda(i)^2)); 
      rho(i) = lambda(i)^2*norm(beta./(s.^2 + lambda(i)^2)); 
   else 
      x_lambda(:,i) = V(:,1:p)*... 
        ((zeta + lambda(i)^2*omega)./(s.^2 + lambda(i)^2)); 
      rho(i) = lambda(i)^2*norm((beta - s.*omega)./(s.^2 + lambda(i)^2)); 
    end 
    eta(i) = norm(x_lambda(:,i)); 
  end 
  if (nargout > 1 & size(U,1) > p) 
    rho = sqrt(rho.^2 + norm(b - U(:,1:n)*[beta;U(:,p+1:n)'*b])^2); 
  end
  
elseif (m>=n)
      
  % The overdetermined or square general-form case.
  gamma2 = (s(:,1)./s(:,2)).^2; 
  if (nargin==6), omega = V\x_0; omega = omega(1:p); end 
  if (p==n) 
    x0 = zeros(n,1); 
  else 
    x0 = V(:,p+1:n)*U(:,p+1:n)'*b;  
  end 
  for i=1:ll 
    if (nargin==5)
      xi = zeta./(s(:,1).^2 + lambda(i)^2*s(:,2).^2);
      x_lambda(:,i) = V(:,1:p)*xi + x0; 
      rho(i) = lambda(i)^2*norm(beta./(gamma2 + lambda(i)^2)); 
    else
      xi = (zeta + lambda(i)^2*(s(:,2).^2).*omega)./(s(:,1).^2 + lambda(i)^2*s(:,2).^2);
      x_lambda(:,i) = V(:,1:p)*xi + x0; 
      rho(i) = lambda(i)^2*norm((beta - s(:,1).*omega)./(gamma2 + lambda(i)^2)); 
    end 
    eta(i) = norm(s(:,2).*xi); 
  end
  if (nargout > 1 & size(U,1) > p) 
    rho = sqrt(rho.^2 + norm(b - U(:,1:n)*[beta;U(:,p+1:n)'*b])^2); 
  end
  
else
      
  % The underdetermined general-form case.
  gamma2 = (s(:,1)./s(:,2)).^2;
  if (nargin==6), error('x_0 not allowed'), end 
  if (p==m) 
    x0 = zeros(n,1); 
  else 
    x0 = V(:,p+1:m)*U(:,p+1:m)'*b;
  end 
  for i=1:ll
    xi = zeta./(s(:,1).^2 + lambda(i)^2*s(:,2).^2);
    x_lambda(:,i) = V(:,1:p)*xi + x0; 
    rho(i) = lambda(i)^2*norm(beta./(gamma2 + lambda(i)^2)); 
    eta(i) = norm(s(:,2).*xi); 
  end
end

声名

1.在学习的过程中,往往都是通过查阅论文进行研究,而我发现在这个领域的研究成果一般都是闭元的,很少有具体的实验案例,毕竟这个学科领域正处在理论研究阶段,大多数的研究案例都是通过数学公式将理论进行阐释,对于很多初学者来讲,往往最容易带来困惑的,往往都是一些细节。而在互联网上的一些贴吧、论坛、网站进行学术交流时,效率实在是慢,各大门户的网站各具特色,同时也带来信息共享渠道不兼容等问题,总之吧,我写这篇博客纯属学术交流,为初学者提供一点帮助。
2.编程仿真都是通过Matlab环境进行编写,实验验证也是通过Matlab进行的,在这里分享的程序也都是基于Matlab环境下的代码。
3.请转载时注明来源。

猜你喜欢

转载自blog.csdn.net/weixin_38858809/article/details/87901445