Skip to content

Commit

Permalink
Better way to handle polar notation
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel Bazdresch committed Apr 5, 2023
1 parent 92386fe commit f7bea22
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 19 deletions.
11 changes: 10 additions & 1 deletion src/SinusoidalRegressions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export sinfit_j, mixlinsinfit_j,
ieee1057,
rmse, mae,
SinusoidalFunctionParameters,
SinusoidP, MixedLinearSinusoidP
SinusoidP, MixedLinearSinusoidP,
torect

include("typedefs.jl")
include("jacquelin_sr.jl")
Expand Down Expand Up @@ -46,6 +47,14 @@ function mae(fit::T, exact::T, x) where {T <: SinusoidalFunctionParameters}
return sum(abs.(fitvalues .- exactvalues))/length(x)
end

"""
torect(M, θ)
Convert polar coordinates to rectangular coordinates `(y, x)` where ``x = M\\cos(θ)`` and
``y = -M\\sin(θ)``
"""
torect(M, θ) = (-M*sin(θ), M*cos(θ))

## Precompilation
@precompile_setup begin
x = [-1.983, -1.948, -1.837, -1.827, -1.663, -0.815, -0.778, -0.754, -0.518, 0.322, 0.418, 0.781,
Expand Down
21 changes: 6 additions & 15 deletions src/typedefs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ struct SinusoidP{T <: Real} <: SinusoidalFunctionParameters
end

"""
SinusoidP{T}(f, DC, Q, I ; polar = false)
SinusoidP{T}(f, DC, Q, I)
Construct a `SinusoidP{T}` with the given parameters, promoting to a common type `T` if
necessary.
If the keyword argument `polar` is `true`, then the arguments are interpreted as frequency,
DC, amplitude `A` and phase `ϕ` in the model ``s(x) = DC + A\\cos(2πfx + ϕ)``.
To express the model as ``s(x) = M\\cos(2πfx + θ)``, use the `torect` function.
Examples
========
Expand All @@ -44,23 +43,15 @@ Sinusoidal parameters SinusoidP{Float64}:
Sine amplitude (Q) : -0.5
Cosine amplitude (I): 1.2
julia> SinusoidP(1, 0, 1, 0, polar = true) # A pure cosine
julia> SinusoidP(1, 0, torect(1, -π/2)...) # A pure sine
Sinusoidal parameters SinusoidP{Float64}:
Frequency (Hz) : 1.0
DC : 0.0
Sine amplitude (Q) : -0.0
Cosine amplitude (I): 1.0
Sine amplitude (Q) : 1.0
Cosine amplitude (I): 0.0
```
"""
function SinusoidP(f, DC, Q, I ; polar = false)
if polar
# argument Q is amplitude; I is phase
cosamp = Q*cos(I)
sinamp = -Q*sin(I)
return SinusoidP(promote(f, DC, sinamp, cosamp)... )
end
SinusoidP(promote(f, DC, Q, I)...)
end
SinusoidP(f, DC, Q, I) = SinusoidP(promote(f, DC, Q, I)...)

"""
SinusoidP{T}(; f, DC, Q, I)
Expand Down
11 changes: 8 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,22 @@ using Test
end

@testset "Polar notation for SinusoidP" begin
s = SinusoidP(1, 0, 1, 0, polar = true) # A pure cosine
s = SinusoidP(1, 0, torect(1, 0)...) # A pure cosine
@test s.f == 1
@test s.DC == 0
@test s.Q 0
@test s.I 1
s = SinusoidP(1, 0, 1, -π/2, polar = true) # A pure sine
s = SinusoidP(1, 0, torect(1, -π/2)...) # A pure sine
@test s.f == 1
@test s.DC == 0
@test s.Q 1 atol = 1e-12
@test s.I 0 atol = 1e-12
s = SinusoidP(1, 5, 1, -π/4, polar = true) # A mix
s = SinusoidP(1, 0, torect(1, 3π/2)...) # Another pure sine
@test s.f == 1
@test s.DC == 0
@test s.Q 1 atol = 1e-12
@test s.I 0 atol = 1e-12
s = SinusoidP(1, 5, torect(1, -π/4)...) # A mix
@test s.f == 1
@test s.DC == 5
@test s.Q sqrt(2)/2 atol = 1e-12
Expand Down

0 comments on commit f7bea22

Please sign in to comment.