diff --git a/docs/Project.toml b/docs/Project.toml index dfa65cd1..54ef6071 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,2 +1,9 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DynamicQuantities = "06fc5a27-2a28-4c7c-a15d-362465fb6821" + +[compat] +Documenter = "1" + +[sources] +DynamicQuantities = {path = ".."} diff --git a/docs/make.jl b/docs/make.jl index 96120d1f..41bf14e6 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,6 +2,7 @@ using DynamicQuantities using DynamicQuantities.Units using DynamicQuantities: constructorof, with_type_parameters, dimension_names using Documenter +using Documenter.Remotes: GitHub DocMeta.setdocmeta!(DynamicQuantities, :DocTestSetup, :(using DynamicQuantities); recursive=true) doctest(DynamicQuantities) @@ -31,7 +32,7 @@ end makedocs(; modules=[DynamicQuantities, DynamicQuantities.Units], authors="MilesCranmer and contributors", - repo="https://github.com/SymbolicML/DynamicQuantities.jl/blob/{commit}{path}#{line}", + repo=GitHub("SymbolicML/DynamicQuantities.jl"), sitename="DynamicQuantities.jl", format=Documenter.HTML(; prettyurls=get(ENV, "CI", "false") == "true", @@ -39,6 +40,7 @@ makedocs(; edit_link="main", assets=String[] ), + doctest = false, pages=[ "Home" => "index.md", "Examples" => "examples.md", diff --git a/docs/src/examples.md b/docs/src/examples.md index 47a056ee..1ba5eef4 100644 --- a/docs/src/examples.md +++ b/docs/src/examples.md @@ -112,7 +112,7 @@ Say that we wish to track angles as a unit, rather than assume the SI convention that `1 rad = 1`. We can do this by creating a new struct to track dimensions: -```julia +```@example dimensional-angle using DynamicQuantities struct AngleDimensions{R} <: AbstractDimensions{R} @@ -130,15 +130,14 @@ end Simply by inheriting from `AbstractDimensions`, we get all the constructors and operations as defined on `Dimensions`: -```julia -julia> x = Quantity(1.0, AngleDimensions(length=1, angle=-1)) -1.0 m angle⁻¹ +```@repl dimensional-angle +x = Quantity(1.0, AngleDimensions(length=1, angle=-1)) ``` However, perhaps we want to set the default `angle` dimension as `rad`. We can do this by defining a method for `dimension_name`: -```julia +```@example dimensional-angle import DynamicQuantities: DynamicQuantities as DQ function DQ.dimension_name(::AngleDimensions, k::Symbol) @@ -154,13 +153,13 @@ function DQ.dimension_name(::AngleDimensions, k::Symbol) ) return get(default_dimensions, k, string(k)) end +nothing # hide ``` This gives us the following behavior: -```julia -julia> x = Quantity(1.0, AngleDimensions(length=1, angle=-1)) -1.0 m rad⁻¹ +```@repl dimensional-angle +x = Quantity(1.0, AngleDimensions(length=1, angle=-1)) ``` Next, say that we are working with existing quantities defined using @@ -169,7 +168,7 @@ standard `Dimensions`. We want to promote these to our new `AngleDimensions` typ For this, we define two functions: `promote_rule` and a constructor for `AngleDimensions` from regular `Dimensions`: -```julia +```@example dimensional-angle function Base.promote_rule(::Type{AngleDimensions{R1}}, ::Type{Dimensions{R2}}) where {R1,R2} return AngleDimensions{promote_type(R1, R2)} end @@ -183,6 +182,7 @@ function Base.convert(::Type{Quantity{T,AngleDimensions{R}}}, q::Quantity{<:Any, ) ) end +nothing # hide ``` This means that whenever a `Quantity{<:Any,<:Dimensions}` @@ -194,22 +194,16 @@ tracked.) Let's define a constant for `rad`: -```julia -julia> const rad = Quantity(1.0, AngleDimensions(angle = 1)) -1.0 rad +```@repl dimensional-angle +const rad = Quantity(1.0, AngleDimensions(angle = 1)) ``` and use it in a calculation: -```julia -julia> x = 2rad -2.0 rad - -julia> y = 10u"min" -600.0 s - -julia> angular_velocity = x / y -0.0033333333333333335 s⁻¹ rad +```@repl dimensional-angle +x = 2rad +y = 10u"min" +angular_velocity = x / y ``` which as we can see, automatically promotes to diff --git a/src/affine_dimensions.jl b/src/affine_dimensions.jl index 70cdab59..60033d6f 100644 --- a/src/affine_dimensions.jl +++ b/src/affine_dimensions.jl @@ -38,7 +38,7 @@ for op in [:*, :/, :+, :-], (first, second) in [(:AffineUnit, :Number), (:Number # Skip the already defined value * unit case op == :* && first == :Number && second == :AffineUnit && continue - + @eval function Base.$op(a::$first, b::$second) throw(ArgumentError("Affine units only support scalar multiplication in the form 'number * unit', e.g., 22 * ua\"degC\", which will immediately convert it to a regular `Quantity{Float64,Dimensions{R}}`. Other operations are not supported.")) end @@ -122,7 +122,7 @@ Convert a quantity `q` to the numerical value in terms of affine units specified then strip the units. This allows getting the numerical value in terms of degrees Celsius or Fahrenheit. # Examples -```julia +```jldoctest julia> ustrip(ua"degC", 27ua"degC") 27.0 diff --git a/src/arrays.jl b/src/arrays.jl index e0bf619c..53a1522d 100644 --- a/src/arrays.jl +++ b/src/arrays.jl @@ -16,30 +16,41 @@ and so can be used in most places where a normal array would be used, including - `QuantityArray(v::AbstractArray, d::AbstractDimensions)`: Create a `QuantityArray` with value `v` and dimensions `d`, using `Quantity` if the eltype of `v` is numeric, and `GenericQuantity` otherwise. + - `QuantityArray(v::AbstractArray{<:Number}, q::AbstractQuantity)`: Create a `QuantityArray` with value `v` and dimensions inferred - with `dimension(q)`. This is so that you can easily create an array with the units module, like so: - ```julia - julia> A = QuantityArray(randn(32), 1u"m") - ``` + with `dimension(q)`. This is so that you can easily create an array with the units module, like so: + + ```julia + A = QuantityArray(randn(32), 1u"m") + ``` + - `QuantityArray(v::AbstractArray{<:Any}, q::AbstractGenericQuantity)`: Create a `QuantityArray` with - value `v` and dimensions inferred with `dimension(q)`. - This is so that you can easily create quantity arrays of non-numeric eltypes, like so: - ```julia - julia> A = QuantityArray([[1.0], [2.0, 3.0]], GenericQuantity(1u"m")) - ``` + value `v` and dimensions inferred with `dimension(q)`. + This is so that you can easily create quantity arrays of non-numeric eltypes, like so: + + ```julia + A = QuantityArray([[1.0], [2.0, 3.0]], GenericQuantity(1u"m")) + ``` + - `QuantityArray(v::AbstractArray{<:UnionAbstractQuantity})`: Create a `QuantityArray` from an array of quantities. This means the following syntax works: + ```julia - julia> A = QuantityArray(randn(32) .* 1u"km/s") + A = QuantityArray(randn(32) .* 1u"km/s") ``` + - `QuantityArray(v::AbstractArray; kws...)`: Create a `QuantityArray` with dimensions inferred from the keyword arguments. For example: + ```julia - julia> A = QuantityArray(randn(32); length=1) + A = QuantityArray(randn(32); length=1) ``` + is equivalent to + ```julia - julia> A = QuantityArray(randn(32), u"m") + A = QuantityArray(randn(32), u"m") ``` + The keyword arguments are passed to `DEFAULT_DIM_TYPE`. """ struct QuantityArray{T,N,D<:AbstractDimensions,Q<:UnionAbstractQuantity{T,D},V<:AbstractArray{T,N}} <: AbstractArray{Q,N} @@ -480,7 +491,7 @@ end for dim1 in ((3,), (3, 3)), dim2 in ((3,), (3, 3)) A = QuantityArray(rand(T, dim1...), Q{T}(u"m")) B = QuantityArray(rand(T, dim2...), Q{T}(u"s^2")) - + if dim1 == (3,) && dim2 == (3,) @test ustrip(A / B) ≈ ustrip(A) / ustrip(B) @test dimension(A / B) == dimension(A) / dimension(B) diff --git a/src/register_units.jl b/src/register_units.jl index 680ff13f..1bbfd129 100644 --- a/src/register_units.jl +++ b/src/register_units.jl @@ -23,14 +23,14 @@ a particular value. # Example -```julia +```jldoctest register-unit julia> @register_unit MyVolt 1.5u"V" ``` This will register a new unit `MyVolt` with a value of `1.5u"V"`. You can then use this unit in your calculations: -```julia +```jldoctest register-unit julia> x = 20us"MyVolt^2" 20.0 MyVolt² diff --git a/src/symbolic_dimensions.jl b/src/symbolic_dimensions.jl index 6f9a8f2a..965202fa 100644 --- a/src/symbolic_dimensions.jl +++ b/src/symbolic_dimensions.jl @@ -173,7 +173,7 @@ Convert a quantity `q` with base SI units to the symbolic units of `qout`, for ` Mathematically, the result has value `q / uexpand(qout)` and units `dimension(qout)`. You can also use `|>` as a shorthand for `uconvert`: -```julia +```jldoctest julia> q = 1u"m/s^2" |> us"km/h^2" 12960.0 km h⁻² ``` diff --git a/src/units.jl b/src/units.jl index 2cfc7ccc..d4471b89 100644 --- a/src/units.jl +++ b/src/units.jl @@ -147,7 +147,7 @@ end C, ) @doc( - "Voltage in Volts. Available variants: `pV`, `nV`, `μV` (/`uV`), `mV`, kV`, `MV`, `GV`.", + "Voltage in Volts. Available variants: `pV`, `nV`, `μV` (/`uV`), `mV`, `kV`, `MV`, `GV`.", V, ) @doc( diff --git a/src/utils.jl b/src/utils.jl index dcce2597..d507a243 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -46,7 +46,7 @@ For example, `promote_quantity_on_value(Quantity, Float64)` would return `Quanti `promote_quantity_on_value(RealQuantity, String)` would return `GenericQuantity`. The user should overload this function to define a custom type hierarchy. -Also see `promote_quantity_on_quantity`. +Also see [`promote_quantity_on_quantity`](@ref). """ @unstable @inline promote_quantity_on_value(::Type{<:Union{GenericQuantity,Quantity,RealQuantity}}, ::Type{<:Any}) = GenericQuantity @unstable @inline promote_quantity_on_value(::Type{<:Union{Quantity,RealQuantity}}, ::Type{<:Number}) = Quantity @@ -63,7 +63,7 @@ as it can store both `Quantity` and `GenericQuantity` values. Similarly, `promote_quantity_on_quantity(RealQuantity, RealQuantity)` would return `RealQuantity`, as that is the most specific type. -Also see `promote_quantity_on_value`. +Also see [`promote_quantity_on_value`](@ref). """ @unstable @inline promote_quantity_on_quantity(::Type{<:Union{GenericQuantity,Quantity,RealQuantity}}, ::Type{<:Union{GenericQuantity,Quantity,RealQuantity}}) = GenericQuantity @unstable @inline promote_quantity_on_quantity(::Type{<:Union{Quantity,RealQuantity}}, ::Type{<:Union{Quantity,RealQuantity}}) = Quantity @@ -395,14 +395,14 @@ Convert quantity `q` to the units specified by `unit`, then strip the units. This is equivalent to `ustrip(q / unit)`, but also verifies the dimensions are compatible. # Examples -```julia +```jldoctest julia> ustrip(u"km", 1000u"m") 1.0 julia> ustrip(u"s", 1u"minute") 60.0 -julia> ustrip(u"km", [1000u"m", 2000u"m"]) +julia> ustrip.(u"km", [1000u"m", 2000u"m"]) 2-element Vector{Float64}: 1.0 2.0