Skip to content

Commit

Permalink
Merge pull request #229 from jverzani/v0.7b
Browse files Browse the repository at this point in the history
V0.7b
  • Loading branch information
jverzani committed Jul 17, 2018
2 parents 797f16c + b3f47e3 commit a1ffa2c
Show file tree
Hide file tree
Showing 20 changed files with 206 additions and 156 deletions.
73 changes: 43 additions & 30 deletions src/SymPy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ import Base: show
import Base: convert, promote_rule
import Base: getindex
import Base: start, next, done
import Base: complex
import Base: complex, real, imag, float
import Base: eps
import Base: sin, cos, tan, sinh, cosh, tanh, asin, acos,
atan, asinh, acosh, atanh, sec, csc, cot, asec,
acsc, acot, sech, csch, coth, asech, acsch, acoth,
Expand All @@ -51,31 +52,45 @@ import Base: sin, cos, tan, sinh, cosh, tanh, asin, acos,
sinpi, cospi,
log, log2,
log10, log1p, exponent, exp, exp2, expm1, cbrt, sqrt,
erf, erfc, erfcx, erfi, erfinv, erfcinv, dawson, ceil, floor,
ceil, floor,
trunc, round, significand,
abs, max, min, maximum, minimum,
sign, dot,
abs, abs2, max, min, maximum, minimum, diff,
sign,
zero, one,
hypot
import Base: transpose
import Base: diff
import Base: factorial, gcd, lcm, isqrt
import Base: length, size
import Base: expand, collect
import Base: !=, ==
import Base: inv, conj, det,
cross, eigvals, eigvecs, trace, norm, chol
import Base: promote_rule
import Base: inv, conj
import Base: match, replace, round
import Base: intersect, union, symdiff
import Base: +, -, *, /, //, \
import Base: ^, .^
import Base: !=, ==
import Base: &, |, !, >, >=, ==, <=, <
import Base: isless, isequal
import Base: rad2deg, deg2rad
import Base: copysign, signbit, flipsign, isinf, isnan, typemax, typemin
import Base: zero, zeros, one, ones
import Base: contains, in, replace, match
import Base: promote_rule

## poly.jl
import Base: div
import Base: div, rem, divrem
import Base: trunc
import Base: isinf, isnan
import Base: real, imag
import Base: nullspace


using Compat.LinearAlgebra
import Compat.LinearAlgebra: norm, chol, eigvals, eigvecs, rank,
nullspace, dot, det, cross
if VERSION >= v"0.7.0-"
import Compat.LinearAlgebra: cholesky, tr
end
import SpecialFunctions: erf, erfc, erfcx, erfi, erfinv, erfcinv, dawson


export sympy, sympy_meth, @sympy_str, object_meth, call_matrix_meth
Expand Down Expand Up @@ -151,13 +166,11 @@ for meth in union(
)

meth_name = string(meth)
# eval(Expr(:import, :Base, meth)) # (kept in import list above)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
""" ->

# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# """ ->
($meth)(ex::Sym, args...; kwargs...) =
sympy_meth($meth_name, ex, args...; kwargs...)
end
Expand All @@ -184,10 +197,10 @@ for meth in union(core_sympy_methods,

meth_name = string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
""" ->
# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# """ ->
($meth)(ex::T, args...; kwargs...) where {T<:SymbolicObject} = sympy_meth($meth_name, ex, args...; kwargs...)

end
Expand All @@ -202,10 +215,10 @@ for meth in union(math_object_methods_base,

meth_name = string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
""" ->
# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# """ ->
($meth)(ex::SymbolicObject, args...; kwargs...) = object_meth(ex, $meth_name, args...; kwargs...)
end
end
Expand All @@ -220,10 +233,10 @@ for meth in union(core_object_methods,

meth_name = string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
""" ->
# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# """ ->
($meth)(ex::SymbolicObject, args...; kwargs...) = object_meth(ex, $meth_name, args...; kwargs...)
end
eval(Expr(:export, meth))
Expand Down Expand Up @@ -293,12 +306,12 @@ function _sympy_str(fn, args...; kwargs...)
catch err
try
xs = [args...]
x = shift!(xs)
x = popfirst!(xs)
object_meth(x, fn, xs...; kwargs...)
catch err
try
xs = [args...]
x = shift!(xs)
x = popfirst!(xs)
call_matrix_meth(x, fn, xs...; kwargs...)
catch err
try
Expand Down
11 changes: 6 additions & 5 deletions src/assumptions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ filter(x -> ask(Q.prime(x)), [1:1000])
"""
ask(x::Sym, args...) = sympy_meth(:ask, x, args...)
ask(x::Bool, args...) = x
ask(x::Void, args...) = x
ask(x::Nothing, args...) = x
export ask

## should we support & and | for (sym,sym) pairs? Not sure
Expand Down Expand Up @@ -89,6 +89,7 @@ matrices are not used, though a replacement is given.
module Q
import SymPy
import PyCall
import Compat.LinearAlgebra: det, norm

##http://docs.sympy.org/dev/_modules/sympy/assumptions/ask.html#ask
Q_predicates = (:antihermitian,
Expand Down Expand Up @@ -138,10 +139,10 @@ Q_predicates = (:antihermitian,
for meth in Q_predicates
nm = string(meth)
@eval begin
@doc """
`$($nm)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($nm)
""" ->
# @doc """
# `$($nm)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($nm)
# """ ->
($meth)(x) = PyCall.pycall(SymPy.sympy["Q"][$nm], SymPy.Sym, x)::SymPy.Sym
end
end
Expand Down
4 changes: 2 additions & 2 deletions src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ latex(s::SymbolicObject, args...; kwargs...) = sympy_meth(:latex, s, args...; k
"create basic printed output"
function jprint(x::SymbolicObject)
out = PyCall.pycall(pybuiltin("str"), String, PyObject(x))
if ismatch(r"\*\*", out)
out = replace(out, "**", "^")
if occursin(r"\*\*", out)
out = replace(out, "**" => "^")
end
out
end
Expand Down
1 change: 0 additions & 1 deletion src/dsolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ approach breaks down, then those steps can be done manually starting
with the output of `dsolve` without the initial conditions.
"""

dsolve(ex::Sym;kwargs...) = sympy_meth(:dsolve, ex; kwargs...)
dsolve(exs::Vector{Sym};kwargs...) = sympy_meth(:dsolve, exs; kwargs...)
dsolve(exs::Vector{Sym}, fx::Sym; kwargs...) = sympy_meth(:dsolve, exs, fx; kwargs...)
Expand Down
26 changes: 14 additions & 12 deletions src/lambdify.jl
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,12 @@ This is a *temporary* solution. The proper fix is to do this in SymPy.
"""
function lambdify(ex::Sym, vars=free_symbols(ex); typ=Any, fns=Dict(), values=Dict())
# if :julia_code printer is there, use it
if haskey(sympy, :julia_code)
body = parse(sympy_meth(:julia_code, ex))
else
body = walk_expression(ex, fns=fns, values=values)
end
# if haskey(sympy, :julia_code)
# body = parse(sympy_meth(:julia_code, ex)) # issue here with 2.*...
# else
# body = walk_expression(ex, fns=fns, values=values)
# end
body = walk_expression(ex, fns=fns, values=values)
try
syms = typ == Any ? map(Symbol,vars) : map(s->Expr(:(::),s,typ), Symbol.(vars))
fn = eval(Expr(:function, Expr(:call, gensym(), syms...), body))
Expand All @@ -156,9 +157,9 @@ end

# from @mistguy cf. https://github.com/JuliaPy/SymPy.jl/issues/218
# T a data type to convert to, when specified
function lambdify(exs::Array{S, N}, vars = union(free_symbols.(exs)...); T::DataType=Void, kwargs...) where {S <: Sym, N}
function lambdify(exs::Array{S, N}, vars = union(free_symbols.(exs)...); T::DataType=Nothing, kwargs...) where {S <: Sym, N}
f = lambdify.(exs, (vars,)) # prevent broadcast in vars
if T == Void
if T == Nothing
(args...) -> map.(f, args...)
else
(args...) -> convert(Array{T,N}, map.(f, args...))
Expand Down Expand Up @@ -203,11 +204,12 @@ lambdify_expr(x*y^2, [y, x]) # alternate ordering
"""
function lambdify_expr(ex::Sym, vars=free_symbols(ex); name=gensym(), typ=Any, fns=Dict(), values=Dict())
# if :julia_code printer is there, use it
if haskey(sympy, :julia_code)
body = parse(sympy_meth(:julia_code, ex))
else
body = walk_expression(ex, fns=fns, values=values)
end
# if haskey(sympy, :julia_code)
# body = parse(sympy_meth(:julia_code, ex))
# else
# body = walk_expression(ex, fns=fns, values=values)
# end
body = walk_expression(ex, fns=fns, values=values)
try
syms = typ == Any ? map(Symbol,vars) : map(s->Expr(:(::),s,typ), Symbol.(vars))
Expr(:function, Expr(:call, name, syms...), body)
Expand Down
8 changes: 4 additions & 4 deletions src/logical.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const relational_sympy_values = (:GreaterThan, :LessThan,
for meth in relational_sympy_values
meth_name = string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function. [cf.](http://docs.sympy.org/dev/_modules/sympy/core/relational.html)
""" ->
# @doc """
# `$($meth_name)`: a SymPy function. [cf.](http://docs.sympy.org/dev/_modules/sympy/core/relational.html)
# """ ->
($meth)(a::Real, b::Real) = sympy_meth($meth_name,a, b)
end
# eval(Expr(:export, meth))
Expand Down Expand Up @@ -128,5 +128,5 @@ function !=(x::Sym, y::T) where {T <: Complex}
end

function init_logical()
global const SympyTRUE = sympy_meth(:Lt, 0,1)
global SympyTRUE = sympy_meth(:Lt, 0,1)
end
13 changes: 10 additions & 3 deletions src/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ Base.eps(::Type{Sym}) = zero(Sym)

import Base: min, max
min(x::Sym, a) = sympy_meth(:Min, x, a)
min(a, x::Union{SA, Real}) where {SA <: Sym} = min(x,a)
VERSION < v"0.7.0-" && (min(a, x::Union{SA, Real}) where {SA <: Sym} = min(x,a))

max(x::Sym, a) = sympy_meth(:Max, x, a)
max(a, x::Union{SA, Real}) where {SA <: Sym} = max(x,a)
VERSION < v"0.7.0-" && (max(a, x::Union{SA, Real}) where {SA <: Sym} = max(x,a))

# SymPy names
Min(ex::Sym, ex1::Sym) = sympy_meth(:Min, ex, ex1)
Expand Down Expand Up @@ -190,7 +190,7 @@ const Piecewise = piecewise

piecewise_fold(ex::Sym) = sympy_meth(:piecewise_fold, ex)

Base.ifelse(ex::Sym, a, b) = piecewise((a, ex), (b, true))
VERSION < v"0.7.0-" && (Base.ifelse(ex::Sym, a, b) = piecewise((a, ex), (b, true)))

"""
Indicator expression: (Either `\\Chi[tab](x,a,b)` or `Indicator(x,a,b)`)
Expand Down Expand Up @@ -240,6 +240,13 @@ Base.typemin(::Type{Sym}) = -oo
## * if numeric return a julia object
## * if symbolic, return a symbolic object

Base.float(x::Sym) = _float(N(x))
_float(x::Sym) = throw(ArgumentError("variable must have no free symbols"))
_float(x) = float(x)
Base.Float64(x::Sym) = _Float64(N(x))
_Float64(x::Sym) = throw(ArgumentError("variable must have no free symbols"))
_Float64(x) = Float64(x)

Base.real(x::Sym) = _real(N(x))
_real(x::Sym) = sympy_meth(:re, x)
_real(x) = real(x)
Expand Down
8 changes: 4 additions & 4 deletions src/mathops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
-(x::SymbolicObject, y::SymbolicObject) = x + (-y)
-(x::SymbolicObject) = (-1) * x
/(x::SymbolicObject, y::SymbolicObject) = x * inv(y)
^(x::SymbolicObject, y::SymbolicObject) = pycall(sympy["Pow"], Sym, y, -1)::Sym
^(x::SymbolicObject, y::SymbolicObject) = pycall(sympy["Pow"], Sym, x, y)::Sym
^(x::SymbolicObject, y::Rational) = x^convert(Sym,y)
^(x::SymbolicObject, y::Integer) = x^convert(Sym,y) # no Union{Integer, Rational}, as that has ambiguity
^(x::Sym, y::Sym) = pycall(sympy["Pow"], Sym, x, y)::Sym
#^(x::SymbolicObject, y::Integer) = x^convert(Sym,y) # no Union{Integer, Rational}, as that has ambiguity
//(x::SymbolicObject, y::Int) = x / Sym(y)
//(x::SymbolicObject, y::Rational) = x / Sym(y)
//(x::SymbolicObject, y::SymbolicObject) = x / y
Expand All @@ -17,4 +16,5 @@


#inv(x::Sym) = x\one(x)
inv(x::Sym) = x^(-1)
#inv(x::Sym) = x^(-1)
inv(x::Sym) = pycall(sympy["Pow"], Sym, x, -1)
40 changes: 22 additions & 18 deletions src/matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ end

get_matrix_index(s::PyObject, i::Integer...) = get(s, Sym, ntuple(k -> i[k]-1, length(i)))
function get_matrix_index(s::PyObject, i::Integer)
ind = ind2sub(matrix_size(s), i-1) # 0-base PyThon, 1 base Julia
if length(ind) == 1
get(s, Sym, ind[1])
sz = matrix_size(s)
if length(sz) == 1
ind = i - 1
elseif VERSION < v"0.7.0-"
ind = ind2sub(sz, i)
else
get(s, Sym, ind)
ind = Tuple(Base.CartesianIndices(sz)[i])
end
get(s, Sym, ind)
end

function convert(::Type{Array{Sym}}, o::PyObject)
Expand Down Expand Up @@ -79,12 +82,12 @@ sympy_matrix_methods = (:jordan_cell,
for meth in sympy_matrix_methods
meth_name=string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)

Specific docs may also be found at [SymPy Docs for matrices](http://docs.sympy.org/latest/modules/matrices/matrices.html#module-sympy.matrices.matrices)
""" ->
# Specific docs may also be found at [SymPy Docs for matrices](http://docs.sympy.org/latest/modules/matrices/matrices.html#module-sympy.matrices.matrices)
# """ ->
($meth)(args...; kwargs...) = sympy_meth(Symbol($meth_name), args...; kwargs...)
end
eval(Expr(:export, meth))
Expand Down Expand Up @@ -122,12 +125,12 @@ matrix_methods = (:LDLsolve,
for meth in matrix_methods
meth_name = string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)

Specific docs may also be found at [SymPy Docs for matrices](http://docs.sympy.org/latest/modules/matrices/matrices.html#module-sympy.matrices.matrices)
""" ->
# Specific docs may also be found at [SymPy Docs for matrices](http://docs.sympy.org/latest/modules/matrices/matrices.html#module-sympy.matrices.matrices)
# """ ->
($meth)(ex::Matrix{Sym}, args...; kwargs...) = call_matrix_meth(ex, Symbol($meth_name), args...;kwargs...)
end
eval(Expr(:export, meth))
Expand All @@ -149,17 +152,18 @@ matrix_properties = (:H, :C,
for meth in matrix_properties
meth_name = string(meth)
@eval begin
@doc """
`$($meth_name)`: a SymPy function.
The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
""" ->
# @doc """
# `$($meth_name)`: a SymPy function.
# The SymPy documentation can be found through: http://docs.sympy.org/latest/search.html?q=$($meth_name)
# """ ->
($meth)(ex::Matrix{Sym}, args...; kwargs...) = ex[Symbol($meth_name)]
end
eval(Expr(:export, meth))
end


## These are special cased
inv(A::Matrix{Sym}) = inverse_LU(A)
norm(a::AbstractVector{Sym}, args...; kwargs...) = call_matrix_meth(a, :norm, args...; kwargs...)
norm(a::AbstractMatrix{Sym}, args...; kwargs...) = call_matrix_meth(a, :norm, args...; kwargs...)
chol(a::Matrix{Sym}) = cholesky(a)
Expand Down
Loading

0 comments on commit a1ffa2c

Please sign in to comment.