BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Tom25
Calcite | Level 5

Hello,

 

I previously read that the Cumulative Distribution Function (CDF) for the Generalized Extreme Value (GEV) distribution can be calculated using the CDF function with the 'GEV' distribution type, where the syntax is: CDF('GEV', x, mu, sigma, xi).

 

The following was given as an example code:
data _null_;
mu = 10;
sigma = 2;
xi = 0.5;
x = 12;
cdf_value = CDF('GEV', x, mu, sigma, xi);
put cdf_value;
run;

 

Upon implementing the example code in SAS 9.5, I got the following error:
106 data _null_;
107
108 mu = 10;
109
110 sigma = 2;
111
112 xi = 0.5;
113
114 x = 12;
115
116 cdf_value = CDF('GEV', x, mu, sigma, xi);
117
118 put cdf_value;
119 run;
ERROR: The first argument of the CDF function must be a character string with a value of BERNOULLI,
BETA, BINOMIAL, CAUCHY, CHISQUARE, EXPONENTIAL, F, GAMMA, GAUSSIAN, GEOMETRIC, GENPOISSON,
HYPERGEOMETRIC, IGAUSS, LAPLACE, LOGISTIC, LOGNORMAL, NEGB, NORMAL, NORMALMIX, PARETO,
POISSON, T, UNIFORM, WALD or WEIBULL.
NOTE: Argument 1 to function CDF('GEV',12,10,2,0.5) at line 116 column 15 is invalid.

 

How can this error be resolved?

 

Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

For a general implementation of the GEV in Base SAS (using PROC FCMP and the DATA step), see the article

Implement the generalized extreme value distribution in SAS - The DO Loop

which includes functions for the CDF, PDF, quantiles, and random variates.

 

> I would appreciate it if you could post the codes for pasting the data step for calculating the CDF of GEV into an proc IML module that we call for each value of simulated x data from uniform distribution.

 

OK. Here it is. See the article for additional IML modules that compute the CDF, PDF, quantile function, and random variates.

 

/* compute CDF in an IML function */
proc iml;
/* this function takes a single scalar value (x) and returns the 
   CDF(x) for the GEV(mu, sigma, xi) distribution */
start GEV_CDF(x, mu, sigma, xi);
   if sigma <= 0 then return(.);
   z = (x-mu)/sigma;
   if xi=0 then 
      CDF = exp(-exp(-z));
   else if xi^=0 & xi*z > -1 then 
      CDF = exp(-(1 + xi*z)##(-1/xi));
   else if xi > 0 & z <= -1/xi then 
      CDF = 0;
   else if xi < 0 & z >= 1/abs(xi) then 
      CDF = 1;
   else 
      CDF = .;
   return( CDF );
finish;

/* set the parameters */
mu = 10;
sigma = 2;
xi = 0.5;

/* compute the CDF function on [0,25] */ 
x = T(do(0,25,0.25));
CDF = j(nrow(x),1);
do i = 1 to nrow(x);
   CDF[i] = GEV_CDF(x[i], mu, sigma, xi);
end;

/* visualize the CDF function */ 
title "CDF for GEV Distribution";
call series(x, CDF) grid={x y};

Rick_SAS_0-1753795887036.png

 

View solution in original post

8 REPLIES 8
Quentin
Super User

There is no SAS 9.5 yet (unless you're a SAS insider and doing some early testing of unreleased software. : )

 

The error message is clear.  'GEV' is not an allowed value for for that first argument.  Was it maybe ChatGPT or similar that told you it would work? One of the interesting things about the LLMs is that even when they 'hallucinate' they can do it in ways that make sense.  There could be a 'GEV' argument, and it might be reasonable to assume that there is a 'GEV' argument, but there isn't.

 

If you have PROC IML, this blog post from Rick Wicklin might be a helpful approach:

https://blogs.sas.com/content/iml/2019/07/24/gumbel-distribution-sas.html

 

Tom25
Calcite | Level 5

Thank you for your response. The 9.5 was a typo. I am using SAS 9.4.

Rick_SAS
SAS Super FREQ

You can use the formula for the CDF (see Wikipedia) to implement the CDF. You can either do it inline in the DATA step or define the CDF in PROC FCMP and then call it from the DATA step. I implement the second option below:

proc fcmp outlib=work.funcs.ProbDist;
function GEV_CDF(x, mu, sigma, xi);
   /* CDF formula from 
      https://en.wikipedia.org/wiki/Generalized_extreme_value_distribution
   */
   if sigma <= 0 then return(.);
   z = (x-mu)/sigma;
   if xi=0 then
      CDF = exp(-exp(-z));
   else if xi^=0 and xi*z > -1 then 
      CDF = exp(-(1 + xi*z)**(-1/xi));
   else if xi > 0 and z <= -1/xi then 
      CDF = 0;
   else if xi < 0 and z >= 1/abs(xi) then
      CDF = 1;
   else 
      CDF = .;
   return (CDF);
endsub;
run;

options cmplib=work.funcs;  /* define location of SafeLog function */
data GEV_Test;
mu = 10;
sigma = 2;
xi = 0.5;
do x = 0 to 25 by 0.1;
   CDF = GEV_CDF(x, mu, sigma, xi);
   output;
end;
run;

title "Generalized Extreme Value CDF";
title2 "mu = 10; sigma = 2; xi = 0.5;";
proc sgplot data=GEV_Test;
   series x=x y=CDF;
   yaxis grid min=0 max=1;
run;
Tom25
Calcite | Level 5

Thank you, Rick, for your response. I have a couple of questions:

  1. How can I implement the CDF of the GEV inline in the DATA step?
  2. How can I implement the CDF of the GEV inside proc iml?
Rick_SAS
SAS Super FREQ

@Tom25 wrote:
  1. How can I implement the CDF of the GEV inline in the DATA step?
  2. How can I implement the CDF of the GEV inside proc iml?

1. Copy the body of the FCMP function and paste it into a DATA step. Like this:

/* compute CDF directly in DATA step */
data GEV_Test;
mu = 10;
sigma = 2;
xi = 0.5;
do x = 0 to 25 by 1;
   if sigma <= 0 then CDF=.;
   else do;
   z = (x-mu)/sigma;
   if xi=0 then 
      CDF = exp(-exp(-z));
   else if xi^=0 and xi*z > -1 then 
      CDF = exp(-(1 + xi*z)**(-1/xi));
   else if xi > 0 and z <= -1/xi then 
      CDF = 0;
   else if xi < 0 and z >= 1/abs(xi) then 
      CDF = 1;
   else 
      CDF = .;
   end;
   output;
end;
run;

2. Paste the body into an IML module that you call for each value of x.

Tom25
Calcite | Level 5

Thank you, Rick, for your response.

 

I would appreciate it if you could post the codes for pasting the data step for calculating the CDF of GEV into an proc IML module that we call for each value of simulated x data from uniform distribution.

 

Thanks 

Rick_SAS
SAS Super FREQ

For a general implementation of the GEV in Base SAS (using PROC FCMP and the DATA step), see the article

Implement the generalized extreme value distribution in SAS - The DO Loop

which includes functions for the CDF, PDF, quantiles, and random variates.

 

> I would appreciate it if you could post the codes for pasting the data step for calculating the CDF of GEV into an proc IML module that we call for each value of simulated x data from uniform distribution.

 

OK. Here it is. See the article for additional IML modules that compute the CDF, PDF, quantile function, and random variates.

 

/* compute CDF in an IML function */
proc iml;
/* this function takes a single scalar value (x) and returns the 
   CDF(x) for the GEV(mu, sigma, xi) distribution */
start GEV_CDF(x, mu, sigma, xi);
   if sigma <= 0 then return(.);
   z = (x-mu)/sigma;
   if xi=0 then 
      CDF = exp(-exp(-z));
   else if xi^=0 & xi*z > -1 then 
      CDF = exp(-(1 + xi*z)##(-1/xi));
   else if xi > 0 & z <= -1/xi then 
      CDF = 0;
   else if xi < 0 & z >= 1/abs(xi) then 
      CDF = 1;
   else 
      CDF = .;
   return( CDF );
finish;

/* set the parameters */
mu = 10;
sigma = 2;
xi = 0.5;

/* compute the CDF function on [0,25] */ 
x = T(do(0,25,0.25));
CDF = j(nrow(x),1);
do i = 1 to nrow(x);
   CDF[i] = GEV_CDF(x[i], mu, sigma, xi);
end;

/* visualize the CDF function */ 
title "CDF for GEV Distribution";
call series(x, CDF) grid={x y};

Rick_SAS_0-1753795887036.png

 

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 857 views
  • 6 likes
  • 3 in conversation