1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00
gnosygnu_xowa/400_xowa/src_060_utl/gplx/StatRng.java
2014-06-30 00:15:52 -04:00

143 lines
4.8 KiB
Java

/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
class StatRng_fxt {
StatRng rng;
public StatRng_fxt ini_(int lo_ary_len, int hi_ary_len, int... slot_hi_ary) {
rng = new StatRng(lo_ary_len, hi_ary_len, slot_hi_ary);
return this;
}
public StatRng_fxt tst_(int... vals) {
for (int i = 0; i < vals.length; i++) {
int val = vals[i];
rng.Assign(val, val);
}
Tfds.Eq(expd_count, rng.Count, "Count");
Tfds.Eq(expd_lo, rng.Lo, "Lo");
Tfds.Eq(expd_hi, rng.Hi, "Hi");
Tfds.Eq_float(expd_avg, rng.Avg());
Tfds.Eq_ary(expd_lo_ary, XtoIntAry(rng.Lo_ary), "Lo_ary");
Tfds.Eq_ary(expd_hi_ary, XtoIntAry(rng.Hi_ary), "Hi_ary");
Tfds.Eq_ary(expd_slots, XtoIntAry(rng.Slot_ary), "Slots");
return this;
}
int[] XtoIntAry(StatItm[] ary) {
int[] rv = new int[ary.length];
for (int i = 0; i < rv.length; i++)
rv[i] = ary[i].Val;
return rv;
}
int[] XtoIntAry(StatRng[] ary) {
int[] rv = new int[ary.length];
for (int i = 0; i < rv.length; i++)
rv[i] = ary[i].Count;
return rv;
}
public StatRng_fxt Count_(int v) {expd_count = v; return this;} private int expd_count;
public StatRng_fxt Lo_(int v) {expd_lo = v; return this;} private int expd_lo;
public StatRng_fxt Hi_(int v) {expd_hi = v; return this;} private int expd_hi;
public StatRng_fxt Avg_(float v) {expd_avg = v; return this;} float expd_avg;
public StatRng_fxt Lo_ary_(int... v) {expd_lo_ary = v; return this;} private int[] expd_lo_ary;
public StatRng_fxt Hi_ary_(int... v) {expd_hi_ary = v; return this;} private int[] expd_hi_ary;
public StatRng_fxt Slots_(int... v) {expd_slots = v; return this;} private int[] expd_slots;
}
class StatRng {
// public String Key;
public int Lo = Int_.MaxValue;
public int Hi = Int_.MinValue;
public long Sum = 0;
public int Count = 0;
public float Avg() {return Sum / Count;}
public final StatItm[] Lo_ary;
public int Lo_ary_bound;
public int Lo_ary_len;
public final StatItm[] Hi_ary;
public int Hi_ary_bound;
public int Hi_ary_len;
public StatRng[] Slot_ary;
public int Slot_ary_len;
public StatRng(int lo_ary_len, int hi_ary_len, int... slot_hi_ary) {
this.Lo_ary_len = lo_ary_len;
this.Lo_ary_bound = Int_.MaxValue;
this.Lo_ary = NewBoundAry(lo_ary_len, Int_.MaxValue);
this.Hi_ary_len = hi_ary_len;
this.Hi_ary_bound = Int_.MinValue;
this.Hi_ary = NewBoundAry(hi_ary_len, Int_.MinValue);
if (slot_hi_ary != null && slot_hi_ary.length > 0) {
Slot_ary_len = slot_hi_ary.length + 1; // + 1 to hold max value
Slot_ary = new StatRng[Slot_ary_len];
int slot_lo = Int_.MinValue;
for (int i = 0; i < Slot_ary_len - 1; i++) {
int slot_hi = slot_hi_ary[i];
Slot_ary[i] = NewSlot(slot_lo, slot_hi);
slot_lo = slot_hi;
}
Slot_ary[Slot_ary_len - 1] = NewSlot(slot_lo, Int_.MaxValue);
}
}
public void Assign(Object key, int val) {
if (val < Lo) Lo = val;
if (val > Hi) Hi = val;
Sum += val;
++Count;
if (Slot_ary_len > 0) {
for (int i = 0; i < Slot_ary_len; i++) {
StatRng slot = Slot_ary[i];
if (val >= slot.Lo && val < slot.Hi)
slot.Assign(key, val);
}
}
if (val < Lo_ary_bound) {
Lo_ary_bound = CalcCutoff(Lo_ary, CompareAble_.More, Int_.MinValue, key, val);
}
if (val > Hi_ary_bound) {
Hi_ary_bound = CalcCutoff(Hi_ary, CompareAble_.Less, Int_.MaxValue, key, val);
}
}
int CalcCutoff(StatItm[] ary, int comp, int bgn_bound, Object key, int val) {
int new_bound = bgn_bound;
for (int i = 0; i < ary.length; i++) {
StatItm itm = ary[i];
if (Int_.Compare(itm.Val, val) == comp) {
itm = new StatItm(key, val);
ary[i] = itm;
}
if (Int_.Compare(itm.Val, new_bound) == comp) new_bound = itm.Val;
}
return new_bound;
}
StatRng NewSlot(int lo, int hi) {
StatRng rv = new StatRng(0, 0);
rv.Lo = lo;
rv.Hi = hi;
return rv;
}
StatItm[] NewBoundAry(int len, int dflt) {
StatItm[] rv = new StatItm[len];
for (int i = 0; i < len; i++)
rv[i] = new StatItm(null, dflt);
return rv;
}
}
class StatItm {
public Object Key;
public int Val;
public StatItm(Object key, int val) {this.Key = key; this.Val = val;}
}