Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decorations for reverse functions #43

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/IntervalContractors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ include("inverse_trig.jl")
include("hyperbolic.jl")
include("inverse_hyperbolic.jl")
include("extrema.jl")
include("decorations.jl")

"""
Dictionary mapping functions to their reverse functions.
Expand Down
17 changes: 13 additions & 4 deletions src/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ function power_rev(a::Interval, b::Interval, n::Integer) # a = b^n, log(a) = n
b1 = b ∩ root
b2 = b ∩ (-root)

elseif n == 0
b_new = Interval(1, 1)
return(a, isempty(a ∩ b_new) ? ∅ : b, n)

elseif iseven(n)
root = a^(1//n)

Expand Down Expand Up @@ -133,7 +137,7 @@ end

power_rev(a, b, c) = power_rev(promote(a, b, c)...)


power_rev(a::Interval{T}, c) where T<:Real = power_rev(a, entireinterval(T), c)
"""
Reverse square root
"""
Expand Down Expand Up @@ -162,7 +166,7 @@ function sqr_rev(c, x) # c = x^2; refine x
return (c, hull(x1, x2))
end

sqr_rev(c) = sqr_rev(c, -∞..∞)
sqr_rev(c::Interval{T}) where T<:Real = sqr_rev(c, entireinterval(T))

"""
Reverse abs
Expand All @@ -176,6 +180,8 @@ function abs_rev(y, x) # y = abs(x); refine x

return (y, hull(x1, x2))
end

abs_rev(c::Interval{T}) where T<:Real = abs_rev(c, entireinterval(T))
#=
"""
Reverse sign
Expand All @@ -201,10 +207,13 @@ According to the IEEE-1788 standard:
When `∘` is commutative, these agree and we write `∘_rev(b, c, x)`.
"""

function mul_rev_IEEE1788(b, c, x) # c = b*x
return x ∩ (c / b)
function mul_rev_IEEE1788(b, c, x)
temp = extended_div(c, b)
return x ∩ (temp[1] ∪ temp[2])
end

mul_rev_IEEE1788(b::Interval{T}, c::Interval{T}) where T<:Real = mul_rev_IEEE1788(b, c, entireinterval(T))

function pow_rev1(b, c, x) # c = x^b
return x ∩ c^(1/b) # replace by 1//b
end
Expand Down
60 changes: 60 additions & 0 deletions src/decorations.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Reverse Functions
Decorated interval extension; the result is decorated as `trv`,
following the IEEE-1788 Standard (see Sect. 11.7.1, pp 47).
"""
reverse_functions =(
:sqr_rev , :abs_rev, :sin_rev, :cos_rev, :tan_rev, :cosh_rev)

for f in reverse_functions
@eval function $(f)(xx::DecoratedInterval{T}) where T
x = xx.interval
r = $f(x)[2]
d = min(decoration(r), decoration(xx), trv)
krish8484 marked this conversation as resolved.
Show resolved Hide resolved
DecoratedInterval(r, d)
end
end


for f in reverse_functions
@eval function $(f)(xx::DecoratedInterval, yy::DecoratedInterval)
x = xx.interval
y = yy.interval
r = $f(x,y)[2]
d = min(decoration(x), decoration(y), decoration(r), trv)
DecoratedInterval(r, d)
end
end

function mul_rev_IEEE1788(xx::DecoratedInterval, yy::DecoratedInterval)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this just be included in the previous piece of code?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we will need a separate tuple especially for mul_rev_IEEE1788 because this function is not accepting single intervals as input like other functions in the tuple reverse_functions.

x = xx.interval
y = yy.interval
r = mul_rev_IEEE1788(x, y)
d = min(decoration(x), decoration(y), decoration(r), trv)
DecoratedInterval(r, d)
end


function mul_rev_IEEE1788(xx::DecoratedInterval, yy::DecoratedInterval, zz::DecoratedInterval)
x = xx.interval
y = yy.interval
z = zz.interval
r = mul_rev_IEEE1788(x, y, z)
d = min(decoration(x), decoration(y), decoration(z), decoration(r), trv)
DecoratedInterval(r, d)
end

function power_rev(xx::DecoratedInterval, nn::Integer)
x = xx.interval
r = power_rev(x, nn)[2]
d = min(decoration(x), decoration(r), trv)
DecoratedInterval(r, d)
end

function power_rev(xx::DecoratedInterval, yy::DecoratedInterval, nn::Integer)
x = xx.interval
y = yy.interval
r = power_rev(x, y, nn)[2]
d = min(decoration(x), decoration(r), decoration(y), trv)
DecoratedInterval(r, d)
end
15 changes: 11 additions & 4 deletions src/hyperbolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ end
"""
Reverse function for `cosh`.
"""
function cosh_rev(y::Interval,x::Interval)
y_new = y ∩ Interval(1.,∞)
x = x ∩ acosh(y)
cosh_main(y::Interval,x::Interval) = x ∩ acosh(y)

return y_new, x
function cosh_rev(x::Interval, y::Interval)
y1 = y ∩ Interval(-Inf,1)
y2 = y ∩ Interval(1,Inf)

x_new = x ∩ Interval(1.,∞)

z = -cosh_main(x,-y1) ∪ cosh_main(x,y2)
return x_new, z
end

cosh_rev(x::Interval{T}) where T<:Real = cosh_rev(x, entireinterval(T))

"""
Reverse function for `tanh`.
"""
Expand Down
6 changes: 5 additions & 1 deletion src/trig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function sin_rev(y::Interval, x::Interval)
return X_new[2], X_new[1] # return in order y, x
end


sin_rev(y::Interval{T}) where T<:Real = sin_rev(y, entireinterval(T))
## cos contractor: alters x and y
"""
Contractor for main branch of cos, from x = 0 to π.
Expand Down Expand Up @@ -104,6 +104,8 @@ function cos_rev(y::Interval, x::Interval)
return X_new[2], X_new[1] # return in order y, x
end

cos_rev(y::Interval{T}) where T<:Real = cos_rev(y, entireinterval(T))


"""
Contractor for "main branch" of tan, from x = -π/2 to π/2.
Expand Down Expand Up @@ -141,3 +143,5 @@ function tan_rev(y::Interval, x::Interval)

return X_new[2], X_new[1] # return in order y, x
end

tan_rev(y::Interval{T}) where T<:Real = tan_rev(y, entireinterval(T))
6 changes: 3 additions & 3 deletions test/Non1788tests/hyperbolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ end
@testset "cosh_rev_test" begin
@test isapprox(cosh_rev(∅, -∞..∞)[2], ∅)
@test isapprox(cosh_rev(Interval(-10.0, -1.0), -∞..∞)[2], ∅)
@test isapprox(cosh_rev(Interval(0.0, Inf), -∞..∞)[2], Interval(0.0, ∞))
@test isapprox(cosh_rev(Interval(0.0, Inf), -∞..∞)[2], Interval(-∞, ∞))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is isapprox being used here? We should be testing equality I think?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests were not added by me, I have only edited them to return negative values as well.
Should I replace isapprox too?

@test isapprox(cosh_rev(Interval(0.0, 1.0), -∞..∞)[2], Interval(0, 0))
@test isapprox(cosh_rev(Interval(-0.5, 1.0), -∞..∞)[2], Interval(0, 0))
@test isapprox(cosh_rev(Interval(-1000.0, 1.0), -∞..∞)[2], Interval(0, 0))
@test isapprox(cosh_rev(Interval(0.0, 25.0), -∞..∞)[2], Interval(0, 3.91163))
@test isapprox(cosh_rev(Interval(-1.0, 25.0), -∞..∞)[2], Interval(0, 3.91163))
@test isapprox(cosh_rev(Interval(0.0, 25.0), -∞..∞)[2], Interval(-3.91163, 3.91163))
@test isapprox(cosh_rev(Interval(-1.0, 25.0), -∞..∞)[2], Interval(-3.91163, 3.91163))
end

@testset "tanh_rev_test" begin
Expand Down
Loading