+ public int compareTo(AltosTimeSeries other) {
+ return label.compareTo(other.label);
+ }
+
+ public void add(AltosTimeValue tv) {
+ data_changed = true;
+ values.add(tv);
+ }
+
+ public void erase_values() {
+ data_changed = true;
+ this.values = new ArrayList<AltosTimeValue>();
+ }
+
+ public void clear_changed() {
+ data_changed = false;
+ }
+
+// public boolean changed() {
+// return data_changed;
+// }
+
+ public void add(double time, double value) {
+ add(new AltosTimeValue(time, value));
+ }
+
+ public AltosTimeValue get(int i) {
+ return values.get(i);
+ }
+
+ private double lerp(AltosTimeValue v0, AltosTimeValue v1, double t) {
+ /* degenerate case */
+ if (v0.time == v1.time)
+ return (v0.value + v1.value) / 2;
+
+ return (v0.value * (v1.time - t) + v1.value * (t - v0.time)) / (v1.time - v0.time);
+ }
+
+ private int after_index(double time) {
+ int lo = 0;
+ int hi = values.size() - 1;
+
+ while (lo <= hi) {
+ int mid = (lo + hi) / 2;
+
+ if (values.get(mid).time < time)
+ lo = mid + 1;
+ else
+ hi = mid - 1;
+ }
+ return lo;
+ }
+
+ /* Compute a value for an arbitrary time */
+ public double value(double time) {
+ int after = after_index(time);
+ double ret;
+
+ if (after == 0)
+ ret = values.get(0).value;
+ else if (after == values.size())
+ ret = values.get(after - 1).value;
+ else {
+ AltosTimeValue b = values.get(after-1);
+ AltosTimeValue a = values.get(after);
+ ret = lerp(b, a, time);
+ }
+ return ret;
+ }
+
+ /* Find the value just before an arbitrary time */
+ public double value_before(double time) {
+ int after = after_index(time);
+
+ if (after == 0)
+ return values.get(0).value;
+ return values.get(after-1).value;
+ }
+
+ /* Find the value just after an arbitrary time */
+ public double value_after(double time) {
+ int after = after_index(time);
+
+ if (after == values.size())
+ return values.get(after-1).value;
+ return values.get(after).value;
+ }
+
+ public double time_of(double value) {
+ double last = AltosLib.MISSING;
+ for (AltosTimeValue v : values) {
+ if (v.value >= value)
+ return v.time;
+ last = v.time;
+ }
+ return last;
+ }
+
+ public int size() {
+ return values.size();