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? ⇒ 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.
103 104 105 |
# File 'lib/flt/tolerance.rb', line 103 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.
249 250 251 252 253 254 255 256 |
# File 'lib/flt/tolerance.rb', line 249 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.
235 236 237 |
# File 'lib/flt/tolerance.rb', line 235 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.
228 229 230 |
# File 'lib/flt/tolerance.rb', line 228 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.
219 220 221 222 223 |
# File 'lib/flt/tolerance.rb', line 219 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.
241 242 243 |
# File 'lib/flt/tolerance.rb', line 241 def epsilon(num_class, mult=1) num_class.context.epsilon*mult end |
Instance Method Details
#[](x) ⇒ Object
Shorthand for value()
117 118 119 |
# File 'lib/flt/tolerance.rb', line 117 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.
204 205 206 |
# File 'lib/flt/tolerance.rb', line 204 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)
209 210 211 |
# File 'lib/flt/tolerance.rb', line 209 def descr_value @value.to_s end |
#eq?(x, y) ⇒ Boolean
equals: x == y within tolerance (relaxed)
158 159 160 |
# File 'lib/flt/tolerance.rb', line 158 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
180 181 182 |
# File 'lib/flt/tolerance.rb', line 180 def equal_to?(x, y) (x-y).abs <= relative_to(y) end |
#greater_than?(x, y) ⇒ Boolean
x > correct value y within tolerance
175 176 177 |
# File 'lib/flt/tolerance.rb', line 175 def greater_than?(x,y) x-y > relative_to(y) end |
#gt?(x, y) ⇒ Boolean
greater_than: x > y within tolerance
153 154 155 |
# File 'lib/flt/tolerance.rb', line 153 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
139 140 141 142 143 |
# File 'lib/flt/tolerance.rb', line 139 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
133 134 135 136 |
# File 'lib/flt/tolerance.rb', line 133 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
170 171 172 |
# File 'lib/flt/tolerance.rb', line 170 def less_than?(x,y) y-x > relative_to(y) end |
#lt?(x, y) ⇒ Boolean
less-than: x < y within tolerance
148 149 150 |
# File 'lib/flt/tolerance.rb', line 148 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.
187 188 189 |
# File 'lib/flt/tolerance.rb', line 187 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
197 198 199 |
# File 'lib/flt/tolerance.rb', line 197 def relative_to_many(mode, *xs) xs.map{|x| relative_to(x)}.send(mode) end |
#seq? ⇒ Boolean
strongly equals: x == y within tolerance (strict)
163 164 165 |
# File 'lib/flt/tolerance.rb', line 163 def seq? (x-y).abs <= relative_to_many(:min, x, y) end |
#to_s ⇒ Object
Description of the tolerance
122 123 124 |
# File 'lib/flt/tolerance.rb', line 122 def to_s descr_value end |
#value(x = nil) ⇒ Object
Value of the tolerance for a given (floating-point) quantity
108 109 110 111 112 113 114 |
# File 'lib/flt/tolerance.rb', line 108 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?
128 129 130 |
# File 'lib/flt/tolerance.rb', line 128 def zero?(x, y=nil) x.zero? || x.abs < value(y || x) end |