Class: YPetri::Net::DataSet
- Inherits:
-
Hash
- Object
- Hash
- YPetri::Net::DataSet
- Defined in:
- lib/y_petri/net/data_set.rb
Overview
Dataset is a collection of labeled state records.
Instance Attribute Summary collapse
-
#settings ⇒ Object
readonly
more like event_type, idea not matured yet.
-
#type ⇒ Object
readonly
more like event_type, idea not matured yet.
Class Method Summary collapse
Instance Method Summary collapse
-
#ceiling(event, equal_ok = true) ⇒ Object
Returns the nearest event greater or equal to the supplied event-type argument.
-
#delta(*args) ⇒ Object
Returns a subset of this dataset with only the specified delta features identified by the arguments retained.
-
#distance(other) ⇒ Object
Computes the distance to another dataset.
-
#firing(*args) ⇒ Object
Returns a subset of this dataset with only the specified firing features identified by the arguments retained.
-
#floor(event, equal_ok = true) ⇒ Object
Returns the nearest event smaller or equal to the supplied event-type argument.
-
#flux(ids = nil) ⇒ Object
Returns a subset of this dataset with only the specified flux features identified by the arguments retained.
-
#gradient(*args) ⇒ Object
Returns a subset of this dataset with only the specified gradient features identified by the arguments retained.
-
#inspect ⇒ Object
Inspect string of the instance.
-
#interpolate(event) ⇒ Object
Interpolates the recording an the given point (event).
-
#marking(ids = nil) ⇒ Object
Returns a subset of this dataset with only the specified marking features identified by the arguments retained.
-
#plot(element_ids = nil, time: nil, except: [], **nn) ⇒ Object
Plots the dataset.
-
#print(precision: 4, distance: precision + 4) ⇒ Object
Pretty print the dataset.
-
#reconstruct(event: (fail "No event given!"), **settings) ⇒ Object
Recreates the simulation at a given event label.
-
#record(event) ⇒ Object
Returns the Record instance corresponding to the given recorded event.
-
#reduce_features(*args) ⇒ Object
Expects a hash of features (:marking (alias :state) of places, :firing of tS transitions, :delta of places and/or transitions) and returns the corresponding mapping of the recording.
-
#resample(**nn) ⇒ Object
Resamples the recording.
-
#series(arg = nil) ⇒ Object
Returns the data series for the specified features.
-
#timed? ⇒ Boolean
Type of the dataset.
-
#to_csv ⇒ Object
Outputs the current recording in CSV format.
-
#to_s ⇒ Object
Returns a string briefly discribing the dataset.
Instance Attribute Details
#settings ⇒ Object (readonly)
more like event_type, idea not matured yet
36 37 38 |
# File 'lib/y_petri/net/data_set.rb', line 36 def settings @settings end |
#type ⇒ Object (readonly)
more like event_type, idea not matured yet
36 37 38 |
# File 'lib/y_petri/net/data_set.rb', line 36 def type @type end |
Class Method Details
.__new__ ⇒ Object
7 |
# File 'lib/y_petri/net/data_set.rb', line 7 alias __new__ new |
.new(type: nil) ⇒ Object
9 10 11 12 13 14 15 16 17 |
# File 'lib/y_petri/net/data_set.rb', line 9 def new type: nil __new__ do |hsh, missing| case missing when Float then nil else hsh[ missing.to_f ] end end.tap { |inst| inst.instance_variable_set :@type, type } end |
Instance Method Details
#ceiling(event, equal_ok = true) ⇒ Object
Returns the nearest event greater or equal to the supplied event-type argument. The second optional ordered argument, true by default, controls whether equality is accepted. If set to false, then the nearest greater event is sought.
66 67 68 69 |
# File 'lib/y_petri/net/data_set.rb', line 66 def ceiling( event, equal_ok=true ) e = events.ascending_ceiling( event, equal_ok ) e.nil? ? nil : e end |
#delta(*args) ⇒ Object
Returns a subset of this dataset with only the specified delta features identified by the arguments retained. If no arguments are given, all the delta features from the receiver dataset are selected.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/y_petri/net/data_set.rb', line 242 def delta *args Δt = if args.last.is_a? Hash then args.last.may_have( :delta_time, syn!: :Δt ) args.last.delete( :delta_time ) .tap { args.delete_at( -1 ) if args.last.empty? } end if Δt then return reduce_features net.State.delta, delta_time: Δt if args.empty? reduce_features delta: args, delta_time: Δt else return reduce_features net.State.delta if args.empty? reduce_features delta: args end end |
#distance(other) ⇒ Object
Computes the distance to another dataset.
129 130 131 132 133 134 135 136 |
# File 'lib/y_petri/net/data_set.rb', line 129 def distance( other ) sum_of_sq = events .map { |e| [ e, other.interpolate( e ) ] } .map { |rec1, rec2| rec1.euclidean_distance rec2 } .map { |dist| dist * dist } .reduce( :+ ) sum_of_sq ** 0.5 end |
#firing(*args) ⇒ Object
Returns a subset of this dataset with only the specified firing features identified by the arguments retained. If no arguments are given, all the firing features from the receiver dataset are selected.
205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/y_petri/net/data_set.rb', line 205 def firing *args Δt = if args.last.is_a? Hash then args.last.may_have( :delta_time, syn!: :Δt ) args.last.delete( :delta_time ) .tap { args.delete_at( -1 ) if args.last.empty? } end if Δt then return reduce_features net.State.firing, delta_time: Δt if args.empty? reduce_features firing: args.first, delta_time: Δt else return reduce_features net.State.firing if args.empty? reduce_features firing: args.first end end |
#floor(event, equal_ok = true) ⇒ Object
Returns the nearest event smaller or equal to the supplied event-type argument. The second optional ordered argument, true by default, controls whether equality is accepted. If set to false, then the nearest smaller event is sought.
56 57 58 59 |
# File 'lib/y_petri/net/data_set.rb', line 56 def floor( event, equal_ok=true ) e = events.ascending_floor( event, equal_ok ) e.nil? ? nil : e end |
#flux(ids = nil) ⇒ Object
Returns a subset of this dataset with only the specified flux features identified by the arguments retained. If no arguments are given, all the flux features from the receiver dataset are selected.
224 225 226 227 |
# File 'lib/y_petri/net/data_set.rb', line 224 def flux ids=nil return reduce_features net.State.flux if ids.nil? reduce_features flux: ids end |
#gradient(*args) ⇒ Object
Returns a subset of this dataset with only the specified gradient features identified by the arguments retained. If no arguments are given, all the gradient features from the receiver dataset are selected.
233 234 235 236 |
# File 'lib/y_petri/net/data_set.rb', line 233 def gradient *args return reduce_features net.State.gradient if args.empty? reduce_features gradient: args end |
#inspect ⇒ Object
Inspect string of the instance.
331 332 333 |
# File 'lib/y_petri/net/data_set.rb', line 331 def inspect to_s end |
#interpolate(event) ⇒ Object
Interpolates the recording an the given point (event). Return value is the Record class instance.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/y_petri/net/data_set.rb', line 93 def interpolate( event ) begin record( event ) rescue KeyError => msg timed? or raise TypeError, "Event #{event} not recorded! (%s)" % "simulation type: #{type.nil? ? 'nil' : type}" # (Remark: #floor, #ceiling supported by timed datasets only) fe = floor( event ) fail "Event #{event} has no floor!" if fe.nil? f = Matrix.column_vector record( fe ) ce = ceiling( event ) fail "Event #{event} has no ceiling!" if ce.nil? c = Matrix.column_vector record( ce ) rslt = f + ( c - f ) / ( ce - fe ) * ( event - fe ) features.load( rslt.column_to_a ) end end |
#marking(ids = nil) ⇒ Object
Returns a subset of this dataset with only the specified marking features identified by the arguments retained. If no arguments are given, all the marking features from the receiver dataset are selected.
196 197 198 199 |
# File 'lib/y_petri/net/data_set.rb', line 196 def marking ids=nil return reduce_features net.State.marking if ids.nil? reduce_features marking: ids end |
#plot(element_ids = nil, time: nil, except: [], **nn) ⇒ Object
Plots the dataset. Takes several optional arguments: The list of elements can be supplied as optional first ordered argument, which are then converted into features using Net::State::Features.infer_from_elements
method. Similarly, the features to exclude can be specifies as a list of elements (or a feature-specifying hash) supplied under except:
keyword. Otherwise, feature specification can be passed to the method as named arguments. If no feature specification is explicitly provided, it is assumed that all the features of this dataset are meant to be plotted.
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/y_petri/net/data_set.rb', line 272 def plot( element_ids=nil, time: nil, except: [], **nn ) time = nn.may_have :time, syn!: :time_range events = events() if element_ids.nil? then nn_ff = nn.slice [ :marking, :flux, :firing, :gradient, :delta ] ff = nn_ff.empty? ? features : net.State.features( nn_ff ) else ff = net.State.Features.infer_from_elements( element_ids ) end xff = case except when Array then net.State.Features.infer_from_elements( except ) when Hash then net.State.features( except ) else fail TypeError, "Wrong type of :except argument: #{except.class}" end ff -= xff data_ss = series( ff ) x_range = if time.nil? then from = events.first || 0 to = events.last && events.last > from ? events.last : events.first + 1 "[#{from}:#{to}]" elsif time.is_a? Range then "[#{time.begin}:#{time.end}]" else "[-0:#{SY::Time.magnitude( time ).amount rescue time}]" end Gnuplot.open do |gp| Gnuplot::Plot.new gp do |plot| plot.xrange x_range if nn.has? :yrange, syn!: :y_range then if nn[:yrange].is_a? Range then plot.yrange "[#{nn[:yrange].begin}:#{nn[:yrange].end}]" else fail TypeError, "Argument :yrange is not a range!" end end plot.title nn[:title] || "#{net} plot" plot.ylabel nn[:ylabel] || "Values" plot.xlabel nn[:xlabel] || "Time [s]" ff.labels.zip( data_ss ).each do |label, data_array| plot.data << Gnuplot::DataSet.new( [ events, data_array ] ) { |ds| ds.with = "linespoints" ds.title = label } end end end end |
#print(precision: 4, distance: precision + 4) ⇒ Object
Pretty print the dataset. Takes :precision
and :distance
named arguments, that control the shape of the printed table.
338 339 340 341 342 343 344 345 |
# File 'lib/y_petri/net/data_set.rb', line 338 def print precision: 4, distance: precision + 4 features.labels.print_as_line precision: precision, distance: distance puts '-' * features.size * distance records.each { |record| record.print_as_line precision: precision, distance: distance } return nil end |
#reconstruct(event: (fail "No event given!"), **settings) ⇒ Object
Recreates the simulation at a given event label.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/y_petri/net/data_set.rb', line 79 def reconstruct event: (fail "No event given!"), **settings # settings may include marking clamps, marking, inital marking... rec = interpolate( event ) settings = settings().merge settings if settings() if timed? then rec.reconstruct time: event, **settings else rec.reconstruct **settings end end |
#record(event) ⇒ Object
Returns the Record instance corresponding to the given recorded event.
47 48 49 |
# File 'lib/y_petri/net/data_set.rb', line 47 def record( event ) features.load( fetch event ) end |
#reduce_features(*args) ⇒ Object
Expects a hash of features (:marking (alias :state) of places, :firing of tS transitions, :delta of places and/or transitions) and returns the corresponding mapping of the recording.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/y_petri/net/data_set.rb', line 150 def reduce_features *args Δt = if args.last.is_a? Hash then args.last.may_have( :delta_time, syn!: :Δt ) args.last.delete( :delta_time ) .tap { args.delete_at( -1 ) if args.last.empty? } end reduced_features = net.State.features *args rf_Record = reduced_features.Record reduced_features.new_dataset( type: type ).tap { |dataset| ( events >> records ).each_pair { |event, record| absent_features = reduced_features - features() if absent_features.empty? then # it is a subset line = reduced_features.map { |feature| record.fetch feature } else # it will require simulation reconstruction sim = reconstruct event: event if absent_features.any? { |f| f.timed? rescue false } then fail ArgumentError, "Reconstruction of timed features requires " + "the named arg :delta_time to be given!" unless Δt line = reduced_features.map do |feature| if absent_features.include? feature then if ( feature.timed? rescue false ) then feature.extract_from( sim ).( Δt ) else feature.extract_from( sim ) end else record.fetch feature end end else line = reduced_features.map do |feat| if absent_features.include? feat then feat.extract_from( sim ) else record.fetch( feat ) end end end end dataset.update event => rf_Record.load( line ) } } end |
#resample(**nn) ⇒ Object
Resamples the recording.
113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/y_petri/net/data_set.rb', line 113 def resample **nn time_range = nn.may_have( :time_range, syn!: :time ) || events.first .. events.last sampling = nn.must_have :sampling t0, target_time = time_range.begin, time_range.end t = t0 o = self.class.new type: type loop do o.update t => interpolate( t ) t += sampling return o if t > target_time end end |
#series(arg = nil) ⇒ Object
Returns the data series for the specified features.
140 141 142 143 144 |
# File 'lib/y_petri/net/data_set.rb', line 140 def series arg=nil return records.transpose if arg.nil? reduce_features( State().features( arg ) ).series end |
#timed? ⇒ Boolean
Type of the dataset.
41 42 43 |
# File 'lib/y_petri/net/data_set.rb', line 41 def timed? type == :timed end |
#to_csv ⇒ Object
Outputs the current recording in CSV format.
259 260 261 |
# File 'lib/y_petri/net/data_set.rb', line 259 def to_csv map { |lbl, rec| [ lbl, *rec ].join ',' }.join "\n" end |
#to_s ⇒ Object
Returns a string briefly discribing the dataset.
322 323 324 325 326 327 |
# File 'lib/y_petri/net/data_set.rb', line 322 def to_s "#<DataSet: " + "#{keys.size} records, " + "features: #{features}" + ">" end |