The Trunk: Collections-nice.926.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Collections-nice.926.mcz

commits-2
Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.926.mcz

==================== Summary ====================

Name: Collections-nice.926
Author: nice
Time: 3 March 2021, 10:46:01.17162 am
UUID: bb5d2ec0-d044-c54f-9e8a-5442626c7573
Ancestors: Collections-nice.925

Fix LimitedPrecisionInterval>>collect: it should avoid accumulating increments which also accumulates rounding errors and make collect: behavior diverge from do:.

Rather than modifying Interval>>collect:, implement the specific inexact arithmetic handling in specific subclass.

Do the same with do: and reverseDo:. This enables restoring the legacy Interval enumerations which perform only one operation per loop instead of two.

Do not check rangeIncludes: in indexOf:startingAt:. This is useless foe exact Interval, and now redundant for LimitedPrecisionInterval thanks to more carefull  implementation of #size.

=============== Diff against Collections-nice.925 ===============

Item was changed:
  ----- Method: Interval>>do: (in category 'enumerating') -----
+ do: aBlock
+
+ | aValue |
+ aValue := start.
+ step < 0
+ ifTrue: [[stop <= aValue]
+ whileTrue:
+ [aBlock value: aValue.
+ aValue := aValue + step]]
+ ifFalse: [[stop >= aValue]
+ whileTrue:
+ [aBlock value: aValue.
+ aValue := aValue + step]]!
- do: aBlock
- "Evaluate aBlock for each value of the interval.
- Implementation note: instead of repeatedly incrementing the value
-    aValue := aValue + step.
- until stop is reached,
- We prefer to recompute value from start
-    aValue := start + (index * step).
- This is better for floating points accuracy, while not degrading Integer and Fraction speed too much.
- Moreover, this is consistent with methods #at: and #size"
-
- | aValue index size |
- index := 0.
- size := self size.
- [index < size]
- whileTrue: [aValue := start + (index * step).
- index := index + 1.
- aBlock value: aValue]!

Item was changed:
  ----- Method: Interval>>indexOf:startingAt: (in category 'accessing') -----
  indexOf: anElement startingAt: startIndex
  "startIndex is an positive integer, the collection index where the search is started."
 
  | index |
- (self rangeIncludes: anElement) ifFalse: [ ^0 ].
  index := (anElement - start / step) rounded + 1.
  (index between: startIndex and: self size) ifFalse: [ ^0 ].
  (self at: index) = anElement ifFalse: [ ^0 ].
  ^index!

Item was changed:
  ----- Method: Interval>>reverseDo: (in category 'enumerating') -----
  reverseDo: aBlock
+ "Evaluate aBlock for each element of my interval, in reverse order."
+ | aValue |
+ aValue := self last.
+ step < 0
+ ifTrue: [[start >= aValue]
+ whileTrue: [aBlock value: aValue.
+ aValue := aValue - step]]
+ ifFalse: [[start <= aValue]
+ whileTrue: [aBlock value: aValue.
+ aValue := aValue - step]]!
- "Evaluate aBlock for each element of my interval, in reverse order.
- Implementation notes: see do: for an explanation on loop detail"
-
- | aValue index |
- index := self size.
- [index > 0]
- whileTrue: [
- index := index - 1.
- aValue := start + (index * step).
- aBlock value: aValue]!

Item was added:
+ ----- Method: LimitedPrecisionInterval>>collect: (in category 'enumerating') -----
+ collect: aBlock
+ "Evaluate aBlock with each of the receiver's elements as the argument.  
+ Collect the resulting values into a collection like the receiver. Answer  
+ the new collection.
+ Implementation notes: see do: for an explanation on loop detail"
+ | result |
+ result := self species new: self size.
+ 1 to: result size do:
+ [:i |
+ "(self at: i) is inlined here to avoid repeated bound checking"
+ result at: i put: i - 1 * step + start].
+ ^ result!

Item was added:
+ ----- Method: LimitedPrecisionInterval>>do: (in category 'enumerating') -----
+ do: aBlock
+ "Evaluate aBlock for each value of the interval.
+ Implementation note: instead of repeatedly incrementing the value
+    aValue := aValue + step.
+ until stop is reached,
+ We prefer to recompute value from start
+    aValue := start + (index * step).
+ This is better for floating points accuracy, while not degrading Integer and Fraction speed too much.
+ Moreover, this is consistent with methods #at: and #size"
+
+ | aValue index size |
+ index := 0.
+ size := self size.
+ [index < size]
+ whileTrue: [aValue := start + (index * step).
+ index := index + 1.
+ aBlock value: aValue]!

Item was added:
+ ----- Method: LimitedPrecisionInterval>>reverseDo: (in category 'enumerating') -----
+ reverseDo: aBlock
+ "Evaluate aBlock for each element of my interval, in reverse order.
+ Implementation notes: see do: for an explanation on loop detail"
+
+ | aValue index |
+ index := self size.
+ [index > 0]
+ whileTrue: [
+ index := index - 1.
+ aValue := start + (index * step).
+ aBlock value: aValue]!