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
function parse_piecewise(val, cond, other)
IfElse.ifelse(cond, val, other)
end
allowed_funs = Dict(
# Operators
default_symbolics_mapping = Dict(
"+" => :+,
"-" => :-,
"*" => :*,
"/" => :/,
"power" => :^,
# Relational functions
"lt" => :<,
"leq" => :<=,
"geq" => :>=,
"gt" => :>,
# Other
"factorial" => :factorial,
"ceiling" => :ceil,
"floor" => :floor,
"piecewise" => SBML.parse_piecewise,
#TODO add further translations of SBML functions to Julia
"piecewise" => :(Core.ifelse),
#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)
conv(x::SBML.MathApply) =
eval(allowed_sym(x.fn))(conv.(x.args)...)
conv(x::SBML.MathIdent) =
Num(Variable(Symbol(x.id))).val
function Base.convert(::Type{Num}, x::SBML.Math; mapping = default_symbolics_mapping)
conv(x::SBML.MathApply) = eval(allowed_sym(x.fn, mapping))(conv.(x.args)...)
conv(x::SBML.MathIdent) = Num(Variable(Symbol(x.id))).val
conv(x::SBML.MathVal) = x.val
conv(x::SBML.MathLambda) =
throw(DomainError(x, "can't translate lambdas to symbolics"))
conv(x::SBML.MathLambda) = throw(DomainError(x, "can't translate lambdas to symbolics"))
conv(x)
end
......@@ -6,18 +6,30 @@
D = Symbolics.Variable(Symbol("D"))
E = Symbolics.Variable(Symbol("E"))
test = SBML.MathApply("*", SBML.Math[
SBML.MathApply("+", SBML.Math[
SBML.MathApply("*", SBML.Math[
SBML.MathIdent("A"),
SBML.MathIdent("B")]),
SBML.MathApply("-", SBML.Math[
SBML.MathApply("*", SBML.Math[
SBML.MathIdent("C"),
SBML.MathIdent("D")])])]),
SBML.MathIdent("E")])
test = SBML.MathApply(
"*",
SBML.Math[
SBML.MathApply(
"+",
SBML.Math[
SBML.MathApply(
"*",
SBML.Math[SBML.MathIdent("A"), SBML.MathIdent("B")],
),
SBML.MathApply(
"-",
SBML.Math[SBML.MathApply(
"*",
SBML.Math[SBML.MathIdent("C"), SBML.MathIdent("D")],
)],
),
],
),
SBML.MathIdent("E"),
],
)
expr_true = (A*B - C*D) * E
ex = convert(Num,test)
@test isequal(convert(Num,test), expr_true)
end
\ No newline at end of file
expr_true = (A * B - C * D) * E
ex = convert(Num, test)
@test isequal(convert(Num, test), expr_true)
end
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