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

Only finds one root of tan #186

Open
dpsanders opened this issue Jan 6, 2017 · 6 comments
Open

Only finds one root of tan #186

dpsanders opened this issue Jan 6, 2017 · 6 comments

Comments

@dpsanders
Copy link
Member

julia> find_roots(tan, -50, 50)
1-element Array{ValidatedNumerics.RootFinding.Root{Float64},1}:
 ValidatedNumerics.RootFinding.Root{Float64}([3.14159, 3.1416],:unique)
@dpsanders
Copy link
Member Author

dpsanders commented Jan 6, 2017

And yet

julia> find_roots(tan, 30..40)
1-element Array{ValidatedNumerics.RootFinding.Root{Float64},1}:
 ValidatedNumerics.RootFinding.Root{Float64}([34.5575, 34.5576],:unique)

Which is wrongcorrect:

julia> tan(34.5575)
-1.9189487730536465e-5

julia> 34.5575/pi
10.999993891796345

@dpsanders
Copy link
Member Author

This seems to be because the Newton method behaves badly for this function, presumably due to the singularities.

@dpsanders
Copy link
Member Author

This can be captured with decorations:

julia> displaymode(decorations=true)

julia> x = @decorated(30, 40)
[30, 40]_com

julia> tan(x)
[-∞, ∞]_trv

julia> ForwardDiff.derivative(tan, x)
[1, ∞]_trv

@lbenet
Copy link
Member

lbenet commented Jan 7, 2017

I think that there are two issues here: First, the theorem requires the function needs to be twice continuously differentiable in the interval, which I think is useful if the interval contains no singularities.

Secondly, I think that (part of) the odd behavior is related to guarded_mid, which is somehow defined in relative terms:

julia> RootFinding.guarded_mid(-5pi..5pi)
0.9817477042468106

julia> RootFinding.guarded_mid(-50pi..50pi)
9.817477042468113

In both cases, the shifted point is actually too far from zero.

The consequence is that the Newton operator N then yields something different:

julia> RootFinding.N(tan,-50pi..50pi, 1.0..Inf)
[9.40326, 9.81748]

julia> RootFinding.N(tan,-5pi..5pi, 1.0..Inf)
[-0.514859, 0.981748]

@dpsanders
Copy link
Member Author

Somehow we need to encode in tan where the discontinuities are. ApproxFun does this "automatically", I believe by treating tan as sin/cos and knowing (or finding!) the roots of cos.

@dpsanders
Copy link
Member Author

dpsanders commented Mar 19, 2017

Note that the following works. It is currently unable to recognise the singularity EDIT as a singularity, but it correctly reports that it exists and is not known to be a root; and the roots are correctly identified.

julia v0.5> newton(x->sin(x)/cos(x), -10..10, tolerance=1e-3)
13-element Array{ValidatedNumerics.RootFinding.Root{Float64},1}:
 ValidatedNumerics.RootFinding.Root{Float64}([-9.42485, -9.42471],:unique)
 ValidatedNumerics.RootFinding.Root{Float64}([-7.85412, -7.85346],:unknown)
 ValidatedNumerics.RootFinding.Root{Float64}([-6.28319, -6.28318],:unique)
 ValidatedNumerics.RootFinding.Root{Float64}([-4.7128, -4.71214],:unknown)
 ValidatedNumerics.RootFinding.Root{Float64}([-3.1416, -3.14159],:unique)
 ValidatedNumerics.RootFinding.Root{Float64}([-1.57082, -1.57016],:unknown)
 ValidatedNumerics.RootFinding.Root{Float64}([-1.45505e-06, 2.08322e-06],:unique)
 ValidatedNumerics.RootFinding.Root{Float64}([1.57028, 1.57086],:unknown)
 ValidatedNumerics.RootFinding.Root{Float64}([3.14159, 3.1416],:unique)
 ValidatedNumerics.RootFinding.Root{Float64}([4.71225, 4.71283],:unknown)
 ValidatedNumerics.RootFinding.Root{Float64}([6.28318, 6.28319],:unique)
 ValidatedNumerics.RootFinding.Root{Float64}([7.85366, 7.85424],:unknown)
 ValidatedNumerics.RootFinding.Root{Float64}([9.42477, 9.42479],:unique)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants