How do you make sure the function taylor() from Symbolics.jl is type stable ?
I want to use bigint for large order asymptotic expansion not to overflow the classic int64 (order=17 of the following function already overflows, inspired by tutorial on the package site)
Hence my use of :
big(0):big(order)
It works and doesn’t overflow anymore but mixes int64 and bigint in the expansion as you can see in the evaluation of the following snippet.
function funcky(order)
x = Symbolics.variable(:x) :: Num
ϵ = Symbolics.variable(:ϵ) :: Num
a = Symbolics.variables(:a, 0:order) :: Vector{Num}
x_taylor = series(a, ϵ, big(0):big(order)) # expand x in a power series in ϵ
equation = x_taylor^5 + ϵ*x_taylor -1 ~ 0
eq_taylor = taylor(equation, ϵ, big(0):big(order)) #:: Equation
eq_taylor
end
funcky(2)
>>> -1 + a₀^5 + (a₀ + 5(a₀^4)*a₁)*ϵ + (1//2)*(2a₁ + 10(a₀^4)*a₂ + 20(a₀^3)*(a₁^2))*(ϵ^2) ~ 0//1
And result in ‘any’ in the following semi lowered code, which as I understand makes my code much slower.
@code_warntype funcky(2)
>>>
MethodInstance for funcky(::Int64)
from funcky(order) @ Main ~/test_symbolics.jl:75
Arguments
#self#::Core.Const(funcky)
order::Int64
Locals
eq_taylor::Any
equation::Equation
x_taylor::Num
a::Vector{Num}
ϵ::Num
x::Num
Body::Any
1 ─ %1 = Symbolics.variable::Core.Const(Symbolics.variable)
│ %2 = (%1)(:x)::Num
│ (x = Core.typeassert(%2, Main.Num))
│ %4 = Symbolics.variable::Core.Const(Symbolics.variable)
│ %5 = (%4)(:ϵ)::Num
│ (ϵ = Core.typeassert(%5, Main.Num))
│ %7 = Symbolics.variables::Core.Const(Symbolics.variables)
│ %8 = (0:order)::Core.PartialStruct(UnitRange{Int64}, Any[Core.Const(0), Int64])
│ %9 = (%7)(:a, %8)::Vector{Num}
│ %10 = Core.apply_type(Main.Vector, Main.Num)::Core.Const(Vector{Num})
│ (a = Core.typeassert(%9, %10))
│ %12 = a::Vector{Num}
│ %13 = ϵ::Num
│ %14 = Main.big(0)::BigInt
│ %15 = Main.big(order)::BigInt
│ %16 = (%14:%15)::UnitRange{BigInt}
│ (x_taylor = Main.series(%12, %13, %16))
│ %18 = Main.:^::Core.Const(^)
│ %19 = x_taylor::Num
│ %20 = Core.apply_type(Base.Val, 5)::Core.Const(Val{5})
│ %21 = (%20)()::Core.Const(Val{5}())
│ %22 = Base.literal_pow(%18, %19, %21)::Num
│ %23 = (ϵ * x_taylor)::Num
│ %24 = (%22 + %23)::Num
│ %25 = (%24 - 1)::Num
│ (equation = (%25 ~ 0))
│ %27 = equation::Core.PartialStruct(Equation, Any[Any, Core.Const(0)])
│ %28 = ϵ::Num
│ %29 = Main.big(0)::BigInt
│ %30 = Main.big(order)::BigInt
│ %31 = (%29:%30)::UnitRange{BigInt}
│ (eq_taylor = Main.taylor(%27, %28, %31))
└── return eq_taylor
How would you deal with that ?
Should I dig in the package function source code and dispatch for BigInt myself ?
Thx in advance ![]()