# julia

### Site Tools

roots

snippet.juliarepl
`julia> pkgchk.( [ "julia" => v"1.0.3", "Roots" => v"0.7.3", "ForwardDiff" => v"0.9.0", "IntervalArithmetic" => v"0.15.0", "IntervalRootFinding" => v"0.4.0" ] );`

# Roots and Solving

## Uni-Dimensional Roots

### Find One Root

snippet.juliarepl
```julia> using Roots

julia> fsqr10(x::AbstractFloat)::Float64= sqrt(x)–10;		## a generic function, can be int, float, etc.

julia> fzero( fsqr10, 0.0, 1000.0)	## recommended root-finder. find a root between 0 and 1000
100.00000000000001

julia> fzero(sin, BigFloat(3.0))	## insane precision
3.141592653589793238462643383279502884197169399375105820974944592307816406286198```

With the Newton method:

snippet.juliarepl
```julia> using ForwardDiff, Roots

julia> fsqr10(x)= sqrt(x)–10;	## WARNING: function must not be typed, or ForwardDiff will not work

julia> dfsqr10= x -> ForwardDiff.derivative(fsqr10, float(x))
7 (generic function with 1 method)

julia> Roots.newton( fsqr10, dfsqr10, 2.0 )
100.0```

### Find Many Roots

snippet.juliarepl
```julia> using IntervalArithmetic, IntervalRootFinding

julia> roots( x->sin(x), –10..10 )
7-element Array{Root{Interval{Float64}},1}:
Root([9.42477, 9.42478], :unique)
Root([6.28318, 6.28319], :unique)
Root([3.14159, 3.1416], :unique)
Root([–1.33533e–16, 9.89335e–18], :unique)
Root([–3.1416, –3.14159], :unique)
Root([–6.28319, –6.28318], :unique)
Root([–9.42478, –9.42477], :unique)```
• `:unique` indicates guaranteed. `:unknown` can indicate uncertaint (such as at `x^2+eps(Float64)/100.0`)

## MultiDimensional Roots (Solvers)

### Find One Root

snippet.juliafixme
```[download only julia statements]
julia> pkgchk.("NLsolve" => v"2.1.0");

julia> using NLsolve

julia> function f!( F::Vector{Float64}, x::Vector{Float64} )::Nothing
F[1] = (x[1]+3)*(x[2]^3-7)+18
F[2] = sin(x[2]*exp(x[1])-1)
## ok:  F .= [ (x[1]+3)*(x[2]^3-7)+18, sin(x[2]*exp(x[1])-1) ]
## bad: F = [ (x[1]+3)*(x[2]^3-7)+18, sin(x[2]*exp(x[1])-1) ]`
##      ...fails, because the outside F is not replaced.  It needs `.=`, not `=`
nothing
end;#function##

julia> nlsolve(f!, [ 0.1; 1.2])
Results of Nonlinear Solver Algorithm
* Algorithm: Trust-region with dogleg and autoscaling
* Starting Point: [0.1, 1.2]
* Zero: [-7.77555e-17, 1.0]
* Inf-norm of residuals: 0.000000
* Iterations: 4
* Convergence: true
* |x - x'| < 0.0e+00: false
* |f(x)| < 1.0e-08: true
* Function Calls (f): 5
* Jacobian Calls (df/dx): 5

julia> function j!( J::Matrix{Float64}, x::Vector{Float64} )::Nothing
J[1, 1] = x[2]^3-7
J[1, 2] = 3*x[2]^2*(x[1]+3)
u = exp(x[1])*cos(x[2]*exp(x[1])-1)
J[2, 1] = x[2]*u
J[2, 2] = u
nothing
end;#function##

julia> nlsolve(f!, j!, [ 0.1; 1.2])
Results of Nonlinear Solver Algorithm
* Algorithm: Trust-region with dogleg and autoscaling
* Starting Point: [0.1, 1.2]
* Zero: [-3.7818e-16, 1.0]
* Inf-norm of residuals: 0.000000
* Iterations: 4
* Convergence: true
* |x - x'| < 0.0e+00: false
* |f(x)| < 1.0e-08: true
* Function Calls (f): 5
* Jacobian Calls (df/dx): 5```

# Backmatter

## Useful Packages on Julia Repository

1. JuMP: JUlia for Mathematical OPtimization
2. Optim: Native Julia Optimization Code
snippet.julianoeval
```[download only julia statements]
julia> using IntervalArithmetic, IntervalRootFinding, StaticArrays

julia> function rosenbrock( xx );  (x, y) = xx; SVector( 1 - x, 100 * (y - x^2) ); end;#function rosenbrock#

julia> roots( rosenbrock, (-5..5) × (-5..5) )		## tangent zero at location [1,1]
1-element Array{Root{IntervalBox{2,Float64}},1}:
Root([1, 1] × [1, 1], :unique)

julia> roots(rosenbrock, IntervalBox(-1e5..1e5, 2) )
1-element Array{Root{IntervalBox{2,Float64}},1}:
Root([1, 1] × [1, 1], :unique)```

## Notes

1. Other Topics in Minimizations (Integers, Multiple Objectives, etc.)