Skip to content

Commit

Permalink
math: Add cumprod and cumproded
Browse files Browse the repository at this point in the history
  • Loading branch information
lbartoletti committed Apr 10, 2024
1 parent 9b37829 commit cb6b814
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
28 changes: 28 additions & 0 deletions lib/pure/math.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,33 @@ func prod*[T](x: openArray[T]): T =
result = T(1)
for i in items(x): result = result * i

func cumprod*[T](x: var openArray[T]) =
## Transforms ``x`` in-place (must be declared as `var`) into its
## product.
##
## See also:
## * `sum proc <#sum,openArray[T]>`_
## * `cumprodmed proc <#cumprodmed,openArray[T]>`_ for a version which
## returns cumprodmed sequence
runnableExamples:
var a = [1, 2, 3, 4]
cumprod(a)
doAssert a == @[1, 2, 6, 24]
for i in 1 ..< x.len: x[i] = x[i-1] * x[i]

func cumproded*[T](x: openArray[T]): seq[T] =
## Return cumulative (aka prefix) product of ``x``.
##
## See also:
## * `sum proc <#prod,openArray[T]>`_
## * `cumsum proc <#cumprod,openArray[T]>`_ for the in-place version
runnableExamples:
let a = [1, 2, 3, 4]
doAssert cumproded(a) == @[1, 2, 6, 24]
result.setLen(x.len)
result[0] = x[0]
for i in 1 ..< x.len: result[i] = result[i-1] * x[i]

func cumsummed*[T](x: openArray[T]): seq[T] =
## Returns the cumulative (aka prefix) summation of `x`.
##
Expand Down Expand Up @@ -1309,3 +1336,4 @@ func lcm*[T](x: openArray[T]): T {.since: (1, 1).} =
result = x[0]
for i in 1 ..< x.len:
result = lcm(result, x[i])

20 changes: 20 additions & 0 deletions tests/stdlib/tmath.nim
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,25 @@ template main() =
empty.cumsum
doAssert empty == @[]

block: # cumprod
block: #cumprod int seq return
let counts = [ 1, 2, 3, 4 ]
check counts.cumproded == [ 1, 2, 6, 24 ]

block: # cumprod float seq return
let counts = [ 1.0, 2.0, 3.0, 4.0 ]
check counts.cumproded == [ 1.0, 2.0, 6.0, 24.0 ]

block: # cumprod int in-place
var counts = [ 1, 2, 3, 4 ]
counts.cumprod
check counts == [ 1, 2, 6, 24 ]

block: # cumprod float in-place
var counts = [ 1.0, 2.0, 3.0, 4.0 ]
counts.cumprod
check counts == [ 1.0, 2.0, 6.0, 24.0 ]

block: # ^ compiles for valid types
doAssert: compiles(5 ^ 2)
doAssert: compiles(5.5 ^ 2)
Expand Down Expand Up @@ -471,3 +490,4 @@ when not defined(js) and not defined(danger):

doAssertRaises(OverflowDefect):
discard sum(x)

0 comments on commit cb6b814

Please sign in to comment.