-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Chad Scherrer <[email protected]> Co-authored-by: David Widmann <[email protected]>
- Loading branch information
1 parent
0e4a682
commit dd6e408
Showing
5 changed files
with
74 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# This file is a part of InverseFunctions.jl, licensed under the MIT License (MIT). | ||
|
||
|
||
""" | ||
struct FunctionWithInverse{F,InvF} <: Function | ||
A function with an inverse. | ||
Do not construct directly, use [`setinverse(f, invf)`](@ref) instead. | ||
""" | ||
struct FunctionWithInverse{F,InvF} <: Function | ||
f::F | ||
invf::InvF | ||
end | ||
|
||
|
||
(f::FunctionWithInverse)(x) = f.f(x) | ||
|
||
inverse(f::FunctionWithInverse) = setinverse(f.invf, f.f) | ||
|
||
|
||
""" | ||
setinverse(f, invf) | ||
Return a function that behaves like `f` and uses `invf` as its inverse. | ||
Useful in cases where no inverse is defined for `f` or to set an inverse that | ||
is only valid within a given context, e.g. only for a limited argument | ||
range that is guaranteed by the use case but not in general. | ||
For example, `asin` is not a valid inverse of `sin` for arbitrary arguments | ||
of `sin`, but can be a valid inverse if the use case guarantees that the | ||
argument of `sin` will always be within `-π` and `π`: | ||
```jldoctest | ||
julia> foo = setinverse(sin, asin); | ||
julia> x = π/3; | ||
julia> foo(x) == sin(x) | ||
true | ||
julia> inverse(foo)(foo(x)) ≈ x | ||
true | ||
julia> inverse(foo) === setinverse(asin, sin) | ||
true | ||
``` | ||
""" | ||
setinverse(f, invf) = FunctionWithInverse(_unwrap_f(f), _unwrap_f(invf)) | ||
export setinverse | ||
|
||
_unwrap_f(f) = f | ||
_unwrap_f(f::FunctionWithInverse) = f.f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# This file is a part of InverseFunctions.jl, licensed under the MIT License (MIT). | ||
|
||
using Test | ||
using InverseFunctions | ||
|
||
|
||
@testset "setinverse" begin | ||
@test @inferred(setinverse(sin, asin)) === InverseFunctions.FunctionWithInverse(sin, asin) | ||
@test @inferred(setinverse(sin, setinverse(asin, sqrt))) === InverseFunctions.FunctionWithInverse(sin, asin) | ||
@test @inferred(setinverse(setinverse(sin, sqrt), asin)) === InverseFunctions.FunctionWithInverse(sin, asin) | ||
@test @inferred(setinverse(setinverse(sin, asin), setinverse(asin, sqrt))) === InverseFunctions.FunctionWithInverse(sin, asin) | ||
|
||
InverseFunctions.test_inverse(setinverse(sin, asin), π/4) | ||
InverseFunctions.test_inverse(setinverse(asin, sin), 0.5) | ||
end |