Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/mathops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,16 @@ Base.one(::Type{T}) where {T<:BasicType} = BasicType(Basic(1))
## Math constants
## no oo!

for op in [:IM, :PI, :E, :EulerGamma, :Catalan, :GoldenRatio, :oo, :zoo, :NAN]
for op in [:IM, :PI, :E, :EulerGamma, :Catalan, :GoldenRatio, :oo, :zoo, :NAN, :ZERO, :ONE, :MINUSONE]
@eval begin
const $op = Basic(C_NULL)
end
eval(Expr(:export, op))
end

True, False = Basic(C_NULL), Basic(C_NULL);
export True, False

macro init_constant(op, libnm)
tup = (Base.Symbol("basic_const_$libnm"), libsymengine)
alloc_tup = (:basic_new_stack, libsymengine)
Expand All @@ -124,14 +127,20 @@ function init_constants()
@init_constant oo infinity
@init_constant zoo complex_infinity
@init_constant NAN nan
@init_constant ZERO zero
@init_constant ONE one
@init_constant MINUSONE minus_one
ccall((:bool_set_true, libsymengine), Nothing, (Ref{Basic},), True)
ccall((:bool_set_false, libsymengine), Nothing, (Ref{Basic},), False)
end

## ## Conversions
## Conversions
Base.convert(::Type{Basic}, x::Irrational{:π}) = PI
Base.convert(::Type{Basic}, x::Irrational{:e}) = E
Base.convert(::Type{Basic}, x::Irrational{:γ}) = EulerGamma
Base.convert(::Type{Basic}, x::Irrational{:catalan}) = Catalan
Base.convert(::Type{Basic}, x::Irrational{:φ}) = (1 + Basic(5)^Basic(1//2))/2
Base.convert(::Type{Basic}, x::Bool) = x ? True : False
Base.convert(::Type{BasicType}, x::Irrational) = BasicType(convert(Basic, x))

## Logical operators
Expand Down
6 changes: 6 additions & 0 deletions src/numerics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ function evalf(b::Basic, bits::Integer=53, real::Bool=false)
if status == 0
return c
else
# replace any True/False with 1/0
m = CMapBasicBasic()
m[True] = ONE; m[False] = ZERO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this map a global variable instead of creating it every time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need your help with that. I was trying, but kept getting segfaults. The construction of Basic objects is a bit different than that of CMapBasicBasic, so I was having issue initializing the map in __init__.

One thing about what I have here that bothers me is I'd like to cheaply test if an expression has a BooleanAtom and then try to evaluate that expression after substitution with evalf, but it seemed easier to do the substitution and then compare the result to the original. I wasn't sure if substituting in a map with no matches would always return the original expression, as the test has that assumption.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked in what I thought I'd tried earlier and it seems to not cause an issue. I'll add a direct test to be sure.

b′ = subs(b, m)
b′ != b && return evalf(b′, bits, real)
throw(ArgumentError("symbolic value cannot be evaluated to a numeric value"))
end
end
Expand Down Expand Up @@ -91,6 +96,7 @@ N(::Val{:RealMPFR}, b::Basic) = _convert(BigFloat, b)
N(::Val{:Complex}, b::Basic) = complex(N(real(b)), N(imag(b)))
N(::Val{:ComplexMPC}, b::Basic) = complex(N(real(b)), N(imag(b)))
N(::Val{:ComplexDouble}, b::Basic) = complex(N(real(b)), N(imag(b)))
N(::Val{:BooleanAtom}, b::Basic) = b == True ? 1 : 0

N(::Val{:NaN}, b::Basic) = NaN
function N(::Val{:Infty}, b::Basic)
Expand Down
2 changes: 1 addition & 1 deletion src/subs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function _convert(::Type{Expr}, ex::Basic)

if fn == :Symbol
return nameof(ex)
elseif (fn in number_types) || (fn == :Constant)
elseif (fn in number_types) || (fn == :Constant) || (fn == :BooleanAtom)
return N(ex)
end

Expand Down
1 change: 1 addition & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Basic(x::Basic) = x
Base.promote_rule(::Type{Basic}, ::Type{S}) where {S<:Number} = Basic
Base.promote_rule(::Type{S}, ::Type{Basic}) where {S<:Number} = Basic
Base.promote_rule(::Type{S}, ::Type{Basic}) where {S<:AbstractIrrational} = Basic
Base.promote_rule(::Type{Bool}, ::Type{Basic}) = Basic

## Class ID
get_type(s::Basic) = ccall((:basic_get_type, libsymengine), UInt, (Ref{Basic},), s)
Expand Down
1 change: 0 additions & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,3 @@ function have_component(comp::String)
false
end
end

Loading