2 * Copyright © 2017 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
15 package org.altusmetrum.altoslib_11;
19 public class AltosTimeSeries implements Iterable<AltosTimeValue> {
21 public AltosUnits units;
22 List<AltosTimeValue> values;
24 public void add(AltosTimeValue tv) {
28 public void add(double time, double value) {
29 add(new AltosTimeValue(time, value));
32 public AltosTimeValue get(int i) {
40 public Iterator<AltosTimeValue> iterator() {
41 return values.iterator();
45 double max = AltosLib.MISSING;
46 for (AltosTimeValue tv : values) {
47 if (max == AltosLib.MISSING || tv.value > max)
54 double min = AltosLib.MISSING;
55 for (AltosTimeValue tv : values) {
56 if (min == AltosLib.MISSING || tv.value < min)
62 public AltosTimeSeries integrate(AltosTimeSeries integral) {
68 for (AltosTimeValue v : values) {
73 value += (pvalue + v.value) / 2.0 * (v.time - time);
77 // System.out.printf("%g %g %g\n", time, v.value, value);
78 integral.add(time, value);
84 public AltosTimeSeries differentiate(AltosTimeSeries diff) {
89 for (AltosTimeValue v: values) {
95 double dx = v.time - time;
96 double dy = v.value - value;
99 diff.add(time, dy/dx);
108 private int find_left(int i, double dt) {
110 double t = values.get(i).time - dt;
111 for (j = i; j >= 0; j--) {
112 if (values.get(j).time < t)
119 private int find_right(int i, double dt) {
121 double t = values.get(i).time + dt;
122 for (j = i; j < values.size(); j++) {
123 if (values.get(j).time > t)
130 private double filter_coeff(double dist, double width) {
131 double ratio = dist / (width / 2);
133 return Math.cos(ratio * Math.PI / 2);
136 public AltosTimeSeries filter(AltosTimeSeries f, double width) {
137 double half_width = width/2;
138 for (int i = 0; i < values.size(); i++) {
139 double center_time = values.get(i).time;
140 double left_time = center_time - half_width;
141 double right_time = center_time + half_width;
142 double total_coeff = 0.0;
143 double total_value = 0.0;
145 int left = find_left(i, half_width);
146 int right = find_right(i, half_width);
147 for (int j = left; j <= right; j++) {
148 double j_time = values.get(j).time;
150 if (left_time <= j_time && j_time <= right_time) {
151 double coeff = filter_coeff(j_time - center_time, width);
152 total_coeff += coeff;
153 total_value += coeff * values.get(j).value;
156 if (total_coeff != 0.0)
157 f.add(center_time, total_value / total_coeff);
162 public AltosTimeSeries(String label, AltosUnits units) {
165 this.values = new ArrayList<AltosTimeValue>();