HP Forums
NORMALD_ICDF (LEFT/CENTER/RIGHT) - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: NORMALD_ICDF (LEFT/CENTER/RIGHT) (/thread-14541.html)

Pages: 1 2


NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 02-20-2020 09:03 PM

Of course there are ways to work around this, but my colleagues and I kind'a like this from the otherwise quite backward TI-84 Plus CE-T.

Could the function NORMALD_ICDF() be enhanced with an additional optional argument LEFT/CENTER/RIGHT indicating the position of area p?
If not supplied, then option LEFT is assumed standard.

NORMALD_ICDF(185,10,.85,RIGHT)=NORMALD_ICDF(185,10,1-0.85)=174.635...
NORMALD_ICDF(185,10,.85,CENTER)={170.604...; 199.395...}


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Wes Loewer - 02-21-2020 04:10 AM

(02-20-2020 09:03 PM)StephanP Wrote:  Of course there are ways to work around this, but my colleagues and I kind'a like this from the otherwise quite backward TI-84 Plus CE-T.

Could the function NORMALD_ICDF() be enhanced with an additional optional argument LEFT/CENTER/RIGHT indicating the position of area p?
If not supplied, then option LEFT is assumed standard.

NORMALD_ICDF(185,10,.85,RIGHT)=NORMALD_ICDF(185,10,1-0.85)=174.635...
NORMALD_ICDF(185,10,.85,CENTER)={170.604...; 199.395...}

I agree. My stats students with the TI-84 Plus CE really like this feature. It would be a very welcomed addition to the Prime. In fact, besides adding RIGHT to complement LEFT, I would also add OUTSIDE (or maybe TAILS) to complement CENTER.

Unfortunately, the TI-84 Plus CE only has this feature for the inverse Normal function. Why not include it in the inverse T, Chi Square, and F distributions as well?


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Wes Loewer - 02-29-2020 06:18 AM

(02-20-2020 09:03 PM)StephanP Wrote:  NORMALD_ICDF(185,10,.85,RIGHT)=NORMALD_ICDF(185,10,1-0.85)=174.635...
NORMALD_ICDF(185,10,.85,CENTER)={170.604...; 199.395...}

I've been thinking about this suggestion. Using RIGHT or CENTER works well on the TI-84+ CE because there is a dialog box ("Wizard") that makes selecting RIGHT or CENTER very easy. If I had to actually type out "RIGHT" then I think I would resort to using 1-0.85.

Since Prime stats functions already allow for an optional number of arguments, what if calling NORMALD_ICDF with no arguments popped up dialog box, say something like:

Code:
//////////////////////////
// Inverse Normal CDF   //
//////////////////////////

// local but persistent
LOCAL mu=0, sigma=1, area=0.05, tail=1;

EXPORT NormalInv()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {area,[0],{20,50,2}},
     {tail,{"left","right","inner","outer"},{20,25,3}}
   },
   "Inverse Normal CDF",
   {"Mean:","StdDev:","Area:","Tail:"},
   {"mean of the distribution","standard deviation of the distribution","area (probability)","left, right, inner, or outer area"}
  );
 IF status==0 THEN
  RETURN "canceled";
 END;
 CASE
  // left
  IF tail==1 THEN RETURN NORMALD_ICDF(mu,sigma,area); END
  // right
  IF tail==2 THEN RETURN -NORMALD_ICDF(-mu,sigma,area); END // more precise than NORMALD_ICDF(mu,sigma,1-area) for very small areas
  // inner
  IF tail==3 THEN RETURN {NORMALD_ICDF(mu,sigma,(1-area)/2),-NORMALD_ICDF(-mu,sigma,(1-area)/2)}; END
  // outer (2 tail)
  IF tail==4 THEN RETURN {NORMALD_ICDF(mu,sigma,area/2),-NORMALD_ICDF(-mu,sigma,area/2)}; END
  DEFAULT RETURN "invalid tail";
 END;
END;

When the 84+ introduced the Wizard option for stats functions back in 2011, it make a huge difference in my stats classes. Previously, my students always had difficulty remembering the order of the arguments in the commands. With Stats Wizards, that problem instantly went away.


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 02-29-2020 06:49 AM

Yes!
A Wizard like this would be fantastic!

As an alternative to the full words LEFT, RIGHT, CENTER, OUTER/TAILS, abbreviations L, R, C, O/T would keep the command line version compact as well.

Would the development team be tempted to take up this suggestion, pretty please?


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 02-29-2020 08:29 AM

@Wes
On my desktop PC, the emulator (version 20200116) executes the code perfectly. Really nice. Thank you.

On my laptop, as well as the device connected to it, the same code does not run.
Upon checking, I get a syntax error at line 6, position 12 (at "sigma=1")
As if the word sigma following the comma isn't right.
I've tried switching the language of the device/emulatorconnectivity kit between English and Dutch, suspecting a confusion between decimal point vs. decimal comma. But this did not help.

It's quite odd as both emulators are at the same version 20200116.
My G2 device is at version 20200120.


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 02-29-2020 08:46 AM

Further to this syntax error.
I decided to edit the code on my HP Prime device.
There I noticed that if I press a "," a ";" is written.
Also if i press a "." a "," is written.
So it IS a confusion of delimiters.

Once I replaced all comma's for semicolons in line 6, the check proceeded to the line with
{mu, [0]...
Hmm, it would seem that all comma's need replacing with semicolons.
Yes, after replacing all code related comma's with semicolons, the program runs just fine.

I wonder where this confusion between delimiter comma/semicolon and decimal point/comma is coming from.


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Wes Loewer - 02-29-2020 10:11 AM

(02-29-2020 08:46 AM)StephanP Wrote:  Hmm, it would seem that all comma's need replacing with semicolons.
Yes, after replacing all code related comma's with semicolons, the program runs just fine.

I wonder where this confusion between delimiter comma/semicolon and decimal point/comma is coming from.

Sorry, that's my fault. I forgot to put in the #pragma line which was created for this very purpose of exchanging programs on an international forum. Please insert the following line as the first line of the code and then it should run fine everywhere. (The program was written with US mode settings.)

Code:
#pragma mode( separator(.,;) integer(h64) )



RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - parisse - 03-01-2020 08:08 AM

Would that fit:
Code:

0>> normald_icdf(0.8)
0.841621233573
// Time 0
1>> normald_icdf(0.8,left)
0.841621233573
// Time 0
2>> normald_icdf(0.8,right)
-0.841621233573
// Time 0
3>> normald_icdf(0.8,center)
[-1.28155156554,1.28155156554]
// Time 0
4>> normald_icdf(0.8,tail)
[-0.253347103136,0.253347103136]
// Time 0

0>> normald_icdf(1,2,.8,left)
2.68324246715
// Time 0
1>> normald_icdf(1,2,.8,right)
-0.683242467146
// Time 0
2>> normald_icdf(1,2,.8,center)
[-1.56310313109,3.56310313109]
// Time 0
3>> normald_icdf(1,2,.8,tail)
[0.493305793728,1.50669420627]
// Time 0
source code:
Code:

  gen _normal_icdf(const gen & g,GIAC_CONTEXT){
    if ( g.type==_STRNG && g.subtype==-1) return  g;
    if (g.type!=_VECT)
      return normal_icdf(g,contextptr);
    vecteur v=*g._VECTptr;
    int s=v.size();
    if (s==2 && (v.back()==at_left || v.back()==at_right || v.back()==at_centre|| v.back()==at_tail)){
      v=makevecteur(0,1,v[0],v[1]);
      s=4;
    }    
    if (s<3)
      return gensizeerr(contextptr);
    if (s==4 && v.back()==at_centre)
      v[2]=(1-v[2])/2;
    if (s==4 && v.back()==at_tail)
      v[2]=v[2]/2;
    gen g2(normal_icdf(v[2],contextptr));
    gen g1=v[0]-v[1]*g2;
    g2=v[0]+v[1]*g2;
    if (s==4 && (v.back()==at_centre || v.back()==at_tail))
      return makevecteur(g2,g1);
    if (s==4 && v.back()==at_right)
      return g1;
    return g2;
  }



RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 03-01-2020 08:35 AM

I think that would do very well, indeed.
Are you a member of the development team?

One minor discussion topic: in his code Wes opted for the terms inner/outer as opposed to the center/tail I suggested.
1. if we choose "center" then I think its counterpart should be the plural form "tails"
2. inner/outer are fine with me as well
I leave the decision to those more knowledgeable.

Would the other inverse distribution functions (T, Chi Square, F) be enhanced in a similar way?
What do you think of Wes' suggestion to open a Wizard if this function is called without parameters?


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - parisse - 03-01-2020 02:00 PM

There is no tails command, while tail already exists, that's why I'm using tail as optional argument.


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Mark Hardman - 03-02-2020 03:21 AM

(03-01-2020 08:35 AM)StephanP Wrote:  Are you a member of the development team?

<Groan>

Bernard IS the developer.

https://en.wikipedia.org/wiki/Xcas#History


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Wes Loewer - 03-02-2020 04:39 AM

(03-01-2020 08:35 AM)StephanP Wrote:  One minor discussion topic: in his code Wes opted for the terms inner/outer as opposed to the center/tail I suggested.
1. if we choose "center" then I think its counterpart should be the plural form "tails"

The only reason I used the word "inner" instead of "center" is that I wanted to do the same thing with the other distributions (t, chi square, F) and since chi square and F are not symmetric, calling the interval "center" didn't seem quite right. And if I went with "inner" it seemed only natural to call the opposite "outer". I just made those up. If there is something more standard in textbooks, then I would go with that.

Using "tail" rather than "tails" does seem a bit ambiguous. It could mean "right tail", "left tail", or "two tail".


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - parisse - 03-02-2020 08:31 AM

I (and probably HP too) do not want to add new keywords for something that seems very specialized. If you can find existing keywords that fit better than center or tail, I can change to these keywords. I don't think it's really important, because either HP adds an UI, then the user will not have to worry about, or they don't support this enhancement and only a few experts will know about that...


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 03-02-2020 09:38 AM

I agree that left/right/center/tail are obvious parameters for normald_icdf()

I checked the TI-84 Plus CE-T (OS version 5.4.0.0034)
- only invNorm() offers the additional tail positioning parameter: left/right/center (no tail/outer)
- The other inverse function invT() does not provide this additional positioning parameter.
Maybe we should leave it at normald_icdf() as well.
[attachment=8135]
If you further proceed on this little enhancement, might I ask that abbreviations of these parameters (L/R/C/T) be also allowed, so as to ease entering these values via the command line.
Also, Wes' idea of a Wizard similar to that of the TI-84 does offer students a more fail safe way of entering all parameters in a correct manner.


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - parisse - 03-02-2020 01:16 PM

I don't like the idea to use R/L/C/T, because these are Prime variables and they would be eval-ed unless I make normal_icdf a quoted function and eval by hand all other arguments, but that's too much work...


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 03-02-2020 02:48 PM

(03-02-2020 01:16 PM)parisse Wrote:  I don't like the idea to use R/L/C/T, because these are Prime variables ...
Right.

Would you be warming to the idea of popping up a Wizard if the function is called without any parameters?


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Wes Loewer - 03-02-2020 03:25 PM

(03-02-2020 09:38 AM)StephanP Wrote:  I checked the TI-84 Plus CE-T (OS version 5.4.0.0034)
- only invNorm() offers the additional tail positioning parameter: left/right/center (no tail/outer)
- The other inverse function invT() does not provide this additional positioning parameter.

Yeah, I think TI dropped the ball on this one. Why limit such a useful feature to only one of the distributions? (And why did they leave out inverse chi square and inverse F altogether, even on their CE models?)


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - parisse - 03-03-2020 06:04 AM

(03-02-2020 02:48 PM)StephanP Wrote:  Would you be warming to the idea of popping up a Wizard if the function is called without any parameters?

Well, this is against the philosophy of separating the GUI and the computing kernel, and it would require coding a GUI for each port of Giac. I think that's the job of HP to add a GUI in one of its app.


RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - Wes Loewer - 03-03-2020 06:17 PM

(03-03-2020 06:04 AM)parisse Wrote:  Well, this is against the philosophy of separating the GUI and the computing kernel, and it would require coding a GUI for each port of Giac. I think that's the job of HP to add a GUI in one of its app.

StephanP,
In case you're wondering, Parisse is the brains behind the CAS that HP uses for Prime. I think the rest of the Prime mostly comes HP.

I hope HP does put in an easy to use GUI for the probability distributions. If they do, I'm sure it will look much more professional than mine, but in the mean time, feel free to use the following. I've added the rest of the continuous distributions and put in easy to edit strings so that you can put in whatever descriptions you prefer. (I want to eventually do the same for the discrete distributions, but right now in my stats class, I'm covering topics related to continuous distributions, so that's what's on my mind.)

(corrections welcomed)

Code:

#pragma mode( separator(.,;) integer(h64) )

// Probability Distribution UI

// local but persistent
LOCAL x=0, x2=1, mu=0, sigma=1, area=0.05, tail=1;
LOCAL df=30, ddf=30;


// strings
sLeft = "left tail";
sRight = "right tail";
sInner = "inner interval";
sOuter = "outer tails";
sCanceled = "canceled";
sInvalidTail = "invalid tail";


// label strings
lblMean = "Mean:";
lblStdDev = "StdDev:";
lblX = "X:";
lblX1 = "X1:";
lblX2 = "X2:";
lblDF = "df:";
lblNDF = "Num df:";
lblDDF = "Den df:";
lblArea = "Area:";
lblTail = "Tail:";


// help strings
hMean = "mean of the distribution";
hStdDev = "standard deviation of the distribution";
hX = "independent variable x";
hX1 = "left x";
hX2 = "right x";
hDF = "degrees of freedom";
hNDF = "numerator degrees of freedom";
hDDF = "denominator degrees of freedom";
hArea = "area (probability)";
hTail = "left tail, right tail, inner interval, or outer tails area";


//////////////////////////////////////////////////////////////////////////////////////////
// Normal PDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT NormalPDF()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {x,[0],{20,50,2}}
   },
   "Normal PDF",
   {lblMean,lblStdDev,lblX},
   {hMean,hStdDev,hX}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;
 RETURN NORMALD(mu, sigma, x);
END;


//////////////////////////////////////////////////////////////////////////////////////////
// Normal CDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT NormalCDF()
BEGIN
 LOCAL status;

 status:=CHOOSE(tail,"Normal CDF Tail",sLeft,sRight,sInner,sOuter);
 IF status==0 THEN
  RETURN sCanceled;
 END;

 CASE
  // left
  IF tail==1 THEN 
   status:=INPUT(
    {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {x,[0],{20,50,2}}
    },
    "Normal CDF Left Tail",
    {lblMean,lblStdDev,lblX},
    {hMean,hStdDev,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  NORMALD_CDF(mu, sigma, x);
  END;

  // right
  IF tail==2 THEN 
   status:=INPUT(
    {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {x,[0],{20,50,2}}
    },
    "Normal CDF Right Tail",
    {lblMean,lblStdDev,lblX},
    {hMean,hStdDev,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  NORMALD_CDF(-mu, sigma, -x); // 1-NORMALD_CDF(mu, sigma, x)
  END;

  // inner
  IF tail==3 THEN 
   status:=INPUT(
    {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {x,[0],{20,50,2}},
     {x2,[0],{20,50,3}}
    },
    "Normal CDF Inner Interval",
    {lblMean,lblStdDev,lblX1,lblX2},
    {hMean,hStdDev,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  NORMALD_CDF(mu, sigma, x, x2);
  END;

  // outer
  IF tail==4 THEN 
   status:=INPUT(
    {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {x,[0],{20,50,2}},
     {x2,[0],{20,50,3}}
    },
    "Normal CDF Outer Tails",
    {lblMean,lblStdDev,lblX1,lblX2},
    {hMean,hStdDev,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  NORMALD_CDF(mu, sigma, x)+NORMALD_CDF(-mu, sigma, -x2); //1-NORMALD_CDF(mu, sigma, x, x2)
  END;

  DEFAULT RETURN sInvalidTail;
 END;
END;



//////////////////////////////////////////////////////////////////////////////////////////
// Normal Inverse CDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT NormalInv()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {mu,[0],{20,50,0}},
     {sigma,[0],{20,50,1}},
     {area,[0],{20,50,2}},
     {tail,{sLeft,sRight,sInner,sOuter},{20,25,3}}
   },
   "Normal Inverse CDF",
   {lblMean,lblStdDev,lblArea,lblTail},
   {hMean,hStdDev,hArea,hTail}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;

 CASE
  // left
  IF tail==1 THEN RETURN NORMALD_ICDF(mu,sigma,area); END;
  // right
  IF tail==2 THEN RETURN -NORMALD_ICDF(-mu,sigma,area); END; // NORMALD_ICDF(mu,sigma,1-area)
  // inner
  IF tail==3 THEN RETURN {NORMALD_ICDF(mu,sigma,(1-area)/2),-NORMALD_ICDF(-mu,sigma,(1-area)/2)}; END // NORMALD_ICDF(mu,sigma,(1+area)/2)
  // outer (2 tail)
  IF tail==4 THEN RETURN {NORMALD_ICDF(mu,sigma,area/2),-NORMALD_ICDF(-mu,sigma,area/2)}; END // NORMALD_ICDF(mu,sigma,1-area/2)
  DEFAULT RETURN sInvalidTail;
 END;
END;


//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////
// Student-t PDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT StudentPDF()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,1}}
   },
   "Student-t PDF",
   {lblDF,lblX},
   {hDF,hX}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;
 RETURN STUDENT(df, x);
END;

//////////////////////////////////////////////////////////////////////////////////////////
// Student-t CDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT StudentCDF()
BEGIN
 LOCAL status;

 status:=CHOOSE(tail,"Student-t CDF Tail",sLeft,sRight,sInner,sOuter);
 IF status==0 THEN
  RETURN sCanceled;
 END;

 CASE
  // left
  IF tail==1 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,1}}
    },
    "Student-t CDF Left Tail",
    {lblDF,lblX},
    {hDF,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  STUDENT_CDF(df, x);
  END;

  // right
  IF tail==2 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,1}}
    },
    "Student-t CDF Right Tail",
    {lblDF,lblX},
    {hDF,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN STUDENT_CDF(df, -x); // 1-STUDENT_CDF(df, x)
  END;


  // inner
  IF tail==3 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,2}},
     {x2,[0],{20,50,3}}
    },
    "Student-t CDF Inner Interval",
    {lblDF,lblX1,lblX2},
    {hDF,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  STUDENT_CDF(df, x, x2);
  END;

  // outer
  IF tail==4 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,2}},
     {x2,[0],{20,50,3}}
    },
    "Student-t CDF Outer Tails",
    {lblDF,lblX1,lblX2},
    {hDF,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  STUDENT_CDF(df, x) + STUDENT_CDF(df, -x2); // 1-STUDENT_CDF(df, x, x2)
  END;
 END;
END;


/////////////////////////////////////////////
// Student-t Inverse CDF
/////////////////////////////////////////////
EXPORT StudentInv()
BEGIN
 LOCAL status, t;

 status:=INPUT(
   {
     {df,[0],{20,50,0}},
     {area,[0],{20,50,1}},
     {tail,{sLeft,sRight,sInner,sOuter},{20,25,2}}
   },
   "Student-t Inverse CDF",
   {lblDF,lblArea,lblTail},
   {hDF,hArea,hTail}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;
 CASE
  // left
  IF tail==1 THEN RETURN STUDENT_ICDF(df,area); END;
  // right
  IF tail==2 THEN RETURN -STUDENT_ICDF(df,area); END;
  // inner
  IF tail==3 THEN 
    t:=STUDENT_ICDF(df,(1-area)/2);
    RETURN {t,-t};
  END
  // outer (2 tail)
  IF tail==4 THEN
   t:=STUDENT_ICDF(df,area/2);
   RETURN {t,-t}; 
  END
  DEFAULT RETURN sInvalidTail;
 END;
END;


//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////
// Chi Square PDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT ChiSqPDF()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,1}}
   },
   "Chi Square PDF",
   {lblDF,lblX},
   {hDF,hX}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;
 RETURN CHISQUARE(df, x);
END;


//////////////////////////////////////////////////////////////////////////////////////////
// Chi Square CDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT ChiSqCDF()
BEGIN
 LOCAL status;

 status:=CHOOSE(tail,"Chi Square CDF Tail",sLeft,sRight,sInner,sOuter);
 IF status==0 THEN
  RETURN sCanceled;
 END;

 CASE
  // left
  IF tail==1 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,1}}
    },
    "Chi Square CDF Left Tail",
    {lblDF,lblX},
    {hDF,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  CHISQUARE_CDF(df, x);
  END;

  // right
  IF tail==2 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,1}}
    },
    "Chi Square CDF Right Tail",
    {lblDF,lblX},
    {hDF,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN 1-CHISQUARE_CDF(df, x);
  END;

  // inner
  IF tail==3 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,2}},
     {x2,[0],{20,50,3}}
    },
    "Chi Square CDF Inner Interval",
    {lblDF,lblX1,lblX2},
    {hDF,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN CHISQUARE_CDF(df, x, x2);
  END;

  // outer
  IF tail==4 THEN 
   status:=INPUT(
    {
     {df,[0],{20,50,0}},
     {x,[0],{20,50,2}},
     {x2,[0],{20,50,3}}
    },
    "Chi Square CDF Outer Tails",
    {lblDF,lblX1,lblX2},
    {hDF,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN 1-CHISQUARE_CDF(df, x, x2);
  END;
 END;
END;



/////////////////////////////////////////////
// Chi Square Inverse CDF
/////////////////////////////////////////////

EXPORT ChiSqInv()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {df,[0],{20,50,0}},
     {area,[0],{20,50,1}},
     {tail,{sLeft,sRight,sInner,sOuter},{20,25,2}}
   },
   "Inverse Chi Square CDF",
   {lblDF,lblArea,lblTail},
   {hDF,hArea,hTail}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;

 CASE
  // left
  IF tail==1 THEN RETURN CHISQUARE_ICDF(df,area); END;
  // right
  IF tail==2 THEN RETURN CHISQUARE_ICDF(df,1-area); END;
  // inner
  IF tail==3
   THEN RETURN {CHISQUARE_ICDF(df,(1-area)/2),CHISQUARE_ICDF(df,(1+area)/2)}; END
  // outer (2 tail)
  IF tail==4 THEN RETURN {CHISQUARE_ICDF(df,area/2),CHISQUARE_ICDF(df,1-area/2)}; END
  DEFAULT
   RETURN sInvalidTail;
 END;
END;



//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////
// Fisher PDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT FisherPDF()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {df,[0],{25,50,0}},
     {ddf,[0],{25,50,1}},
     {x,[0],{25,50,2}}
   },
   "Chi Square PDF",
   {lblNDF,lblDDF,lblX},
   {hNDF,hDDF,hX}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;
 RETURN FISHER(df,ddf,x);
END;


//////////////////////////////////////////////////////////////////////////////////////////
// Fisher CDF
//////////////////////////////////////////////////////////////////////////////////////////

EXPORT FisherCDF()
BEGIN
 LOCAL status;

 status:=CHOOSE(tail,"F CDF Tail",sLeft,sRight,sInner,sOuter);
 IF status==0 THEN
  RETURN sCanceled;
 END;

 CASE
  // left
  IF tail==1 THEN 
   status:=INPUT(
    {
     {df,[0],{25,50,0}},
     {ddf,[0],{25,50,1}},
     {x,[0],{25,50,2}}
    },
    "F CDF Left Tail",
    {lblNDF,lblDDF,lblX},
    {hNDF,hDDF,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN  FISHER_CDF(df,ddf,x);
  END;

  // right
  IF tail==2 THEN 
   status:=INPUT(
    {
     {df,[0],{25,50,0}},
     {ddf,[0],{25,50,1}},
     {x,[0],{25,50,2}}
    },
    "F CDF Right Tail",
   {lblNDF,lblDDF,lblX},
    {hNDF,hDDF,hX}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN 1-FISHER_CDF(df,ddf,x);
  END;

  // inner
  IF tail==3 THEN 
   status:=INPUT(
    {
     {df,[0],{25,50,0}},
     {ddf,[0],{25,50,1}},
     {x,[0],{25,50,2}},
     {x2,[0],{25,50,3}}
    },
    "F CDF Inner Interval",
    {lblNDF,lblDDF,lblX1,lblX2},
    {hNDF,hDDF,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN FISHER_CDF(df,ddf,x,x2);
  END;

  // outer
  IF tail==4 THEN 
   status:=INPUT(
    {
     {df,[0],{25,50,0}},
     {ddf,[0],{25,50,1}},
     {x,[0],{25,50,2}},
     {x2,[0],{25,50,3}}
    },
    "F CDF Outer Tails",
    {lblNDF,lblDDF,lblX1,lblX2},
    {hNDF,hDDF,hX1,hX2}
   );   
   IF status==0 THEN
    RETURN sCanceled;
   END;
   RETURN 1-FISHER_CDF(df,ddf,x,x2);
  END;
 END;
END;


/////////////////////////////////////////////
// Fisher Inverse CDF
/////////////////////////////////////////////

EXPORT FisherInv()
BEGIN
 LOCAL status;

 status:=INPUT(
   {
     {df,[0],{25,50,0}},
     {ddf,[0],{25,50,1}},
     {area,[0],{25,50,2}},
     {tail,{sLeft,sRight,sInner,sOuter},{25,25,3}}
   },
   "Inverse F Distribution CDF",
   {lblNDF,lblDDF,lblArea,lblTail},
   {hNDF,hDDF,hArea,hTail}
  );
 IF status==0 THEN
  RETURN sCanceled;
 END;
 CASE
  // left
  IF tail==1 THEN RETURN FISHER_ICDF(df,ddf,area); END;
  // right
  IF tail==2 THEN RETURN FISHER_ICDF(df,ddf,1-area); END;
  // inner
  IF tail==3
   THEN RETURN {FISHER_ICDF(df,ddf,(1-area)/2),FISHER_ICDF(df,ddf,(1+area)/2)}; END
  // outer (2 tail)
  IF tail==4 THEN RETURN {FISHER_ICDF(df,ddf,area/2),FISHER_ICDF(df,ddf,1-area/2)}; END
  DEFAULT
   RETURN sInvalidTail;
 END;
END;



RE: NORMALD_ICDF (LEFT/CENTER/RIGHT) - StephanP - 03-03-2020 07:29 PM

Yeah parisse, I looked him up after I got the groan.

Nice piece of work you've produced here.
I'll give it a test run tomorrow.
Thanks very much.
Unfortunately this won't be available in test mode, so any enhancement in the standard functions/apps will be much appreciated. We'll wait and see.