1 package org.opentrafficsim.road.gtu.strategical.od;
2
3 import java.util.List;
4
5 import org.djunits.unit.DurationUnit;
6 import org.djunits.unit.FrequencyUnit;
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] = trips[i]
90 / (timeVector.get(i + 1).getInUnit(DurationUnit.HOUR) - timeVector.get(i).getInUnit(DurationUnit.HOUR));
91 }
92
93 putDemandVector(origin, destination, category, new FrequencyVector(flow, FrequencyUnit.PER_HOUR, StorageType.DENSE),
94 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),
163 time.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, final int periodIndex,
187 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 = trips / (time.get(periodIndex + 1).getInUnit(DurationUnit.HOUR)
199 - time.get(periodIndex).getInUnit(DurationUnit.HOUR));
200 double[] dem = demand.getValuesInUnit(FrequencyUnit.PER_HOUR);
201 dem[periodIndex] += additionalDemand;
202 putDemandVector(origin, destination, category, new FrequencyVector(dem, FrequencyUnit.PER_HOUR, StorageType.DENSE),
203 time, Interpolation.STEPWISE);
204 }
205 catch (ValueException exception)
206 {
207
208 throw new RuntimeException("Could not get number of trips.", exception);
209 }
210 }
211
212
213
214
215
216
217
218
219 public final int originTotal(final Node origin)
220 {
221 int sum = 0;
222 for (Node destination : getDestinations())
223 {
224 sum += originDestinationTotal(origin, destination);
225 }
226 return sum;
227 }
228
229
230
231
232
233
234
235
236 public final int destinationTotal(final Node destination)
237 {
238 int sum = 0;
239 for (Node origin : getOrigins())
240 {
241 sum += originDestinationTotal(origin, destination);
242 }
243 return sum;
244 }
245
246
247
248
249
250 public final int matrixTotal()
251 {
252 int sum = 0;
253 for (Node origin : getOrigins())
254 {
255 for (Node destination : getDestinations())
256 {
257 sum += originDestinationTotal(origin, destination);
258 }
259 }
260 return sum;
261 }
262
263
264
265
266
267
268
269
270
271 public final int originDestinationTotal(final Node origin, final Node destination)
272 {
273 int sum = 0;
274 for (Category category : getCategories(origin, destination))
275 {
276 DurationVector time = getTimeVector(origin, destination, category);
277 FrequencyVector demand = getDemandVector(origin, destination, category);
278 Interpolation interpolation = getInterpolation(origin, destination, category);
279 for (int i = 0; i < time.size() - 1; i++)
280 {
281 try
282 {
283 sum += interpolation.integrate(demand.get(i), time.get(i), demand.get(i + 1), time.get(i + 1));
284 }
285 catch (ValueException exception)
286 {
287
288 throw new RuntimeException("Could not determine total trips over time.", exception);
289 }
290 }
291 }
292 return sum;
293 }
294
295
296 public final String toString()
297 {
298 return "ODMatrixTrips [" + getOrigins().size() + " origins, " + getDestinations().size() + " destinations, "
299 + getCategorization() + " ]";
300 }
301
302 }