API
Create new grids
AdaptiveDensityApproximation.create_grid
— Functioncreate_grid(axis_ticks::AbstractArray...;
initial_weight = 1.0,
exclude_strings = [""],
string_length = 10
)
Create a multidimensional grid, where the axis_ticks
define the corner points of the blocks.
For each dimension a separate array of axis-ticks is required. Each axis-ticks array must have at least 3 elements.
Keywords
initial_weight
: Initial weight for the blocks.exclude_strings
: Strings that will not be used for the block names / keys.string_length
: Length for the block names / keys.
Examples
julia> create_grid([1,2,3],[1,2,3],[1,2,3])
julia> create_grid(LinRange(0,1,10),LinRange(0,100,100))
create_grid(axis_ticks::AbstractArray;
initial_weight = 1.0,
exclude_strings = [""],
string_length = 10
)
Create a one-dimensional grid where the axis_ticks
define the start/end points of the intervals.
There must be at least 3 elements in the axis_ticks array.
Keywords
initial_weight
: Initial weight for the intervals.exclude_strings
: Strings that will not be used for the block names / keys.string_length
: Length for the block names / keys.
Examples
julia> create_grid([1,2,3,4])
julia> create_grid(LinRange(1,10,100))
Approximate density functions
AdaptiveDensityApproximation.approximate_density!
— Functionapproximate_density!(grid::Union{OneDimGrid,Grid},f::Function;
mode = :center,
mesh_size = 4,
volume_normalization = false
)
Approximate the density function f
with the grid
, changing the weights to the function values and return the mutated grid.
mode = :center
: Evaluate the density function in the center of the interval/block.mode = :mean
: Evaluate the density function at all corner points of the interval/block and use the mean value.mode = :mesh
: Evaluate the density function at all mesh points of the interval/block and use the mean value.mesh_size = 4
: Number of block discretization points in each dimension. Only applicable tomode = :mesh
.volume_normalization = false
: Iftrue
the density value is normalized to the interval length / block volume (weight = value × volume
).
Import and Export
AdaptiveDensityApproximation.export_weights
— Functionexport_weights(grid::Union{OneDimGrid,Grid})
Return a vector that contains the weights of the intervals/blocks.
The weights are sorted according to the center points of the intervals/blocks.
AdaptiveDensityApproximation.export_all
— Functionexport_all(grid::Union{OneDimGrid,Grid})
Return the vectors: centers, volumes, weights
.
The vector elements are sorted according to the center points of the intervals/blocks.
AdaptiveDensityApproximation.import_weights!
— Functionimport_weights!(grid::Union{OneDimGrid,Grid}, weights)
Import weights and return the mutated grid.
For the import, the intervals/blocks are sorted according to their center points.
Refine a grid
AdaptiveDensityApproximation.refine!
— Functionrefine!(grid::Union{OneDimGrid,Grid};
block_variation::Function = default_block_variation,
selection::Function = maximum,
split_weights::Bool = false
)
Subdivide intervals/blocks in a grid based on the respective variations. Return the mutated grid and the indices of subdivided (i.e. new) blocks (The index order is the order of export_weights
and export_all
).
By default the variation of a block is the largest difference of weights compared to the weights of the neighboring blocks. The blocks to be subdivided are those that have the largest variation. If several blocks have the same variation, all those blocks are subdivided.
Changing the selection of blocks
block_variation
: Function to calculate the variation value for a block. Must use the following signature(block_center,block_volume, block_weight, neighbor_center,neighbor_volumes, neighbor_weights)
.selection
: Function to select the the blocks based on the variation value. Must have the signature(variations)
where variations is a one-dim array of the variation values.
Changing the weight splitting
By default, the subdividing blocks retain the weight of the original block. If split_weights = true
, the weight of the original block is split up evenly between the subdividing blocks (i.e. divided by the number of subdividing blocks).
Example
Select the block(s) with the smallest possible weight difference to its neighbors:
min_difference(c,v,w,C,V,W) = minimum(abs.(w .- W))
refine!(grid, block_variation= min_difference, selection = minimum)
AdaptiveDensityApproximation.subdivide!
— Functionsubdivide!(grid::Union{OneDimGrid,Grid},block_name::AbstractString;
split_weights::Bool = false
)
Split the block with name block_name
into 2^dim
sub-blocks. Return the mutated grid.
Changing the weight splitting
By default, the subdividing blocks retain the weight of the original block. If split_weights = true
, the weight of the original block is split up evenly between the subdividing blocks (i.e. divided by the number of subdividing blocks).
Restrict the grid domain
AdaptiveDensityApproximation.restrict_domain!
— Functionrestrict_domain!(grid::OneDimGrid;
lower::Real = -Inf,
upper::Real = Inf,
weight_distribution::Symbol = :none
)
Restrict the domain of a grid to the domain defined by lower
and upper
.
weight_distribution = :linear
: If a block gets split up, the weight is rescaled w.r.t. the proportion of the block within the domain.weight_distribution = :log
: If a block gets split up, the weight is rescaled w.r.t. the proportion of the block within the domain, as it appears in a logarithmically scaled plot.
restrict_domain!(grid::Grid;
lower = [-Inf,...,-Inf],
upper = [Inf,...,Inf],
weight_distribution::Symbol = :none
)
Restrict the domain of a grid to the domain defined by lower
and upper
.
weight_distribution = :linear
: If a block gets split up, the weight is rescaled w.r.t. the proportion of the block within the domain.weight_distribution = :log
: If a block gets split up, the weight is rescaled w.r.t. the proportion of the block within the domain, as it appears in a logarithmically scaled plot.
AdaptiveDensityApproximation.select_indices
— Functionselect_indices(grid::OneDimGrid; lower::Real=-Inf,upper::Real=Inf)
Return indices of intervals with centers between lower
and upper
. The index order is the order of export_weights
and export_all
select_indices(grid::Grid; lower= [-Inf,...,-Inf],upper=[Inf, ..., Inf])
Return indices of intervals with centers between lower
and upper
. The index order is the order of export_weights
and export_all
.
Simple calculations
Base.sum
— Methodsum(grid::Union{OneDimGrid, Grid};
lower = nothing,
upper = nothing,
weight_distribution::Symbol = :none
)
Return the sum of all weights.
lower
,upper
andweight_distribution
can be used to restrict the domain, similar torestrict_domain!
. This does not mutate thegrid
.- Too restrictive boundaries (empty grid) raise a warning and the default value 0 is returned.
Base.sum
— Methodsum(f::Function,grid::Union{OneDimGrid, Grid};
lower = nothing,
upper = nothing,
weight_distribution::Symbol = :none
)
Return the sum of f(weight)
for all weights.
lower
,upper
andweight_distribution
can be used to restrict the domain, similar torestrict_domain!
. This does not mutate thegrid
.- Too restrictive boundaries (empty grid) raise a warning and the default value 0 is returned.
Base.prod
— Methodprod(grid::Union{OneDimGrid, Grid};
lower = nothing,
upper = nothing,
weight_distribution::Symbol = :none
)
Return the product of all weights.
lower
,upper
andweight_distribution
can be used to restrict the domain, similar torestrict_domain!
. This does not mutate thegrid
.- Too restrictive boundaries (empty grid) raise a warning and the default value 1 is returned.
Base.prod
— Methodprod(f::Function,grid::Union{OneDimGrid, Grid};
lower = nothing,
upper = nothing,
weight_distribution::Symbol = :none
)
Return the product of f(weight)
for all weights.
lower
,upper
andweight_distribution
can be used to restrict the domain, similar torestrict_domain!
. This does not mutate thegrid
.- Too restrictive boundaries (empty grid) raise a warning and the default value 1 is returned.
AdaptiveDensityApproximation.integrate
— Functionintegrate(grid)
Return the sum over all intervals/blocks of volume × weight
.
When the grid weights approximate a density φ
, integrate(grid)
approximates the integral of the density over the grid domain: ∫_grid φ dV
. This does not apply, if the gird weights already approximate the area/volume under the density (see volume_normalization
for approximate_density!
).
Integral models
AdaptiveDensityApproximation.integral_model
— Functionintegral_model(grid,f::Function, g::Function = f)
Create an approximation for the integral model ∫_grid f(x,y,φ(y),args...) dy
. Returns
- the approximated model (function).
- the grid weights as initial parameters (array).
- individual block functions using
g
instead off
(array of functions).
Let the grid approximate the density φ
. That is, the weight of blocks are characteristic density values for the blocks. For example, λ_i = φ(c_i)
where c_i
are the centers of the blocks. Furthermore let V_i
denote the volumes of the blocks. Then:
- the returned approximated model is:
(x,λ,args...) -> ∑_i V_i ⋅ f(x,c_i,λ_i,...)
- the returned parameters are:
[λ_1,...,λ_n]
- the individual block functions are:
[(x,λ,args...) -> V_i ⋅ g(x,c_i,λ_i,...) for i = 1:number_of_blocks]
Using an optional integral kernel function g
, allows to obtain modified functions for the individual blocks (if g
is not provided the default case is g=f
). The functions f
and g
should have the arguments (x,center,weight,args...)
. This can be useful if one wants to obtain partial derivatives of the approximated model. For further details see Advanced calculations: Integral models
Numeric PDF and CDF
AdaptiveDensityApproximation.get_pdf
— Functionget_pdf(grid::Union{OneDimGrid,Grid}; normalize::Bool = true)
Return the discrete empirical pdf function of a grid. For this, the grid is understood as histogram, where the blocks are the bins, and the weights are the corresponding values. If normalize = true
the values are normalized s.t. the sum of all values is 1.
AdaptiveDensityApproximation.get_cdf
— Functionget_cdf(grid::Union{OneDimGrid,Grid};normalize::Bool = true)
Return the discrete empirical cdf function of a grid. For this, the grid is understood as histogram, where the blocks are the bins, and the weights are the corresponding values. If normalize = true
the values are normalized s.t. the sum of all values is 1.
Grid slices
AdaptiveDensityApproximation.get_slice
— Functionget_slice(grid::Grid, slice_selection)
Return a grid of blocks (from grid
) that intersect with a slice defined by slice_selection
.
3-dim example: the y-axis is defined by slice_selection = [0,nothing,0]
, the y-z-plane at x = 5
is defined by slice_selection = [5,nothing,nothing]
, etc..
AdaptiveDensityApproximation.dimension
— Functiondimension(grid::Union{OneDimGrid,Grid})
Return the dimension of the grid
.