From 96849408ddb7dc09f1572310fb3c83a35d67e0bf Mon Sep 17 00:00:00 2001 From: "Bowen S. Zhu" Date: Sat, 25 May 2024 00:19:59 -0400 Subject: [PATCH] Add symbolic number constructor and conversion --- src/types.jl | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/basics.jl | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/types.jl b/src/types.jl index 2202a8df1..daebbc05d 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. + +```julia +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 SymbolicUtils.Symbolic(x::T) where {T<:Number} + SymbolicUtils.Term{T}(identity, [x]) +end +function SymbolicUtils.Symbolic{T}(x::Number) where {T} + SymbolicUtils.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{SymbolicUtils.BasicSymbolic{T}}, x::Number) where {T} + SymbolicUtils.BasicSymbolic{T}(x) +end + ### ### Metadata ### diff --git a/test/basics.jl b/test/basics.jl index cc3464eab..24204bd91 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -315,3 +315,36 @@ 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)) + 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)) + 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)) + 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)) + end + + @testset "Assigning Number to Array" begin + @syms x y + arr = [x, y] + arr[1] = 2 + arr[2] = 1.0 + end +end