function [max_qnt, min_qnt] = maxminqnt(record, dur_ratio, CDF_qnt) % This function, written by Joseph A. Main, is a modified version of a % function previously written by Fahim Sadek, based on the procedure % described in the following paper: % % Sadek, F. and Simiu, E. (2002). "Peak non-gaussian wind effects for % database-assisted low-rise building design." Journal of Engineering % Mechanics, 128(5), 530-539. % % The function estimates probability distributions for the peaks of a % time series and returns maximum and minimum values corresponding to the % specified probabilities of non-exceedence. % % INPUT ARGUMENTS: % Each row of "record" is a time series. % "dur_ratio" = (duration for expected peaks)/(duration of record). % If unspecified, a value of 1 is used. % "CDF_qnt" is a vector giving the probabilities of non-exceedence for which % quantiles are desired. For the minima, quantiles corresponding to a % cumulative distribution of 1-CDF_qnt are returned in the output argument % "min_qnt". For example, if a value of 0.75 is specified for "CDF_qnt", % then the resulting value of "max_qnt" has a 25% probability of being % exceeded in the positive direction, while the resulting value of % "min_qnt" has a 25% probability of being exceeded in the negative direction. % % OUTPUT ARGUMENTS: % "max_qnt" gives the maximum values of each row of "record" % corresponding to the non-exceedance probabilities in "CDF_qnt". % "min_qnt" gives the minimum values of each row of "record" % corresponding to the non-exceedance probabilities in "CDF_qnt". % % Both "max_qnt" and "min_qnt" are r by q matrices, where r % is the number of rows in "record", and q is the number of % probabilities in "CDF_qnt". % % updated 7 Nov 2006 if nargin~=3 error(['Three input arguments expected (' nargin ' provided)']); end if isempty( record ) error('First input argument (time series) must not be empty'); elseif isempty( CDF_qnt ) error('Third input argument (probabilities of non-exceedance) must not be empty'); elseif isempty( dur_ratio ) dur_ratio = 1; end plot_on = 1; % turns plotting on (1) [for diagnostics] or off (0) if max(CDF_qnt)>=1 || min(CDF_qnt)<=0 error('The range of the second input argument must be between 0 and 1.'); end rsize = size(record); CDF_qnt = reshape(CDF_qnt,1,length(CDF_qnt)); % make sure CDF_qnt is a row vector max_qnt = zeros(rsize(1),length(CDF_qnt)); min_qnt = zeros(rsize(1),length(CDF_qnt)); for i=1:rsize(1) x = record(i,:); n = length(x); mean_x = mean( x ); std_x = std(x, 1); % biased estimate skew_x = sum((x - mean_x).^3)/ (n*std_x^3); % biased estimate (Matlab default for 'skewness') X = x*sign(skew_x); % Change sign (if necessary) to have positive skewness sort_X = sort( X ); % sort in ascending order: mean_X = mean_x*sign(skew_x); std_X = std_x; CDF_X = (1:n)/(n+1); % Empirical Cumulative Distribution Function % resample CDF more coarsely for more efficient parameter estimation: n_coarse = min([n 1000]); CDF_coarse = linspace(1/(n_coarse+1),n_coarse/(n_coarse+1),n_coarse); X_coarse = interp1(CDF_X, sort_X, CDF_coarse); % Estimate shape parameter of gamma distribution from coarse CDF: mean_X_coarse = mean(X_coarse); std_X_coarse = std(X_coarse); gamma_min = 1; gamma_max = 125; n_gamma = 19; % number of trial values of gamma n_start = 8; % start checking with this index in gamma_list gamma_list = logspace(log10(gamma_min),log10(gamma_max),n_gamma); gam_PPCC_list = zeros(size(gamma_list)); count = 0; % first try decreasing gamma: for j = n_start:-1:1 count = count+1; % Obtain the Gamma Distribution Parameters for current gamma: s_gam_j = stdgaminv(CDF_coarse(:), gamma_list(j)); % standard variate mean_s_gam_j = mean(s_gam_j); % linear regression: beta_coarse_list(j) = (sum(s_gam_j(:).*X_coarse(:))-n_coarse*mean_s_gam_j*mean_X_coarse)/(sum(s_gam_j.^2)-n_coarse*mean_s_gam_j^2); mu_coarse_list(j) = mean_X_coarse - beta_coarse_list(j)*mean_s_gam_j; % Probability Plot Correlation Coefficient: gam_PPCC_list(j) = beta_coarse_list(j)*std(s_gam_j)/std_X_coarse; X_coarse_fit_j = mu_coarse_list(j) + beta_coarse_list(j)*s_gam_j; if plot_on figure(1) if count==1, clf; end subplot(7,3,count) plot(s_gam_j,X_coarse,'.',s_gam_j,X_coarse_fit_j,'-'); title(['gamma: ' num2str(round(10*gamma_list(j))/10) ' PPCC: ' num2str(gam_PPCC_list(j))]); end if gam_PPCC_list(j)==max(gam_PPCC_list) gam = gamma_list(j); gam_PPCC_max = gam_PPCC_list(j); else break; % stop searching once the PPCC starts to decrease end end if gam_PPCC_list(n_start-1)=X_u & X(1:end-1)0 max_qnt(i,:) = X_max; min_qnt(i,:) = X_min; else max_qnt(i,:) = -X_min; min_qnt(i,:) = -X_max; end end