package edu.nd.nina.math;
import java.util.Collections;
import java.util.Vector;
import edu.nd.nina.structs.Pair;
/**
* Statistical-Moments
*
* @author weninger
*
*/
public class Moment {
// ClassTPV(TMom, PMom, TMomV)//{
private boolean DefP;
private Vector<Pair<Float, Float>> ValWgtV;
private Float SumW, ValSumW;
private Integer Vals;
private boolean UsableP;
private Float UnusableVal;
private Float Mn, Mx;
private Float Mean, Vari, SDev, SErr;
private Float Median, Quart1, Quart3;
private Vector<Float> DecileV; // 0=min 1=1.decile, ..., 9=9.decile, 10=max
private Vector<Float> PercentileV; // 0=min 1=1.percentile, ...,
// 9=9.percentile, 10=max
public Moment() {
DefP = false;
ValWgtV = new Vector<Pair<Float, Float>>();
SumW = 0f;
ValSumW = 0f;
Vals = 0;
UsableP = false;
UnusableVal = -1f;
Mn = (float)Integer.MAX_VALUE;
Mx = (float)Integer.MIN_VALUE;
Mean = 0f;
Vari = 0f;
SDev = 0f;
SErr = 0f;
Median = 0f;
Quart1 = 0f;
Quart3 = 0f;
DecileV = new Vector<Float>();
PercentileV = new Vector<Float>();
}
public Moment(final Moment Mom) {
DefP = Mom.DefP;
ValWgtV = Mom.ValWgtV;
SumW = Mom.SumW;
ValSumW = Mom.ValSumW;
Vals = Mom.Vals;
UsableP = Mom.UsableP;
UnusableVal = Mom.UnusableVal;
Mn = Mom.Mn;
Mx = Mom.Mx;
Mean = Mom.Mean;
Vari = Mom.Vari;
SDev = Mom.SDev;
SErr = Mom.SErr;
Median = Mom.Median;
Quart1 = Mom.Quart1;
Quart3 = Mom.Quart3;
DecileV = Mom.DecileV;
PercentileV = Mom.PercentileV;
}
public void add(float d) {
add(d,1f);
}
public void add(float Val, float Wgt) {
assert(!DefP);
ValWgtV.add(new Pair<Float, Float>(Val, Wgt));
SumW+=Wgt;
ValSumW+=Wgt*Val;
Vals++;
}
public boolean isDef() {
return DefP;
}
public void def() {
assert (!DefP);
DefP = true;
UsableP = (SumW > 0) && (ValWgtV.size() > 0);
if (UsableP) {
// Mn, Mx
Mn = ValWgtV.get(0).p1;
Mx = ValWgtV.get(0).p1;
// Mean, Variance (Mn, Mx), Standard-Error
Mean = ValSumW / SumW;
Vari = 0f;
if (ValWgtV.size() > 1) {
for (int ValN = 0; ValN < ValWgtV.size(); ValN++) {
final double Val = ValWgtV.get(ValN).p1;
Vari += ValWgtV.get(ValN).p2
* (float) Math.sqrt(Math.abs(Val - Mean));
if (Val < Mn) {
Mn = (float) Val;
}
if (Val > Mx) {
Mx = (float) Val;
}
}
Vari = Vari / SumW;
SErr = (float) Math.sqrt(Vari
/ (ValWgtV.size() * (ValWgtV.size() - 1)));
}
// Standard-Deviation
SDev = (float) Math.sqrt(Vari);
// Median
Collections.sort(ValWgtV);
double CurSumW = 0;
for (int ValN = 0; ValN < ValWgtV.size(); ValN++) {
CurSumW += ValWgtV.get(ValN).p2;
if (CurSumW > 0.5 * SumW) {
Median = ValWgtV.get(ValN).p1;
break;
} else if (CurSumW == 0.5 * SumW) {
Median = (float) (0.5 * (ValWgtV.get(ValN).p1 + ValWgtV
.get(ValN + 1).p1));
break;
}
}
// Quartile-1 and Quartile-3
Quart1 = Quart3 = (float) Integer.MIN_VALUE;
CurSumW = 0;
for (int ValN = 0; ValN < ValWgtV.size(); ValN++) {
CurSumW += ValWgtV.get(ValN).p2;
if (Quart1 == (float) Integer.MIN_VALUE) {
if (CurSumW > 0.25 * SumW) {
Quart1 = ValWgtV.get(ValN).p1;
}
// else if (CurSumW == 0.25*SumW) { Quart1 = 0.5 *
// (ValWgtV[ValN].Val1+ValWgtV[ValN+1].Val1); }
}
if (Quart3 == (float) Integer.MIN_VALUE) {
if (CurSumW > 0.75 * SumW) {
Quart3 = ValWgtV.get(ValN).p1;
}
// else if (CurSumW == 0.75*SumW) { Quart3 = 0.5 *
// (ValWgtV[ValN].Val1+ValWgtV[ValN+1].Val1); }
}
}
// Deciles & Percentiles
CurSumW = 0;
int DecileN = 1, PercentileN = 1;
DecileV = new Vector<Float>(11);
for (int i = 0; i < 11; i++)
DecileV.add(0f);
PercentileV = new Vector<Float>(101);
for (int i = 0; i < 101; i++)
PercentileV.add(0f);
DecileV.set(0, Mn);
DecileV.set(10, Mx);
PercentileV.set(0, Mn);
PercentileV.set(100, Mx);
for (int ValN = 0; ValN < ValWgtV.size(); ValN++) {
CurSumW += ValWgtV.get(ValN).p2;
if (CurSumW > SumW * DecileN * 0.1) {
DecileV.set(DecileN, ValWgtV.get(ValN).p1);
DecileN++;
}
if (CurSumW > SumW * PercentileN * 0.01) {
PercentileV.set(PercentileN, ValWgtV.get(ValN).p1);
PercentileN++;
}
}
}
ValWgtV.clear();
}
public Float getMean() {
return Mean;
}
public Float getSDev() {
return SDev;
}
public Integer getVals() {
return Vals;
}
public Float getMedian() {
return Median;
}
public Float getMin() {
return Mn;
}
public Float getMax() {
return Mx;
}
}