⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_principal_components.m

📁 基于Matlab的地震数据处理显示和测井数据显示于处理的小程序
💻 M
字号:
function [pc,aux]=s_principal_components(seismic,varargin)% Function computes principal components of seismic data. It can output the % input data represented by any combination of the principal components --- % usually the first few. % It can also output a seismic data set representing one or more of the principal components%% Written by: E. R.: July 18, 2000% Last updated: August 2, 2006: Fix bug in headers.%%             [pc,aux]=s_principal_components(seismic,varargin)% INPUT% seismic     seismic data set% varargin    one or more cell arrays; the first element of each cell array is a keyword,%             the other elements are parameters. Presently, keywords are:%             'output' Type of output. Possible values are: %                     'pc' (principal components), 'seismic', 'coefficients'. %                      In the first case one trace is output for each principal %                      component requested; headers which are constant are output as well.%                      In the second case the number of output traces equals the number%                      of input traces and all headers are copied.%                      In the third case the coefficients of each with %                      which the principal components are multiplied to form one %                      trace are output.%                      Default: {'output','seismic'}%             'components' Principal components requested. Possible values are integers > 0.%                      The maximum value is the smaller of the number of%                      samples and the number of traces. A request for principal components%                      with higher order is ignored. %                      Default: if {'output','seismic'} then {'components',1}%                               if {'output','pc'} then {'components',1:maximum_value}%             'scale'  Only used if {'output','pc'}. Possible values are: 'yes' (scale them by%                      energy) or 'no'. Default: {'scale','yes'}% OUTPUT% pc          seismic structure; if {'output','seismic'} it is the seismic input data %             represented by the principal components defined via keyword 'components'.%             if {'output','pc'} it is the principal components defined via keyword %             'components'.% aux         structure with auxiliary information%     if output is "seismic'%     'energy' row vector: scaled energy of the principal components of each trace%     'd'     column vector: cumulative sum of the squared singular values (scaled so that %             the last entry is 1)%     if output is "pc"%     'sing_values"   singular valuesif ~isstruct(seismic)  error(' First input argument must be a structure')endif isfield(seismic,'null') & isnan(seismic.null)  error(' Seismic data must not contain NaNs')endpc=seismic;[nsamp,ntr]=size(seismic.traces);min_nsamp_ntr=min([nsamp,ntr]);% 	Set default valuesparam.output='seismic';param.components=[];%       Decode and assign input argumentsparam=assign_input(param,varargin);%       Set/check number of principal components requested.if isempty(param.components)   if strcmpi(param.output,'seismic')      param.components=1;   else      param.components=1:min_nsamp_ntr;   endelse%   idx=find(param.components <= min_nsamp_ntr);   param.components=param.components(param.components <= min_nsamp_ntr);endswitch param.output           	case 'seismic'[pr_cmp,energy,d]=princ_comp_no1(seismic.traces,param.components);pc.traces=pr_cmp;%   	Copy rest of the fieldspc=copy_fields(seismic,pc);%	Add history field if it exists in seismicaux.energy=energy;aux.d=d;pc=s_header(pc,'add_ne','energy',energy,'n/a','Fraction of total trace energy retained');         	case 'pc'[pc.traces,sing_val]=princ_comp_no2(seismic.traces,param.components);%   	Copy rest of the fields% pc=copy_fields(seismic,pc);%   	Copy headers that are constant and delete othersif isfield(seismic,'header_info')   nh=size(seismic.headers,1);   headers=zeros(nh,1);   header_info=cell(nh,3);   icount=0;   for ii=1:nh      if min(seismic.headers(ii,:)) == max(seismic.headers(ii,:))         icount=icount+1;         headers(icount)=seismic.headers(ii,1);         header_info(icount,:)=seismic.header_info(ii,:);      end   end   if icount > 0      pc.headers=headers(1:icount,:);      pc.header_info=header_info(1:icount,:);   else      pc=rmfield(pc,{'headers','header_info'});   endend      %	Choose sign of the principal components so that they best% 	represents the average of the input datastack=sum(seismic.traces,2);pcc=pc.traces'*stack;idx=find(pcc < 0);if  ~isempty(idx),    pc.traces(:,idx)=-pc.traces(:,idx); endif nargout > 1   aux.sing_values=sing_val;end                case 'coefficients'[pc.traces,d]=princ_comp_no3(seismic.traces,param.components);if nargout > 1   aux.sing_values=d;endpc.first=1;pc.last=length(param.components);pc.step=1;pc.unit='samples';pc.tag='principal_components';pc.row_label=param.components(:);  		otherwiseerror([' Unknowm option for keyword "output": ',param.output])		end		% End of switch block%	Add entry to the history field if it exists in seismichtext=[' Principal components: ',num2str(param.components)];pc=s_history(pc,'append',htext); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [pc,energy,dd]=princ_comp_no1(s,npc)% Function computes principal components of s over the range npc and outputs% them together with the total relative energy in each column of s.%       [pc,energy,d]=princ_comp(s,npc)% INPUT% s     input array% npc   indices of principal components to use%       max(npc) <= number of columns of s% OUTPUT% pc    principal components% energy  fraction of total trace energy[ns,ntr]=size(s);if ns >= ntr  [u,d,v]=svd(s,0);else  [v,d,u]=svd(s',0);endd=diag(d);if nargout > 2;    dd=d.^2;   scf=1/sum(dd);   dd=cumsum(dd)*scf; else   scf=1/sum(d.^2);end%scf=1/sum(d.^2);ik=0;for ii=npc   ik=ik+1;   vv(:,ik)=v(:,ii)*d(ii);endpc=u(:,npc)*vv';if ik == 1   energy=reshape((vv.^2)*scf,1,[]);else   energy=sum(vv.^2,2)*scf;end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [pc,sing_val]=princ_comp_no2(s,npc)% Function computes principal components of s over the range of indices npc % and outputs them together with the total relative energy in each column of s.%%           [pc,sing_val]=princ_comp1(s,npc)% INPUT% s         input array% npc       indices of principal components to use% OUTPUT% pc        principal components% sing_val  normalized singular values (sum of squares = 1)[u,d]=svd(s,0);pc=u(:,npc);sing_val=d(npc)./sqrt(sum(diag(d).^2));%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [vv,d]=princ_comp_no3(s,npc)% Function computes coefficients of the principal components of s over% the range of indices npc and outputs them together with the total % relative energy in each column of s.%%           [pc,sing_val]=princ_comp1(s,npc)% INPUT% s         input array% npc       indices of principal components to use% OUTPUT% vv        Matrix with coefficients of the principal components for each column of s%           there are as many columns as there are columns of "s"% d         all singular values [ns,ntr]=size(s);if ns >= ntr   [u,d,v]=svd(s,0);else   [v,d]=svd(s',0);endd=diag(d);ik=0;for ii=npc   ik=ik+1;   vv(:,ik)=v(:,ii)*d(ii);endif ns < ntr   vv=vv';end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -