SymPy.jl
SymPy.jl copied to clipboard
use symbols as `Real` type
I want to use your symbols with the Distributions package, but I get an undefined method error for the symbolic inputs because most distribution parameters are expected to be Real
while Sym <: Number
.
example:
using SymPy, Distributions
μ, σ = symbols("μ, σ", real=true)
LogNormal(μ, σ)
Is it possible to create a symbol that is a Real
or more general, another type?
Thanks.
PS: it seems all builds and tests are failing, all the buttons are red on github..
Interesting question, I'll have to think about it, as nothing pops into mind as to how to do this easily.
As for the tests, I'm hopeful the first two badges will turn green on the next package update, but the last two are an issue with the testing environment (the linux is an older version of linux, the windows my own inability to sort out the proper configuration).
So far I haven't thought of any way to do this, but for your specific example I think you would need to convert from a symbolic SymPy value to numeric Julia value. For that the N
operator will help. It will convert real numbers to real numbers.
I was able to run the example by changing the Real
to Number
in the Distributions package. This is however not a long term solution.
I've also been thinking about it and looking a bit in the code, no breakthrough. Could it be we need multiple inheritence? Then with metaprogramming we could be able to define a subtype like
Sym_Type <: SymbolicObject, Type
x::PyCall.PyObject
end
where Type
would be Real
for my use case.
Good idea. I'm guessing a type union can be used here instead of multiple inheritance. Something like this might work. I'll have to check:
type SymbolicObject <: Number
o
end
type SymbolicReal <: Real
o
end
type SymbolicInt <: Integer
o
end
Sym = Union(SymbolicObject, SymbolicReal, SymbolicInt)
using PyCall
@pyimport sympy
function symbols(x::String; integer=false, real=false)
if integer
SymbolicInt(sympy.symbols(x,integer=true))
elseif real
SymbolicReal(sympy.symbols(x,real=true))
else
SymbolicObject(sympy.symbols(x))
end
end
f(x::Sym) = typeof(x)
The symbols
constructor would be a bit verbose, but not the end of the world.
Strike that idea, creating the objects is the easy part, but there seems to be no way to easily propagate the type information after simple operations, let alone more complicated ones. If/when there is multiple inheritance this can be revisited.
I don't understand it well enough, but maybe it's an idea to use the traits package for this? https://github.com/mauro3/Traits.jl