mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
math: Add cumprod and cumproded (#23416)
This pull request adds the `cumproded` function along with its in-place
equivalent, `cumprod`, to the math library. These functions provide
functionality similar to `cumsum` and `cumsummed`, allowing users to
calculate the cumulative sum of elements.
The `cumprod` function computes the cumulative product of elements
in-place, while `cumproded` additionally returns the prod seq.
(cherry picked from commit 4aff12408c)
This commit is contained in:
committed by
narimiran
parent
72ce16990b
commit
f6167cb0c8
@@ -1146,6 +1146,37 @@ 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:
|
||||
## * `prod proc <#sum,openArray[T]>`_
|
||||
## * `cumproded proc <#cumproded,openArray[T]>`_ for a version which
|
||||
## returns cumproded 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:
|
||||
## * `prod proc <#prod,openArray[T]>`_
|
||||
## * `cumprod proc <#cumprod,openArray[T]>`_ for the in-place version
|
||||
runnableExamples:
|
||||
let a = [1, 2, 3, 4]
|
||||
doAssert cumproded(a) == @[1, 2, 6, 24]
|
||||
result = @[]
|
||||
let xLen = x.len
|
||||
if xLen == 0:
|
||||
return @[]
|
||||
result.setLen(xLen)
|
||||
result[0] = x[0]
|
||||
for i in 1 ..< xLen: result[i] = result[i-1] * x[i]
|
||||
|
||||
func cumsummed*[T](x: openArray[T]): seq[T] =
|
||||
## Returns the cumulative (aka prefix) summation of `x`.
|
||||
##
|
||||
@@ -1354,3 +1385,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])
|
||||
|
||||
|
||||
@@ -245,6 +245,25 @@ template main() =
|
||||
empty.cumsum
|
||||
doAssert empty == @[]
|
||||
|
||||
block: # cumprod
|
||||
block: #cumprod int seq return
|
||||
let counts = [ 1, 2, 3, 4 ]
|
||||
doAssert counts.cumproded == [ 1, 2, 6, 24 ]
|
||||
|
||||
block: # cumprod float seq return
|
||||
let counts = [ 1.0, 2.0, 3.0, 4.0 ]
|
||||
doAssert counts.cumproded == [ 1.0, 2.0, 6.0, 24.0 ]
|
||||
|
||||
block: # cumprod int in-place
|
||||
var counts = [ 1, 2, 3, 4 ]
|
||||
counts.cumprod
|
||||
doAssert counts == [ 1, 2, 6, 24 ]
|
||||
|
||||
block: # cumprod float in-place
|
||||
var counts = [ 1.0, 2.0, 3.0, 4.0 ]
|
||||
counts.cumprod
|
||||
doAssert counts == [ 1.0, 2.0, 6.0, 24.0 ]
|
||||
|
||||
block: # ^ compiles for valid types
|
||||
doAssert: compiles(5 ^ 2)
|
||||
doAssert: compiles(5.5 ^ 2)
|
||||
@@ -525,3 +544,4 @@ when not defined(js) and not defined(danger):
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard sum(x)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user