[Cuis-dev] On ArrayedCollection >> incrementFraction

Juan Vuletich juan at cuis.st
Fri May 15 09:18:21 PDT 2026


Hi Francisco,

I just pushed to GitHub a slight variation of your Sliding Window 
iteration (keeping your author initials).

I didn't include the change to existing behavior, as it changes 
semantics and would require further discussion.

I also did not include the changes to FloatArray. I also believe they 
would require further discussion, and in any case, it would delay them 
until an actual use case shows the preferred behavior.

I also added you as a known code author.

WRT how to submit contributions to the base image, email to the list (as 
you did) is the preferred way.

Thanks!

On 2026-05-13 7:28 PM, Francisco Garau via Cuis-dev wrote:
> I've specialized the implementation of the #collectSlidingWindow: so 
> that it uses the bulk primitives. As with the previous version there 
> is a slight difference in behaviour as the resulting array is shorter 
> than the original one. Performance wise, it should be the same as the 
> current implementation. I've created a changeset but couldn't find how 
> to make a PR out of it.
>
> This change makes it easier to add new sliding window operations of 
> any size ... (all current examples are pairs but it could be triples 
> or n-tuples).
>
> *SequenceableCollection >> collectSlidingWindow: aBlock*
>
>     |  numArgs newSize result  slidingWindow |
>     numArgs := aBlock numArgs.
>     self size < numArgs ifTrue: [self errorCollectionTooSmall].
>     newSize := self size - numArgs + 1.
>
>     slidingWindow := Array new: numArgs.
>     result := self species new: newSize.
>     1 to: newSize do: [ :index |
>
>         1 to: numArgs do: [:nArg | slidingWindow at: nArg put: (self
>         at: index - 1 + nArg)].
>
>         result at: index put: (aBlock valueWithArguments:
>         slidingWindow).].
>
>     ^result
>
>
> *FloatArray>>collectSlidingWindow: aBlock*
>
>     |  numArgs newSize  slidedArrays |
>     numArgs := aBlock numArgs.
>     self size < numArgs ifTrue: [self errorCollectionTooSmall].
>     newSize := self size - numArgs + 1.
>
>     slidedArrays := (1 to: numArgs) collect: [:index | | slided |
>
>         slided := self species new: newSize.
>
>         slided replaceFrom: 1 to: newSize with: self startingAt: index].
>
>
>     ^aBlock valueWithArguments: slidedArrays
>
>
> *FloatArray >> slidingAdditions*
>
>     "
>     #(1 3 8 13) asFloat32Array slidingAdditions printString =  'a
>     Float32Array:3(4.0 11.0 21.0)'.
>     "
>     ^self collectSlidingWindow: [:a :b | a += b ]
>
>
>
>
> On Wed, 13 May 2026 at 14:31, Luciano Notarfrancesco via Cuis-dev 
> <cuis-dev at lists.cuis.st> wrote:
>
>     Hi Pancho,
>     Is it really more efficient? I think the idea of the original is
>     to take advantage of the bulk primitives in Float32Array and
>     Float64Array, it should be much faster (Although it contains a
>     superfluous copy, it could be improved a bit).
>
>     On Wed, May 13, 2026 at 19:31 Francisco Garau via Cuis-dev
>     <cuis-dev at lists.cuis.st> wrote:
>
>         I've prepared a more generic and efficient implementation of
>         these methods (with a small difference in behavior) -- I would
>         prefer to submit this changes with a couple of PRs (one for
>         the base image and one for the numerical package). Appreciate
>         if there is any documentation for new contributions.
>
>         #( 3 5 8 ) successiveRatios = { 1. 5/3 . 8/5} ." -- currently
>         the first element is always 1 -- "
>         #( 3 5 8 ) successiveRatios = { 5/3 . 8/5} . " -- the ratios
>         will be calculated in between pairs --"
>
>         *ArrayedCollection >> successiveRatios*
>
>             "
>             #( 3 5 8 ) successiveRatios = {5/3 . 8/5}.
>             ([#(3) successiveRatios] on: Error do: [:ex | ex
>             description ] ) = 'Error: this collection is too small'.
>             "
>             ^self collectSlidingWindow: [:a :b | b / a ]
>
>
>
>         *SequenceableCollection >> collectSlidingWindow: aBlock*
>
>             "
>             (#( 3 5 8 13 ) collectSlidingWindow: [:a :b | a at b]) = {3 at 5
>             . 5 at 8 . 8 at 13}.
>             (#( 3 5 8 13 ) collectSlidingWindow: [:a :b :c | {a. b.
>             c}]) = {{3. 5. 8}. {5. 8. 13.}}.
>             ('hello_word'  collectSlidingWindow: [:a | Character
>             codePoint: a codePoint - 32]) = 'HELLO?WORD'.
>
>             ([#(3) collectWithSlidingWindow: [:a :b | a + b]] on:
>             Error do: [:ex | ex description]) = 'Error: this
>             collection is too small'.
>             "
>             |  tupleSize newSize answer  blockArgs |
>             tupleSize := aBlock numArgs.
>             self size < tupleSize ifTrue: [self errorCollectionTooSmall].
>             newSize := self size - tupleSize + 1.
>             answer := self species new: newSize.
>             blockArgs := Array new: tupleSize.
>             1 to: newSize do: [ :i |
>             1 to: tupleSize do: [:m | blockArgs at: m put: (self at: i
>             + m -1 )].
>             answer at: i put: (aBlock valueWithArguments: blockArgs).].
>             ^ answer
>
>
>
>         On Mon, 11 May 2026 at 20:12, Juan Vuletich via Cuis-dev
>         <cuis-dev at lists.cuis.st> wrote:
>
>             Hi Ezequiel,
>
>             (inline)
>
>             On 2026-05-03 1:48 AM, Ezequiel Birman via Cuis-dev wrote:
>>             Hi!,
>>
>>             I want to collect the successive ratios in a collection
>>             of numbers in order to appreciate how “fast” they grow. I
>>             noticed that the image already implements
>>             ArrayedCollection >> incrementFraction, which is almost
>>             equal to ArrayedCollection >> derivative:
>>
>>                 incrementFraction
>>                 "
>>                 #(10 12.5 15 20) incrementFraction
>>                 "
>>                 | displaced answer |
>>                 displaced := self class new: self size.
>>                 displaced replaceFrom: 2 to: self size with: self
>>                 startingAt: 1.
>>                 displaced at: 1 put: self first.
>>                 answer := self copy.
>>                 answer -= displaced. 
>>
>>                 ^answer / displaced
>>
>>
>>                 derivative
>>                 | displaced answer |
>>                 displaced := self class new: self size.
>>                 displaced replaceFrom: 2 to: self size with: self
>>                 startingAt: 1.
>>                 displaced at: 1 put: self first - self first. "Some
>>                 reasonable zero"
>>                 answer := self copy.
>>                 answer -= displaced.
>>                 ^answer 
>>
>>
>>             I think I want something similar, except for the
>>             subtraction:
>>
>>                 myThing
>>
>>                 | displaced answer |
>>                 displaced := self class new: self size.
>>                 displaced replaceFrom: 2 to: self size with: self
>>                 startingAt: 1.
>>                 displaced at: 1 put: self first.
>>                 answer := self copy. 
>>
>>                 ^answer / displaced
>>
>>
>>             I'll probably need both, since I'm doing exploratory
>>             analysis. And while `myThing`, (which could be named
>>             `successiveRatios` or something along those lines) can
>>             answer if there is a constant or varying growth,
>>             `incrementFraction` measures the rate at which the growth
>>             itself is scaling.
>
>             This makes a lot of sense. I've just added your method
>             with selector #successiveRatios and your author initials.
>             Thanks!
>
>>
>>             Neither `derivative` nor `incrementFraction` nor
>>             `Integral` have senders. Juan, maybe you remember why or
>>             under which circumstances you added them in 2024?
>
>             I'd guess they are older than that. They are there because
>             they are ilustrative and could be of use. It is nice to
>             have this kind of stuff in the image. I believe it shows
>             general Smalltalk-fu.
>
>>              Are there any efforts / packages for numeric or data
>>             analysis?
>
>
>             Not specifically for that, but a good place for it would
>             be https://github.com/Cuis-Smalltalk/Numerics
>
>             Cheers,
>
>>
>>             -- 
>>             Eze
>
>             -- 
>             Juan Vuletich
>             www.cuis.st <http://www.cuis.st>
>             github.com/jvuletich <http://github.com/jvuletich>
>             researchgate.net/profile/Juan-Vuletich <http://researchgate.net/profile/Juan-Vuletich>
>             independent.academia.edu/JuanVuletich <http://independent.academia.edu/JuanVuletich>
>             patents.justia.com/inventor/juan-manuel-vuletich <http://patents.justia.com/inventor/juan-manuel-vuletich>
>
>             -- 
>             Cuis-dev mailing list
>             Cuis-dev at lists.cuis.st
>             https://lists.cuis.st/mailman/listinfo/cuis-dev
>
>         -- 
>         Cuis-dev mailing list
>         Cuis-dev at lists.cuis.st
>         https://lists.cuis.st/mailman/listinfo/cuis-dev
>
>     -- 
>     Cuis-dev mailing list
>     Cuis-dev at lists.cuis.st
>     https://lists.cuis.st/mailman/listinfo/cuis-dev
>
>
-- 
Juan Vuletich
www.cuis.st
github.com/jvuletich
researchgate.net/profile/Juan-Vuletich
independent.academia.edu/JuanVuletich
patents.justia.com/inventor/juan-manuel-vuletich
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20260515/15546bbc/attachment-0001.htm>


More information about the Cuis-dev mailing list