Class: YPetri::Net::State::Features::Record

Inherits:
Array
  • Object
show all
Defined in:
lib/y_petri/net/state/features/record.rb

Overview

A collection of values for a given set of state features.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.load(values) ⇒ Object

Constructs a new Record object from a given collection of values.



13
14
15
# File 'lib/y_petri/net/state/features/record.rb', line 13

def load values
  new( values.dup )
end

Instance Method Details

#delta(pl = nil, transitions: nil) ⇒ Object

Expects a gradient feature identifier (place identifier, or Delta instance), qualified by an array of transitions (named argument :transitions, defaults to all timed transitions in the net), and returns the value for that feature in this record. If an array of delta feature identifiers is supplied, it is mapped to the array of corresponding values. If no delta feature identifier is given, values from this record for all the present delta features are returned.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/y_petri/net/state/features/record.rb', line 154

def delta pl=nil, transitions: nil
  if id.nil? then
    return delta( features.delta ) if transitions.nil?
    delta( features.delta.select do |f|
             f.transitions == transitions.map { |t| net.transition t }
           end )
  else
    return delta( id, transitions: net.tt ) if transitions.nil?
    case id
    when Array then
      id.map { |id| delta id, transitions: transitions }
    else
      fetch( features.delta id, transitions: net.tt( transitions ) )
    end
  end
end

#dump(precision: nil) ⇒ Object

Outputs the record as a plain array.



26
27
28
29
# File 'lib/y_petri/net/state/features/record.rb', line 26

def dump precision: nil
  return features.map &method( :fetch ) if precision.nil?
  features.map { |f| fetch( f ).round( precision ) }
end

#euclidean_distance(other) ⇒ Object

Computes the Euclidean distance from another record.



173
174
175
176
177
# File 'lib/y_petri/net/state/features/record.rb', line 173

def euclidean_distance other
  sum_of_sq = features.map { |f|
    fetch( f ) - other.fetch( f )
  }.map { |dist| dist * dist }.reduce( :+ )
end

#fetch(feature) ⇒ Object

Returns an identified feature, or fails.



40
41
42
43
44
45
46
47
# File 'lib/y_petri/net/state/features/record.rb', line 40

def fetch feature
  super begin
          Integer( feature )
        rescue TypeError
          feat = State().feature( feature )
          features.index( feat )
        end
end

#firing(id = nil) ⇒ Object

Expects a firing feature identifier (transition identifier or Firing instance), and returns the value for that feature in this record. If an array of firing feature identifiers is supplied, it is mapped to the array of corresponding values. If no argument is given, values from this record for all the present flux features are returned.



114
115
116
117
118
119
# File 'lib/y_petri/net/state/features/record.rb', line 114

def firing id=nil
  return firing( features.firing ) if id.nil?
  case id
  when Array then id.map { |id| firing net.transition( id ) }
  else fetch( features.firing id ) end
end

#flux(id = nil) ⇒ Object

Expects a flux feature identifier (transition identifier or Flux instance), and returns the value for that feature in this record. If an array of flux feature identifiers is supplied, it is mapped to the array of corresponding values. If no argument is given, values from this record for all the present flux features are returned.



101
102
103
104
105
106
# File 'lib/y_petri/net/state/features/record.rb', line 101

def flux id=nil
  return flux( features.flux ) if id.nil?
  case id
  when Array then id.map { |id| flux net.transition( id ) }
  else fetch( features.flux id ) end
end

#gradient(id = nil, transitions: nil) ⇒ Object

Expects a gradient feature identifier (place identifier, or Gradient instance), qualified by an array of transitions (named argument :transitions, defaults to all timed transitions in the net), and returns the value for that feature in this record. If an array of gradient feature identifiers is supplied, it is mapped to the array of corresponding values. If no gradient feature identifier is given, values from this record for all the present gradient features are returned.



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/y_petri/net/state/features/record.rb', line 129

def gradient id=nil, transitions: nil
  if id.nil? then
    return gradient( features.gradient ) if transitions.nil?
    gradient( features.gradient.select do |f|
                f.transitions == transitions.map { |t| net.transition t }
              end )
  else
    return gradient( id, transitions: net.T_tt ) if transitions.nil?
    case id
    when Array then
      pl.map { |id| gradient id, transitions: transitions }
    else
      fetch( features.gradient id, transitions: transitions )
    end
  end
end

#marking(arg = nil) ⇒ Object

Expects a marking feature identifier (place identifier or Marking instance), and returns the value for that feature in this record. If an array of marking feature identifiers is supplied, it is mapped to the array of corresponding values. If no argument is given, values from this record for all the present marking features are returned.



88
89
90
91
92
93
# File 'lib/y_petri/net/state/features/record.rb', line 88

def marking arg=nil
  return marking( features.marking ) if arg.nil?
  case arg
  when Array then arg.map { |id| marking id }
  else fetch( features.marking arg ) end
end

Pretty prints the record with feature names.



33
34
35
36
# File 'lib/y_petri/net/state/features/record.rb', line 33

def print gap: 4, precision: 4
  hsh = features.labels >> dump( precision: precision )
  hsh.pretty_print_numeric_values gap: gap, precision: precision
end

#reconstruct(**settings) ⇒ Object

Given a set of marking clamps complementary to the marking features of this record, reconstructs a Simulation instance with the corresponding state. If the net is timed, or if the construction of the simulation from the net has need for any special settings, these must be supplied to this method. (Timed nets eg. require :time named argument for successful construction.)



74
75
76
77
78
79
80
# File 'lib/y_petri/net/state/features/record.rb', line 74

def reconstruct **settings
  marking_clamps = settings[:marking_clamps] || {}
  clamped_places = net.places( marking_clamps.keys )
  ff = features.marking - net.State.marking( clamped_places )
  m_hsh = ff.map { |feat| feat.place } >> marking
  net.simulation marking_clamps: marking_clamps, marking: m_hsh, **settings
end

#state(marking_clamps: {}) ⇒ Object

Returns the state instance implied by the receiver record, and a set of complementary marking clamps supplied as the argument.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/y_petri/net/state/features/record.rb', line 52

def state marking_clamps: {}
  cc = marking_clamps.with_keys { |k| net.place k }.with_values! do |v|
    case v
    when YPetri::Place then v.marking
    when ~:call then v.call
    else v end
  end
  msg = "Marking clamps given in the argument taken together with this " +
    "record's markings must complete the full state of the net!"
  fail TypeError, msg unless
    features.marking.map( &:place ) + net.places( cc.keys ) == net.places
  State().new net.places.map do |place|
    begin; cc.fetch place; rescue IndexError; fetch marking( place ) end
  end
end