Skip to content

summation functions should be lazy, more general than openArray #288

@timotheecour

Description

@timotheecour

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 statistics

This 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.2

note2

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions