@@ -387,7 +387,7 @@ function parameter(key::Symbol,
387387 scaling:: Function = identity,
388388 regimes:: Dict{Symbol,OrderedDict{Int64,Any}} = Dict {Symbol,OrderedDict{Int64,Any}} (),
389389 description:: String = " No description available." ,
390- tex_label:: String = " " ) where {V<: Vector , T <: Float64 , U <: Transform } # {V<:Vector, S<:Real, T <: Float64, U <:Transform}
390+ tex_label:: String = " " ) where {V<: Vector , T <: Real , U <: Transform } # {V<:Vector, S<:Real, T <: Float64, U <:Transform}
391391
392392 # If fixed=true, force bounds to match and leave prior as null. We need to define new
393393 # variable names here because of lexical scoping.
@@ -445,6 +445,32 @@ function parameter(key::Symbol,
445445 end
446446end
447447
448+ function parameter (key:: Symbol ,
449+ value:: Union{T1, V} , # value::Union{S,V},
450+ valuebounds:: Interval{T2} = (value,value),
451+ transform_parameterization:: Interval{T3} = (value,value),
452+ transform:: U = Untransformed (),
453+ prior:: Union{NullableOrPriorUnivariate, NullableOrPriorMultivariate} = NullablePriorUnivariate ();
454+ fixed:: Bool = true ,
455+ scaling:: Function = identity,
456+ regimes:: Dict{Symbol,OrderedDict{Int64,Any}} = Dict {Symbol,OrderedDict{Int64,Any}} (),
457+ description:: String = " No description available." ,
458+ tex_label:: String = " " ) where {V<: Vector , T1 <: Real , T2 <: Real , T3 <: Real , U <: Transform }
459+ warn_str = " The element types of the fields `value` ($(typeof (value)) ), `valuebounds` ($(eltype (valuebounds)) ), " *
460+ " and `transform_parameterization` ($(eltype (transform_parameterization)) ) do not match. " *
461+ " Attempting to convert all types to the same type as `value`. Note that the element type for the prior " *
462+ " distribution should also be $(typeof (value)) ."
463+ @warn warn_str
464+
465+ valuebounds_new = (convert (T1, valuebounds[1 ]), convert (T1, valuebounds[2 ]))
466+ transform_parameterization_new = (convert (T1, transform_parameterization[1 ]),
467+ convert (T1, transform_parameterization[2 ]))
468+
469+ return parameter (key, value, valuebounds_new, transform_parameterization_new,
470+ transform, prior; fixed = fixed, scaling = scaling,
471+ regimes = regimes, description = description, tex_label = tex_label)
472+ end
473+
448474function parameter_ad (key:: Symbol ,
449475 value:: Union{S,V} ,
450476 valuebounds:: Interval{T} = (value,value),
@@ -750,8 +776,60 @@ function transform_to_model_space(p::Parameter{T,Exponential}, x::T) where T
750776 a + exp (c* (x- b))
751777end
752778
753- transform_to_model_space (pvec:: ParameterVector{T} , values:: Vector{T} ) where T = map (transform_to_model_space, pvec, values)
754- transform_to_model_space (pvec:: ParameterVector , values:: Vector{S} ) where S = map (transform_to_model_space, pvec, values)
779+ @inline function transform_to_model_space (pvec:: ParameterVector{T} , values:: Vector{T} ;
780+ regime_switching:: Bool = false ) where T
781+ if regime_switching
782+ # Transform values in the first regime
783+ output = similar (values)
784+ plen = length (pvec)
785+ map! (transform_to_model_space, output, pvec, values[1 : plen])
786+
787+ # Now transform values in the second regime and on
788+ i = 0
789+ for p in pvec
790+ if ! isempty (p. regimes)
791+ for (k, v) in p. regimes[:value ]
792+ if k != 1 # Skip the first regime.
793+ i += 1 # `values` stores regime values (after the first regime) beside each other.
794+ output[plen + i] = transform_to_model_space (p, values[plen + i])
795+ end
796+ end
797+ end
798+ end
799+
800+ return output
801+ else
802+ return map (transform_to_model_space, pvec, values)
803+ end
804+ end
805+
806+ @inline function transform_to_model_space (pvec:: ParameterVector , values:: Vector{S} ;
807+ regime_switching:: Bool = false ) where S
808+
809+ if regime_switching
810+ # Transform values in the first regime
811+ output = similar (values)
812+ plen = length (pvec)
813+ map! (transform_to_model_space, output, pvec, values[1 : plen])
814+
815+ # Now transform values in the second regime and on
816+ i = 0
817+ for p in pvec
818+ if ! isempty (p. regimes)
819+ for (k, v) in p. regimes[:value ]
820+ if k != 1 # Skip the first regime.
821+ i += 1 # `values` stores regime values (after the first regime) beside each other.
822+ output[plen + i] = transform_to_model_space (p, values[plen + i])
823+ end
824+ end
825+ end
826+ end
827+
828+ return output
829+ else
830+ return map (transform_to_model_space, pvec, values)
831+ end
832+ end
755833
756834"""
757835```
@@ -837,8 +915,57 @@ function transform_to_real_line(p::Parameter{T,Exponential}, x::T = p.value) whe
837915 b + (1 ./ c) * log (x- a)
838916end
839917
840- transform_to_real_line (pvec:: ParameterVector{T} , values:: Vector{T} ) where T = map (transform_to_real_line, pvec, values)
841- transform_to_real_line (pvec:: ParameterVector{T} ) where T = map (transform_to_real_line, pvec)
918+ @inline function transform_to_real_line (pvec:: ParameterVector{T} , values:: Vector{T} ; regime_switching:: Bool = false ) where T
919+ if regime_switching
920+ # Transform values in the first regime
921+ output = similar (values)
922+ plen = length (pvec)
923+ map! (transform_to_real_line, output, pvec, values[1 : plen])
924+
925+ # Now transform values in the second regime and on
926+ i = 0
927+ for p in pvec
928+ if ! isempty (p. regimes)
929+ for (k, v) in p. regimes[:value ]
930+ if k != 1 # Skip the first regime.
931+ i += 1 # `values` stores regime values (after the first regime) beside each other.
932+ output[plen + i] = transform_to_real_line (p, values[plen + i])
933+ end
934+ end
935+ end
936+ end
937+
938+ return output
939+ else
940+ map (transform_to_real_line, pvec, values)
941+ end
942+ end
943+ @inline function transform_to_real_line (pvec:: ParameterVector{T} ; regime_switching:: Bool = false ) where T
944+ if regime_switching
945+ values = get_values (pvec) # regime-switching parameters returned by default
946+
947+ # Transform values in the first regime
948+ plen = length (pvec) # since values is not passed, we can mutate values directly to avoid extra allocations
949+ map! (transform_to_real_line, (@view values[1 : plen]), pvec, values[1 : plen])
950+
951+ # Now transform values in the second regime and on
952+ i = 0
953+ for p in pvec
954+ if ! isempty (p. regimes)
955+ for (k, v) in p. regimes[:value ]
956+ if k != 1 # Skip the first regime.
957+ i += 1 # `values` stores regime values (after the first regime) beside each other.
958+ values[plen + i] = transform_to_real_line (p, values[plen + i])
959+ end
960+ end
961+ end
962+ end
963+
964+ return values
965+ else
966+ map (transform_to_real_line, pvec)
967+ end
968+ end
842969
843970"""
844971```
0 commit comments