Skip to content

Commit

Permalink
Restructure domain, polar, and index conversions into separate files
Browse files Browse the repository at this point in the history
This needed organization.
  • Loading branch information
Sagnac committed Oct 28, 2024
1 parent d43a493 commit 21429d4
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 172 deletions.
35 changes: 35 additions & 0 deletions src/Domain.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
macro domain(ex, msg::String, val)
esc(:($ex ? nothing : throw(DomainError($val, $msg))))
end

macro domain(ex, msg::String, vals...)
esc(:(@domain($ex, $msg, ($(vals...),))))
end

macro domain(ex, val)
esc(:(@domain($ex, $(string("\nDomain:\n", ex, "\n")), $val)))
end

macro domain(ex, vals...)
esc(:(
@domain($ex, join($(string.(vals)) .* " = " .* string.(($(vals...),)), ", "))
))
end

macro domain_check_mn()
quote
@domain(n 0 && μ n && iseven(n - μ),
"""
\nDomain:
n ≥ 0
|m| ≤ n
n ≡ m (mod 2)
""",
m, n
)
end |> esc
end

macro domain_check_j()
esc(:(@domain(j 0, j)))
end
104 changes: 104 additions & 0 deletions src/IndexConversions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# normalization constant for Fringe coefficients
N(j::Vector{Int}) = broadcast(x -> radicand(x...), get_mn.(j))

struct Standard
v::Vector{Float64}
end

struct Noll
v::Vector{Float64}
end

struct Fringe
v::Vector{Float64}
end

Standard(noll::Noll) = Standard(standardize(noll))
Standard(fringe::Fringe) = Standard(standardize(fringe))

Noll(fringe::Fringe) = (Noll Standard standardize)(fringe)

Fringe(noll::Noll) = (Fringe Standard standardize)(noll)

function Noll(s::Standard)
sv = s.v
j = eachindex(sv) .- 1
noll = j_to_noll.(j)
v = zeros(maximum(noll))
v[noll] = sv
return Noll(v)
end

function Fringe(s::Standard)
sv = s.v
j = [i for i 0:length(sv)-1 if i valid_fringes]
fringe = j_to_fringe.(j)
v = zeros(maximum(fringe))
v[fringe] .= N(j) .* sv[j.+1]
return Fringe(v)
end

function noll_to_j(noll::Int)
@domain(noll 1, noll)
n::Int = trunc((2noll - 1) + 0.5) - 1
n_mod_2 = isodd(n)
m::Int = 2((2noll - (n + 1)n + 1 + n_mod_2) ÷ 4) - n_mod_2
m = flipsign(m, iseven(noll) ? 1 : -1)
get_j(m, n)
end

function j_to_noll(j::Int)
@domain_check_j
m, n = get_mn(j)
i = n % 4 0:1
k = m > 0 && i || m < 0 && !i ? 0 : 1
(n + 1)n ÷ 2 + abs(m) + k
end

function fringe_to_j(fringe::Int)
@domain(fringe 1:37, fringe)
if fringe == 37
return get_j(0, 12)
end
d = trunc(Int, (fringe - 1)) + 1
d2 = d^2 - fringe
m::Int = (d2 + 1) ÷ 2
m = flipsign(m, isodd(d2) ? -1 : 1)
n::Int = 2(d - 1) - abs(m)
get_j(m, n)
end

function j_to_fringe(j::Int)
@domain_check_j
mn = get_mn(j)
mn == (0, 12) && return 37
m, n = mn
μ = abs(m)
fringe = ((μ + n) ÷ 2 + 1)^2 - 2μ + fld(1 - sign(m), 2)
@domain(fringe 1:36,
"""
\nPolynomial does not have a Fringe representation.
See Zernike.valid_fringes for valid polynomial indices.
""",
j
)
return fringe
end

function standardize(noll::Noll)
(; v) = noll
p = [noll_to_j(i) + 1 for i in eachindex(v)]
u = zeros(maximum(p))
u[p] = v
return u
end

function standardize(fringe::Fringe)
(; v) = fringe
j = fringe_to_j.(eachindex(v))
n_max = get_n(maximum(j))
j_max = get_j(n_max)
a = zeros(eltype(v), j_max + 1)
a[j.+1] = v ./ N(j)
return a
end
30 changes: 30 additions & 0 deletions src/Polar.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
function polar((u, v)::NTuple{2, Int})
θ = range(0.0, 2π, u)
ρ = range(0.0, 1.0, v)
return ρ, θ
end

function polar::Int = ϵ_fit)
ρ, θ = polar((ϵ, ϵ))
return ρ', θ
end

function polar(m::Int, n::Int; finesse = finesse)
m = abs(m)
finesse = clamp(finesse, 1, 100)
ϵ_n = finesse * (ceil(Int, π * n) + 1)
ϵ_n = min(ϵ_n, ϵ_max)
ϵ_m = finesse * (2m + 1)
ϵ_m = min(ϵ_m, ϵ_max)
ρ = range(0.0, 1.0, ϵ_n)
θ = range(0.0, 2π, ϵ_m)
return ρ, θ
end

polar(z::Complex) = abs(z), angle(z)

function polar_mat(ρ, θ)
ρᵪ = [ρⱼ * cos(θᵢ) for θᵢ θ, ρⱼ ρ]
ρᵧ = [ρⱼ * sin(θᵢ) for θᵢ θ, ρⱼ ρ]
return ρᵪ, ρᵧ
end
175 changes: 3 additions & 172 deletions src/Zernike.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,82 +68,9 @@ struct Output
high_order::Bool
end

# normalization constant for Fringe coefficients
N(j::Vector{Int}) = broadcast(x -> radicand(x...), get_mn.(j))

struct Standard
v::Vector{Float64}
end

struct Noll
v::Vector{Float64}
end

struct Fringe
v::Vector{Float64}
end

Standard(noll::Noll) = Standard(standardize(noll))
Standard(fringe::Fringe) = Standard(standardize(fringe))

Noll(fringe::Fringe) = (Noll Standard standardize)(fringe)

Fringe(noll::Noll) = (Fringe Standard standardize)(noll)

function Noll(s::Standard)
sv = s.v
j = eachindex(sv) .- 1
noll = j_to_noll.(j)
v = zeros(maximum(noll))
v[noll] = sv
return Noll(v)
end

function Fringe(s::Standard)
sv = s.v
j = [i for i 0:length(sv)-1 if i valid_fringes]
fringe = j_to_fringe.(j)
v = zeros(maximum(fringe))
v[fringe] .= N(j) .* sv[j.+1]
return Fringe(v)
end

macro domain(ex, msg::String, val)
esc(:($ex ? nothing : throw(DomainError($val, $msg))))
end

macro domain(ex, msg::String, vals...)
esc(:(@domain($ex, $msg, ($(vals...),))))
end

macro domain(ex, val)
esc(:(@domain($ex, $(string("\nDomain:\n", ex, "\n")), $val)))
end

macro domain(ex, vals...)
esc(:(
@domain($ex, join($(string.(vals)) .* " = " .* string.(($(vals...),)), ", "))
))
end

macro domain_check_mn()
quote
@domain(n 0 && μ n && iseven(n - μ),
"""
\nDomain:
n ≥ 0
|m| ≤ n
n ≡ m (mod 2)
""",
m, n
)
end |> esc
end

macro domain_check_j()
esc(:(@domain(j 0, j)))
end

include("Domain.jl")
include("IndexConversions.jl")
include("Polar.jl")
include("RadialCoefficients.jl")
include("FormatStrings.jl")
include("WavefrontError.jl")
Expand Down Expand Up @@ -171,37 +98,6 @@ end

(Z::Output)(ρ, θ) = Z.Z(ρ, θ)

function polar((u, v)::NTuple{2, Int})
θ = range(0.0, 2π, u)
ρ = range(0.0, 1.0, v)
return ρ, θ
end

function polar::Int = ϵ_fit)
ρ, θ = polar((ϵ, ϵ))
return ρ', θ
end

function polar(m::Int, n::Int; finesse = finesse)
m = abs(m)
finesse = clamp(finesse, 1, 100)
ϵ_n = finesse * (ceil(Int, π * n) + 1)
ϵ_n = min(ϵ_n, ϵ_max)
ϵ_m = finesse * (2m + 1)
ϵ_m = min(ϵ_m, ϵ_max)
ρ = range(0.0, 1.0, ϵ_n)
θ = range(0.0, 2π, ϵ_m)
return ρ, θ
end

polar(z::Complex) = abs(z), angle(z)

function polar_mat(ρ, θ)
ρᵪ = [ρⱼ * cos(θᵢ) for θᵢ θ, ρⱼ ρ]
ρᵧ = [ρⱼ * sin(θᵢ) for θᵢ θ, ρⱼ ρ]
return ρᵪ, ρᵧ
end

# radial order
get_n(j::Int) = ceil(Int, (-3 + (9 + 8j)) / 2)

Expand All @@ -226,71 +122,6 @@ function get_mn(j::Int)
return m, n
end

function noll_to_j(noll::Int)
@domain(noll 1, noll)
n::Int = trunc((2noll - 1) + 0.5) - 1
n_mod_2 = isodd(n)
m::Int = 2((2noll - (n + 1)n + 1 + n_mod_2) ÷ 4) - n_mod_2
m = flipsign(m, iseven(noll) ? 1 : -1)
get_j(m, n)
end

function j_to_noll(j::Int)
@domain_check_j
m, n = get_mn(j)
i = n % 4 0:1
k = m > 0 && i || m < 0 && !i ? 0 : 1
(n + 1)n ÷ 2 + abs(m) + k
end

function standardize(noll::Noll)
(; v) = noll
p = [noll_to_j(i) + 1 for i in eachindex(v)]
u = zeros(maximum(p))
u[p] = v
return u
end

function fringe_to_j(fringe::Int)
@domain(fringe 1:37, fringe)
if fringe == 37
return get_j(0, 12)
end
d = trunc(Int, (fringe - 1)) + 1
d2 = d^2 - fringe
m::Int = (d2 + 1) ÷ 2
m = flipsign(m, isodd(d2) ? -1 : 1)
n::Int = 2(d - 1) - abs(m)
get_j(m, n)
end

function j_to_fringe(j::Int)
@domain_check_j
mn = get_mn(j)
mn == (0, 12) && return 37
m, n = mn
μ = abs(m)
fringe = ((μ + n) ÷ 2 + 1)^2 - 2μ + fld(1 - sign(m), 2)
@domain(fringe 1:36,
"""
\nPolynomial does not have a Fringe representation.
See Zernike.valid_fringes for valid polynomial indices.
""",
j
)
return fringe
end

function standardize(fringe::Fringe)
(; v) = fringe
j = fringe_to_j.(eachindex(v))
n_max = get_n(maximum(j))
j_max = get_j(n_max)
a = zeros(eltype(v), j_max + 1)
a[j.+1] = v ./ N(j)
return a
end

function validate_length(v::Vector)
len = length(v)
j_max = len - 1
Expand Down

0 comments on commit 21429d4

Please sign in to comment.