1classdef RewardStateView < handle
2 % REWARDSTATEVIEW View of reward state subset with aggregation operations
4 % Provides aggregation operations (sum, max, min, count) on a subset
5 % of the state vector. Returned by RewardState.at() and forClass().
8 % total() - Sum all values in
this view
9 % max() - Maximum value in
this view
10 % min() - Minimum value in
this view
11 % count() - Number of non-zero entries in
this view
13 % Filter Methods (to transition between views):
14 % atClass(
jobclass) - Filter station view to specific class
15 % atStation(station) - Filter class view to specific station
19 % view = state.at(queue1);
20 % total = view.total(); % Total jobs at queue1
21 % jobs_class1 = view.atClass(class1); % Class1 jobs at queue1
23 % % Class view (all stations)
24 % view = state.forClass(class1);
25 % total = view.total(); % Total class1 jobs
26 % jobs_queue1 = view.atStation(queue1); % Class1 jobs at queue1
28 % See also: RewardState, Reward, setReward
30 properties (Access =
private)
31 values % Vector of state subset values [1 x N]
32 parentState % RewardState reference (for filtering)
33 stationIdx % Station index if this
is a station view, [] otherwise
34 classIdx % Class index if this
is a class view, [] otherwise
38 function self = RewardStateView(vals, parent, stIdx, clIdx)
39 % REWARDSTATEVIEW Constructor
41 % SELF = REWARDSTATEVIEW(VALS, PARENT, STIDX, CLIDX)
43 % VALS - Vector of values [1 x N]
44 % PARENT - RewardState parent
object
45 % STIDX - Station index if station view, [] if class view
46 % CLIDX - Class index if class view, [] if station view
49 self.parentState = parent;
50 self.stationIdx = stIdx;
51 self.classIdx = clIdx;
54 function result = total(self)
55 % TOTAL Sum all values in this view
57 % RESULT = TOTAL(SELF) returns the sum of all state values
60 % view = state.at(queue1);
61 % total_jobs = view.total();
63 result = sum(self.values);
66 function result = max(self)
67 % MAX Maximum value in this view
69 % RESULT = MAX(SELF) returns the maximum state value
72 % view = state.at(queue1);
73 % max_class = max(view);
75 if isempty(self.values)
78 result = max(self.values);
82 function result = min(self)
83 % MIN Minimum value in this view
85 % RESULT = MIN(SELF) returns the minimum state value
88 % view = state.at(queue1);
89 % min_class = min(view);
91 if isempty(self.values)
94 result = min(self.values);
98 function result = count(self)
99 % COUNT Number of non-zero entries
101 % RESULT = COUNT(SELF) returns the number of non-zero values
104 % view = state.at(queue1);
105 % nonempty_classes = count(view);
107 result = sum(self.values > 0);
110 function result = atClass(self,
jobclass)
111 % ATCLASS Filter station view to specific class
113 % RESULT = ATCLASS(SELF, JOBCLASS) returns the scalar population
114 % of JOBCLASS at the station in this view.
116 % Only valid if this
is a station view (created by state.at(station))
119 % view = state.at(queue1);
120 % class1_at_queue1 = view.atClass(class1);
122 if isempty(self.stationIdx)
123 error('RewardStateView:InvalidOperation', ...
124 'atClass()
is only valid for station views (created by state.at(station))');
127 % Return scalar for this station and class
128 result = self.parentState.at(self.stationIdx,
jobclass);
131 function result = atStation(self, station)
132 % ATSTATION Filter class view to specific station
134 % RESULT = ATSTATION(SELF, STATION) returns the scalar population
135 % of the class in this view at the specified STATION.
137 % Only valid if this
is a class view (created by state.forClass(class))
140 % view = state.forClass(class1);
141 % class1_at_queue1 = view.atStation(queue1);
143 if isempty(self.classIdx)
144 error('RewardStateView:InvalidOperation', ...
145 'atStation()
is only valid for class views (created by state.forClass(class))');
148 % Return scalar for this class and station
149 result = self.parentState.at(station, self.classIdx);
153 % Allow arithmetic operations on views
155 function result = plus(self, other)
156 % PLUS Add scalar or compatible view
157 if isa(other, 'RewardStateView')
158 result = sum(self.values) + sum(other.values);
160 result = sum(self.values) + other;
164 function result = minus(self, other)
165 % MINUS Subtract scalar or compatible view
166 if isa(other, 'RewardStateView')
167 result = sum(self.values) - sum(other.values);
169 result = sum(self.values) - other;
173 function result = times(self, other)
174 % TIMES Multiply view values by scalar
175 if isa(other, 'RewardStateView')
176 result = sum(self.values .* other.values);
178 result = self.values * other;
182 function result = mtimes(self, other)
183 % MTIMES Matrix multiply (scalar multiplication)
185 result = sum(self.values) * other;
187 error('RewardStateView:InvalidOperation', ...
188 'Matrix multiplication not supported');
192 function result = ge(self, threshold)
193 % GE Greater than or equal (for conditional rewards)
194 result =
double(sum(self.values) >= threshold);
197 function result = le(self, threshold)
198 % LE Less than or equal (for conditional rewards)
199 result =
double(sum(self.values) <= threshold);
202 function result = gt(self, threshold)
203 % GT Greater than (for conditional rewards)
204 result =
double(sum(self.values) > threshold);
207 function result = lt(self, threshold)
208 % LT Less than (for conditional rewards)
209 result =
double(sum(self.values) < threshold);
216 % DISP Display RewardStateView
217 fprintf('RewardStateView with values: [');
218 fprintf('%g ', self.values);
220 fprintf(' Total: %g\n', self.total());