Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 4 additions & 1 deletion src/mathops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ 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
Expand Down Expand Up @@ -127,6 +127,9 @@ 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
Expand Down
12 changes: 6 additions & 6 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 @@ -125,12 +130,7 @@ end
function N(::Val{<:Any}, b::Basic)
is_constant(b) ||
throw(ArgumentError("Object can have no free symbols"))

# replace any True/False with 1/0
m = CMapBasicBasic()
m[True] = Basic(1); m[False] = Basic(0)

out = evalf(subs(b, m))
out = evalf(b)
imag(out) == Basic(0.0) ? N(real(out)) : N(out)
end

Expand Down
Loading