Commit 83d490fe authored by Miroslav Kratochvil's avatar Miroslav Kratochvil
Browse files

make the mapping parametrizable by user

This potentially saves a lot of headache with various custom functions or stuff
where support may be complicated/ambiguous. In this precise case, we're
allowing it because the user needs to `@register` the factorial function with
Symbolics manually, so that it can be translated properly.
parent 18463414
@register Base.factorial(x) # Todo: remove this line once factorial is registered per default default_symbolics_mapping = Dict(
function parse_piecewise(val, cond, other)
IfElse.ifelse(cond, val, other)
end
allowed_funs = Dict(
# Operators
"+" => :+, "+" => :+,
"-" => :-, "-" => :-,
"*" => :*, "*" => :*,
"/" => :/, "/" => :/,
"power" => :^, "power" => :^,
# Relational functions
"lt" => :<, "lt" => :<,
"leq" => :<=, "leq" => :<=,
"geq" => :>=, "geq" => :>=,
"gt" => :>, "gt" => :>,
# Other
"factorial" => :factorial,
"ceiling" => :ceil, "ceiling" => :ceil,
"floor" => :floor, "floor" => :floor,
"piecewise" => SBML.parse_piecewise, "piecewise" => :(Core.ifelse),
#TODO add further translations of SBML functions to Julia #TODO extend this in the future
) )
allowed_sym(x) = haskey(allowed_funs,x) ? allowed_funs[x] : throw(DomainError(x,"Unknown SBML function")) allowed_sym(x, allowed_funs) =
haskey(allowed_funs, x) ? allowed_funs[x] :
throw(DomainError(x, "Unknown SBML function"))
function Base.convert(::Type{Num}, x::SBML.Math) function Base.convert(::Type{Num}, x::SBML.Math; mapping = default_symbolics_mapping)
conv(x::SBML.MathApply) = conv(x::SBML.MathApply) = eval(allowed_sym(x.fn, mapping))(conv.(x.args)...)
eval(allowed_sym(x.fn))(conv.(x.args)...) conv(x::SBML.MathIdent) = Num(Variable(Symbol(x.id))).val
conv(x::SBML.MathIdent) =
Num(Variable(Symbol(x.id))).val
conv(x::SBML.MathVal) = x.val conv(x::SBML.MathVal) = x.val
conv(x::SBML.MathLambda) = conv(x::SBML.MathLambda) = throw(DomainError(x, "can't translate lambdas to symbolics"))
throw(DomainError(x, "can't translate lambdas to symbolics"))
conv(x) conv(x)
end end
...@@ -6,18 +6,30 @@ ...@@ -6,18 +6,30 @@
D = Symbolics.Variable(Symbol("D")) D = Symbolics.Variable(Symbol("D"))
E = Symbolics.Variable(Symbol("E")) E = Symbolics.Variable(Symbol("E"))
test = SBML.MathApply("*", SBML.Math[ test = SBML.MathApply(
SBML.MathApply("+", SBML.Math[ "*",
SBML.MathApply("*", SBML.Math[ SBML.Math[
SBML.MathIdent("A"), SBML.MathApply(
SBML.MathIdent("B")]), "+",
SBML.MathApply("-", SBML.Math[ SBML.Math[
SBML.MathApply("*", SBML.Math[ SBML.MathApply(
SBML.MathIdent("C"), "*",
SBML.MathIdent("D")])])]), SBML.Math[SBML.MathIdent("A"), SBML.MathIdent("B")],
SBML.MathIdent("E")]) ),
SBML.MathApply(
"-",
SBML.Math[SBML.MathApply(
"*",
SBML.Math[SBML.MathIdent("C"), SBML.MathIdent("D")],
)],
),
],
),
SBML.MathIdent("E"),
],
)
expr_true = (A*B - C*D) * E expr_true = (A * B - C * D) * E
ex = convert(Num,test) ex = convert(Num, test)
@test isequal(convert(Num,test), expr_true) @test isequal(convert(Num, test), expr_true)
end end
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment