Mercurial > forge
changeset 11336:a7de0aafd809 octave-forge
new gev* functions added to statistics
author | nir-krakauer |
---|---|
date | Fri, 28 Dec 2012 00:04:09 +0000 |
parents | a9cdb3c433f4 |
children | 3f7da417c367 |
files | main/statistics/INDEX main/statistics/NEWS main/statistics/inst/gevcdf.m main/statistics/inst/gevfit.m main/statistics/inst/gevinv.m main/statistics/inst/gevlike.m main/statistics/inst/gevpdf.m main/statistics/inst/gevrnd.m main/statistics/inst/gevstat.m |
diffstat | 9 files changed, 943 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/main/statistics/INDEX Thu Dec 27 22:11:24 2012 +0000 +++ b/main/statistics/INDEX Fri Dec 28 00:04:09 2012 +0000 @@ -11,6 +11,7 @@ gamlike gamstat geostat + gevcdf gevfit gevinv gevlike gevpdf gevrnd gevstat hygestat jsucdf jsupdf
--- a/main/statistics/NEWS Thu Dec 27 22:11:24 2012 +0000 +++ b/main/statistics/NEWS Fri Dec 28 00:04:09 2012 +0000 @@ -4,7 +4,11 @@ ** The following functions are new: regress_gp dendogram plsregress - + + ** New functions for the generalized extreme value (GEV) distribution: + + gevcdf gevfit gevinv gevlike gevpdf gevrnd gevstat + ** The interface of the following functions has been modified: mvnrnd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevcdf.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,131 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{p} =} gevcdf (@var{x}, @var{k}, @var{sigma}, @var{mu}) +## Compute the cumulative distribution function of the generalized extreme value (GEV) distribution. +## +## @subheading Arguments +## +## @itemize @bullet +## @item +## @var{x} is the support. +## +## @item +## @var{k} is the shape parameter of the GEV distribution. (Also denoted gamma or xi.) +## @item +## @var{sigma} is the scale parameter of the GEV distribution. The elements +## of @var{sigma} must be positive. +## @item +## @var{mu} is the location parameter of the GEV distribution. +## @end itemize +## The inputs must be of common size, or some of them must be scalar. +## +## @subheading Return values +## +## @itemize @bullet +## @item +## @var{p} is the cumulative distribution of the GEV distribution at each +## element of @var{x} and corresponding parameter values. +## @end itemize +## +## @subheading Examples +## +## @example +## @group +## x = 0:0.5:2.5; +## sigma = 1:6; +## k = 1; +## mu = 0; +## y = gevcdf (x, k, sigma, mu) +## @end group +## +## @group +## y = gevcdf (x, k, 0.5, mu) +## @end group +## @end example +## +## @subheading References +## +## @enumerate +## @item +## Rolf-Dieter Reiss and Michael Thomas. @cite{Statistical Analysis of Extreme Values with Applications to Insurance, Finance, Hydrology and Other Fields}. Chapter 1, pages 16-17, Springer, 2007. +## +## @end enumerate +## @seealso{gevfit, gevinv, gevlike, gevpdf, gevrnd, gevstat} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: CDF of the generalized extreme value distribution + +function p = gevcdf (x, k, sigma, mu) + + # Check arguments + if (nargin != 4) + print_usage (); + endif + + if (isempty (x) || isempty (k) || isempty (sigma) || isempty (mu) || ~ismatrix (x) || ~ismatrix (k) || ~ismatrix (sigma) || ~ismatrix (mu)) + error ("gevcdf: inputs must be a numeric matrices"); + endif + + [retval, x, k, sigma, mu] = common_size (x, k, sigma, mu); + if (retval > 0) + error ("gevcdf: inputs must be of common size or scalars"); + endif + + z = 1 + k .* (x - mu) ./ sigma; + + # Calculate pdf + p = exp(-(z .^ (-1 ./ k))); + + p(z <= 0 & x < mu) = 0; + p(z <= 0 & x > mu) = 1; + + inds = (k == 0); %use a different formula + if any(inds) + z = (mu(inds) - x(inds)) ./ sigma(inds); + p(inds) = exp(-exp(z)); + endif + + +endfunction + +%!test +%! x = 0:0.5:2.5; +%! sigma = 1:6; +%! k = 1; +%! mu = 0; +%! p = gevcdf (x, k, sigma, mu); +%! expected_p = [0.36788 0.44933 0.47237 0.48323 0.48954 0.49367]; +%! assert (p, expected_p, 0.001); + +%!test +%! x = -0.5:0.5:2.5; +%! sigma = 0.5; +%! k = 1; +%! mu = 0; +%! p = gevcdf (x, k, sigma, mu); +%! expected_p = [0 0.36788 0.60653 0.71653 0.77880 0.81873 0.84648]; +%! assert (p, expected_p, 0.001); + +%!test #check for continuity for k near 0 +%! x = 1; +%! sigma = 0.5; +%! k = -0.03:0.01:0.03; +%! mu = 0; +%! p = gevcdf (x, k, sigma, mu); +%! expected_p = [0.88062 0.87820 0.87580 0.87342 0.87107 0.86874 0.86643]; +%! assert (p, expected_p, 0.001);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevfit.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,85 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{paramhat}, @var{paramci} =} gevfit (@var{data}) +## Find the maximum likelihood estimator (@var{paramhat}) of the generalized extreme value (GEV) distribution to fit @var{data}. +## +## @subheading Arguments +## +## @itemize @bullet +## @item +## @var{data} is the vector of given values. +## +## @end itemize +## +## @subheading Return values +## +## @itemize @bullet +## @item +## @var{parmhat} is the 3-parameter maximum-likelihood parameter vector [@var{k}, @var{sigma}, @var{mu}], where @var{k} is the shape parameter of the GEV distribution, @var{sigma} is the scale parameter of the GEV distribution, and @var{mu} is the location parameter of the GEV distribution. +## @item +## @var{paramci} has the approximate 95% confidence intervals of the parameter values based on the Fisher information matrix at the maximum-likelihood position. +## +## @end itemize +## +## @subheading Examples +## +## @example +## @group +## data = 1:50; +## [pfit, pci] = gevfit (data); +## p1 = gevcdf(data,pfit(1),pfit(2),pfit(3)); +## plot(data, p1) +## @end group +## @end example +## @seealso{gevcdf, gevinv, gevlike, gevpdf, gevrnd, gevstat} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: Maximum likelihood parameter estimation for the generalized extreme value distribution + +function [paramhat, paramci] = gevfit (data) + + # Check arguments + if (nargin < 1) + print_usage; + endif + + #initial guess for parameter values + p0 = [0 1 0]'; + + #cost function to minimize + f = @(p) gevlike(p, data); + + paramhat = fminunc(f, p0); + + if nargout > 1 + [nlogL, ACOV] = gevlike (paramhat, data); + param_se = sqrt(diag(-ACOV)); + paramci(:, 1) = paramhat - 1.96*param_se; + paramci(:, 2) = paramhat + 1.96*param_se; + endif + +endfunction + + + +%!test +%! data = 1:50; +%! [pfit, pci] = gevfit (data); +%! sigma = 0.3; +%! expected_p = [-0.44 15.19 21.53]'; +%! assert (pfit, expected_p, 0.1);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevinv.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,88 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{X} =} gevinv (@var{P}, @var{k}, @var{sigma}, @var{mu}) +## Compute a desired quantile (inverse CDF) of the generalized extreme value (GEV) distribution. +## +## @subheading Arguments +## +## @itemize @bullet +## @item +## @var{P} is the desired quantile of the GEV distribution. (Between 0 and 1.) +## @item +## @var{k} is the shape parameter of the GEV distribution. (Also denoted gamma or xi.) +## @item +## @var{sigma} is the scale parameter of the GEV distribution. The elements +## of @var{sigma} must be positive. +## @item +## @var{mu} is the location parameter of the GEV distribution. +## @end itemize +## The inputs must be of common size, or some of them must be scalar. +## +## @subheading Return values +## +## @itemize @bullet +## @item +## @var{X} is the value corresponding to each quantile of the GEV distribution +## @end itemize +## @subheading References +## +## @enumerate +## @item +## Rolf-Dieter Reiss and Michael Thomas. @cite{Statistical Analysis of Extreme Values with Applications to Insurance, Finance, Hydrology and Other Fields}. Chapter 1, pages 16-17, Springer, 2007. +## @item +## J. R. M. Hosking (2012). @cite{L-moments}. R package, version 1.6. URL: http://CRAN.R-project.org/package=lmom. +## +## @end enumerate +## @seealso{gevcdf, gevfit, gevlike, gevpdf, gevrnd, gevstat} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: Inverse CDF of the generalized extreme value distribution + +function [X] = gevinv (P, k = 0, sigma = 1, mu = 0) + + [retval, P, k, sigma, mu] = common_size (P, k, sigma, mu); + if (retval > 0) + error ("gevinv: inputs must be of common size or scalars"); + endif + + X = P; + + ii = (k == 0); + X(ii) = mu(ii) - sigma(ii) .* log(-log(P(ii))); + X(~ii) = mu(~ii) + sigma(~ii) .* (-1 - (log(P(~ii)).^ -k(~ii))) ./ k(~ii); + +endfunction + +%!test +%! p = 0.1:0.1:0.9; +%! k = 0; +%! sigma = 1; +%! mu = 0; +%! x = gevinv (p, k, sigma, mu); +%! c = gevcdf(x, k, sigma, mu); +%! assert (c, p, 0.001); + +%!test +%! p = 0.1:0.1:0.9; +%! k = 1; +%! sigma = 1; +%! mu = 0; +%! x = gevinv (p, k, sigma, mu); +%! c = gevcdf(x, k, sigma, mu); +%! assert (c, p, 0.001); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevlike.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,292 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{nlogL}, @var{ACOV}, @var{Grad} =} gevlike (@var{params}, @var{data}) +## Compute the negative log-likelihood of data under the generalized extreme value (GEV) distribution with given parameter values. +## +## @subheading Arguments +## +## @itemize @bullet +## @item +## @var{params} is the 3-parameter vector [@var{k}, @var{sigma}, @var{mu}], where @var{k} is the shape parameter of the GEV distribution, @var{sigma} is the scale parameter of the GEV distribution, and @var{mu} is the location parameter of the GEV distribution. +## @item +## @var{data} is the vector of given values. +## +## @end itemize +## +## @subheading Return values +## +## @itemize @bullet +## @item +## @var{nlogL} is the negative log-likelihood. +## @item +## @var{ACOV} is the 3 by 3 Fisher information matrix (negative second derivative of the log likelihood with respect to the parameter values) +## @var{Grad} is the 3 by 1 gradient vector (first derivative of the log likelihood with respect to the parameter values) +## +## @end itemize +## +## @subheading Examples +## +## @example +## @group +## x = -5:-1; +## k = -0.2; +## sigma = 0.3; +## mu = 0.5; +## [L, C] = gevlike ([k sigma mu], x); +## @end group +## @end example +## +## @subheading References +## +## @enumerate +## @item +## Rolf-Dieter Reiss and Michael Thomas. @cite{Statistical Analysis of Extreme Values with Applications to Insurance, Finance, Hydrology and Other Fields}. Chapter 1, pages 16-17, Springer, 2007. +## +## @end enumerate +## @seealso{gevcdf, gevfit, gevinv, gevpdf, gevrnd, gevstat} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: Negative log-likelihood for the generalized extreme value distribution + +function [nlogL, ACOV, Grad] = gevlike (params, data) + + # Check arguments + if (nargin != 2) + print_usage; + endif + + k = params(1); + sigma = params(2); + mu = params(3); + + #calculate negative log likelihood + nlogL = sum(gevnll (data, k, sigma, mu) (:)); + + if nargout > 1 + ACOV = -gevfim (data, k, sigma, mu); + if nargout > 2 + Grad = gevgrad (data, k, sigma, mu); + endif + endif + +endfunction + + +function nlogL = gevnll (x, k, sigma, mu) +#internal function to calculate negative log likelihood for gevlike +#no input checking done + + if k == 0 + z = (mu - x) ./ sigma; + nlogL = exp(z) - z + log(sigma); + else + z = 1 + k .* (x - mu) ./ sigma; + nlogL = z .^ (-1 ./ k) + (1 + 1 ./ k) .* log(z) + log(sigma); + nlogL(z <= 0) = Inf; + endif + +endfunction + +function G = gevgrad (x, k, sigma, mu) +#calculate the gradient of the negative log likelihood of data x with respect to the parameters of the generalized extreme value distribution for gevlike +#no input checking done + +G = ones(3, 1); + +if k == 0 ##use the expressions for first derivatives that are the limits as k --> 0 + a = (x - mu) ./ sigma; + f = exp(a); + #k + g = -(2 * x .* (mu .* (1 - f) - sigma .* f) + 2 .* sigma .* mu .* f + (x.^2 + mu.^2).*(f - 1)) ./ (2 * f .* sigma .^ 2); + G(1) = sum(g(:)); + + #sigma + g = ((a ./ f) - a + 1) ./ sigma; + G(2) = sum(g(:)); + + #mu + g = (1 ./ f - 1) ./ sigma; + G(3) = sum(g(:)); + + return +endif + +z = 1 + k .* (x - mu) ./ sigma; +if any (z <= 0) + G(:) = 0; #negative log likelihood is locally infinite + return +end + +#k +a = (x - mu) ./ sigma; +b = k .* a + 1; +c = log(b); +d = 1 ./ k + 1; +g = (c ./ k - a ./ b) ./ (k .* b .^ (1/k)) - c ./ (k .^ 2) + a .* d ./ b; +G(1) = sum(g(:)); + +#sigma +g = (a .* b .^ (-d) - d .* k .* a ./ b + 1) ./ sigma; +G(2) = sum(g(:)); + +#mu +g = (b .^ (-d) - d .* k ./ b) ./ sigma; +G(3) = sum(g(:)); + + +endfunction + +function ACOV = gevfim (x, k, sigma, mu) +#internal function to calculate the (negative) Fisher information matrix for gevlike +#no input checking done + +#calculate the various second derivatives (used Maxima to find the expressions) + +ACOV = ones(3); + +if k == 0 ##use the expressions for second derivatives that are the limits as k --> 0 + #k, k + a = (x - mu) ./ sigma; + f = exp(a); + der = (x .* (24 * mu .^ 2 .* sigma .* (f - 1) + 24 * mu .* sigma .^ 2 .* f - 12 * mu .^ 3) + x .^ 3 .* (8 * sigma .* (f - 1) - 12*mu) + x .^ 2 .* (-12 * sigma .^ 2 .* f + 24 * mu .* sigma .* (1 - f) + 18 * mu .^ 2) - 12 * mu .^ 2 .* sigma .^ 2 .* f + 8 * mu .^ 3 .* sigma .* (1 - f) + 3 * (x .^ 4 + mu .^ 4)) ./ (12 .* f .* sigma .^ 4); + ACOV(1, 1) = sum(der(:)); + + #sigma, sigma + der = (sigma .^ -2) .* ... + ((-2*a ./ f) + ... + a .^ 2 ./ f + ... + 2*a - 1); + ACOV(2, 2) = sum(der(:)); + + #mu, mu + der = (sigma .^ -2) ./ f; + ACOV(3, 3) = sum(der(:)); + + #k, sigma + der = (x .^2 .* (2*sigma .* (f - 1) - 3*mu) + ... + x .* (-2 * sigma .^ 2 .* f + 4 * mu .* sigma .* (1 - f) + 3 .* mu .^ 2) + ... + 2 * mu .^ 2 .* sigma .* (f - 1) + 2 * mu * sigma .^ 2 * f + x .^ 3 - mu .^ 3) ... + ./ (2 .* f .* sigma .^ 4); + ACOV(1, 2) = ACOV(2, 1) = sum(der(:)); + + #k, mu + der = (x .* (2*sigma .* (f - 1) - 2*mu) - 2 * f .* sigma .^ 2 + ... + 2 .* mu .* sigma .* (1 - f) + x .^ 2 + mu .^ 2)... + ./ (2 .* f .* sigma .^ 3); + ACOV(1, 3) = ACOV(3, 1) = sum(der(:)); + + #sigma, mu + der = (sigma + (x - sigma - mu) ./ f) ./ (sigma .^ 3); + ACOV(2, 3) = ACOV(3, 2) = sum(der(:)); + + return +endif + + +#general case + +z = 1 + k .* (x - mu) ./ sigma; + +if any (z <= 0) + ACOV(:) = 0; #negative log likelihood is locally infinite + return +end + +#k, k +a = (x - mu) ./ sigma; +b = k .* a + 1; +c = log(b); +d = 1 ./ k + 1; +der = ((((c ./ k.^2) - (a ./ (k .* b))) .^ 2) ./ (b .^ (1 ./ k))) + ... + ((-2*c ./ k.^3) + (2*a ./ (k.^2 .* b)) + ((a ./ b) .^ 2 ./ k)) ./ (b .^ (1 ./ k)) + ... + 2*c ./ k.^3 - ... + (2*a ./ (k.^2 .* b)) - (d .* (a ./ b) .^ 2); +ACOV(1, 1) = sum(der(:)); + +#sigma, sigma +der = (sigma .^ -2) .* (... + -2*a .* b .^ (-d) + ... + d .* k .* a .^ 2 .* (b .^ (-d-1)) + ... + 2 .* d .* k .* a ./ b - ... + d .* (k .* a ./ b) .^ 2 - 1); +ACOV(2, 2) = sum(der(:)); + +#mu, mu +der = (d .* (sigma .^ -2)) .* (... + k .* (b .^ (-d-1)) - ... + (k ./ b) .^ 2); +ACOV(3, 3) = sum(der(:)); + +#k, sigma +der = (a ./ sigma) .* (... +(b .^ (-d)) .* (c ./ k - a ./ b) ./ k + ... +-a .* (b .^ (-d-1)) + ... +((1 ./ k) - d) ./ b + ... +a .* k .* d ./ (b .^ 2)); +ACOV(1, 2) = ACOV(2, 1) = sum(der(:)); + +#k, mu +der = ( (b .^ (-d)) .* (c ./ k - a ./ b) ./ k - ... +a .* (b .^ (-d-1)) + ... +((1 ./ k) - d) ./ b + +a .* k .* d ./ (b .^ 2)) ./ sigma; +ACOV(1, 3) = ACOV(3, 1) = sum(der(:)); + +#sigma, mu +der = ( -(b .^ (-d)) + ... +a .* k .* d .* (b .^ (-d-1)) + ... +(d .* k ./ b) - a .* (k./b).^2 .* d) ./ (sigma .^ 2); +ACOV(2, 3) = ACOV(3, 2) = sum(der(:)); + +endfunction + + + + +%!test +%! x = 1; +%! k = 0.2; +%! sigma = 0.3; +%! mu = 0.5; +%! [L, C] = gevlike ([k sigma mu], x); +%! expected_L = 0.75942; +%! expected_C = -[-0.12547 1.77884 1.06731; 1.77884 16.40761 8.48877; 1.06731 8.48877 0.27979]; +%! assert (L, expected_L, 0.001); +%! assert (C, expected_C, 0.001); + +%!test +%! x = 1; +%! k = 0; +%! sigma = 0.3; +%! mu = 0.5; +%! [L, C] = gevlike ([k sigma mu], x); +%! expected_L = 0.65157; +%! expected_C = -[0.090036 3.41229 2.047337; 3.412229 24.760027 12.510190; 2.047337 12.510190 2.098618]; +%! assert (L, expected_L, 0.001); +%! assert (C, expected_C, 0.001); + +%!test +%! x = -5:-1; +%! k = -0.2; +%! sigma = 0.3; +%! mu = 0.5; +%! [L, C] = gevlike ([k sigma mu], x); +%! expected_L = 3786.4; +%! expected_C = [-1.4937e+06 1.0083e+06 -6.1837e+04; 1.0083e+06 -8.1138e+05 4.0917e+04; -6.1837e+04 4.0917e+04 -2.0422e+03]; +%! assert (L, expected_L, -0.001); +%! assert (C, expected_C, -0.001);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevpdf.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,130 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{y} =} gevpdf (@var{x}, @var{k}, @var{sigma}, @var{mu}) +## Compute the probability density function of the generalized extreme value (GEV) distribution. +## +## @subheading Arguments +## +## @itemize @bullet +## @item +## @var{x} is the support. +## +## @item +## @var{k} is the shape parameter of the GEV distribution. (Also denoted gamma or xi.) +## @item +## @var{sigma} is the scale parameter of the GEV distribution. The elements +## of @var{sigma} must be positive. +## @item +## @var{mu} is the location parameter of the GEV distribution. +## @end itemize +## The inputs must be of common size, or some of them must be scalar. +## +## @subheading Return values +## +## @itemize @bullet +## @item +## @var{y} is the probability density of the GEV distribution at each +## element of @var{x} and corresponding parameter values. +## @end itemize +## +## @subheading Examples +## +## @example +## @group +## x = 0:0.5:2.5; +## sigma = 1:6; +## k = 1; +## mu = 0; +## y = gevpdf (x, k, sigma, mu) +## @end group +## +## @group +## y = gevpdf (x, k, 0.5, mu) +## @end group +## @end example +## +## @subheading References +## +## @enumerate +## @item +## Rolf-Dieter Reiss and Michael Thomas. @cite{Statistical Analysis of Extreme Values with Applications to Insurance, Finance, Hydrology and Other Fields}. Chapter 1, pages 16-17, Springer, 2007. +## +## @end enumerate +## @seealso{gevcdf, gevfit, gevinv, gevlike, gevrnd, gevstat} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: PDF of the generalized extreme value distribution + +function y = gevpdf (x, k, sigma, mu) + + # Check arguments + if (nargin != 4) + print_usage (); + endif + + if (isempty (x) || isempty (k) || isempty (sigma) || isempty (mu) || ~ismatrix (x) || ~ismatrix (k) || ~ismatrix (sigma) || ~ismatrix (mu)) + error ("gevpdf: inputs must be a numeric matrices"); + endif + + [retval, x, k, sigma, mu] = common_size (x, k, sigma, mu); + if (retval > 0) + error ("gevpdf: inputs must be of common size or scalars"); + endif + + z = 1 + k .* (x - mu) ./ sigma; + + # Calculate pdf + y = exp(-(z .^ (-1 ./ k))) .* (z .^ (-1 - 1 ./ k)) ./ sigma; + + y(z <= 0) = 0; + + inds = (k == 0); %use a different formula + if any(inds) + z = (mu(inds) - x(inds)) ./ sigma(inds); + y(inds) = exp(z-exp(z)) ./ sigma(inds); + endif + + +endfunction + +%!test +%! x = 0:0.5:2.5; +%! sigma = 1:6; +%! k = 1; +%! mu = 0; +%! y = gevpdf (x, k, sigma, mu); +%! expected_y = [0.367879 0.143785 0.088569 0.063898 0.049953 0.040997]; +%! assert (y, expected_y, 0.001); + +%!test +%! x = -0.5:0.5:2.5; +%! sigma = 0.5; +%! k = 1; +%! mu = 0; +%! y = gevpdf (x, k, sigma, mu); +%! expected_y = [0 0.735759 0.303265 0.159229 0.097350 0.065498 0.047027]; +%! assert (y, expected_y, 0.001); + +%!test #check for continuity for k near 0 +%! x = 1; +%! sigma = 0.5; +%! k = -0.03:0.01:0.03; +%! mu = 0; +%! y = gevpdf (x, k, sigma, mu); +%! expected_y = [0.23820 0.23764 0.23704 0.23641 0.23576 0.23508 0.23438]; +%! assert (y, expected_y, 0.001);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevrnd.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,121 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} gevrnd (@var{k}, @var{sigma}, @var{mu}) +## @deftypefnx {Function File} {} gevrnd (@var{k}, @var{sigma}, @var{mu}, @var{r}) +## @deftypefnx {Function File} {} gevrnd (@var{k}, @var{sigma}, @var{mu}, @var{r}, @var{c}, @dots{}) +## @deftypefnx {Function File} {} gevrnd (@var{k}, @var{sigma}, @var{mu}, [@var{sz}]) +## Return a matrix of random samples from the generalized extreme value (GEV) distribution with parameters +## @var{k}, @var{sigma}, @var{mu}. +## +## When called with a single size argument, returns a square matrix with +## the dimension specified. When called with more than one scalar argument the +## first two arguments are taken as the number of rows and columns and any +## further arguments specify additional matrix dimensions. The size may also +## be specified with a vector @var{sz} of dimensions. +## +## If no size arguments are given, then the result matrix is the common size of +## the input parameters. +## @seealso{gevcdf, gevfit, gevinv, gevlike, gevpdf, gevstat} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: Random deviates from the generalized extreme value distribution + +function rnd = gevrnd (k, sigma, mu, varargin) + + if (nargin < 3) + print_usage (); + endif + + if any (sigma <= 0) + error ("gevrnd: sigma must be positive"); + endif + + if (!isscalar (k) || !isscalar (sigma) || !isscalar (mu)) + [retval, k, sigma, mu] = common_size (k, sigma, mu); + if (retval > 0) + error ("gevrnd: k, sigma, mu must be of common size or scalars"); + endif + endif + + if (iscomplex (k) || iscomplex (sigma) || iscomplex (mu)) + error ("gevrnd: k, sigma, mu must not be complex"); + endif + + if (nargin == 3) + sz = size (k); + elseif (nargin == 4) + if (isscalar (varargin{1}) && varargin{1} >= 0) + sz = [varargin{1}, varargin{1}]; + elseif (isrow (varargin{1}) && all (varargin{1} >= 0)) + sz = varargin{1}; + else + error ("gevrnd: dimension vector must be row vector of non-negative integers"); + endif + elseif (nargin > 4) + if (any (cellfun (@(x) (!isscalar (x) || x < 0), varargin))) + error ("gevrnd: dimensions must be non-negative integers"); + endif + sz = [varargin{:}]; + endif + + if (!isscalar (k) && !isequal (size (k), sz)) + error ("gevrnd: k, sigma, mu must be scalar or of size SZ"); + endif + + if (isa (k, "single") || isa (sigma, "single") || isa (mu, "single")) + cls = "single"; + else + cls = "double"; + endif + + rnd = gevinv (rand(sz), k, sigma, mu); + + if (strcmp (cls, "single")) + rnd = single (rnd); + endif + +endfunction + + +%!assert(size (gevrnd (1,2,1)), [1, 1]); +%!assert(size (gevrnd (ones(2,1), 2, 1)), [2, 1]); +%!assert(size (gevrnd (ones(2,2), 2, 1)), [2, 2]); +%!assert(size (gevrnd (1, 2*ones(2,1), 1)), [2, 1]); +%!assert(size (gevrnd (1, 2*ones(2,2), 1)), [2, 2]); +%!assert(size (gevrnd (1, 2, 1, 3)), [3, 3]); +%!assert(size (gevrnd (1, 2, 1, [4 1])), [4, 1]); +%!assert(size (gevrnd (1, 2, 1, 4, 1)), [4, 1]); + +%% Test input validation +%!error gevrnd () +%!error gevrnd (1, 2) +%!error gevrnd (ones(3),ones(2),1) +%!error gevrnd (ones(2),ones(3),1) +%!error gevrnd (i, 2, 1) +%!error gevrnd (2, i, 1) +%!error gevrnd (2, 0, 1) +%!error gevrnd (1,2, 1, -1) +%!error gevrnd (1,2, 1, ones(2)) +%!error gevrnd (1,2, 1, [2 -1 2]) +%!error gevrnd (1,2, 1, 1, ones(2)) +%!error gevrnd (1,2, 1, 1, -1) +%!error gevrnd (ones(2,2), 2, 1, 3) +%!error gevrnd (ones(2,2), 2, 1, [3, 2]) +%!error gevrnd (ones(2,2), 2, 1, 2, 3) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/statistics/inst/gevstat.m Fri Dec 28 00:04:09 2012 +0000 @@ -0,0 +1,90 @@ +## Copyright (C) 2012 Nir Krakauer <nkrakauer@ccny.cuny.edu> +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{y} =} gevstat (@var{k}, @var{sigma}, @var{mu}) +## Compute the mean and variance of the generalized extreme value (GEV) distribution. +## +## @subheading Arguments +## +## @itemize @bullet +## @item +## @var{k} is the shape parameter of the GEV distribution. (Also denoted gamma or xi.) +## @item +## @var{sigma} is the scale parameter of the GEV distribution. The elements +## of @var{sigma} must be positive. +## @item +## @var{mu} is the location parameter of the GEV distribution. +## @end itemize +## The inputs must be of common size, or some of them must be scalar. +## +## @subheading Return values +## +## @itemize @bullet +## @item +## @var{m} is the mean of the GEV distribution +## +## @item +## @var{v} is the variance of the GEV distribution +## @end itemize +## @seealso{gevcdf, gevfit, gevinv, gevlike, gevpdf, gevrnd} +## @end deftypefn + +## Author: Nir Krakauer <nkrakauer@ccny.cuny.edu> +## Description: Moments of the generalized extreme value distribution + +function [m, v] = gevstat (k, sigma, mu) + + # Check arguments + if (nargin < 3) + print_usage (); + endif + + if (isempty (k) || isempty (sigma) || isempty (mu) || ~ismatrix (k) || ~ismatrix (sigma) || ~ismatrix (mu)) + error ("gevstat: inputs must be numeric matrices"); + endif + + [retval, k, sigma, mu] = common_size (k, sigma, mu); + if (retval > 0) + error ("gevstat: inputs must be of common size or scalars"); + endif + + eg = 0.57721566490153286; %Euler-Mascheroni constant + + m = v = k; + + #find the mean + m(k >= 1) = Inf; + m(k == 0) = mu(k == 0) + eg*sigma(k == 0); + m(k < 1 & k ~= 0) = mu(k < 1 & k ~= 0) + sigma(k < 1 & k ~= 0) .* (gamma(1-k(k < 1 & k ~= 0)) - 1) ./ k(k < 1 & k ~= 0); + + #find the variance + v(k >= 0.5) = Inf; + v(k == 0) = (pi^2 / 6) * sigma(k == 0) .^ 2; + v(k < 0.5 & k ~= 0) = (gamma(1-2*k(k < 0.5 & k ~= 0)) - gamma(1-k(k < 0.5 & k ~= 0)).^2) .* (sigma(k < 0.5 & k ~= 0) ./ k(k < 0.5 & k ~= 0)) .^ 2; + + + +endfunction + +%!test +%! k = [-1 -0.5 0 0.2 0.4 0.5 1]; +%! sigma = 2; +%! mu = 1; +%! [m, v] = gevstat (k, sigma, mu); +%! expected_m = [1 1.4551 2.1544 2.6423 3.4460 4.0898 Inf]; +%! expected_v = [4 3.4336 6.5797 13.3761 59.3288 Inf Inf]; +%! assert (m, expected_m, -0.001); +%! assert (v, expected_v, -0.001);