SymPy.jl icon indicating copy to clipboard operation
SymPy.jl copied to clipboard

use symbols as `Real` type

Open Ken-B opened this issue 9 years ago • 6 comments

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..

Ken-B avatar Jul 08 '15 15:07 Ken-B

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).

jverzani avatar Jul 08 '15 22:07 jverzani

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.

jverzani avatar Jul 14 '15 22:07 jverzani

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.

Ken-B avatar Jul 15 '15 07:07 Ken-B

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.

jverzani avatar Jul 15 '15 14:07 jverzani

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.

jverzani avatar Jul 17 '15 11:07 jverzani

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

Ken-B avatar Sep 16 '15 16:09 Ken-B