diff --git a/src/AbstractAlgebra.jl b/src/AbstractAlgebra.jl index abefdabcf3..4360a7198e 100644 --- a/src/AbstractAlgebra.jl +++ b/src/AbstractAlgebra.jl @@ -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! @@ -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 diff --git a/src/generic/Misc/Rings.jl b/src/generic/Misc/Rings.jl index 0734a5cc97..4a66e21497 100644 --- a/src/generic/Misc/Rings.jl +++ b/src/generic/Misc/Rings.jl @@ -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