From fdbd10ccfe60cd34aecc102eb2986fb81a4fcd07 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 20 Mar 2024 16:16:58 -0500 Subject: [PATCH 1/5] add dep on SymbolicLimits.jl and export `limit` --- Project.toml | 2 ++ src/Symbolics.jl | 5 +++++ src/limits.jl | 20 ++++++++++++++++++++ test/limits.jl | 13 +++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 src/limits.jl create mode 100644 test/limits.jl diff --git a/Project.toml b/Project.toml index d83642f33..5f4228de6 100644 --- a/Project.toml +++ b/Project.toml @@ -36,6 +36,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5" +SymbolicLimits = "19f23fe9-fdab-4a78-91af-e7b7767979c3" SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b" [weakdeps] @@ -81,6 +82,7 @@ Setfield = "1" SpecialFunctions = "2" StaticArrays = "1.1" SymbolicIndexingInterface = "0.3" +SymbolicLimits = "0.2.0" SymbolicUtils = "1.4" julia = "1.10" diff --git a/src/Symbolics.jl b/src/Symbolics.jl index cb177dd88..e221c9f99 100644 --- a/src/Symbolics.jl +++ b/src/Symbolics.jl @@ -37,6 +37,8 @@ using PrecompileTools using MacroTools using SymbolicIndexingInterface + + import SymbolicLimits end @reexport using SymbolicUtils RuntimeGeneratedFunctions.init(@__MODULE__) @@ -149,6 +151,9 @@ include("error_hints.jl") include("struct.jl") include("operators.jl") +include("limits.jl") +export limit + # Hacks to make wrappers "nicer" const NumberTypes = Union{AbstractFloat,Integer,Complex{<:AbstractFloat},Complex{<:Integer}} (::Type{T})(x::SymbolicUtils.Symbolic) where {T<:NumberTypes} = throw(ArgumentError("Cannot convert Sym to $T since Sym is symbolic and $T is concrete. Use `substitute` to replace the symbolic unwraps.")) diff --git a/src/limits.jl b/src/limits.jl new file mode 100644 index 000000000..89b1172f6 --- /dev/null +++ b/src/limits.jl @@ -0,0 +1,20 @@ +""" + limit(expr, var, h[, side::Symbol]) + +Compute the limit of `expr` as `var` approaches `h`. + +`side` indicates the direction from which `var` approaches `h`. It may be one of `:left`, +`:right`, or `:both`. If `side` is `:both` and the two sides do not align, an error is +thrown. Side defaults to `:both` for finite `h`, `:left` for `h = Inf`, and `:right` for +`h = -Inf`. + +`expr` must be compoesed of `log`, `exp`, constants, and the rational opperators `+`, `-`, +`*`, and `/`. This limitation may eventually be relaxed. + +!!! Warning + Because symbolic limit computation is undecidable, this function necessarily employs + heuristics and may occasionally return wrong answers. Nevertheless, please report wrong + answers as issues as we aim to have heuristics that produce correct answers in all + practical cases. +""" +limit(expr, var, h, side...) = SymbolicLimits.limit(expr, var, h, side...)[1] diff --git a/test/limits.jl b/test/limits.jl new file mode 100644 index 000000000..fd29067c9 --- /dev/null +++ b/test/limits.jl @@ -0,0 +1,13 @@ +using Symbolics, Test + +@testset "limits" begin + @syms x + @test limit(exp(x+exp(-x))-exp(x), x, Inf) == 1 + @test limit(x^7/exp(x), x, Inf) == 0 + @test limit(log(log(x*exp(x*exp(x))+1))-exp(exp(log(log(x))+1/x)), x, Inf) == 0 + @test limit(2exp(-x)/exp(-x), x, 0) == 2 + + @test_throws ArgumentError limit(1/x, x, 0) + @test limit(1/x, x, 0, :left)[1] == -Inf + @test limit(1/x, x, 0, :right)[1] == Inf +end From 172c4b3a6f571b22d17711ff453dab03289b2667 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 20 Mar 2024 16:53:53 -0500 Subject: [PATCH 2/5] empty commit From 8983dad505f07d20a02eb4edaf1e6873bc1a4c8c Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 20 Mar 2024 17:58:25 -0500 Subject: [PATCH 3/5] Add basic docs and fixup docstring --- docs/make.jl | 1 + docs/src/manual/limits.md | 8 ++++++++ src/limits.jl | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 docs/src/manual/limits.md diff --git a/docs/make.jl b/docs/make.jl index 62f8c657d..641d892a5 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -50,6 +50,7 @@ makedocs( "manual/sparsity_detection.md", "manual/types.md", "manual/faq.md" + "manual/limits.md" ], "Comparison Against SymPy" => "comparison.md", ] diff --git a/docs/src/manual/limits.md b/docs/src/manual/limits.md new file mode 100644 index 000000000..e164c6d8d --- /dev/null +++ b/docs/src/manual/limits.md @@ -0,0 +1,8 @@ +# Symbolic Limits + +Experimental symbolic limit support is provided by the [`limit`](@ref) function, documented +below. + +```@docs +limit +``` diff --git a/src/limits.jl b/src/limits.jl index 89b1172f6..e61ee3670 100644 --- a/src/limits.jl +++ b/src/limits.jl @@ -11,7 +11,7 @@ thrown. Side defaults to `:both` for finite `h`, `:left` for `h = Inf`, and `:ri `expr` must be compoesed of `log`, `exp`, constants, and the rational opperators `+`, `-`, `*`, and `/`. This limitation may eventually be relaxed. -!!! Warning +!!! warning Because symbolic limit computation is undecidable, this function necessarily employs heuristics and may occasionally return wrong answers. Nevertheless, please report wrong answers as issues as we aim to have heuristics that produce correct answers in all From ac1de23a85f3d08c6cee30cde426516890fa8b48 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 20 Mar 2024 18:02:12 -0500 Subject: [PATCH 4/5] a wee bit more docs --- docs/src/manual/limits.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/manual/limits.md b/docs/src/manual/limits.md index e164c6d8d..50d418d28 100644 --- a/docs/src/manual/limits.md +++ b/docs/src/manual/limits.md @@ -1,7 +1,8 @@ # Symbolic Limits Experimental symbolic limit support is provided by the [`limit`](@ref) function, documented -below. +below. See [SymbolicLimits.jl](https://github.com/SciML/SymbolicLimits.jl) for more +information and implementation details. ```@docs limit From dec5bd309abcf0b1ad980d090be76fc44fe39c8f Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 20 Mar 2024 23:23:12 +0000 Subject: [PATCH 5/5] Fix typo --- docs/make.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 641d892a5..e3aac1f72 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -49,8 +49,8 @@ makedocs( "manual/io.md", "manual/sparsity_detection.md", "manual/types.md", - "manual/faq.md" - "manual/limits.md" + "manual/faq.md", + "manual/limits.md", ], "Comparison Against SymPy" => "comparison.md", ]