Means API - StephenG1CMZ - 01-04-2018 10:18 AM
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
RE: Means API - StephenG1CMZ - 01-04-2018 10:24 AM
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;
RE: Means API - salvomic - 01-04-2018 10:29 AM
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
|