Skip to content

Commit 6d90f17

Browse files
hyrodiumsethaxen
andauthored
Add docs/src/examples/basics.md page (#134)
* update docs * update docs * add dependency on HalfIntegers in docs * update basics * update docs * Fix docs/src/examples/basics.md Co-authored-by: Seth Axen <[email protected]> * Fix typo in docs/src/examples/basics.md Co-authored-by: Seth Axen <[email protected]> * Fix docs/src/examples/basics.md Co-authored-by: Seth Axen <[email protected]> * Fix docs/src/examples/basics.md Co-authored-by: Seth Axen <[email protected]> * Fix docs/src/examples/basics.md Co-authored-by: Seth Axen <[email protected]> * Fix docs/src/examples/basics.md Co-authored-by: Seth Axen <[email protected]> * add docs for `sign` * add type_parameter.md * remove `warnonly=true` * update first examples * Fix `ishurwitz` by replacing `ishalfinteger` with `ishalfodd` * add `ishalfodd` in the documentation because HalfIntegers.jl#59 takes time --------- Co-authored-by: Seth Axen <[email protected]>
1 parent e82a56f commit 6d90f17

File tree

6 files changed

+182
-4
lines changed

6 files changed

+182
-4
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,27 @@ A Julia implementation of quaternions.
1111
as representations of 3D rotational orientation.
1212
They can also be viewed as an extension of complex numbers.
1313

14+
## First example
15+
16+
```julia
17+
julia> using Quaternions
18+
19+
julia> k = quat(0, 0, 0, 1)
20+
Quaternion{Int64}(0, 0, 0, 1)
21+
22+
julia> j = quat(0, 0, 1, 0)
23+
Quaternion{Int64}(0, 0, 1, 0)
24+
25+
julia> i = j*k
26+
Quaternion{Int64}(0, 1, 0, 0)
27+
28+
julia> i^2 == j^2 == k^2 == i*j*k == -1 # Similar to `im^2`.
29+
true
30+
31+
julia> 1 + i + k + j # Compatible with arithmetic operations as a `Number`.
32+
Quaternion{Int64}(1, 1, 1, 1)
33+
```
34+
35+
Check out [the docs](https://juliageometry.github.io/Quaternions.jl) for further instructions.
36+
1437
In JuliaGeometry organization, there is also [Octonions.jl](https://github.com/JuliaGeometry/Octonions.jl) package.

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
33
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
4+
HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721"
45
Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
56

67
[compat]

docs/make.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Quaternions
22
using Documenter
3+
using HalfIntegers
34

45
DocMeta.setdocmeta!(Quaternions, :DocTestSetup, :(using Quaternions); recursive=true)
56

@@ -17,6 +18,8 @@ makedocs(;
1718
"Home" => "index.md",
1819
"APIs" => "api.md",
1920
"Examples" => [
21+
"examples/basics.md",
22+
"examples/type_parameter.md",
2023
"examples/rotations.md",
2124
"examples/dual_quaternions.md"
2225
],

docs/src/examples/basics.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Basics
2+
3+
## Basic operations for quaternions
4+
Quaternions can be defined with the [`Quaternion`](@ref) constructor or [`quat`](@ref) function.
5+
Note that the order of the arguments is ``w+xi+yj+zk``, not ``xi+yj+zk+w``.
6+
7+
```@repl intro
8+
using Quaternions
9+
q1 = Quaternion(1,2,3,4)
10+
q2 = quat(5,6,7,8)
11+
q3 = quat(9)
12+
```
13+
14+
The multiplication is not commutative.
15+
```@repl intro
16+
q1 * q2
17+
q2 * q1
18+
```
19+
20+
The multiplicative inverse can be calculated with [`Base.inv`](@ref).
21+
```@repl intro
22+
inv(q1)
23+
inv(q1) * q1
24+
```
25+
26+
The division is also not commutative.
27+
28+
```@repl intro
29+
q1 / q2 # Same as `q1*inv(q2)` mathematically.
30+
q2 \ q1 # Same as `inv(q2)*q1` mathematically.
31+
```
32+
33+
A conjugate of a quaternion can be calculated with [`Base.conj`](@ref).
34+
But `Base.imag(::Quaternion)` is not defined because it should return three real values which is not consistent with `imag(::Complex)` and `imag(::Real)`.
35+
Instead, the [`imag_part`](@ref) function can be used to obtain the imaginary part of a quaternion.
36+
See [issue#61](https://github.com/JuliaGeometry/Quaternions.jl/issues/61) for more discussion.
37+
38+
```@repl intro
39+
conj(q1)
40+
imag(q1) # Not supported.
41+
imag_part(q1) # Use this instead.
42+
```
43+
44+
Unit quaternions can be obtained with [`sign`](@ref).
45+
46+
```@repl intro
47+
sign(q1)
48+
sign(q2)
49+
sign(q3)
50+
sign(quat(0)) # Zero-quaternion will not be normalized.
51+
```
52+
53+
## `Quaternion` vs `quat`
54+
The general rule is that [`quat`](@ref) is to [`Quaternion`](@ref) as [`complex`](https://docs.julialang.org/en/v1/base/numbers/#Base.complex-Tuple{Complex}) is to [`Complex`](https://docs.julialang.org/en/v1/base/numbers/#Base.Complex).
55+
`Complex` and `Quaternion` are both constructors so should return an object of the corresponding type, whereas `quat` and `complex` both can operate on types and arrays.
56+
57+
```@setup Quaternion-quat
58+
using Quaternions
59+
```
60+
61+
```@repl Quaternion-quat
62+
Quaternion(1,2,3,4)
63+
quat(1,2,3,4)
64+
Quaternion(Int) # Similar to `Complex(Int)`.
65+
quat(Int) # Similar to `complex(Int)`.
66+
```
67+
68+
## Compatibility with `Complex`
69+
There is no natural embedding ``\mathbb{C}\to\mathbb{H}``.
70+
Thus, `quat(w,x,0,0)` is not equal to `complex(w,x)`, i.e.
71+
72+
```math
73+
\mathbb{C} \ni w+ix \ne w+ix+0j+0k \in \mathbb{H}.
74+
```
75+
76+
```@setup complex
77+
using Quaternions
78+
```
79+
80+
```@repl complex
81+
1 + complex(1,2) # `Complex` is compatible with `Real`
82+
1 + quat(1,2,3,4) # `Quaternion` is compatible with `Real`
83+
1 + complex(1,2) + quat(1,2,3,4) # no compatibility
84+
complex(1,2) == quat(1,2,0,0) # no compatibility
85+
complex(1) == quat(1) # no compatibility
86+
complex(1) == 1 == quat(1) # Both `quat(1)` and `complex(1)` are equal to `1`.
87+
```
88+
89+
See [issue#62](https://github.com/JuliaGeometry/Quaternions.jl/issues/62) for more discussion.

docs/src/examples/type_parameter.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# The type parameter `T` in `Quaternion{T}`
2+
3+
The type parameter `T <: Real` in `Quaternion{T}` represents the type of real and imaginary parts of a quaternion.
4+
5+
## Lipschitz quaternions
6+
By using this type parameter, some special quaternions such as [**Lipschitz quaternions**](https://en.wikipedia.org/wiki/Hurwitz_quaternion) ``L`` can be represented.
7+
8+
```math
9+
L = \left\{a+bi+cj+dk \in \mathbb{H} \mid a,b,c,d \in \mathbb{Z}\right\}
10+
```
11+
12+
```@setup LipschitzHurwitz
13+
using Quaternions
14+
```
15+
16+
```@repl LipschitzHurwitz
17+
q1 = Quaternion{Int}(1,2,3,4)
18+
q2 = Quaternion{Int}(5,6,7,8)
19+
islipschitz(q::Quaternion) = isinteger(q.s) & isinteger(q.v1) & isinteger(q.v2) & isinteger(q.v3)
20+
islipschitz(q1)
21+
islipschitz(q2)
22+
islipschitz(q1 + q2)
23+
islipschitz(q1 * q2)
24+
islipschitz(q1 / q2) # Division is not defined on L.
25+
q1 * q2 == q2 * q1 # non-commutative
26+
```
27+
28+
## Hurwitz quaternions
29+
If all coefficients of a quaternion are integers or half-integers, the quaternion is called a [**Hurwitz quaternion**](https://en.wikipedia.org/wiki/Hurwitz_quaternion).
30+
The set of Hurwitz quaternions is defined by
31+
32+
```math
33+
H = \left\{a+bi+cj+dk \in \mathbb{H} \mid a,b,c,d \in \mathbb{Z} \ \text{or} \ a,b,c,d \in \mathbb{Z} + \tfrac{1}{2}\right\}.
34+
```
35+
36+
Hurwitz quaternions can be implemented with [HalfIntegers.jl](https://github.com/sostock/HalfIntegers.jl) package.
37+
38+
```@repl LipschitzHurwitz
39+
using HalfIntegers
40+
q1 = Quaternion{HalfInt}(1, 2, 3, 4)
41+
q2 = Quaternion{HalfInt}(5.5, 6.5, 7.5, 8.5)
42+
q3 = Quaternion{HalfInt}(1, 2, 3, 4.5) # not Hurwitz quaternion
43+
ishalfodd(x::Number) = isodd(twice(x)) # Should be defined in HalfIntegers.jl (HalfIntegers.jl#59)
44+
ishurwitz(q::Quaternion) = (isinteger(q.s) & isinteger(q.v1) & isinteger(q.v2) & isinteger(q.v3)) | (ishalfodd(q.s) & ishalfodd(q.v1) & ishalfodd(q.v2) & ishalfodd(q.v3))
45+
ishurwitz(q1)
46+
ishurwitz(q2)
47+
ishurwitz(q3)
48+
ishurwitz(q1 + q2)
49+
ishurwitz(q1 * q2)
50+
ishurwitz(q1 / q2) # Division is not defined on H.
51+
q1 * q2 == q2 * q1 # non-commucative
52+
abs2(q1) # Squared norm is always an integer.
53+
abs2(q2) # Squared norm is always an integer.
54+
abs2(q3) # Squared norm is not an integer because `q3` is not Hurwitz quaternion.
55+
```
56+
57+
## Biquaternions
58+
If all coefficients of a quaternion are complex numbers, the quaternion is called a [**Biquaternion**](https://en.wikipedia.org/wiki/Biquaternion).
59+
However, the type parameter `T` is restricted to `<:Real`, so biquaternions are not supported in this package.
60+
Note that `Base.Complex` has the same type parameter restriction, and [bicomplex numbers](https://en.wikipedia.org/wiki/Bicomplex_number) are not supported in Base.
61+
See [issue#79](https://github.com/JuliaGeometry/Quaternions.jl/issues/79) for more discussion.

docs/src/index.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ pkg> add Quaternions
1818

1919
```@repl
2020
using Quaternions
21-
q = quat(0.0, 0.0, 0.0, 1.0)
22-
r = quat(0, 0, 1, 0)
23-
q*r
24-
q+r
21+
k = quat(0, 0, 0, 1)
22+
j = quat(0, 0, 1, 0)
23+
i = j*k
24+
i^2 == j^2 == k^2 == i*j*k == -1 # Similar to `im^2`.
25+
1 + i + k + j # Compatible with arithmetic operations as a `Number`.
2526
```

0 commit comments

Comments
 (0)