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

📄 l_regression.m

📁 基于Matlab的地震数据处理显示和测井数据显示于处理的小程序
💻 M
字号:
function [wlog,aux]=l_regression(wlog,expression,varargin)% Function creates new log curve using the mathematical expression contained in the% third input argument. Null values (NaNs) in the log curves are ignored when computing% the regression parameters.%% Written by E. R., March 16, 2001% Last updated: July 12, 2001: Creates initial values even if no bounds are given%%             [wlog,aux]=l_regression(wlog,expression,varargin)% INPUT% wlog        log structure% expression  expression in MATLAB syntax between curves of wlog. These curves are  %             represented by their mnemonics. No default.%             EXAMPLE:  'rho = x1*Vp^x2' which estimates a Gardner-type relationship%                       for the density%             The curve to the left of the equal sign is called the target curve %             ('rho' in this example)%             The parameters to be estimated are represented by "x1","x2",...,"x9".% varargin    one or more cell arrays; the first element of each cell array is a%             keyword, the other elements are parameters. Presently, keywords are:%      'depths'  start and end depth of curves used for regression calculation%             Default: {'depths',wlog.first,wlog.last}%      'rows' string with logical expression involving one more of the curve mnemonics%             Can be used to restrict curve values used for regression to certain lithologies%             Default: {'rows',''} (implies all rows)%      'lbounds'  lower limits for the values of the parameters to be %             estimated.%             No defaults.%      'ubounds'  upper limits for the values of the parameters to be %             estimated.%             No defaults.%      'description'   description of the newly created curve%      'x'    initial values of the parameters%             Default: {'x',0.5*(ubounds-lbounds)}%             Error message if any of the bounds are infinite.%      'mnem' mnemonic of the estimated curve.%             Default: {'mnem','curve_pred'} where "curve" is the mnmonic of the %                      target curve in "expression"; in the example above it %                      would be 'rho_pred')%      'norm' Norm to use; possible values are 'L1' (minimizes the sum of the%             absolute values of the error; more robust) or 'L2' (sum of the %             squares of the error; faster). If norm is 'L1', two additional parameters%             may be given which allow treating positve deflections different from %             negative ones. Not case-sensitive.%             Default: {'norm','L1')% OUTPUT% wlog        input log with the additional curve appended (including an updated field %             "curve_info")% aux         structure with auxiliary information. The following fields are present:%             x1, x2, ... estimated parameters;%             x       estimated paramters as a row vector%             fval    final function value (error)%             exitflag of the minimization routine%             general info from minimization routine (important only for debugging)%       Set defaults of input argumentsparam.depths=[];param.rows=[];param.lbounds=[];param.ubounds=[];% param.description='';param.x=[];param.mnem=[];param.norm='l1';%       Decode and assign input argumentsparam=assign_input(param,varargin);%       Find all the words in the expressionwords=extract_words(expression);%       Check if mnemonic of output curve (first variable in expression) existsmnem=words{1};[index,ier]=curve_index1(wlog,mnem,0);if ier   if isempty(index)      disp([char(13),' No curve with mnemonic "',mnem,'" found in log structure'])   else      disp([char(13),' More than one curve with mnemonic "',mnem,'" found in log structure'])   end   error(' Abnormal termination')end%       Set default name for target curve (if not defined in argument list)if isempty(param.mnem)   param.mnem=[mnem,'_pred'];endnsamp=size(wlog.curves,1);% words=extract_words(expression);vars=symvar(expression);%       Find all the parametersx1to9={'x1','x2','x3','x4','x5','x6','x7','x8','x9'};lindex=ismember(vars,x1to9);xi=vars(lindex);lxi=length(xi);%       Check initial values for parametersif ~isempty(param.x)   if length(param.x) ~= lxi      disp([char(13),' Discrepancy: ',num2str(lxi),' parameters found in expression, but ', ...             num2str(length(param.x)),' initial value(s) found'])      error(' Abnormal termination')   end   if iscell(param.x)      param.x=cat(2,param.x{:});   endend%       Check bounds of parametersif isempty(param.lbounds)   param.lbounds=-inf*ones(1,lxi);else   if length(param.lbounds) ~= lxi      disp([char(13),' Number of lower bounds (',num2str(length(param.lbounds)), ...                ') not equal to number of parameters in expression (', ...               num2str(lxi),')'])      disp(' Check number of values entered via keyword "lbounds"')      error(' Abnormal ternination')   end   if iscell(param.lbounds)      param.lbounds=cat(2,param.lbounds{:});   endendif isempty(param.ubounds)   param.ubounds=inf*ones(1,lxi);else   if length(param.ubounds) ~= lxi      disp([char(13),' Number of upper bounds (',num2str(length(param.ubounds)), ...                ') not equal to number of parameters in expression (', ...               num2str(lxi),')'])      disp(' Check number of values entered via keyword "ubounds"')      error(' Abnormal ternination')   end   if iscell(param.ubounds)      param.ubounds=cat(2,param.ubounds{:});   endendif isempty(param.x)   param.x=0.5*(param.ubounds+param.lbounds);   if any(isinf(param.x))      error('There is no default for the starting values if any of the bounds are infinite.')   end   idx=find(isnan(param.x));   if ~isempty(idx)           for ii=1:length(idx)         if param.lbounds(idx(ii)) > -inf             param.x(idx(ii))=param.lbounds(idx(ii)) + 1;         elseif param.ubounds(idx(ii)) < inf             param.x(idx(ii))=param.ubounds(idx(ii)) - 1;         else            param.x(idx(ii))=0;         end      end   endend%       Check if the initial values of the parameters are within the boundstemp=find(param.x < param.lbounds);ier=0;if ~isempty(temp)   ier=1;   disp([char(13),' One or more initial parameter values are below the lower bounds'])endtemp=find(param.x > param.ubounds);if ~isempty(temp)   ier=1;   disp([char(13),' One or more initial parameter values are above the upper bounds'])endif ier   disp(' Initial parameter values:')   disp(param.x)   error(' Abnormal termination')end%       Find all the curves ...curve_names=vars(~lindex);lp=length(curve_names);%       Check if "expression" is a valid MATLAB expressionfor ii=1:lxi   eval([xi{ii},'=param.x(ii);']);endfor ii=1:lp   eval([curve_names{ii},'=1;']);endtry   eval([expression,';'])catch   disp([char(13),' It is very likely, that "',expression,'" is not a valid MATLAB expression']);   error(' Abnormal termination')end  %       Check if there are selection criteria regarding depth range and rowsif ~isempty(param.depths) | ~isempty(param.rows)   if ~isempty(param.depths)      temp=l_select(wlog,{'depths',param.depths{1},param.depths{2}});      if ~isempty(param.rows)         temp=l_select(temp,{'rows',param.rows});      end   else      temp=l_select(wlog,{'rows',param.rows});   end   [aux,rhs_expression]=find_parameters(temp,expression,xi,param,curve_names);else   [aux,rhs_expression]=find_parameters(wlog,expression,xi,param,curve_names);end%       Create new curve with the parameters just estimated and add it%       to input log structurecurves=zeros(nsamp,lp);for ii=1:lp   if ~strcmpi(curve_names(ii),mnem)     curves(:,ii)=l_gc(wlog,curve_names{ii});   endendx=aux.x;test=sum(curves,2);lindex=find(~isnan(test));curves=curves(lindex,:);temp=eval(rhs_expression);new_curve=NaN*zeros(nsamp,1);new_curve(lindex)=temp;wlog=l_curve(wlog,'add_ne',param.mnem,new_curve,l_gu(wlog,mnem), ...     [l_gd(wlog,mnem),' (predicted)']);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [aux,rhs_expression]=find_parameters(wlog,expression,xi,param,curve_names)[nsamp,ntr]=size(wlog.curves);lxi=length(param.x);%       ... and copy them into matrix "curves", ...lp=length(curve_names);curves=zeros(nsamp,lp);for ii=1:lp  eval(['curves(:,ii)=l_gc(wlog,''',curve_names{ii},''');']);end% curves_orig=curves;%       ... remove all null valuestest=sum(curves,2);% idx=find(~isnan(test));curves=curves(~isnan(test),:);% 	Check if there are enough curve samples leftif size(curves,1) < lxi   error(' Not enough valid sampes in requested curves')end%       Transform "expression" into the objective function to be minimized%       1. Modify expression to be valid for vectorsexpr=strrep(expression,'*','.*');expr=strrep(expr,'/','./');expr=strrep(expr,'^','.^');%       2. replace x1, x2, ... by x(1),x(2),...for ii=1:lxi  expr=strrep(expr,xi{ii},['x(',num2str(ii),')']);end%       3. replace "=" sign by "-" signidx=findstr(expr,'=');if length(idx) ~= 1  disp([char(13),' No equal sigh (=) found in expression "',expr])  error(' Abnormal termination')endexpr1=[expr(1:idx-1),'-(',expr(idx+1:end),')'];rhs_expression=expr(idx+1:end);%       4. replace header mnemonics by columns of array,...funct=expr1;for ii=1:lp  funct=strrep(funct,curve_names{ii},['curves(:,',num2str(ii),')']);  rhs_expression=strrep(rhs_expression,curve_names{ii},['curves(:,',num2str(ii),')']);end%       5. define objective function for the minimization conditionif ischar(param.norm)   if strcmpi(param.norm,'L1')      min_cond=['sum(abs(',funct,'))'];   elseif strcmpi(param.norm,'L2')      min_cond=['norm(',funct,')'];   else      disp([char(13),' Unknown norm "',param.norm,'"'])      error(' Abnormal termination')   endelse  if strcmpi(param.norm{1},'L1')    funct1=['(',expr1,')'];    funct2=funct1;    for ii=1:lp      funct1=strrep(funct1,curve_names{ii},['curves(',funct,' > 0,',num2str(ii),')']);      funct2=strrep(funct2,curve_names{ii},['curves(',funct,' < 0,',num2str(ii),')']);    end    min_cond=[num2str(param.norm{3}),'*','sum(abs(',funct1,')) + ', ...               num2str(param.norm{2}),'*','sum(abs(',funct2,'))'];  else     disp([char(13),' Unknown norm "',param.norm,'" or parameters missing from "L1"'])     error(' Abnormal termination')  endend%       Create inline function for the objective functionifunct=inline(min_cond,'x','curves');options=optimset('MaxFunEvals',5000,'LargeScale','off');if isempty(param.lbounds) & isempty(param.ubounds)               % Perform unconstrained minimization   [x,fval,exitflag,output]=fminunc(ifunct,param.x,options,curves);else        % Perform constrained minimization   [x,fval,exitflag,output]=fmincon(ifunct,param.x,[],[],[],[],param.lbounds,param.ubounds, ...            [],options,curves);end%       Prepare outputaux=[];for ii=1:lxi  aux=setfield(aux,xi{ii},x(ii));endaux.x=x;aux.fval=fval;aux.exitflag=exitflag;aux.output=output;

⌨️ 快捷键说明

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