Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Reexport = "1"
Roots = "2"
SavitzkyGolay = "0.9.1"
SpecialFunctions = "1, 2"
TransformVariables = "0.8.19"
TransformVariables = "0.8.21"
TypedTables = "1.4"
Unitful = "1.20"
julia = "1.10"
14 changes: 7 additions & 7 deletions docs/example/fitting_mannitol.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,16 @@ savefig("modelpre.svg"); #md #hide
# Optimization algorithms are happiest when they can run across all real numbers.
# So we use TransformVariables.jl to map all reals to positive values of our parameters, with sensible scales.
# The `TVExp` transform maps all real numbers to positive values, and the `TVScale` transform scales the value to a more reasonable range.
# The transform `ConstWrapTV` is defined in LyoPronto, and makes a constant callable function from a value.

# Kshf needs to be callable.
# Rp needs to be a callable, and the `RpFormFit` struct does that; by passing the new values
# with Rp as a NamedTuple, the constructor for `ParamObjPikal` will unpack it.
# Kshf needs to be callable, so we wrap it in ConstPhysProp.
# Rp needs to be a callable, and the `RpFormFit` struct with fields R0, A1, and A2 does that.
# This `as` function uses TransformVariables to create a transform that maps from 4 real
# numbers to callable Kshf and Rp, with appropriate scaling.

trans_KRp = as((Kshf = ConstWrapTV() ∘ TVScale(Kshf(0)) ∘ TVExp(),
Rp=as((R0 = TVScale(R0) ∘ TVExp(),
trans_KRp = as((Kshf = as(ConstPhysProp, (TVScale(Kshf(0)) ∘ TVExp(),)),
Rp=as(RpFormFit, as((R0 = TVScale(R0) ∘ TVExp(),
A1 = TVScale(A1) ∘ TVExp(),
A2 = TVScale(A2) ∘ TVExp(),))))
A2 = TVScale(A2) ∘ TVExp(),)))))
## Or, using a convenience function for the same,
trans_KRp = KRp_transform_basic(Kshf(0), R0, A1, A2)
trans_Rp = Rp_transform_basic(R0, A1, A2)
Expand Down
1 change: 0 additions & 1 deletion src/LyoPronto.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export gen_sol_pd, obj_pd, gen_nsol_pd, objn_pd
export KRp_transform_basic, K_transform_basic, Rp_transform_basic, KBB_transform_basic
export KBB_transform_bounded
export obj_expT, err_expT, err_expT!, num_errs, nls_pd, nls_pd!
export ConstWrapTV
# plotting tools (mostly already done by macros)
export qrf_integrate
# End of primary drying
Expand Down
9 changes: 5 additions & 4 deletions src/paramfits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ end
Construct a typical transform for fitting Rp.
"""
function Rp_transform_basic(R0g, A1g, A2g)
tr = as((
Rp = as((
tr = as((;
Rp = as(RpFormFit, as((;
R0 = TVScale(R0g) ∘ TVExp(),
A1 = TVScale(A1g) ∘ TVExp(),
A2 = TVScale(A2g) ∘ TVExp(),
)),
)),)
))
return tr
end
Expand All @@ -29,7 +29,7 @@ end
Construct a typical transform for fitting Kshf (a.k.a. Kv).
"""
function K_transform_basic(Kshfg)
tr = as((Kshf = ConstWrapTV() ∘ TVScale(Kshfg) ∘ TVExp(),))
tr = as((;Kshf = as(ConstPhysProp, (TVScale(Kshfg) ∘ TVExp(),))))
return tr
end
"""
Expand Down Expand Up @@ -72,6 +72,7 @@ This small function runs
```
fitprm = transform(tr, fitlog)
new_params = setproperties(po, fitprm)
!isnothing(badprms) && badprms(new_params) && return NaN
prob = ODEProblem(new_params; tspan=(0.0, 1000.0))
sol = solve(prob, Rodas4(autodiff=AutoForwardDiff(chunksize=2)); saveat, kwargs...)
```
Expand Down
6 changes: 0 additions & 6 deletions src/pikal_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,6 @@ function ParamObjPikal(tuptup)
return ParamObjPikal(tuptup[1]..., tuptup[2]..., tuptup[3]...)
end

# This constructor catches if Rp is passed as a tuple or NamedTuple and constructs an appropriate object
function ParamObjPikal(Rp::Union{NamedTuple, Tuple},
hf0, csolid, ρsolution, Kshf, Av, Ap, pch, Tsh)
return ParamObjPikal(RpFormFit(Rp...), hf0, csolid, ρsolution, Kshf, Av, Ap, pch, Tsh)
end

function Base.getindex(p::ParamObjPikal, i::Int)
if i == 1
return (p.Rp, p.hf0, p.csolid, p.ρsolution)
Expand Down
5 changes: 0 additions & 5 deletions src/rf_lumcap_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,6 @@ function ParamObjRF(tuptup::Tuple)
end
Base.size(po::ParamObjRF) = (6,)

# This constructor catches if Rp is passed as a tuple or NamedTuple and constructs an appropriate object
function ParamObjRF(Rp::Union{NamedTuple, Tuple}, args...)
return ParamObjRF(RpFormFit(Rp...), args...)
end

function Base.getindex(po::ParamObjRF, i)
if i == 1
return (po.Rp, po.hf0, po.csolid, po.ρsolution)
Expand Down
11 changes: 1 addition & 10 deletions src/structs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
A1
A2
end
RpFormFit(;R0, A1, A2) = RpFormFit(R0, A1, A2)
@doc """
A convenience type for dealing with the common functional form given to Rp and Kv.

Expand Down Expand Up @@ -267,13 +268,3 @@ function Base.:(==)(p1::PrimaryDryFit, p2::PrimaryDryFit)
cond6 = ismissing(p1.t_end) ? ismissing(p2.t_end) : (p1.t_end == p2.t_end)
return all([cond1, cond2, cond3, cond4, cond5, cond6])
end

# Add a little bit of sugar to our transforms
struct ConstWrapTV <: TransformVariables.ScalarTransform end
TransformVariables.transform(::ConstWrapTV, x) = ConstPhysProp(x)
TransformVariables.inverse(::ConstWrapTV, x) = x.value

# These create method ambiguities with other TransformVariables methods
# I don't think they were needed, but if so can be brought back with more specificity
# TransformVariables.transform(t::TVScale{ConstPhysProp}, x) = ConstPhysProp(t.scale.value*x)
# TransformVariables.inverse(t::TVScale{ConstPhysProp}, x) = x.value/t.scale.value
7 changes: 4 additions & 3 deletions test/test_KRp_opt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ pdfit = PrimaryDryFit(t, T; t_end)
obj = OptimizationFunction(obj_pd, AutoForwardDiff(chunksize=4))
opt = solve(OptimizationProblem(obj, pg, pass), optalg)
vals = transform(tr, opt.u)
@test all(opt.u .!= 0)
@test vals.Kshf(pch(0)) ≈ Kshf(pch(0)) rtol=0.3
@test vals.Rp.R0 ≈ R0 rtol=0.1
@test vals.Rp.A1 ≈ A1 rtol=0.1
@test vals.Rp.A2 ≈ A2 rtol=0.1
@test vals.Rp.A1 ≈ A1 rtol=0.3
@test vals.Rp.A2 ≈ A2 rtol=0.5
end

@testset "Only Rp" begin
Expand All @@ -66,7 +67,7 @@ end
opt = solve(OptimizationProblem(obj, pg, pass), optalg)
vals = transform(tr, opt.u)
@test vals.Rp.R0 ≈ R0 rtol=0.1
@test vals.Rp.A1 ≈ A1 rtol=0.1
@test vals.Rp.A1 ≈ A1 rtol=0.2
@test vals.Rp.A2 ≈ A2 rtol=0.5
end

Expand Down
2 changes: 1 addition & 1 deletion test/test_jet.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using JET
# Can't use `mode = :basic` in CI because the Plots.jl recipe system triggers lots of false
# positives for JET. Not a bad idea to periodically check that manually, though.
test_package(LyoPronto; mode = :typo, target_defined_modules=true)
test_package(LyoPronto; mode = :typo, target_modules=(LyoPronto,))
Loading