Skip to content

Update docs and add doctests #175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DynamicQuantities = "06fc5a27-2a28-4c7c-a15d-362465fb6821"

[compat]
Documenter = "1"

[sources]
DynamicQuantities = {path = ".."}
4 changes: 3 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -31,14 +32,15 @@ end
makedocs(;
modules=[DynamicQuantities, DynamicQuantities.Units],
authors="MilesCranmer <miles.cranmer@gmail.com> 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",
canonical="https://ai.damtp.cam.ac.uk/dynamicquantities/stable",
edit_link="main",
assets=String[]
),
doctest = false,
pages=[
"Home" => "index.md",
"Examples" => "examples.md",
Expand Down
36 changes: 15 additions & 21 deletions docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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}`
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/affine_dimensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
37 changes: 24 additions & 13 deletions src/arrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/register_units.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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²

Expand Down
2 changes: 1 addition & 1 deletion src/symbolic_dimensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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⁻²
```
Expand Down
2 changes: 1 addition & 1 deletion src/units.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 4 additions & 4 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading