Post Reply 
Means API
01-04-2018, 10:18 AM (This post was last modified: 01-04-2018 11:04 PM by StephenG1CMZ.)
Post: #1
Means API
Having noticed that some means are not built-in on the Prime (or perhaps I have overlooked them), here is a collection of common means and other numerical list routines.
See also thread: http://www.hpmuseum.org/forum/thread-9757.html

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
01-04-2018, 10:24 AM
Post: #2
RE: Means API
Means V0.1
Errors are handled by my List program, which should be compiled first (or comment out error messages).
Don't assume negative values are handled as you wish:

Code:

 
 LOCAL CRID:="Means V0.1 © 2018 StephenG1CMZ"; 
 LOCAL MN:="Means.";
 LOCAL MORETEXT:="A bag of mostly means.";//ST:TNG

 //IMPORT({LIST}); //LIST Handles Error Messages

 LOCAL EMPTY0:=0;//ADDITIVE
 LOCAL EMPTY1:=1;//MULTIPLICATIVE

 //NAN CAN BE GENERATED
 //NONE OF THESE ROUTINES HANDLE NAN IN INPUT LST DATA
 //BUT YOU CAN USE List.IsNumeric to check IF A LIST IS OK

 //ERR 
 LOCAL NaN:="NaN";
 LOCAL ListErrK:=1;//1=SHOW ERROR

 //MLSTRING TO MATCH ML
 LOCAL MLS:={
   "MIN:              ",
   "MIN|:             ",
   "HarmonicMean:     ",
   "GeometricMean:    ",
   "GeometricMeanS:   ",
   "GeometricAverage: ",
   "ArithmeticMean:   ",
   "InterQuartileMean: ",
   "MidRange:          ",
   "RootMeanSquare RMS: ",
   "Cubic:             ",
   "ContraHarmonicMean: ",
   "PowerMean(−1):     ",
   "PowerMean(3):      ", 
   "MAX:               ",
   "MAX|:              " };

 EXPORT ABOUT()
 BEGIN
  MSGBOX(CRID);
  MSGBOX(MORETEXT); 
 END;

 // List math procedures
 // Probably only work on numeric lists

 TBD()
 BEGIN
  MSGBOX("TBD");
 END;

 NAN()
 BEGIN
  RETURN NaN;
 END;

 EMPTIES(ST)
 BEGIN 
  RAISE(MN+ST,EL,ListIsEmptyError,"",ListErrK);
  RAISE(MN+ST,EL,ListStatisticsError,"",ListErrK);
  RETURN NAN();
 END;

 DIVBY0(ST)
 BEGIN 
  RAISE(MN+ST,EL,DivBy0Error,"",ListErrK);
  RAISE(MN+ST,EL,ListStatisticsError,"",ListErrK);
  RETURN NAN();//IN LIEU OF +INF OR −INF
 END;

 EXPORT ListΣLIST(LST)
 BEGIN
  RETURN IFTE(SIZE(LST),ΣLIST(LST),EMPTY0); 
 END;

 EXPORT ListΠLIST(LST)
 BEGIN
  LOCAL SZ:=SIZE(LST);
  
  IF SZ>1 THEN RETURN ΠLIST(LST);
  END;
  IF SZ==1 THEN RETURN LST(1);
  END;
  //IF SZ==0 THEN
  RETURN EMPTY1;
  //END;
 END;

 EXPORT ListCUMSUM(LST)
 //Puzzle #41
 //{}={0}
 BEGIN
  RETURN IFTE(SIZE(LST),cumSum(LST),{0}); 
 END;

 EXPORT ListMAX(LST)
 BEGIN
  RETURN IFTE(SIZE(LST),MAX(LST),EMPTY0);
 END;

 EXPORT ListMAXABS(LST)
 //MAX MAGNITUDE IGNORING SIGN
 //
 BEGIN
  RETURN  MAX(ListMAX(LST),−ListMIN(LST));
 END;

 EXPORT ListMEAN(LST)
 BEGIN
  IF SIZE(LST) THEN
   RETURN (mean(LST));
  END;
  RETURN EMPTIES("");
 END;
 //NB MEAN AND MEAN2 CURRENTLY RETURN TYPE RAT
 //USE approx if you prefer real
 EXPORT ListMEAN2(LSTV,LSTF)
 BEGIN
  IF SIZE(LSTV) AND SIZE(LSTF) THEN
   RETURN (mean(LSTV,LSTF));
  END;  
  RETURN EMPTIES("");
 END;
 //MEDIAN
 EXPORT ListMIN(LST)
 BEGIN
  RETURN IFTE(SIZE(LST),MIN(LST),EMPTY0);
 END;

 EXPORT ListMINABS(LST)
 BEGIN
  IF SIZE(LST) THEN
   RETURN MIN(ABS(LST));
  END;
  RETURN 0;
 END;

 //MODE

 EXPORT ArithmeticMean(LST)
 BEGIN
  RETURN ListMEAN(LST);
 END;

 EXPORT ContraHarmonicMean(LST)
 //POSITIVE LST
 BEGIN
  LOCAL DEN:=ListΣLIST(LST);
 
  IF SIZE(LST) THEN
   IF DEN THEN
    RETURN ListΣLIST(LST^2)/DEN;
   ELSE
    RETURN DIVBY0("");
   END;  
  END;
  RETURN EMPTIES(""); 
 END;

EXPORT CubicMean (LST)
 BEGIN
  LOCAL NN:=SIZE(LST);
  IF NN THEN
   RETURN approx(surd(((ListΣLIST(LST^3))/NN),3));
  END;
  RETURN EMPTIES("");
 END;

 GeometricAverage(LST)
 //AVERAGE GROWTH FROM LST(1) TO LST(0) IN NN STEPS.
 //NB INTERMEDIATE VALUES ARE NOT REFERENCED
 //BUT SIZE OF LST IS
 BEGIN
  LOCAL AZ,AN;
  LOCAL NNN:=SIZE(LST)-1;//BECAUSE 1.N NOT 0.N
  IF NNN>0 THEN
   AZ:=LST(1);
   IF AZ THEN
    AN:=LST(SIZE(LST));
    RETURN (AN/AZ)^(1/NNN);
   ELSE
    RETURN DIVBY0("");
   END;
  END;
  RETURN EMPTIES("");
 END;

 EXPORT GeometricMean(LST)
 //Geometric mean
 //Positive (not checked)
 //ANY 0:0
 //Products can overflow:See GMeanS
 BEGIN
  LOCAL NN:=SIZE(LST);
  IF NN THEN 
   //using surd instead of ^1/N avoids <0FAIL
   //negatives may yield imaginary mean
   RETURN approx(surd(ListΠLIST(LST),NN));
  END;
  RETURN EMPTIES("");
 END;

 //NB WHEN NEGATIVES ARE PRESENT
 //GMEAN AND GMEANS YIELD DIFFERING RESULTS
 //VERIFY?

 EXPORT GeometricMeanS(LST)
 //SLOW VERSION USES LOGS TO AVOID OVERFLOW
 //SO ABS TO AVOID NEGATIVES
 //ANY 0=0 AS GMEAN
 BEGIN
 LOCAL MULT,SIGNLST;
 LOCAL NN:=SIZE(LST);
 IF NN THEN
  IF POS(LST,0) THEN
   RETURN 0;
  END;
  //MULTIPLY NEGATIVES TBC
  //RECOMMENDED: MULT=(−1)^(MM/NN): MM=COUNT NEGATIVES
  //TO AVOID COUNTING  MM I THINK MULTIPLYING ALL SIGNS MAY BE QUICKER 
  //TBC
  SIGNLST:=SIGN(LST);
  MULT:=IFTE(POS(SIGNLST,−1),ListΠLIST(SIGNLST),1);//COULD JUST MULTIPLY ALWAYS
 
  //EITHER LOG COULD BE USED
  RETURN MULT*e^(ListΣLIST(LN(ABS(LST)))/NN);
 END;
 RETURN EMPTIES("");
 END;

 EXPORT HarmonicMean(LST)
 //Positive preferred
 //EG(1,−1)=/0=NAN
 BEGIN
  LOCAL NN:=SIZE(LST);
  LOCAL DEN;
  IF NN THEN
   IF POS(LST,0) THEN
    RETURN 0;//ANY 0=0
   END;
   DEN:=ΣLIST(1/LST);//0 UNEXPECTED:UNDERFLOW?=INF MEAN
   RETURN IFTE(DEN,SIZE(LST)/DEN,NAN());//GUARD 0 DEN
  END; 
  RETURN EMPTIES("");
 END;

 EXPORT InterQuartileMean (SORTEDLST)
 //InterQuartileMean:List must be sorted
 //TBC
 //DO THE SLICE INDICES NEED CASTING TO INT
 //IF SO ROUND OR TRUNC?
 //THIS IMPLEMENT IS ONLY CORRECT IF THE SIZE IS DIVISBLE BY 4
 //TBC
 BEGIN
  LOCAL NN:=SIZE(SORTEDLST);
  IF SIZE(SORTEDLST)≥4 THEN
   RETURN (2/NN)*ListΣLIST(SORTEDLST({(NN/4)+1,(3*NN/4)}));
  END;
  //SMALL LIST: FALLBACK TO MEAN
  RETURN ArithmeticMean(SORTEDLST);//In this case it neednt be
 END;

 EXPORT InterQuartileMeanL(LST)
 //This temporary version also works if not divisible by 4
 //But is inefficient
 //It is not recommended
 BEGIN
  LOCAL NN:=SIZE(LST);
  //MAKE LST 4 TIMES BIGGER INSTEAD:MAY FAIL
  LOCAL TMP;
  TMP:=CONCAT(LST,LST);
  TMP:=CONCAT(TMP,LST);
  TMP:=CONCAT(TMP,LST);
  TMP:=SORT(TMP);
  RETURN (ArithmeticMean(TMP({NN+1,3*NN})));
 END;

 EXPORT MidRange(LST)
 BEGIN
  //MSGBOX("MID");
  RETURN (ListMAX(LST)+ListMIN(LST))/2;
 END;
 
EXPORT PowerMean (LST,PWR)
 //AKA GeneralisedMean
 //PWR:REAL NONZERO
 //LST:POSITIVE SO ABS
 //IMPLEMENT MAY DIFFER FROM CUBIC ETC
 BEGIN
  LOCAL NN:=SIZE(LST);
  IF NN THEN
   RETURN IFTE(PWR,approx(surd(((ListΣLIST(ABS(LST)^(PWR)))/NN),PWR)),DIVBY0("")); 
  END;
  RETURN EMPTIES("");
 END;

 EXPORT RMS(LST)
 BEGIN
  LOCAL NN:=SIZE(LST);
  IF NN THEN
   RETURN √((ListΣLIST(LST^2))/NN);
  END;
  RETURN EMPTIES("");
 END;

 EXPORT RootMeanSqare(LST)
 BEGIN
  RETURN RMS(LST);
 END;

 EXPORT TruncatedMean(LST)
 //EXCLUDE EXTREMES
 BEGIN
  TBD();
 END;
 //SPECIFY A PERCENTAGE OR SIMILAR TO EXCLUDE
 EXPORT WinsorisedMean(LST)
 //A VARIATION OF TRUNCATED:CLAMP EXTREMES
 //There is an implementation in the library
 BEGIN
  TBD();
 END;

 EXPORT ManyMeans(LST)
 //WHAT NUMBER DID YOU WANT? :)
 BEGIN
  LOCAL SAVED:=ListShowErrors;
  LOCAL ML:={};
  //SEQUENCE TO MATCH MLS
  ListShowErrors:=0;
  ML:={
   ListMIN(LST),
   ListMINABS(LST),
   HarmonicMean(LST),
   GeometricMean(LST),
   GeometricMeanS(LST),
   GeometricAverage(LST),
   ArithmeticMean(LST),
   InterQuartileMean(SORT(LST)),
   MidRange(LST),
   RMS(LST),
   CubicMean(LST),
   ContraHarmonicMean(LST),
   PowerMean(LST,−1),
   PowerMean(LST,3),
   ListMAX(LST),
   ListMAXABS(LST) };

  ListShowErrors:=SAVED;
  RETURN ML;
 END;
  
 EXPORT ManyMeansCHS(LST)
 BEGIN
  LOCAL II,TM,CHS;
  LOCAL ML:={};
  LOCAL RLST;

  //PRINT(MN+" SIZE: "+SIZE(LST));//SIZE WARNS OF POSSIBLE SLOW CALCS
  TM:=TEVAL(ML:=ManyMeans(LST));//TIMED CALCULATION
  RLST:=MAKELIST((MLS(II)+ML(II)),II,1,SIZE(MLS));
  CHOOSE(CHS,CRID,RLST);
  //PRINT("Used "+TM);//Performance.And confirms list completed.
 END;

 EXPORT ManyMeansPRINT(LST)
 BEGIN
  LOCAL II,TM;
  LOCAL ML:={};

  PRINT();
  PRINT(CRID);
  PRINT(MN+" SIZE: "+SIZE(LST));//SIZE WARNS OF POSSIBLE SLOW CALCS
  TM:=TEVAL(ML:=ManyMeans(LST));//TIMED CALCULATION
  
  FOR II FROM 1 TO SIZE(MLS) DO
   PRINT(MLS(II)+ML(II));
  END;
  PRINT("Used "+TM);//Performance.And confirms list completed.
 END;

 EXPORT IsMEAN(LST,XX,PWR)
 //Is XX a possible mean
 //First exact match
 BEGIN
  LOCAL ML:=ManyMeans(LST);

  RETURN POS(ML,XX);
 END;

 EXPORT IsNAN(LST)
 BEGIN
  MSGBOX(MN+"IsNAN\nUse StephenG1CMZ's List.IsNUMERIC");
  RETURN 0;
 END;

EXPORT MeansSeeAlso ()
 BEGIN
  LOCAL KK;
  LOCAL CatFuns:={
   "cumSum",
   "deltalist",
   "max",
   "mean",
   "min",
   "product",
   "trunc"};
  //Just Listed as a reminder:not Selectable
  CHOOSE(KK,MN+" Relevant Cat Functions",CatFuns)

 END;

 EXPORT MEANS()
 BEGIN
  //DIVBY0("");//TEST
 END;

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
01-04-2018, 10:29 AM
Post: #3
RE: Means API
Well, Stephen, thank you!
I had also post here very short code to get Geometric, Harmonic (and also Weighted, but this is already in the Prime) Mean. I'm putting there the link to your code, now.

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)