-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Description
typical summation functions (in std/sums) only use each input element once, so should be usable in an online mode. However the API's in std/sums take an openArray input, preventing that.
Instead, a better API would maintain a state, and allow to update it when a new element is consumed.
example
instead of this API (nim-lang/Nim#16004)
func sumShewchuck*[T: SomeFloat](x: openArray[T]): T =
...use this:
type ShechukState[T: SomeFloat] = object
... # sufficient statistics
proc initShechukState*[T](): ShechukState[T] = ...
proc add[T: SomeFloat](result: var ShechukState[T], a: T) =
...
proc peekFinal*[T: SomeFloat](a: ShechukState): T =
... # non-destructive, hence `let` input
# computes (in the case of sums) the total from the sufficient statisticsThis would be analog to other procs that can be used online, eg:
hash.!& # analog to add
hash.!$ # analog to peekFinal
md5Update # analog to add
md5Final # analog to peekFinal
note, a high level wrapper can still be defined for convenience, eg:
template sumShewchuck*[T: SomeFloat](iter: untyped): untyped =
var state = initShechukState[T]()
for a in iter: add(state, a)
peekFinal(state)ditto with other summation procs
note
even better, can also be generic wrt the summation algorithm:
template sum*[Algo: Shewchuck | SumTwoSum], T: SomeFloat](algo: typedesc[Algo], iter: untyped): untyped =
...
doAssert Shewchuck.sum(@[1.1, 1.2]) == 1.1+1.2note2
more generally, outside of std/sums, lots of algorithms should be usable online, and openArray isn't the best API for those. For these, an Iterable[T] (for now, untyped) is the better API.
Metadata
Metadata
Assignees
Labels
No labels