Skip to content

Commit

Permalink
Add generic rising_factorial and rising_factorial2 (#1445)
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin authored Sep 19, 2023
1 parent 6f04bb7 commit f23ced5
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/AbstractAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,8 @@ import .Generic: rels
import .Generic: rescale!
import .Generic: retraction_map
import .Generic: reverse
import .Generic: rising_factorial
import .Generic: rising_factorial2
import .Generic: rowlength
import .Generic: section_map
import .Generic: set_exponent_vector!
Expand Down Expand Up @@ -1094,6 +1096,8 @@ export reverse_cols!
export reverse_rows
export reverse_rows!
export right_kernel
export rising_factorial
export rising_factorial2
export rowlength
export rref
export rref_rational
Expand Down
56 changes: 56 additions & 0 deletions src/generic/Misc/Rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,59 @@ function root(a::RingElem, n::Int)
return b
end

@doc raw"""
rising_factorial(x::RingElement, n::Integer)
Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\cdots (x + n - 1)$.
If $n < 0$ we throw a `DomainError()`.
# Examples
```jldoctest; setup = :(using AbstractAlgebra)
julia> R, x = ZZ[:x];
julia> rising_factorial(x, 1)
x
julia> rising_factorial(x, 2)
x^2 + x
julia> rising_factorial(4, 2)
20
```
"""
function rising_factorial(x::RingElement, n::Integer)
n < 0 && throw(DomainError(n, "Argument must be non-negative"))
n == 0 && return one(x)
return prod(x+i-1 for i in 1:Int(n))
end

@doc raw"""
rising_factorial2(x::RingElement, n::Integer)
Return a tuple containing the rising factorial $x(x + 1)\cdots (x + n - 1)$
and its derivative.
If $n < 0$ we throw a `DomainError()`.
# Examples
```jldoctest; setup = :(using AbstractAlgebra)
julia> R, x = ZZ[:x];
julia> rising_factorial2(x, 1)
(x, 1)
julia> rising_factorial2(x, 2)
(x^2 + x, 2*x + 1)
julia> rising_factorial2(4,2)
(20, 9)
```
"""
function rising_factorial2(x::RingElement, n::Integer)
n < 0 && throw(DomainError(n, "Argument must be non-negative"))
n == 0 && return (one(x), zero(x))
f, F = rising_factorial2(x, Int(n)-1)
# use product rule: [(x+n-1)*f(x)]' = (x+n-1)'*f(x) + (x+n-1)*f'(x)
return (x+n-1)*f, f + (x+n-1)*F
end

0 comments on commit f23ced5

Please sign in to comment.