diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index d3cb48a..341357f 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.6.7","generation_timestamp":"2024-11-01T08:14:21","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.6.7","generation_timestamp":"2024-11-13T08:59:28","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index 82252a1..7d68cd8 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -612,176 +612,194 @@ function worker_function(documenterSearchIndex, documenterBaseURL, filters) { }; } -// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! -const filters = [ - ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), -]; -const worker_str = - "(" + - worker_function.toString() + - ")(" + - JSON.stringify(documenterSearchIndex["docs"]) + - "," + - JSON.stringify(documenterBaseURL) + - "," + - JSON.stringify(filters) + - ")"; -const worker_blob = new Blob([worker_str], { type: "text/javascript" }); -const worker = new Worker(URL.createObjectURL(worker_blob)); - /////// SEARCH MAIN /////// -// Whether the worker is currently handling a search. This is a boolean -// as the worker only ever handles 1 or 0 searches at a time. -var worker_is_running = false; - -// The last search text that was sent to the worker. This is used to determine -// if the worker should be launched again when it reports back results. -var last_search_text = ""; - -// The results of the last search. This, in combination with the state of the filters -// in the DOM, is used compute the results to display on calls to update_search. -var unfiltered_results = []; - -// Which filter is currently selected -var selected_filter = ""; - -$(document).on("input", ".documenter-search-input", function (event) { - if (!worker_is_running) { - launch_search(); - } -}); - -function launch_search() { - worker_is_running = true; - last_search_text = $(".documenter-search-input").val(); - worker.postMessage(last_search_text); -} - -worker.onmessage = function (e) { - if (last_search_text !== $(".documenter-search-input").val()) { - launch_search(); - } else { - worker_is_running = false; - } - - unfiltered_results = e.data; - update_search(); -}; +function runSearchMainCode() { + // `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! + const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), + ]; + const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; + const worker_blob = new Blob([worker_str], { type: "text/javascript" }); + const worker = new Worker(URL.createObjectURL(worker_blob)); + + // Whether the worker is currently handling a search. This is a boolean + // as the worker only ever handles 1 or 0 searches at a time. + var worker_is_running = false; + + // The last search text that was sent to the worker. This is used to determine + // if the worker should be launched again when it reports back results. + var last_search_text = ""; + + // The results of the last search. This, in combination with the state of the filters + // in the DOM, is used compute the results to display on calls to update_search. + var unfiltered_results = []; + + // Which filter is currently selected + var selected_filter = ""; + + $(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } + }); -$(document).on("click", ".search-filter", function () { - if ($(this).hasClass("search-filter-selected")) { - selected_filter = ""; - } else { - selected_filter = $(this).text().toLowerCase(); + function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); } - // This updates search results and toggles classes for UI: - update_search(); -}); + worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } -/** - * Make/Update the search component - */ -function update_search() { - let querystring = $(".documenter-search-input").val(); + unfiltered_results = e.data; + update_search(); + }; - if (querystring.trim()) { - if (selected_filter == "") { - results = unfiltered_results; + $(document).on("click", ".search-filter", function () { + if ($(this).hasClass("search-filter-selected")) { + selected_filter = ""; } else { - results = unfiltered_results.filter((result) => { - return selected_filter == result.category.toLowerCase(); - }); + selected_filter = $(this).text().toLowerCase(); } - let search_result_container = ``; - let modal_filters = make_modal_body_filters(); - let search_divider = `
`; + // This updates search results and toggles classes for UI: + update_search(); + }); - if (results.length) { - let links = []; - let count = 0; - let search_results = ""; - - for (var i = 0, n = results.length; i < n && count < 200; ++i) { - let result = results[i]; - if (result.location && !links.includes(result.location)) { - search_results += result.div; - count++; - links.push(result.location); - } - } + /** + * Make/Update the search component + */ + function update_search() { + let querystring = $(".documenter-search-input").val(); - if (count == 1) { - count_str = "1 result"; - } else if (count == 200) { - count_str = "200+ results"; + if (querystring.trim()) { + if (selected_filter == "") { + results = unfiltered_results; } else { - count_str = count + " results"; + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); } - let result_count = `
${count_str}
`; - search_result_container = ` + let search_result_container = ``; + let modal_filters = make_modal_body_filters(); + let search_divider = `
`; + + if (results.length) { + let links = []; + let count = 0; + let search_results = ""; + + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; + links.push(result.location); + } + } + + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; + + search_result_container = ` +
+ ${modal_filters} + ${search_divider} + ${result_count} +
+ ${search_results} +
+
+ `; + } else { + search_result_container = `
${modal_filters} ${search_divider} - ${result_count} -
- ${search_results} -
-
+
0 result(s)
+ +
No result found!
`; - } else { - search_result_container = ` -
- ${modal_filters} - ${search_divider} -
0 result(s)
-
-
No result found!
- `; - } + } - if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").removeClass("is-justify-content-center"); - } + if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").removeClass("is-justify-content-center"); + } - $(".search-modal-card-body").html(search_result_container); - } else { - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").addClass("is-justify-content-center"); + $(".search-modal-card-body").html(search_result_container); + } else { + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); } + } - $(".search-modal-card-body").html(` -
Type something to get started!
- `); + /** + * Make the modal filter html + * + * @returns string + */ + function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); + + return ` +
+ Filters: + ${str} +
`; } } -/** - * Make the modal filter html - * - * @returns string - */ -function make_modal_body_filters() { - let str = filters - .map((val) => { - if (selected_filter == val.toLowerCase()) { - return `${val}`; - } else { - return `${val}`; - } - }) - .join(""); - - return ` -
- Filters: - ${str} -
`; +function waitUntilSearchIndexAvailable() { + // It is possible that the documenter.js script runs before the page + // has finished loading and documenterSearchIndex gets defined. + // So we need to wait until the search index actually loads before setting + // up all the search-related stuff. + if (typeof documenterSearchIndex !== "undefined") { + runSearchMainCode(); + } else { + console.warn("Search Index not available, waiting"); + setTimeout(waitUntilSearchIndexAvailable, 1000); + } } +// The actual entry point to the search code +waitUntilSearchIndexAvailable(); + }) //////////////////////////////////////////////////////////////////////////////// require(['jquery'], function($) { diff --git a/dev/docstring/index.html b/dev/docstring/index.html index 01d44bd..7795b66 100644 --- a/dev/docstring/index.html +++ b/dev/docstring/index.html @@ -1,31 +1,31 @@ -Docstrings · EltypeExtensions

Docstrings

EltypeExtensions._to_precisiontypeMethod
_to_precisiontype(T::Type, S::Type)

Convert type S to have the precisiontype of T. An exception is that if T<:Integer, then Rational will also be unwrapped.

Examples

julia> _to_precisiontype(Float64, Complex{Rational{Int}})
+Docstrings · EltypeExtensions

Docstrings

EltypeExtensions._to_precisiontypeMethod
_to_precisiontype(T::Type, S::Type)

Convert type S to have the precisiontype of T. An exception is that if T<:Integer, then Rational will also be unwrapped.

Examples

julia> _to_precisiontype(Float64, Complex{Rational{Int}})
 ComplexF64 (alias for Complex{Float64})
 
 julia> _to_precisiontype(BigFloat, Matrix{Complex{Bool}})
 Matrix{Complex{BigFloat}} (alias for Array{Complex{BigFloat}, 2})
 
 julia> _to_precisiontype(Int, Complex{Rational{BigInt}})
-Complex{Rational{Int64}}
source
EltypeExtensions.basetypeMethod
basetype(T::Type)

Recursively apply eltype to T until convergence.

Examples

julia> basetype(Matrix{BitArray})
+Complex{Rational{Int64}}
source
EltypeExtensions.basetypeMethod
basetype(T::Type)

Recursively apply eltype to T until convergence.

Examples

julia> basetype(Matrix{BitArray})
 Bool
 
 julia> basetype(Vector{Set{Complex{Float64}}})
 ComplexF64 (alias for Complex{Float64})
 
 julia> basetype([1:n for n in 1:10])
-Int64
source
EltypeExtensions.elconvertMethod
elconvert(T, A)

Similar to convert(T, A), but T refers to the eltype. See also _to_eltype.

Examples

julia> elconvert(Float64, 1:10)
 1.0:1.0:10.0
 
 julia> typeof(elconvert(Float64, rand(Int, 3, 3)))
-Matrix{Float64} (alias for Array{Float64, 2})
source
EltypeExtensions.precisionconvertMethod
precisionconvert(T::Type, A, prec)

Convert A to have the precisiontype of T. prec is optional.

  • When T has static precision (e.g. Float64), prec has no effect.
  • When T has dynamic precision (e.g. BigFloat), prec specifies the precision of conversion. When prec is not provided, the precision is decided by the external setup from T.
  • When T is an integer, the conversion will dig into Rational as well. In contrast, since Rational as a whole is more "precise" than an integer, precisiontype doesn't unwrap Rational.

Examples

julia> precisionconvert(BigFloat, 1//3+im, 128)
+Matrix{Float64} (alias for Array{Float64, 2})
source
EltypeExtensions.precisionconvertMethod
precisionconvert(T::Type, A, prec)

Convert A to have the precisiontype of T. prec is optional.

  • When T has static precision (e.g. Float64), prec has no effect.
  • When T has dynamic precision (e.g. BigFloat), prec specifies the precision of conversion. When prec is not provided, the precision is decided by the external setup from T.
  • When T is an integer, the conversion will dig into Rational as well. In contrast, since Rational as a whole is more "precise" than an integer, precisiontype doesn't unwrap Rational.

Examples

julia> precisionconvert(BigFloat, 1//3+im, 128)
 0.3333333333333333333333333333333333333338 + 1.0im
 
 julia> precisionconvert(Float16, [[m/n for n in 1:3] for m in 1:3])
 3-element Vector{Vector{Float16}}:
  [1.0, 0.5, 0.3333]
  [2.0, 1.0, 0.6665]
- [3.0, 1.5, 1.0]
source
EltypeExtensions.precisiontypeMethod
precisiontype(T::Type)

Returns the type that decides the precision of T. The difference from basetype is that precisiontype unwraps composite basetypes such as Complex and that precisiontype is not generalised.

Examples

julia> precisiontype(Complex{Float32})
+ [3.0, 1.5, 1.0]
source
EltypeExtensions.precisiontypeMethod
precisiontype(T::Type)

Returns the type that decides the precision of T. The difference from basetype is that precisiontype unwraps composite basetypes such as Complex and that precisiontype is not generalised.

Examples

julia> precisiontype(Complex{Float32})
 Float32
 
 julia> precisiontype(Matrix{ComplexF64})
-Float64
source
+Float64
source
diff --git a/dev/index.html b/dev/index.html index 5264a20..fc7dece 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -EltypeExtensions.jl · EltypeExtensions

EltypeExtensions.jl

EltypeExtensions.jl is a mini toolbox for eltype-related conversions. The motivation of this package comes from manipulating (nested) arrays with different eltypes. However if you have any reasonable idea that works on other instances, feel free to write an issue/pull request.

We note that this package has some overlap with TypeUtils.jl and Unitless.jl.

Introduction

elconvert and _to_eltype

elconvert(T, x) works like convert(T, x), except that T refers to the eltype of the result. This can be useful for generic codes.

It should be always true that elconvert(T, x) isa _to_eltype(T, typeof(x)). However, since elconvert and _to_eltype use different routines, it's possible that the equality doesn't hold for some types. Please submit an issue or PR if that happens.

If typeof(x) is not in Base or stdlib, the package who owns the type should implement corresponding _to_eltype or elconvert. elconvert has fallbacks, in which case it could be unnecessary:

  • For a subtype of AbstractArray, elconvert calls the constructor AbstractArray{T} and _to_eltype returns Array.
  • For a subtype of AbstractUnitRange, elconvert calls the constructor AbstractUnitRange{T}.
  • For a subtype of AbstractRange, elconvert uses broadcast through map.
  • For a Tuple, elconvert uses dot broadcast.
  • For other types, elconvert calls convert and _to_eltype.

However, _to_eltype must be implemented for each type to support baseconvert and precisionconvert. The following types from Base and stdlib are explicitly supported by _to_eltype:

AbstractArray, AbstractDict, AbstractSet, Adjoint, Bidiagonal, BitArray, CartesianIndices, Diagonal, Dict, Hermitian, Set, StepRangeLen, Symmetric, SymTridiagonal, Transpose, TwicePrecision, UnitRange

basetype and precisiontype

The basetype is used for nested collections, where eltype is repeatedly applied until the bottom. precisiontype has a similar idea, but goes deeper when possible. precisiontype is used to manipulate the accuracy of (nested) collections.

julia> basetype(Set{Matrix{Vector{Matrix{Complex{Rational{Int}}}}}})Complex{Rational{Int64}}
julia> precisiontype(Set{Matrix{Vector{Matrix{Complex{Rational{Int}}}}}})Rational{Int64}

Method naming convention

  • sometype(T) gets the sometype of type T.
  • sometype(x) = sometype(typeof(x)) is also provided for convenience.
  • _to_sometype(T,S) converts the type S to have the sometype of T.
  • someconvert(T,A) converts A to have the sometype of T.

where some can be el, base and precision.

On precisionconvert

precisionconvert accepts an optional third argument prec.

  • When T has static precision, prec has no effect.
  • When T has dynamic precision, prec specifies the precision of conversion. When prec is not provided, the precision is decided by the external setup from T. The difference is significant when precisionconvert is called by another function:
    julia> precision(BigFloat)256
    julia> f(x) = precisionconvert(BigFloat, x, 256)f (generic function with 1 method)
    julia> g(x) = precisionconvert(BigFloat, x)g (generic function with 1 method)
    julia> setprecision(128)128
    julia> f(π) # static precision3.141592653589793238462643383279502884197169399375105820974944592307816406286198
    julia> g(π) # precision varies with the global setting3.141592653589793238462643383279502884195
  • When T is an integer, the conversion will dig into Rational as well. In contrast, since Rational as a whole is more "precise" than an integer, precisiontype doesn't unwrap Rational.
    julia> precisiontype(precisionconvert(Int128, Int8(1)//Int8(2)))Rational{Int128}
+EltypeExtensions.jl · EltypeExtensions

EltypeExtensions.jl

EltypeExtensions.jl is a mini toolbox for eltype-related conversions. The motivation of this package comes from manipulating (nested) arrays with different eltypes. However if you have any reasonable idea that works on other instances, feel free to write an issue/pull request.

We note that this package has some overlap with TypeUtils.jl and Unitless.jl.

Introduction

elconvert and _to_eltype

elconvert(T, x) works like convert(T, x), except that T refers to the eltype of the result. This can be useful for generic codes.

It should be always true that elconvert(T, x) isa _to_eltype(T, typeof(x)). However, since elconvert and _to_eltype use different routines, it's possible that the equality doesn't hold for some types. Please submit an issue or PR if that happens.

If typeof(x) is not in Base or stdlib, the package who owns the type should implement corresponding _to_eltype or elconvert. elconvert has fallbacks, in which case it could be unnecessary:

  • For a subtype of AbstractArray, elconvert calls the constructor AbstractArray{T} and _to_eltype returns Array.
  • For a subtype of AbstractUnitRange, elconvert calls the constructor AbstractUnitRange{T}.
  • For a subtype of AbstractRange, elconvert uses broadcast through map.
  • For a Tuple, elconvert uses dot broadcast.
  • For other types, elconvert calls convert and _to_eltype.

However, _to_eltype must be implemented for each type to support baseconvert and precisionconvert. The following types from Base and stdlib are explicitly supported by _to_eltype:

AbstractArray, AbstractDict, AbstractSet, Adjoint, Bidiagonal, BitArray, CartesianIndices, Diagonal, Dict, Hermitian, Set, StepRangeLen, Symmetric, SymTridiagonal, Transpose, TwicePrecision, UnitRange

basetype and precisiontype

The basetype is used for nested collections, where eltype is repeatedly applied until the bottom. precisiontype has a similar idea, but goes deeper when possible. precisiontype is used to manipulate the accuracy of (nested) collections.

julia> basetype(Set{Matrix{Vector{Matrix{Complex{Rational{Int}}}}}})Complex{Rational{Int64}}
julia> precisiontype(Set{Matrix{Vector{Matrix{Complex{Rational{Int}}}}}})Rational{Int64}

Method naming convention

  • sometype(T) gets the sometype of type T.
  • sometype(x) = sometype(typeof(x)) is also provided for convenience.
  • _to_sometype(T,S) converts the type S to have the sometype of T.
  • someconvert(T,A) converts A to have the sometype of T.

where some can be el, base and precision.

On precisionconvert

precisionconvert accepts an optional third argument prec.

  • When T has static precision, prec has no effect.
  • When T has dynamic precision, prec specifies the precision of conversion. When prec is not provided, the precision is decided by the external setup from T. The difference is significant when precisionconvert is called by another function:
    julia> precision(BigFloat)256
    julia> f(x) = precisionconvert(BigFloat, x, 256)f (generic function with 1 method)
    julia> g(x) = precisionconvert(BigFloat, x)g (generic function with 1 method)
    julia> setprecision(128)128
    julia> f(π) # static precision3.141592653589793238462643383279502884197169399375105820974944592307816406286198
    julia> g(π) # precision varies with the global setting3.141592653589793238462643383279502884195
  • When T is an integer, the conversion will dig into Rational as well. In contrast, since Rational as a whole is more "precise" than an integer, precisiontype doesn't unwrap Rational.
    julia> precisiontype(precisionconvert(Int128, Int8(1)//Int8(2)))Rational{Int128}