参数化结构体的重载方法

问题描述 投票:0回答:1

简短版本

我有一个类似的结构

@kwdef mutable struct Params{B, C}
    a::Float64 = 42
end

其中

B
C
是符号,用于确定在针对不同符号组合重载的许多函数中使用哪个函数。有效符号例如
:constant
:exponential
。我想编写一个函数,如果其中一个符号与参数化结构中的相应符号匹配,则该函数将被调用,并且无论其他符号如何,也应该调用该函数。举个例子, p = Params{:constant, :gaussian}() foo(p::Params{:constant, <:Symbol}) = 42 foo(p) # should return 42, but throws an error

我该怎么做?

背景

我正在实现一个动态规则(与 DynamicalSystems.jl 一起使用),其中规则的一项是使用高斯分布的 PDF(一种倒数函数)计算的, 或 是恒定的(参见补充信息以及

“B 细胞终末分化的定量模型和淋巴瘤发生机制”

的图 3)。使用简化模型,请参阅以下代码作为我想要执行的操作的示例: using UnPack using DynamicalSystems using Distributions @kwdef mutable struct Params{B, C} mu_p = 10e-6 sigma_p = 9 mu_b = 2 sigma_b = 100 mu_r = 0.1 sigma_r = 2.6 bcr_0 = 0.05 cd_0 = 0.025 end function germinal_center_regulation_rule(u, params, t) @unpack mu_p, sigma_p, mu_b, sigma_b, mu_r, sigma_r, @unpack bcr0, cd0 = params p, b, r = u #######IMPORTANT PART############ bcr = compute_bcr(;u, params, t) cd40 = compute_cd40(;u, params, t) ################################# pdot = mu_p + sigma_p/b bdot = mu_p + sigma_p/b - bcr*b rdot = mu_r * sigma_r/r return SVector(pdot, bdot, rdot) # Different methods for different parameterized struct compute_bcr(;u, params::Params{:constant, <:Symbol}, t) = 15 compute_bcr(;u, params::Params{:gaussian, <:Symbol}, t) = pdf(Normal(), t) compute_cd40(;u, params::Params{<:Symbol, :reciprocal}, t) = params[:bcr0]/u[2] compute_cd40(;u, params::Params{<:Symbol, :gaussian}, t) = pdf(Normal(), t) # Example usage p_constant_bcr_gaussian_cd40 = Params{:constant, :gaussian}() u0 = [0.2, 5.0, 0.2] mixed_ds = CoupledODEs( germinal_center_regulation_rule, u0, p_constant_bcr_gaussian_cd40) total_time = 200 X, t = trajectory(ds, total_time) p_gaussian_bcr_gaussian_cd40 = Params{:gaussian, :gaussian}() gaussian_ds = CoupledODEs( germinal_center_regulation_rule, u0, p_gaussian_bcr_gaussian_cd40) total_time = 200 X, t = trajectory(ds, total_time)


struct julia overloading
1个回答
0
投票
T<:U

表明

T
U
的子类型。但就你而言,
:gaussian
不是
Symbol
subtype,而是
is
Symbol。你可以用
解决这个问题
foo(p::Params{:constant, S}) where {S} = 42

如果必须确保 
S

Symbol
,最好在
Params
的构造函数中执行此操作。
julia> @kwdef mutable struct Params{B, C}
           a::Float64 = 42
           function Params{B, C}(a) where {B, C}
               if !(B isa Symbol && C isa Symbol)
                   error("Params generics must be Symbols")
               end
               return new{B, C}(a)
           end
       end

julia> Params{:a, :b}(2)
Params{:a, :b}(2.0)

julia> Params{:a, 1}(2)
ERROR: Params generics must be Symbols
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] Params{:a, 1}(a::Int64)
   @ Main ./REPL[49]:5
 [3] top-level scope
   @ REPL[51]:1

© www.soinside.com 2019 - 2024. All rights reserved.