1 package org.opentrafficsim.road.gtu.strategical.od;
2
3 import java.util.List;
4
5 import org.djunits.unit.FrequencyUnit;
6 import org.djunits.unit.TimeUnit;
7 import org.djunits.value.StorageType;
8 import org.djunits.value.ValueException;
9 import org.djunits.value.vdouble.vector.DurationVector;
10 import org.djunits.value.vdouble.vector.FrequencyVector;
11 import org.opentrafficsim.core.network.Node;
12
13 import nl.tudelft.simulation.language.Throw;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public class ODMatrixTrips extends ODMatrix
29 {
30
31
32 private static final long serialVersionUID = 20160928L;
33
34
35
36
37
38
39
40
41
42
43
44 public ODMatrixTrips(final String id, final List<Node> origins, final List<Node> destinations,
45 final Categorization categorization, final DurationVector globalTimeVector, final Interpolation globalInterpolation)
46 {
47 super(id, origins, destinations, categorization, globalTimeVector, globalInterpolation);
48 }
49
50
51
52
53
54
55
56
57
58
59 public final void putTripsVector(final Node origin, final Node destination, final Category category, final int[] trips)
60 {
61 putTripsVector(origin, destination, category, trips, getGlobalTimeVector());
62 }
63
64
65
66
67
68
69
70
71
72
73
74
75 public final void putTripsVector(final Node origin, final Node destination, final Category category, final int[] trips,
76 final DurationVector timeVector)
77 {
78
79 Throw.whenNull(trips, "Demand data may not be null.");
80 Throw.whenNull(timeVector, "Time vector may not be null.");
81 Throw.when(trips.length != timeVector.size() - 1, IllegalArgumentException.class,
82 "Trip data and time data have wrong lengths. Trip data should be 1 shorter than time data.");
83
84 double[] flow = new double[timeVector.size()];
85 try
86 {
87 for (int i = 0; i < trips.length; i++)
88 {
89 flow[i] =
90 trips[i] / (timeVector.get(i + 1).getInUnit(TimeUnit.HOUR) - timeVector.get(i).getInUnit(TimeUnit.HOUR));
91 }
92
93 putDemandVector(origin, destination, category, new FrequencyVector(flow, FrequencyUnit.PER_HOUR,
94 StorageType.DENSE), timeVector, Interpolation.STEPWISE);
95 }
96 catch (ValueException exception)
97 {
98
99 throw new RuntimeException("Could not translate trip vector into demand vector.", exception);
100 }
101 }
102
103
104
105
106
107
108
109
110
111
112 public final int[] getTripsVector(final Node origin, final Node destination, final Category category)
113 {
114 FrequencyVector demand = getDemandVector(origin, destination, category);
115 if (demand == null)
116 {
117 return null;
118 }
119 int[] trips = new int[demand.size() - 1];
120 DurationVector time = getTimeVector(origin, destination, category);
121 Interpolation interpolation = getInterpolation(origin, destination, category);
122 for (int i = 0; i < trips.length; i++)
123 {
124 try
125 {
126 trips[i] = interpolation.integrate(demand.get(i), time.get(i), demand.get(i + 1), time.get(i + 1));
127 }
128 catch (ValueException exception)
129 {
130
131 throw new RuntimeException("Could not translate demand vector into trip vector.", exception);
132 }
133 }
134 return trips;
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149 public final int getTrips(final Node origin, final Node destination, final Category category, final int periodIndex)
150 {
151 DurationVector time = getTimeVector(origin, destination, category);
152 if (time == null)
153 {
154 return 0;
155 }
156 Throw.when(periodIndex < 0 || periodIndex >= time.size() - 1, IllegalArgumentException.class,
157 "Period index out of range.");
158 FrequencyVector demand = getDemandVector(origin, destination, category);
159 Interpolation interpolation = getInterpolation(origin, destination, category);
160 try
161 {
162 return interpolation.integrate(demand.get(periodIndex), time.get(periodIndex), demand.get(periodIndex + 1), time
163 .get(periodIndex + 1));
164 }
165 catch (ValueException exception)
166 {
167
168 throw new RuntimeException("Could not get number of trips.", exception);
169 }
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 public final void increaseTrips(final Node origin, final Node destination, final Category category,
187 final int periodIndex, final int trips)
188 {
189 Interpolation interpolation = getInterpolation(origin, destination, category);
190 Throw.when(!interpolation.equals(Interpolation.STEPWISE), UnsupportedOperationException.class,
191 "Can only increase the number of trips for data with stepwise interpolation.");
192 DurationVector time = getTimeVector(origin, destination, category);
193 Throw.when(periodIndex < 0 || periodIndex >= time.size() - 1, IllegalArgumentException.class,
194 "Period index out of range.");
195 FrequencyVector demand = getDemandVector(origin, destination, category);
196 try
197 {
198 double additionalDemand =
199 trips
200 / (time.get(periodIndex + 1).getInUnit(TimeUnit.HOUR) - time.get(periodIndex).getInUnit(TimeUnit.HOUR));
201 double[] dem = demand.getValuesInUnit(FrequencyUnit.PER_HOUR);
202 dem[periodIndex] += additionalDemand;
203 putDemandVector(origin, destination, category, new FrequencyVector(dem, FrequencyUnit.PER_HOUR,
204 StorageType.DENSE), time, Interpolation.STEPWISE);
205 }
206 catch (ValueException exception)
207 {
208
209 throw new RuntimeException("Could not get number of trips.", exception);
210 }
211 }
212
213
214
215
216
217
218
219
220 public final int originTotal(final Node origin)
221 {
222 int sum = 0;
223 for (Node destination : getDestinations())
224 {
225 sum += originDestinationTotal(origin, destination);
226 }
227 return sum;
228 }
229
230
231
232
233
234
235
236
237 public final int destinationTotal(final Node destination)
238 {
239 int sum = 0;
240 for (Node origin : getOrigins())
241 {
242 sum += originDestinationTotal(origin, destination);
243 }
244 return sum;
245 }
246
247
248
249
250
251 public final int matrixTotal()
252 {
253 int sum = 0;
254 for (Node origin : getOrigins())
255 {
256 for (Node destination : getDestinations())
257 {
258 sum += originDestinationTotal(origin, destination);
259 }
260 }
261 return sum;
262 }
263
264
265
266
267
268
269
270
271
272 public final int originDestinationTotal(final Node origin, final Node destination)
273 {
274 int sum = 0;
275 for (Category category : getCategories(origin, destination))
276 {
277 DurationVector time = getTimeVector(origin, destination, category);
278 FrequencyVector demand = getDemandVector(origin, destination, category);
279 Interpolation interpolation = getInterpolation(origin, destination, category);
280 for (int i = 0; i < time.size() - 1; i++)
281 {
282 try
283 {
284 sum += interpolation.integrate(demand.get(i), time.get(i), demand.get(i + 1), time.get(i + 1));
285 }
286 catch (ValueException exception)
287 {
288
289 throw new RuntimeException("Could not determine total trips over time.", exception);
290 }
291 }
292 }
293 return sum;
294 }
295
296
297 public final String toString()
298 {
299 return "ODMatrixTrips [" + getOrigins().size() + " origins, " + getDestinations().size() + " destinations, "
300 + getCategorization() + " ]";
301 }
302
303 }