text:
using ImageCore
using ImageTransformations
using CoordinateTransformations
using OffsetArrays
using Images

export translateImage, rotateImage, warp2translate_cartesian, ellipse2circle_image

function warp2translate_cartesian(cart::CartesianIndex{2})
    return CartesianIndex(-cart[2], cart[1])
end

function translateImage(image::OffsetArray{Float64,2,Array{Float64,2}}, xyshift::Tuple{Prec64,Prec64})
    xyshift = tuple(xyshift[2], -xyshift[1])

    t = Translation(xyshift)
    translated_image = warp(image, t, indices_spatial(image), 0.0)

    return translated_image
end

function translateImage(image::OffsetArray{Float64,2,Array{Float64,2}}, xyshift::CartesianIndex{2})
    x₀ = xyshift[2]
    y₀ = -xyshift[1]
    t = Translation((x₀, y₀))
    translated_image = warp(image, t, indices_spatial(image), 0.0)

    return translated_image
end

function translateImage(image::Array{Float64,2}, xyshift::Tuple{Prec64,Prec64})
    xyshift = tuple(xyshift[2], -xyshift[1])

    t = Translation(xyshift)
    translated_image = warp(image, t, indices_spatial(image), 0.0)

    return translated_image
end

function rotateImage(image::OffsetArray{Float64,2,Array{Float64,2}}, θ::Prec64)
    θ = deg2rad(θ)
    rotated_image = imrotate(image, -θ, indices_spatial(image), 0.0)

    return rotated_image
end

function rotateImage(image::Array{Float64,2}, θ::Prec64)
    θ = deg2rad(θ)
    rotated_image = imrotate(image, -θ, indices_spatial(image), 0.0)

    return rotated_image
end

function ellipse2circle_image(image::OffsetArray{Float64,2,Array{Float64,2}}, ellipse::ParametricFormEllipse)
# takes in a centered stretched ion image and outputs a squished, centered circular ion image
# and the radius of the best fit circle
# currently the radius of the new image is the average of the ellipse height and width

    width = ellipse.axis_lengths[1]
    height = ellipse.axis_lengths[2]
    ellipse_angle = ellipse.ccw_angle

# rotate image such that the ellipse's axes are allilgned with x and y
    image2 = rotateImage(image, -ellipse_angle)

# define the radius of the final circle - average of width and height in this case
    diameter = (width + height) / 2
    x_scale = diameter / width
    y_scale = diameter / height

# scale x axis
    image3 = centered(imresize(image2, round(Int, 301 * x_scale), size(image2)[2]))

# scale y axis
    image4 = centered(imresize(image3, size(image3)[1], round(Int, 301 * y_scale)))

# fit inside new 301 x 301 frame
    image5 = centered(zeros(Float64, (301, 301)))
    if length(indices_spatial(image4)[1]) > 301
        if length(indices_spatial(image4)[2]) > 301
            image5[:, :] = image4[-150:150, -150:150]
        else
            image5[:, indices_spatial(image4)[2]] = image4[-150:150, :]
        end
    else
        if length(indices_spatial(image4)[2]) > 301
            image5[indices_spatial(image4)[1], :] = image4[:, indices_spatial(image5)[2]]
        else
            image5[indices_spatial(image4)[1], indices_spatial(image4)[2]] = image4[:, :]
        end
    end
# the result here is kind of weird. TODO check again img5 in test_files\\flatten_ellipse.jl

# need to recenter again due to pixels being discrete
    circle = kernelize(ParametricFormEllipse([width*x_scale height*y_scale], [0.0 0.0], 0.0))
    maxvalue, maxcoord = findmax(imfilter(image5, circle))
    maxcoord = warp2translate_cartesian(maxcoord)
# actual recentering
    image6 = translateImage(image5, maxcoord)

# rotate back
    return rotateImage(image6, ellipse_angle), diameter/2
end


text:
## test data available for use in PopGen
export dataset, nancycats, gulfsharks

"""
    dataset(::String)
Load an example dataset from either `"gulfsharks"` (SNP) or `"nancycats"` (microsatellite). Can also use `"sharks"` and `"cats"`
as shorthands. Use `?nancycats` and `?gulfsharks` to learn more about
these datasets.

### Example
```
ncats = dataset("nancycats")
gsharks = dataset("sharks")
```
"""
function dataset(name::String)
    lowercase(name) in ["gulfsharks", "sharks"] && return gulfsharks()
    lowercase(name) in ["nancycats", "cats"] && return nancycats()
end

"""
    nancycats()
Returns a `PopObj` of corresponding "nancycats" dataset as featured in
the R package `adegenet`. This is microsatellite data of 9 loci in 237
individuals across 17 populations.

Example:
```
ncats = nancycats()
```
"""
function nancycats()
    filename = normpath(joinpath(@__DIR__,"../..","data", "datasets.jld2"))
    load(filename, "nancycats")
end

"""
    gulfsharks()
Returns a `PopObj` corresponding the Blacknose shark dataset as used in
Dimens et al. 2019. This is a mid-sized SNP dataset of 2213 SNPs in 212
individuals, across 7 populations.

Example:

```
sharks = gulfsharks()
```
"""
function gulfsharks()
    filename = normpath(joinpath(@__DIR__,"../..","data", "datasets.jld2"))
    load(filename, "gulfsharks")
end

ext: jl


text:
module features

using VulkanCore
using ..VkExt
using ..LavaCore
using ..LavaCore: destroy!

include("features/GlfwWindow.jl")
include("features/GlfwOutput.jl")
include("features/Validation.jl")

end


text:
### A Pluto.jl notebook ###
# v0.16.4

using Markdown
using InteractiveUtils

# ╔═╡ 741ec564-51c8-11eb-178d-3d5e49c0e174
begin
	import Pkg
	Pkg.activate(Base.current_project())
	using ReinforcementLearning
	using Flux
	using Statistics
	using Plots
end

# ╔═╡ 9f8815e8-51c8-11eb-2f5c-259a9a7b82b4
md"""
# Chapter 6.2 Random Walk
"""

# ╔═╡ 5550a880-51ca-11eb-3569-0ddbdd915759
md"""
In this section, we'll use the `RandomWalk1D` env provided in `ReinforcementLearning`.
"""

# ╔═╡ 9d9d5a20-51ca-11eb-318a-67b23ba3fab9
env = RandomWalk1D(;rewards=0.0=>1.0)

# ╔═╡ ad5961f2-51ca-11eb-0c9f-2faf60ba2d8f
NS, NA = length(state_space(env)), length(action_space(env))

# ╔═╡ 65bdcf50-51c9-11eb-1d53-d31f41af92b3
md"""
As is explained in the book, the true values of state **A** to **E** are:
"""

# ╔═╡ 7df2251c-51c9-11eb-3827-331375dcf781
true_values = [i/6 for i in 1:5]

# ╔═╡ 96ebb024-51c9-11eb-17cc-478517c1c285
md"""
To estimate the state values, we'll use the `VBasedPolicy` with a random action generator.
"""

# ╔═╡ 45d32c2a-51ca-11eb-1bf3-8b61db88186a
create_TD_agent(α) = Agent(
    policy=VBasedPolicy(
        learner = TDLearner(
            approximator=TabularApproximator(fill(0.5, NS), Descent(α)),
            method=:SRS,
            γ=1.0,
            n=0,
        ),
        mapping = (env, V) -> rand(1:NA)
    ),
    trajectory=VectorSARTTrajectory()
)

# ╔═╡ d3975284-51ca-11eb-09bf-f98c05a416a1
begin
	p_6_2_left = plot(;legend=:bottomright)
	for i in [1, 10, 100]
		agent = create_TD_agent(0.1)
		run(agent, env, StopAfterEpisode(i))
		plot!(
			p_6_2_left,
			agent.policy.learner.approximator.table[2:end - 1],
			label="episode = $i"
		)
	end
	plot!(p_6_2_left, true_values, label="true value")
	p_6_2_left
end

# ╔═╡ 8507c710-51cb-11eb-3a43-75f591e687b6
md"""
To calculate the RMS error, we need to define such a hook first.
"""

# ╔═╡ ad9768f2-51cb-11eb-080c-7723ec21f95d
begin
	Base.@kwdef struct RecordRMS <: AbstractHook
		rms::Vector{Float64} = []
	end

	(f::RecordRMS)(::PostEpisodeStage, agent, env) = push!(
		f.rms,
		sqrt(mean((agent.policy.learner.approximator.table[2:end - 1] - true_values).^2))
	)
end

# ╔═╡ d950e14e-51cb-11eb-1215-37a2ee16c07b
md"""
Now let's take a look at the performance of `TDLearner` under different α.
"""

# ╔═╡ fbae209e-51cb-11eb-04f6-f7edeaac6085
begin
	p_6_2_right = plot()

	for α in [0.05, 0.1, 0.15]
		rms = []
		for _ in 1:100
			agent = create_TD_agent(α)
			hook = RecordRMS()
			run(agent, env, StopAfterEpisode(100),hook)
			push!(rms, hook.rms)
		end
		plot!(p_6_2_right, mean(rms), label ="TD alpha=$α", linestyle=:dashdot)
	end
	p_6_2_right
end

# ╔═╡ 3b38abf8-51cc-11eb-2da8-31a5d185393b
md"""
Then we can compare the differences between `TDLearner` and `MonteCarloLearner`.
"""

# ╔═╡ 7eae5996-51cc-11eb-1c64-5f8f6c59bd8a
create_MC_agent(α) = Agent(
    policy=VBasedPolicy(
        learner=MonteCarloLearner(
            approximator=TabularApproximator(fill(0.5, NS), Descent(α)),
            kind=EVERY_VISIT
        ),
        mapping = (env, V) -> rand(1:NA)
    ),
    trajectory=VectorSARTTrajectory()
)

# ╔═╡ eaa74d56-51cc-11eb-1e18-bd7ffda238d6
for α in [0.01, 0.02, 0.03, 0.04]
    rms = []
    for _ in 1:100
        agent = create_MC_agent(α)
        hook = RecordRMS()
        run(agent, env, StopAfterEpisode(100),hook)
        push!(rms, hook.rms)
    end
    plot!(p_6_2_right, mean(rms), label ="MC alpha=$α")
end

# ╔═╡ 0ad60a5e-51cd-11eb-21ef-6f970a4d9f9c
p_6_2_right

# ╔═╡ 76db1be0-51cd-11eb-1b66-f7823c7b7ef2
begin
	fig_6_2 = plot()

	rms = []
	for _ in 1:100
		agent = create_TD_agent(0.1)
		hook = RecordRMS()
		run(agent, env, StopAfterEpisode(100),hook)
		push!(rms, hook.rms)
	end
	plot!(fig_6_2, mean(rms), label ="TD alpha=0.1", linestyle=:dashdot)

	rms = []
	for _ in 1:100
		agent = create_MC_agent(0.1)
		hook = RecordRMS()
		run(agent, env, StopAfterEpisode(100),hook)
		push!(rms, hook.rms)
	end
	plot!(fig_6_2, mean(rms), label ="MC alpha=0.1")

	fig_6_2
end

# ╔═╡ 501c914a-51ce-11eb-3268-df4813644c08
md"""

!!! warning

	Some of you might have noticed that the above figure is not the same with the one on the book of Figure 6.2. Actually we are not doing **BATCH TRAINING** here, because we're emptying the `trajectory` at the end of each episode. We leave it as an exercise for readers to practice developing new customized algorithms with `ReinforcementLearning.jl`. 😉
"""

# ╔═╡ Cell order:
# ╟─9f8815e8-51c8-11eb-2f5c-259a9a7b82b4
# ╠═741ec564-51c8-11eb-178d-3d5e49c0e174
# ╟─5550a880-51ca-11eb-3569-0ddbdd915759
# ╠═9d9d5a20-51ca-11eb-318a-67b23ba3fab9
# ╠═ad5961f2-51ca-11eb-0c9f-2faf60ba2d8f
# ╟─65bdcf50-51c9-11eb-1d53-d31f41af92b3
# ╠═7df2251c-51c9-11eb-3827-331375dcf781
# ╟─96ebb024-51c9-11eb-17cc-478517c1c285
# ╠═45d32c2a-51ca-11eb-1bf3-8b61db88186a
# ╠═d3975284-51ca-11eb-09bf-f98c05a416a1
# ╟─8507c710-51cb-11eb-3a43-75f591e687b6
# ╠═ad9768f2-51cb-11eb-080c-7723ec21f95d
# ╟─d950e14e-51cb-11eb-1215-37a2ee16c07b
# ╠═fbae209e-51cb-11eb-04f6-f7edeaac6085
# ╟─3b38abf8-51cc-11eb-2da8-31a5d185393b
# ╠═7eae5996-51cc-11eb-1c64-5f8f6c59bd8a
# ╠═eaa74d56-51cc-11eb-1e18-bd7ffda238d6
# ╠═0ad60a5e-51cd-11eb-21ef-6f970a4d9f9c
# ╠═76db1be0-51cd-11eb-1b66-f7823c7b7ef2
# ╟─501c914a-51ce-11eb-3268-df4813644c08


text:
using MimiFUND

# Run FUND
m = MimiFUND.get_model()

run(m)

using Mimi

# Step 3 Access Results: Values
m[:socioeconomic, :income]
m[:socioeconomic, :income][100]

getdataframe(m, :socioeconomic => :income) # request one variable from one component
getdataframe(m, :socioeconomic => :income)[1:16,:] # results for all regions in first year

# Step 4: Access Results: PLots and Graphs
explore(m)
p = Mimi.plot(m, :socioeconomic, :income)
save("test.svg", p)

max_stars_repo_name: tlorans/SustainableFinance

max_issues_repo_name: tlorans/SustainableFinance

max_forks_repo_name: tlorans/SustainableFinance


text:
"""
    $(SIGNATURES)

Empty deviation. Mainly as return object when no match is found in DevVector
"""
function empty_deviation(F1 = Float64)
    return Deviation{F1}(name = :empty)
end

# Do not check that sizes of modelV and dataV match because of `idxV`.
function validate_deviation(d :: Deviation{F1}) where F1
    isValid = true;
    if !all(isfinite.(d.modelV))
        @warn "Model values not finite for $d: $(d.modelV)"
        isValid = false;
    end
    if !all(isfinite.(d.dataV))
        @warn "Data values not finite for $d: $(d.dataV)"
        isValid = false;
    end
    if !all(isfinite.(d.wtV))
        @warn "Weights not finite for $d: $(d.wtV)"
        isValid = false;
    end
    isValid = isValid  &&  (ndims(d.modelV) == ndims(d.dataV))
    return isValid
end

function get_model_values(d :: Deviation{F1}; matchData :: Bool = false) where F1
    if matchData  &&  !isempty(d.idxV)
        modelV = d.modelV[d.idxV...];
    else
        modelV = d.modelV;
    end
    if matchData  ||  isempty(d.idxV)
        @assert size(modelV) == size(get_data_values(d))
    end
    return deepcopy(modelV)
end

function set_model_values(d :: Deviation{F1}, modelV) where F1
    dataV = get_data_values(d);
    if typeof(modelV) != typeof(dataV)
        println(modelV);
        println(dataV);
        error("Type mismatch in $(d.name): $(typeof(modelV)) vs $(typeof(dataV))");
    end
    if isempty(d.idxV)
        # Size can be different in general
        @assert size(modelV) == size(dataV)  "Size mismatch $(d.name): $(size(modelV)) vs $(size(dataV))"
    end
    @assert ndims(modelV) == ndims(dataV)  "Dimension mismatch $(d.name):  $(ndims(modelV)) vs $(ndims(dataV))"
    d.modelV = deepcopy(modelV);
    return nothing
end

"""
    $(SIGNATURES)

Scalar deviation from one Deviation object.

Optionally includes `scalarWt` factor.
Uses a weighted norm. The exponent is determined by the Deviation's `normP` property.
"""
function scalar_dev(d :: Deviation{F1}; inclScalarWt :: Bool = true) where F1
    modelV = get_model_values(d; matchData = true);
    @assert size(modelV) == size(get_data_values(d))

    scalarDev = scalar_deviation(modelV, get_data_values(d), d.wtV;
        p = norm_p(d));
    if inclScalarWt
        scalarDev *= d.scalarWt;
    end
    scalarStr = sprintf1(d.fmtStr, scalarDev);
    @assert scalarDev >= zero(F1)  "Negative deviation for $d: $scalarDev"
    return scalarDev, scalarStr
end

## -----------  Show

Base.show(io :: IO, d :: Deviation{F1}) where F1 =
    Base.print(io, "$(name(d)):  ", short_description(d));

"""
	$(SIGNATURES)

Show a vector / matrix deviation
"""
function deviation_show_fct(d :: Deviation; showModel :: Bool = true, fPath :: String = "")
    io = open_show_path(d, fPath = fPath);

    # Dimensions of data matrix
    dataV = get_data_values(d);
    modelV = get_model_values(d; matchData = true);
    nd = ndims(dataV);
    if nd > 2
        @warn "Showing deviation not implemented for ndims = $nd"
    elseif nd == 2
        (nr, nc) = size(dataV);
    elseif nd == 1
        nr = length(dataV);
        nc = 1;
    else
        error("Empty deviation")
    end

    println(io, "$(d.name):  Model / Data")
    for ir = 1 : nr
        print(io, "\t $ir: ");
        for ic = 1 : nc
            if showModel
                mStr = sprintf1(d.fmtStr, modelV[ir, ic]);
            else
                mStr = "  --  ";
            end
            dStr = sprintf1(d.fmtStr, dataV[ir, ic]);
            print(io, "\t $mStr / $dStr");
        end
        print(io, "\n");
    end

    close_show_path(d, io);
    return nothing
end

# ----------------


text:
module HDParameterGeneratorIO

using NetCDF: NcFile,NcVar,NC_NETCDF4

import HDParameterGenerator: load_input_data,write_hdpara_file
import HDParameterGenerator: Grid,UnstructuredGrid,LatLonGrid

function get_ncells(file_name::AbstractString)
  river_directions::Array{Float64,1} = NetCDF.ncread(file_name,"FDIR")
  return size(river_directions,1)
end

function load_field(file_handle::NcFile,grid::Grid,variable_name::AbstractString,
                    field_type::DataType)
  variable::NcVar = file_handle[variable_name]
  values::Array{field_type,get_number_of_dimensions(grid)} = NetCDF.readvar(variable)
  if isa(grid,LatLonGrid)
    values = permutedims(values, [2,1])
  end
  return values
end

function prep_dims(grid::LatLonGrid)
  lat = NcDim("Lat",grid.nlat)
  lon = NcDim("Lon",grid.nlon)
  dims::Array{NcDim} = NcDim[ lon; lat ]
  return dims
end

function prep_dims(grid::UnstructuredGrid)
  ncells = NcDim("ncells",grid.ncells)
  dims::Array{NcDim} = NcDim[ ncells ]
  return dims
end

function prep_field(dims::Array{NcDim},variable_name::AbstractString,
                    field::Field,fields_to_write::Vector{Pair})
  local variable::NcVar
  if isa(field,LatLonField)
    variable = NcVar(variable_name,dims)
    push!(fields_to_write,Pair(variable,permutedims(get_data(field), [2,1])))
  elseif isa(field,UnstructuredField)
    variable = NcVar(variable_name,dims,atts=Dict("grid_type"=>"unstructured",
                                                  "coordinates"=>"clat clon"))
    push!(fields_to_write,Pair(variable,get_data(field)))
  end
end

function write_fields(grid::Grid,fields_to_write::Vector{Pair},filepath::AbstractString,
                      dims::Array{NcDim})
  variables::Array{NcVar} = NcVar[ pair.first for pair in fields_to_write ]
  if isa(grid,UnstructuredGrid)
    prepare_icon_file(grid,filepath,dims,variables)
  else
    NetCDF.create(filepath,variables,mode=NC_NETCDF4)
  end
  for (variable,data) in fields_to_write
    NetCDF.putvar(variable,data)
  end
end

function prepare_icon_file(grid::UnstructuredGrid,filepath::AbstractString,
                           dims::Array{NcDim},variables::Array{NcVar})
  vertices = NcDim("vertices",3)
  extended_dims::Array{NcDim} = vcat(NcDim[ vertices ], dims)
  clat = NcVar("clat",dims,atts=Dict("long_name"=>"center_latitude",
                                     "units"=>"radians",
                                     "bounds"=>"clat_bnds",
                                     "standard_name"=>"latitude"))
  clon = NcVar("clon",dims,atts=Dict("long_name"=>"center_longitude",
                                     "units"=>"radians",
                                     "bounds"=>"clon_bnds",
                                     "standard_name"=>"longitude"))
  clat_bounds = NcVar("clat_bnds",extended_dims)
  clon_bounds = NcVar("clon_bnds",extended_dims)
  extended_variables::Array{NcVar} = vcat(variables,NcVar[ clat, clon, clat_bounds, clon_bounds])
  NetCDF.create(filepath,extended_variables,mode=NC_NETCDF4)
  NetCDF.putvar(clat,grid.clat)
  NetCDF.putvar(clon,grid.clon)
  NetCDF.putvar(clat_bounds,grid.clat_bounds)
  NetCDF.putvar(clon_bounds,grid.clon_bounds)
end

function write_field(grid::Grid,variable_name::AbstractString,
                     field::Field,filepath::AbstractString)
  dims::Array{NcDim} = prep_dims(grid)
  local variable::NcVar
  if isa(grid,UnstructuredGrid)
    variable = NcVar(variable_name,dims,atts=Dict("grid_type"=>"unstructured",
                                                  "coordinates"=>"clat clon"))
    variables::Array{NcVar} = NcVar[ variable ]
    prepare_icon_file(grid,filepath,dims,variables)
  else
    variable = NcVar(variable_name,dims)
    NetCDF.create(filepath,variable,mode=NC_NETCDF4)
  end
  if isa(grid,LatLonGrid)
    NetCDF.putvar(variable,permutedims(get_data(field), [2,1]))
  else
    NetCDF.putvar(variable,get_data(field))
  end
end

function load_icosahedral_grid(grid_filepath)
  println("Loading: " * grid_filepath)
  file_handle::NcFile = NetCDF.open(grid_filepath)
  ncells::Int64 = file_handle.dim["cell"]
  clat_var::NcVar = file_handle["clat"]
  clat::Array{Float64,1} = readvar(clat_var)
  clon_var::NcVar = file_handle["clon"]
  clon::Array{Float64,1} = readvar(clon_var)
  clat_bounds_var::NcVar = file_handle["clat_bounds"]
  clat_bounds::Array{Float64,2} = readvar(clat_bounds_var)
  clon_bounds_var::NcVar = file_handle["clon_bounds"]
  clon_bounds::Array{Float64,2} = readvar(clon_bounds_var)
  return UnstructuredGrid(ncells,clat,clon,clat_bounds,clon_bounds)
end

function determine_latlon_grid_information(file_handle)
    nlat::Int64 = file_handle.dim["lat"]
    nlon::Int64 = file_handle.dim["lon"]
    lats_var::NcVar = file_handle["lat"]
    lats::Array{Float64,1} = readvar(lats_var)
    lons_var::NcVar = file_handle["lon"]
    lons::Array{Float64,1} = readvar(lons_var)
    return LatLonGrid(nlat,nlon,lats,lons)
end

function load_input_data(input_filepaths::Dict)
  local grid::Grid
  println("Loading: " * input_filepaths["river_directions_filepath"])
  river_directions_file_handle::NcFile = NetCDF.open(input_filepaths["river_directions_filepath"])
  if haskey(input_filepaths,"grid_filepath")
    grid = load_icosahedral_grid(input_filepaths["grid_filepath"])
    river_directions::Array{Int64,ndims} = load_field(river_directions_file_handle,grid,
                                                      input_filepaths["river_directions_fieldname"],
                                                      Int64)
  else
    grid = determine_latlon_grid_information(river_directions_file_handle)
    river_directions::Array{Int64,ndims} =
      round.(Int64,load_field(river_directions_file_handle,grid,
                              input_filepaths["river_directions_fieldname"],Float64)
  end
  ndims::Int64 = size(grid.grid_dimensions)

  println("Loading: " * input_filepaths["orography_variance_filepath"])
  orography_variance_file_handle::NcFile = NetCDF.open(input_filepaths["orography_variance_filepath"]
  orography_variance::Array{Float64,ndims} = load_field(orography_variance_file_handle,grid,
                          input_filepaths["orography_variance__fieldname",Float64)
  println("Loading: " * input_filepaths["innerslope_filepath"])
  innerslope_file_handle::NcFile = NetCDF.open(input_filepaths["innerslope_filepath"]
  innerslope::Array{Float64,ndims} = load_field(innerslope_file_handle,grid,
             input_filepaths["innerslope_fieldname",Float64)
  println("Loading: " * input_filepaths["orography_filepath"])
  orography_file_handle::NcFile = NetCDF.open(input_filepaths["orography_filepath"]
  orography::Array{Float64,ndims} = load_field(orography_file_handle,grid,
                                               input_filepaths["orography_fieldname",
                                               Float64)
  println("Loading: " * input_filepaths["glacier_mask_filepath"])
  glacier_mask_file_handle::NcFile = NetCDF.open(input_filepaths["glacier_mask_filepath"]
  glacier_mask::Array{Bool,ndims} = iszero.(load_field(glacier_mask_file_handle,grid,
                                               input_filepaths["glacier_mask_fieldname",
                                               Int64))
  println("Loading: " * input_filepaths["landsea_mask_filepath"])
  landsea_mask_file_handle::NcFile = NetCDF.open(input_filepaths["landsea_mask_filepath"]
  landsea_mask::Array{Bool,ndims) = iszero.(load_field(landsea_mask_file_handle,grid,
                                            input_filepaths["landsea_mask_fieldname",Float64))
  println("Loading: " * input_filepaths["cell_areas_filepath"])
  cell_areas_file_handle::NcFile = NetCDF.open(input_filepaths["cell_areas_filepath"]
  cell_areas::Array{Float64,ndims} = load_field(cell_areas_file_handle,grid,
                                                input_filepaths["cell_areas_fieldname",
                                                Float64))
  input_data = InputData(landsea_mask,glacier_mask,orography,
                         innerslope,orography_variance,
                         river_directions,cell_areas,grid)
  return input_data::InputData,grid::Grid
end

function write_hdpara_file(output_hdpara_filepath::AbstractString,
                           input_data::InputData,
                           number_of_riverflow_reservoirs{Float64},
                           riverflow_retention_coefficients{Float64},
                           number_of_overlandflow_reservoirs{Float64},
                           overlandflow_retention_coefficients{Float64},
                           number_of_baseflow_reservoirs{Float64},
                           baseflow_retention_coefficients{Float64},
                           grid::Grid)
  dims::Array{NcDim} = prep_dims(grid)
  fields_to_write::Vector{Pair} = Pair[]
  prep_field(dims,"ARF_N",
             number_of_riverflow_reservoirs,fields_to_write)
  prep_field(dims,"ARF_K",
             riverflow_retention_coefficients,fields_to_write)
  prep_field(dims,"ALF_N",
             number_of_overlandflow_reservoirs,fields_to_write)
  prep_field(dims,"ALF_K",
             overlandflow_retention_coefficients,fields_to_write)
  #prep_field(dims,"AGF_N",
  #           number_of_baseflow_reservoirs,fields_to_write)
  prep_field(dims,"AGF_K",
             baseflow_retention_coefficients,fields_to_write)
  prep_field(dims,"Area",
             input_data.cell_areas,fields_to_write)
  if isa(grid,UnstructuredGrid)
    prep_field(dims,"FDIR",
               input_data.grid_specific_input_data.next_cell_index,fields_to_write)
  else
    prep_field(dims,"FDIR",
               input_data.grid_specific_input_data.river_directions,fields_to_write)
  end
  prep_field(dims,"FLAG",
             input_data.landsea_mask,fields_to_write)
  write_fields(grid,fields_to_write,output_hdpara_filepath,dims)
end

end

max_stars_repo_name: ThomasRiddick/DynamicHD

max_issues_repo_name: ThomasRiddick/DynamicHD

max_forks_repo_name: ThomasRiddick/DynamicHD


text:
#=
Author : Ng Yeesian
Modified : Guy Farmer
generates the AmbulanceDeployment package
=#
module AmbulanceDeployment

    import JuMP, Gurobi
    import DataStructures: PriorityQueue, enqueue!, dequeue!
    import DataFrames: DataFrame, nrow
    import Distributions
    import DataStructures: PriorityQueue, enqueue!, dequeue!
    import Pkg
    import CSV, Query
    using Gurobi, CSV, Query, JuMP, Dates, JLD, GLPK
    using DataFrames, CSV, Random, JSON, Distributions #Plots

    const PROJECT_ROOT = pkgdir(AmbulanceDeployment)

    include("problem.jl")
    include("model.jl")
    include("dispatch/closestdispatch.jl")
    include("simulate.jl")
    include("evaluate.jl")
    include(PROJECT_ROOT * "/test/generate_simulation.jl")
    include("deployment/robust.jl")
    include("deployment/stochastic.jl")
    include("deployment/stochastic_hyp.jl")
    include("deployment/stochastic_rem.jl")
    include("deployment/malp.jl")
    include("deployment/mexclp.jl")
    include("plot.jl")
    #include("Ambulance_Deployment_experiments.jl")
    include("Single_Robust.jl")

    export
           DeploymentProblem,
           DispatchProblem,
           RobustDeployment,
           StochasticDeployment,
           MALPDeployment,
           MEXCLPDeployment,
           ClosestDispatch,
           AssignmentModel,
           solve,
           evaluate,
           deployment,
           convergence_plot,
           compose_neighborhoods,
           compose_locations,
           compose_chloropleth,
           performance,
           test_performance,
           plot_timings,
           simulate_events!,
           generate_simulation,
           PROJECT_ROOT,
           optimize!,
           generate_deployment,
           DeploymentModel,
           StochasticDeployment_hyp,
           StochasticDeployment_rem
end

max_stars_repo_name: michaelhilborn/AmbulanceDeployement

max_issues_repo_name: joshua-ong/AmbulanceDeployment

max_forks_repo_name: joshua-ong/AmbulanceDeployment


text:
# Deprecations of Graphics.set_coords that handle GtkReactive types
export set_coords
Graphics.set_coords(c::Union{GtkCanvas,Canvas}, device::BoundingBox, user::BoundingBox) =
    set_coords(getgc(c), device, user)
Graphics.set_coords(c::Union{GtkCanvas,Canvas}, user::BoundingBox) =
    set_coords(c, BoundingBox(0, Graphics.width(c), 0, Graphics.height(c)), user)
function Graphics.set_coords(c::Union{GraphicsContext,Canvas,GtkCanvas}, zr::ZoomRegion)
    xy = zr.currentview
    bb = BoundingBox(xy)
    set_coords(c, bb)
end
function Graphics.set_coords(c::Union{Canvas,GtkCanvas}, inds::Tuple{AbstractUnitRange,AbstractUnitRange})
    y, x = inds
    bb = BoundingBox(first(x), last(x), first(y), last(y))
    set_coords(c, bb)
end


text:
using PtFEM, Test, Compat

ProjDir = dirname(@__FILE__)

data = Dict(
  # Plane(ndim, nst, nxe, nye, nip, direction, finite_element(nod, nodof), axisymmetric)
  :struc_el => Plane(2, 4, 40, 20, 4, :y, Quadrilateral(8, 2), false),
  # ϕ (phi, friction angle), c (cohesion), ψ (psi, dilation angle),
  # γ (gamma, soil unit weight), E, ν (v, Poisson's ratio)
  # [ϕ, c, ψ, γ, E, ν]
  :properties => [20.0 10.0 20.0 16.0 1.0e5 0.3;],
  :x_coords => 0.0:0.25:10.0,
  :y_coords => 5.0:-0.25:0.0,
  :tol => 0.001,
  :limit => 200,
  :incs => 10,
  :nbo2 => 8,       # No of elements to be rigidly displaced in bearing capacity
  :qs => 20,        # Surface surcharge
  :presc => -0.001  # Magnitude of incremental vertical displacements rigid footing
)

@time res_df, g_coord, g_num, disp = p63(data)
println()
res_df

@test res_df[end,:load1] ≈ 274.3514626820244
@test res_df[end,:load2] ≈ 270.01838672066737
@test res_df[end,:iters] == 81


text:
#jl #! format: off
# # Time-varying bid problems with [PowerSimulations.jl](https://github.com/NREL-SIIP/PowerSimulations.jl)

# **Originally Contributed by**: Sourabh Dalvi

# ## Introduction

# PowerSimulations.jl supports the construction of Operations problems in power system
# with three part cost bids for each time step. MarketBidCost allows the user to pass a
# time-series of variable cost for energy and ancillary services jointly.
# This example shows how to build a Operations problem with MarketBidCost and how to add
# the time-series data to the devices.

# ## Dependencies
# ### Modeling Packages
using SIIPExamples
using PowerSystems
using PowerSimulations
const PSI = PowerSimulations

# ### Data management packages
using PowerSystemCaseBuilder
using Dates
using DataFrames
using TimeSeries

# ### Optimization packages
using HiGHS #solver

# ### Data
# Create a `System` from RTS-GMLC data
sys = build_system(PSITestSystems, "modified_RTS_GMLC_DA_sys")

# ### Creating the Time Series data for Energy bid
MultiDay = collect(
    DateTime("2020-01-01T00:00:00"):Hour(1):(DateTime("2020-01-01T00:00:00") + Hour(8783)),
);

# ### Adding a MarketBidCost time series
# Here we add the energy bid
# time series to the system. The TimeSeriesData that holds the energy bid data can be of any
# type (i.e. `SingleTimeSeries` or `Deterministic`), but it has to be consistent with the existing
# data in the `sys`. So, we'll first remove the existing `DeterministicSingleTimeSeries`, then add
# the bid time series as `SingleTimeSeries`, then re-transform all of the time series in `sys`.

remove_time_series!(sys, DeterministicSingleTimeSeries)

for gen in get_components(ThermalGen, sys)
    varcost = get_operation_cost(gen)
    data = TimeArray(MultiDay, repeat([get_cost(get_variable(varcost))], 8784))
    _time_series = SingleTimeSeries("variable_cost", data)
    add_time_series!(sys, gen, _time_series)
    #set_variable_cost!(sys, gen, _time_series)
end

# ### Transforming SingleTimeSeries into Deterministic
transform_single_time_series!(sys, 24, Dates.Hour(24))

# In the [OperationsProblem example](https://nbviewer.jupyter.org/github/NREL-SIIP/SIIPExamples.jl/blob/master/notebook/3_PowerSimulations_examples/01_operations_problems.ipynb)
# we defined a unit-commitment problem with a copper plate representation of the network.
# Here, we want do define unit-commitment problem  with ThermalMultiStartUnitCommitment
# formulation for thermal device representation.

# For now, let's just choose a standard UC formulation.
uc_template = template_unit_commitment()

# And adjust the thermal generator formulation to use `ThermalMultiStartUnitCommitment`
set_device_model!(uc_template, ThermalMultiStart, ThermalMultiStartUnitCommitment)

# Now we can build a 4-hour economic dispatch problem with the RTS data.
solver = optimizer_with_attributes(HiGHS.Optimizer, "mip_rel_gap" => 0.5)

problem = DecisionModel(uc_template, sys, horizon = 4, optimizer = solver)
build!(problem, output_dir = mktempdir())

# And solve it ...
solve!(problem)

max_stars_repo_name: NREL-SIIP/Examples

max_issues_repo_name: NREL-SIIP/Examples

max_forks_repo_name: NREL-SIIP/Examples


text:
#!/usr/bin/env julia

using Luxor

using Test

using Random
Random.seed!(42)

function test_pro_text(fname)
    Drawing(1600, 1800, fname)
    sethue("black")
    strings = [
    "This is bold.",
    "This is italic.",
    "<s>This is strikethrough.</s>",
    "This is subscript.",
    "This is superscript.",
    "This makes the font smaller.",
    "<big>This makes the font larger.</big>",
    "This is underlined text.",
    "<tt>This uses a monospaced font.</tt>",
    "Blue text!",
    "Extra Large Text",
    "Well, time for a quick fontsize change. I think!"
    ]
    col1 = 100
    col2 = 900
    row = 100

    counter = 1
    for i in 4:30
        # pro api:
        setfont("Georgia $i", i)
        settext(
            strings[mod1(counter, end)],
            Point(col1, row),
            halign="left",
            valign="top",
            angle=0,
            markup=true)
        counter += 1

        # toy api:
        fontface("Georgia")
        fontsize(i)
        text("hello in Georgia $i using the Toy API", Point(col2, row))
        row += 30

        # TODO: A weird bug: the markup is applied when I don't think it should be
        # pro api again
        # setfont("Georgia $i", i)
        #settext("hello in Georgia $i using the Pro API", Point(col2, row))

        # row += 30
    end
    settext("Test with no row, col", halign="left", valign="top", angle=0, markup=true)

    @test finish() == true
end

fname = "pro-text-test.pdf"
test_pro_text(fname)
println("...finished test: output in $(fname)")


text:
# This file is a part of AstroLib.jl. License is MIT "Expat".
# Copyright (C) 2016 Mosè Giordano.

"""
    sec2rad(sec) -> radians

### Purpose ###

Convert from seconds to radians.

### Argument ###

* `sec`: number of seconds.

### Output ###

The number of radians corresponding to `sec`.

### Example ###

```jldoctest
julia> using AstroLib

julia> sec2rad(3600 * 30)
0.5235987755982988
```

### Notes ###

Use `rad2sec` to convert radians to seconds.
"""
sec2rad(sec::Real) = deg2rad(sec / 3600)


text:
########################################################################
#                               API                                    #
########################################################################

const DIFF_RULES = Vector{Tuple}()
const NO_DIFF_RULES = Vector{Tuple}()
const CONSTRUCTORS = Vector{Tuple}()
const DIFF_PHS = Set([:x, :u, :v, :w, :t, :i, :j, :k,])

function reset_rules!()
    empty!(DIFF_RULES)
    empty!(NO_DIFF_RULES)
    empty!(CONSTRUCTORS)
end

function resolve_old_broadcast(ex)
    # rewrite dot op symbols like .*, .+, etc. into broadcasting
    for (pat, rpat) in [
        :(.+(_xs...)) => :($broadcast($+, _xs...)),
        :(.-(_xs...)) => :($broadcast($-, _xs...)),
        :(.*(_xs...)) => :($broadcast($*, _xs...)),
        :(./(_xs...)) => :($broadcast($/, _xs...)),
    ]
        ex = Espresso.rewrite_all(ex, pat, rpat)
    end
    return ex
end

function resolve_functions_and_types!(mod::Module, ex)
    if Meta.isexpr(ex, :call)
        # replace function symbol with actual function reference and
        # recursively call on function args
        if string(ex.args[1])[1] != '.'  # .*, .+, etc.
            ex.args[1] = Core.eval(mod, ex.args[1])
        end
        resolve_functions_and_types!(mod, @view ex.args[2:end])
        # for x in ex.args[2:end]
        #     resolve_functions_and_types!(mod, x)
        # end
    elseif Meta.isexpr(ex, :(::))
        ex.args[2] = Core.eval(mod, ex.args[2])
    elseif ex isa Vector || ex isa SubArray
        for (i, x) in enumerate(ex)
            if Meta.isexpr(x, :$)
                ex[i] = Core.eval(mod, x.args[1])
            else
                resolve_functions_and_types!(mod, x)
            end
        end
    end
    return ex
end

function add_diff_rule(rule)
    if !in(rule, DIFF_RULES)
        push!(DIFF_RULES, rule)
    else
        @warn "Skipping duplicate diff rule $rule"
    end
end

add_primitive(primitive) = push!(PRIMITIVES, primitive)
add_constructor(ctor) = push!(CONSTRUCTORS, ctor)

"""
Define a differentiation rule for a function.

Arguments:

 * pat - pattern of a function call, may include argument types
 * var - variable (argument) for which the rule is defined
 * rpat - replacement pattern, i.e. expression that calculates the derivative

Examples:

    @diffrule +(u::Real, v::Real) u dy
    @diffrule sum(u::AbstractArray) u sum_grad(u, dy)
    @diffrule Statistics.mean(u::AbstractArray) u ∇mean(u, dy)
    @diffrule logpdf(_d::MvNormal, x) _d.μ ∇logpdf(dy, _d, x)

Note that diff rules are added dynamically, so it's advised to put @diffrule
to __init__() method of a module to survive module precompilation.

Allowed and special variable names:

 * x, u, v, w and some others (see Yota.DIFF_PHS for the full list)
 * any var beginning with _, e.g. _a, _d, etc.
 * y - special, replaced with the result of the function call (e.g. `y = func(args)`)
 * dy - special, replaced with the derivative w.r.t. to y

See also: @diffrule_kw, @nodiff, @ctor
"""
macro diffrule(pat, var, rpat)
    esc(quote
        mod = @__MODULE__
        local pat, rpat = map($Espresso.sanitize, ($(QuoteNode(pat)), $(QuoteNode(rpat))))
        pat, rpat = map($resolve_old_broadcast, (pat, rpat))
        $resolve_functions_and_types!(mod, pat)
        $resolve_functions_and_types!(mod, rpat)
        $add_diff_rule((pat, $(QuoteNode(var)), rpat))
        $add_primitive(pat.args[1])
        nothing
        end)
end

"""
Define a differentiation rule for a functioin with keyword arguments.
Keyword arguments need not to be specified; instead all kw args are passed to
the gradient functions as is.

Examples:

    conv2d(x, w; stride=1, padding=0, dilation=1) = ...
    ∇conv2d_w(dy, x, w; stride=1, padding=0, dilation=1) = ...
    @diffrule_kw conv2d(x, w) w ∇conv2d_w(dy, x, w)
    @diffrule_kw conv2d(x, w) x ∇conv2d_x(dy, x, w)  # kwargs passed implicitely

See also: @diffrule, @nodiff, @ctor

"""
macro diffrule_kw(pat, var, rpat)
    kw_pat = rewrite(pat, :(_fn(_args...)), :(Core.kwfunc(_fn)(_kw, _, _args...)))
    kw_rpat = rewrite(rpat, :(_fn(_args...)), :(Core.kwfunc(_fn)(_kw, _, _args...)))
    kw_rpat = subs(kw_rpat, Dict(:_ => Expr(:$, rpat.args[1])))
    return esc(
        quote
        @diffrule $pat $var $rpat
        @diffrule $kw_pat $var $kw_rpat
        @nodiff $kw_pat _kw
        @nodiff $kw_pat _
        end)
end

"""
Define a type constructor that should not be traced, but instead recorded
to the tape as is. Here's an example:

    @ctor MvNormal(μ, Σ)

This should be read as:

1) record MvNormal to the tape as is
2) if @diffrule w.r.t. its field is added, propagate it directly to the variable
   that was used to construct that field

For example, after the following diff rule:

    @diffrule logpdf(_d::MvNormal, x) _d.μ ∇logpdf(dy, _d, x)

Yota will _completely bypass_ internals of the constructor and jump directly to the
1st variable passed to MvNormal().

Note that if you don't want to bypass the constructor (which you normally shouldn't do),
you can rely on Yota handling it automatically.

"""
macro ctor(ex)
    esc(quote
        mod = @__MODULE__
        local ex = $Espresso.sanitize($(QuoteNode(ex)))
        ex = $resolve_old_broadcast(ex)
        $resolve_functions_and_types!(mod, ex)
        $add_constructor((ex.args[1], ex.args[2:end]...))
        $add_primitive(ex.args[1])
        nothing
        end)
end

isparameters(a) = isa(a, Expr) && a.head == :parameters

function without_types(pat)
    rpat = copy(pat)
    for i=2:length(rpat.args)
        a = rpat.args[i]
        if !isparameters(a)  # parameters aren't modified
            rpat.args[i] = isa(a, Expr) ? a.args[1] : a
        end
    end
    return rpat
end

function get_arg_names(pat)
    return [isa(a, Expr) ? a.args[1] : a for a in pat.args[2:end] if !isparameters(a)]
end

function get_arg_types(pat)
    return [isa(a, Expr) ? Core.eval(Base, a.args[2]) : Any
            for a in pat.args[2:end] if !isparameters(a)]
end

function match_rule(rule, ex, dep_types, idx)
    tpat, vname, rpat = rule
    # if var name is actually a field expression, e.g. :(str.fld)
    fldname = nothing
    if Meta.isexpr(vname, :(.))
        fldname = vname.args[2].value
        vname = vname.args[1]
    end
    vidx = findfirst(isequal(vname), get_arg_names(tpat))
    if idx != vidx
        return nothing, nothing
    end
    pat_types = get_arg_types(tpat)
    if (length(dep_types) != length(pat_types) ||
        !all([t <: p for (t, p) in zip(dep_types, pat_types)]))
        return nothing, nothing
    end
    pat = without_types(tpat)
    ex_ = without_keywords(ex)
    if !matchingex(pat, ex_; phs=DIFF_PHS)
        return nothing, nothing
    else
        return pat => rpat, fldname
    end
end

function rewrite_with_keywords(ex, pat, rpat)
    if rpat isa Expr && rpat.head == :call
        op, args, kw_args = parse_call_expr(ex)
        ex_no_kw = Expr(:call, op, args...)
        rex_no_kw = rewrite(ex_no_kw, pat, rpat; phs=DIFF_PHS)
        rex = with_keywords(rex_no_kw, kw_args)
    else
        rex = rewrite(ex, pat, rpat; phs=DIFF_PHS)
    end
    return rex
end

"""
For each matched rule, rewrite call expression into its derivative w.r.t.
its argument with index `idx`. If argument under `idx` is a struct,
second returned values is a symbolic name of the field that this derivative
should be attributed to. Otherwise it's nothing.

Example:

```
deriv_exprs(:($sin(x)), [Float64], 1)
# ==> :((cos(x) * ds)), nothing
```
"""
function deriv_exprs(ex, dep_types, idx::Int)
    # try Yota diffrules
    result = Tuple[]   # list of tuples (rewritten_expr, field_name | nothing)
    for rule in DIFF_RULES
        m, fldname = match_rule(rule, ex, dep_types, idx)
        if m != nothing
            pat, rpat = m
            rex = rewrite_with_keywords(ex, pat, rpat)
            push!(result, (rex, fldname))
        end
    end
    if !isempty(result)
        return result
    end
    # try ChainRules
    # since pullback is a closure, we can't just extract pullback function and
    # record it to the tape as constant; instead we must rewrite forward pass as well
    # replacing all f(args...) with _, pb = rrule(f, args...)
    # which breaks significant part of codebase
    # @assert Meta.isexpr(ex, :call)
    # _, df = rrule(ex.args[1], 2.0)
    # dex = Expr(:call, df, )
    error("Can't find differentiation rule for $ex at $idx " *
          "with types $dep_types)")
end

"""
Internal function for finding rule by function name
"""
function find_rules_for(fun)
    return [r for r in DIFF_RULES if r[1].args[1] == fun]
end

## nodiff

add_no_diff_rule(rule) = push!(NO_DIFF_RULES, rule)

"""
Don't propagate derivative of the given function w.r.t. specified variable
"""
macro nodiff(pat, var)
    esc(quote
        mod = @__MODULE__
        local pat = $Espresso.sanitize($(QuoteNode(pat)))
        pat = $resolve_old_broadcast(pat)
        $resolve_functions_and_types!(mod, pat)
        $add_no_diff_rule((pat, $(QuoteNode(var))))
        $add_primitive(pat.args[1])
        nothing
        end)
end

function match_nodiff_rule(rule, ex, dep_types, idx)
    tpat, vname = rule
    vidx = findfirst(isequal(vname), get_arg_names(tpat))
    if idx != vidx
        return false
    end
    pat_types = get_arg_types(tpat)
    if (length(dep_types) != length(pat_types) ||
        !all([t <: p for (t, p) in zip(dep_types, pat_types)]))
        return false
    end
    pat = without_types(tpat)
    ex_ = without_keywords(ex)
    return matchingex(pat, ex_; phs=DIFF_PHS)
end

function dont_diff(tape::Tape, op::AbstractOp, idx::Int)
    if op.fn == broadcast
        ex = to_unbroadcast_expr(tape, op)
        dep_types = [eltype(tape[arg].typ) for arg in op.args[2:end]]
        idx_ = idx - 1
    else
        ex =  to_expr(tape, op)
        dep_types = [tape[arg].typ for arg in op.args]
        idx_ = idx
    end
    for rule in NO_DIFF_RULES
        if match_nodiff_rule(rule, ex, dep_types, idx_)
            return true
        end
    end
    return false
end

include("basic.jl")
include("distributions.jl")


text:
include("types.jl")

##########

function float32name(fname::Symbol)
	name_parts = split(string(fname),"_")
	new_name = name_parts[1]*"f"
	if length(name_parts) > 1
		new_name *= "_"*join(name_parts[2:end])
	end
	Symbol(new_name)
end

#########

for fname in (:xsin,  :xcos,  :xtan,  :xasin,  :xacos,  :xatan,  :xexp,  :xsinh,  :xcosh,  :xtanh,  :xasinh,  :xacosh,  :xatanh,  :xcbrt,  :xexp2,  :xexp10,  :xexpm1, :xsin_u1, :xcos_u1, :xtan_u1,  :xasin_u1,  :xacos_u1,  :xatan_u1, :xcbrt_u1)
	@eval begin
		@inline function $fname(a::Float64)
			ret = ccall(($(QuoteNode(fname)), jl_sleef),VDouble,(VDouble,), a)
			Base.convert(Float64, ret)
		end

		@inline function $fname(a::Float32)
			ret = ccall(($(QuoteNode(float32name(fname))), jl_sleef),VFloat,(VFloat,), a)
			Base.convert(Float32, ret)
		end
	end
end

for fname in (:xlog, :xlog10, :xlog_u1)
	@eval begin
		@inline function $fname(a::Float64)
			isnan(a) || a >= 0.0 || throw(DomainError())
			ret = ccall(($(QuoteNode(fname)), jl_sleef),VDouble,(VDouble,), a)
			Base.convert(Float64, ret)
		end

		@inline function $fname(a::Float32)
			isnan(a) || a >= 0f0 || throw(DomainError())
			ret = ccall(($(QuoteNode(float32name(fname))), jl_sleef),VFloat,(VFloat,), a)
			Base.convert(Float32, ret)
		end
	end
end

@inline function xlog1p(a::Float64)
	isnan(a) || a >= -1.0 || throw(DomainError())
	ret = ccall((:xlog1p, jl_sleef),VDouble,(VDouble,), a)
	Base.convert(Float64, ret)
end

@inline function xlog1p(a::Float32)
	isnan(a) || a >= -1f0 || throw(DomainError())
	ret = ccall((:xlog1pf, jl_sleef),VFloat,(VFloat,), a)
	Base.convert(Float32, ret)
end

for fname in [:xsincos, :xsincos_u1]
	@eval begin
		@inline function $fname(a::Float64)
			ret = ccall(($(QuoteNode(fname)), jl_sleef),VDouble2,(VDouble,), a)
			Base.convert(Tuple{Float64,Float64}, ret)
		end

		@inline function $fname(a::Float32)
			ret = ccall(($(QuoteNode(float32name(fname))), jl_sleef),VFloat2,(VFloat,), a)
			Base.convert(Tuple{Float32,Float32}, ret)
		end
	end
end

for fname in [:xatan2, :xpow, :xatan2_u1]
	@eval begin
		@inline function $fname(a::Float64, b::Float64)
			ret = ccall(($(QuoteNode(fname)), jl_sleef),VDouble,(VDouble,VDouble), a, b)
			Base.convert(Float64, ret)
		end

		@inline function $fname(a::Float32, b::Float32)
			ret = ccall(($(QuoteNode(float32name(fname))), jl_sleef),VFloat,(VFloat,VFloat), a, b)
			Base.convert(Float32, ret)
		end
	end
end

@inline function xldexp(x::Float64, q::Int32)
	ret = ccall((:xldexp, jl_sleef),VDouble,(VDouble, VInt), xv, qv)
	Base.convert(Float64, ret)
end

@inline function xldexp(x::Float32, q::Int32)
	ret = ccall((:xldexpf, jl_sleef),VDouble,(VFloat, VInt2), x, q)
	Base.convert(Float64, ret)
end

@inline function xilogb(a::Float64) #Does not come in Float32 flavor
	ret = ccall((:xilogb, jl_sleef),VInt,(VDouble,), a)
	convert(Int32, ret)
end

##############################