From 093fbbef731b40cb98a52e59f7b684ce2b2ad9d5 Mon Sep 17 00:00:00 2001 From: "Bowen S. Zhu" Date: Sat, 25 May 2024 00:47:37 -0400 Subject: [PATCH] Add symbolic number constructor and conversion --- src/types.jl | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/basics.jl | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/src/types.jl b/src/types.jl index 2202a8df1..e10e1ddc8 100644 --- a/src/types.jl +++ b/src/types.jl @@ -570,6 +570,57 @@ function basic_similarterm(t, f, args, stype; metadata=nothing) end end +""" +$(TYPEDSIGNATURES) + +Construct a [`Symbolic`](@ref) object from a number `x`. + +This function is used to create a symbolic representation of a number. + +```jldoctest +julia> a = SymbolicUtils.Symbolic(3.14) +3.14 + +julia> typeof(a) +SymbolicUtils.BasicSymbolic{Float64} + +julia> b = SymbolicUtils.Symbolic{Real}(6.28) +6.28 + +julia> typeof(b) +SymbolicUtils.BasicSymbolic{Real} +``` +""" +function Symbolic(x::T) where {T<:Number} + Term{T}(identity, [x]) +end +function Symbolic{T}(x::Number) where {T} + Term{T}(identity, [convert(T, x)]) +end + +""" +$(TYPEDSIGNATURES) + +Convert a number `x` to a [`Symbolic`](@ref) object. + +This function is used to convert a number to a symbolic representation. +It is called, for example, when assigning to an array (converts to the array's +element type) or assigning to a field of an object (converts to the declared type +of the field). + +# Examples +```jldoctest +julia> a = convert(SymbolicUtils.BasicSymbolic{Real}, 3.14) +3.14 + +julia> typeof(a) +SymbolicUtils.BasicSymbolic{Real} +``` +""" +function Base.convert(::Type{<:Symbolic{T}}, x::Number) where {T} + Symbolic{T}(x) +end + ### ### Metadata ### diff --git a/test/basics.jl b/test/basics.jl index cc3464eab..ef3b6b0e9 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -315,3 +315,40 @@ end end @test repr(sin(x) + sin(x)) == "sin(x) + sin(x)" end + +@testset "Symbolic Number Constructor and Conversion" begin + @testset "Int" begin + @test Symbolic(1) isa Symbolic{Int} + @test isequal(Symbolic(1), Symbolic{Int}(1)) + @test isequal(convert(Symbolic{Int}, 1), Symbolic{Int}(1)) + @test isequal(convert(BasicSymbolic{Int}, 1), Symbolic{Int}(1)) + end + + @testset "Float64" begin + @test Symbolic(1.0) isa Symbolic{Float64} + @test isequal(Symbolic(1.0), Symbolic{Float64}(1.0)) + @test isequal(convert(Symbolic{Float64}, 1.0), Symbolic{Float64}(1.0)) + @test isequal(convert(BasicSymbolic{Float64}, 1.0), Symbolic{Float64}(1.0)) + end + + @testset "Rational" begin + @test Symbolic(1//2) isa Symbolic{Rational{Int}} + @test isequal(Symbolic(1//2), Symbolic{Rational{Int}}(1//2)) + @test isequal(convert(Symbolic{Rational{Int}}, 1//2), Symbolic{Rational{Int}}(1//2)) + @test isequal(convert(BasicSymbolic{Rational{Int}}, 1//2), Symbolic{Rational{Int}}(1//2)) + end + + @testset "Complex" begin + @test Symbolic(1 + 2im) isa Symbolic{Complex{Int}} + @test isequal(Symbolic(1 + 2im), Symbolic{Complex{Int}}(1 + 2im)) + @test isequal(convert(Symbolic{Complex{Int}}, 1 + 2im), Symbolic{Complex{Int}}(1 + 2im)) + @test isequal(convert(BasicSymbolic{Complex{Int}}, 1 + 2im), Symbolic{Complex{Int}}(1 + 2im)) + end + + @testset "Assigning Number to Array" begin + @syms x y + arr = [x, y] + @test_nowarn arr[1] = 2 + @test_nowarn arr[2] = 1.0 + end +end