Class: Flt::Tolerance
Overview
The Tolerance class is a base class for all tolerances.
Particular tolerance kinds (defined by a type of tolerance and the way to specify its value) are implemented in separate classes derived from Tolerance.
Derived classes must implement at least one of the methods relative_to() or relative_to_many() and may also redefine cast_value() and descr_value()
Direct Known Subclasses
Class Method Summary collapse
-
.big_epsilon(num_class, mult = 1) ⇒ Object
Define a tolerance magnitude in relation to the 'big epsilon' of the floating-point type and context.
-
.bits(n, rounded = true) ⇒ Object
Define a tolerance magnitude as a number of binary digits.
-
.decimals(n, rounded = true) ⇒ Object
Define a tolerance magnitude as a number of decimal digits.
-
.define_sugar(value_class, *tol_classes) ⇒ Object
:nodoc:.
-
.digits(base, n, rounded = true) ⇒ Object
Define a tolerance magnitude as a number of digits of the given base.
-
.epsilon(num_class, mult = 1) ⇒ Object
Define a tolerance magnitude in relation to the 'epsilon' of the floating-point type and context.
Instance Method Summary collapse
-
#[](x) ⇒ Object
Shorthand for value().
-
#cast_value(num_class) ⇒ Object
Returns the tolerance reference value for a numeric class; in derived classes this can be redefined to allow for values which change in value or precision depending on the numeric class or context.
-
#descr_value ⇒ Object
Description of the reference value (can be specialized in derived classes).
-
#eq?(x, y) ⇒ Boolean
equals: x == y within tolerance (relaxed).
-
#equal_to?(x, y) ⇒ Boolean
x == correct value y within tolerance.
-
#greater_than?(x, y) ⇒ Boolean
x > correct value y within tolerance.
-
#gt?(x, y) ⇒ Boolean
greater_than: x > y within tolerance.
-
#initialize(value) ⇒ Tolerance
constructor
A new instance of Tolerance.
-
#integer(x) ⇒ Object
If the argument is close to an integer it rounds it.
-
#integer?(x) ⇒ Boolean
Returns true if the argument is approximately an integer.
-
#less_than?(x, y) ⇒ Boolean
x < correct value y within tolerance.
-
#lt?(x, y) ⇒ Boolean
less-than: x < y within tolerance.
-
#relative_to(x) ⇒ Object
This method is redefined in derived classes to compute the tolerance value in relation to the value x;.
-
#relative_to_many(mode, *xs) ⇒ Object
This method is redefined in derived classes to compute the tolerance value in relation to the values xs; mode must be either :max or :min, and determines if the largerst (relaxed condition) or smallest (strict condition) of the relative tolerances is returned.
-
#seq?(x, y) ⇒ Boolean
strongly equals: x == y within tolerance (strict).
-
#to_s ⇒ Object
Description of the tolerance.
-
#value(x = nil) ⇒ Object
Value of the tolerance for a given (floating-point) quantity.
-
#zero?(x, y = nil) ⇒ Boolean
Is x nearly zero? (zero within tolerance); if a second argument y is specified: is x nearly zero? compared to y?.
Constructor Details
#initialize(value) ⇒ Tolerance
Returns a new instance of Tolerance.
99 100 101 |
# File 'lib/flt/tolerance.rb', line 99 def initialize(value) @value = value end |
Class Method Details
.big_epsilon(num_class, mult = 1) ⇒ Object
Define a tolerance magnitude in relation to the 'big epsilon' of the floating-point type and context. A multiplier may be specified to scale the big epsilon.
This is a tolerance that makes multiplication associative when used with FloatingTolerance.
245 246 247 248 249 250 251 252 |
# File 'lib/flt/tolerance.rb', line 245 def big_epsilon(num_class, mult=1) context = num_class.context e0 = context.epsilon # we could compute with round-up instead of using next_plus, but we can't do that with Float den = (context.Num(1)-e0/2) big_eps = context.next_plus(e0*2/(den*den)) big_eps*mult end |
.bits(n, rounded = true) ⇒ Object
Define a tolerance magnitude as a number of binary digits. If rounded is true it is assumed that results are rounded to n digits; otherwise truncation or directed rounding may occur and the tolerance will be larger.
231 232 233 |
# File 'lib/flt/tolerance.rb', line 231 def bits(n, rounded=true) digits 10, n, rounded end |
.decimals(n, rounded = true) ⇒ Object
Define a tolerance magnitude as a number of decimal digits. If rounded is true it is assumed that results are rounded to n digits; otherwise truncation or directed rounding may occur and the tolerance will be larger.
224 225 226 |
# File 'lib/flt/tolerance.rb', line 224 def decimals(n, rounded=true) digits 10, n, rounded end |
.define_sugar(value_class, *tol_classes) ⇒ Object
:nodoc:
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/flt/tolerance/sugar.rb', line 15 def Tolerance.define_sugar(value_class, *tol_classes) #:nodoc: tol_classes.each do |tol_class| suffix = tol_class.to_s.split('::').last. gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2'). gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase value_class.send(:define_method, suffix) do tol_class.new(self) end end end |
.digits(base, n, rounded = true) ⇒ Object
Define a tolerance magnitude as a number of digits of the given base. If rounded is true it is assumed that results are rounded to n digits; otherwise truncation or directed rounding may occur and the tolerance will be larger.
215 216 217 218 219 |
# File 'lib/flt/tolerance.rb', line 215 def digits(base, n, rounded=true) v = base**(-n) v /= 2 if rounded v end |
.epsilon(num_class, mult = 1) ⇒ Object
Define a tolerance magnitude in relation to the 'epsilon' of the floating-point type and context. A multiplier may be specified to scale the epsilon.
237 238 239 |
# File 'lib/flt/tolerance.rb', line 237 def epsilon(num_class, mult=1) num_class.context.epsilon*mult end |
Instance Method Details
#[](x) ⇒ Object
Shorthand for value()
113 114 115 |
# File 'lib/flt/tolerance.rb', line 113 def [](x) value(x) end |
#cast_value(num_class) ⇒ Object
Returns the tolerance reference value for a numeric class; in derived classes this can be redefined to allow for values which change in value or precision depending on the numeric class or context.
200 201 202 |
# File 'lib/flt/tolerance.rb', line 200 def cast_value(num_class) num_class.context.Num(@value) end |
#descr_value ⇒ Object
Description of the reference value (can be specialized in derived classes)
205 206 207 |
# File 'lib/flt/tolerance.rb', line 205 def descr_value @value.to_s end |
#eq?(x, y) ⇒ Boolean
equals: x == y within tolerance (relaxed)
154 155 156 |
# File 'lib/flt/tolerance.rb', line 154 def eq?(x, y) (x-y).abs <= relative_to_many(:max, x, y) end |
#equal_to?(x, y) ⇒ Boolean
x == correct value y within tolerance
176 177 178 |
# File 'lib/flt/tolerance.rb', line 176 def equal_to?(x, y) (x-y).abs <= relative_to(y) end |
#greater_than?(x, y) ⇒ Boolean
x > correct value y within tolerance
171 172 173 |
# File 'lib/flt/tolerance.rb', line 171 def greater_than?(x,y) x-y > relative_to(y) end |
#gt?(x, y) ⇒ Boolean
greater_than: x > y within tolerance
149 150 151 |
# File 'lib/flt/tolerance.rb', line 149 def gt?(x,y) x-y > relative_to_many(:max, x, y) end |
#integer(x) ⇒ Object
If the argument is close to an integer it rounds it
135 136 137 138 139 |
# File 'lib/flt/tolerance.rb', line 135 def integer(x) # return integer?(x) ? x.round : nil r = x.round ((x-r).abs <= relative_to(x)) ? r : nil end |
#integer?(x) ⇒ Boolean
Returns true if the argument is approximately an integer
129 130 131 132 |
# File 'lib/flt/tolerance.rb', line 129 def integer?(x) # Computing the tolerance at x seems the best option here (x-x.round).abs <= relative_to(x) end |
#less_than?(x, y) ⇒ Boolean
x < correct value y within tolerance
166 167 168 |
# File 'lib/flt/tolerance.rb', line 166 def less_than?(x,y) y-x > relative_to(y) end |
#lt?(x, y) ⇒ Boolean
less-than: x < y within tolerance
144 145 146 |
# File 'lib/flt/tolerance.rb', line 144 def lt?(x,y) y-x > relative_to_many(:max, x, y) end |
#relative_to(x) ⇒ Object
This method is redefined in derived classes to compute the tolerance value in relation to the value x;
If not redefined, relative_to_many will be used.
183 184 185 |
# File 'lib/flt/tolerance.rb', line 183 def relative_to(x) relative_to_many(:max, x) end |
#relative_to_many(mode, *xs) ⇒ Object
This method is redefined in derived classes to compute the tolerance value in relation to the values xs; mode must be either :max or :min, and determines if the largerst (relaxed condition) or smallest (strict condition) of the relative tolerances is returned.
If not redefined, relative_to will be used, but redefining this method can be used to optimize the performance
193 194 195 |
# File 'lib/flt/tolerance.rb', line 193 def relative_to_many(mode, *xs) xs.map{|x| relative_to(x)}.send(mode) end |
#seq?(x, y) ⇒ Boolean
strongly equals: x == y within tolerance (strict)
159 160 161 |
# File 'lib/flt/tolerance.rb', line 159 def seq?(x, y) (x-y).abs <= relative_to_many(:min, x, y) end |
#to_s ⇒ Object
Description of the tolerance
118 119 120 |
# File 'lib/flt/tolerance.rb', line 118 def to_s descr_value end |
#value(x = nil) ⇒ Object
Value of the tolerance for a given (floating-point) quantity
104 105 106 107 108 109 110 |
# File 'lib/flt/tolerance.rb', line 104 def value(x=nil) if x relative_to(x) else @value end end |
#zero?(x, y = nil) ⇒ Boolean
Is x nearly zero? (zero within tolerance); if a second argument y is specified: is x nearly zero? compared to y?
124 125 126 |
# File 'lib/flt/tolerance.rb', line 124 def zero?(x, y=nil) x.zero? || x.abs < value(y || x) end |