Skip to content

Complex default ctor#871

Open
langestefan wants to merge 2 commits intoJuliaSymbolics:masterfrom
langestefan:complex-default
Open

Complex default ctor#871
langestefan wants to merge 2 commits intoJuliaSymbolics:masterfrom
langestefan:complex-default

Conversation

@langestefan
Copy link

@langestefan langestefan commented Mar 1, 2026

Currently UnionAll types like Complex do not have a good default constructor.

Which would lead to:

@syms z::Complex
MethodError: Cannot `convert` an object of type Type{Complex} to an object of type DataType

The function normalize_symtype handles this case, so that now Complex defaults to Complex{Real}.

I also updated the readme example, it wasn't working.

@langestefan langestefan changed the title Complex default Complex default ctor Mar 1, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

Benchmark Results (Julia vlts)

Time benchmarks
master ce3bfaa... master / ce3bfaa...
arithmetic/2-arg mul 14 ± 0.37 μs 13.3 ± 0.28 μs 1.05 ± 0.036
arithmetic/addition 0.0797 ± 0.00089 ms 0.079 ± 0.001 ms 1.01 ± 0.017
arithmetic/division 27.5 ± 0.75 μs 27 ± 0.66 μs 1.02 ± 0.037
arithmetic/multiplication 0.0633 ± 0.0018 ms 0.0611 ± 0.0018 ms 1.04 ± 0.042
overhead/acrule/a+2 2.5 ± 0.09 μs 2.44 ± 0.06 μs 1.02 ± 0.045
overhead/acrule/a+2+b 0.07 ± 0 μs 0.07 ± 0 μs 1 ± 0
overhead/acrule/a+b 4.38 ± 0.19 μs 4.29 ± 0.19 μs 1.02 ± 0.063
overhead/acrule/noop:Int 0.041 ± 0.01 μs 0.049 ± 0.01 μs 0.837 ± 0.27
overhead/acrule/noop:Sym 0.05 ± 0.01 μs 0.051 ± 0.01 μs 0.98 ± 0.27
overhead/get_degrees/large_poly 0.09 ± 0.001 μs 0.08 ± 0.01 μs 1.12 ± 0.14
overhead/rule/noop:Int 0.061 ± 0.01 μs 0.069 ± 0.01 μs 0.884 ± 0.19
overhead/rule/noop:Sym 0.061 ± 0.01 μs 0.06 ± 0.001 μs 1.02 ± 0.17
overhead/rule/noop:Term 0.06 ± 0.01 μs 0.06 ± 0.001 μs 1 ± 0.17
overhead/ruleset/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/ruleset/noop:Sym 0.301 ± 0.011 μs 0.301 ± 0.011 μs 1 ± 0.052
overhead/ruleset/noop:Term 1.21 ± 0.011 μs 1.23 ± 0.02 μs 0.985 ± 0.018
overhead/simplify/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/simplify/noop:Sym 30 ± 10 ns 30 ± 10 ns 1 ± 0.47
overhead/simplify/noop:Term 29.5 ± 0.7 μs 29 ± 0.92 μs 1.02 ± 0.04
overhead/simplify/randterm (+, *):serial 0.236 ± 0.0031 s 0.234 ± 0.0023 s 1.01 ± 0.016
overhead/simplify/randterm (+, *):thread 0.278 ± 0.027 s 0.27 ± 0.031 s 1.03 ± 0.15
overhead/simplify/randterm (/, *):serial 0.0863 ± 0.0021 ms 0.085 ± 0.0017 ms 1.02 ± 0.032
overhead/simplify/randterm (/, *):thread 0.0899 ± 0.0022 ms 0.0892 ± 0.0021 ms 1.01 ± 0.034
overhead/substitute/a 0.0416 ± 0.0011 ms 0.0421 ± 0.00087 ms 0.986 ± 0.033
overhead/substitute/a,b 0.0499 ± 0.0013 ms 0.051 ± 0.001 ms 0.978 ± 0.032
overhead/substitute/a,b,c 0.0445 ± 0.001 ms 0.0465 ± 0.001 ms 0.957 ± 0.031
polyform/easy_iszero 23.3 ± 0.45 μs 23 ± 0.47 μs 1.01 ± 0.029
polyform/isone 1.1 ± 0.025 ms 1.07 ± 0.024 ms 1.03 ± 0.033
polyform/isone:noop 0.1 ± 0.001 μs 0.09 ± 0.009 μs 1.11 ± 0.11
polyform/iszero 0.942 ± 0.03 ms 0.912 ± 0.024 ms 1.03 ± 0.043
polyform/iszero:noop 0.1 ± 0.009 μs 0.09 ± 0.009 μs 1.11 ± 0.15
polyform/simplify_fractions 1.19 ± 0.03 ms 1.16 ± 0.026 ms 1.02 ± 0.035
printing/large_poly 0.207 ± 0.0018 s 0.206 ± 0.0037 s 1.01 ± 0.02
time_to_load 1.29 ± 0.022 s 1.26 ± 0.0078 s 1.03 ± 0.019
Memory benchmarks
master ce3bfaa... master / ce3bfaa...
arithmetic/2-arg mul 0.078 k allocs: 2.72 kB 0.078 k allocs: 2.72 kB 1
arithmetic/addition 0.438 k allocs: 16 kB 0.438 k allocs: 16 kB 1
arithmetic/division 0.142 k allocs: 5.47 kB 0.142 k allocs: 5.47 kB 1
arithmetic/multiplication 0.356 k allocs: 11.7 kB 0.356 k allocs: 11.7 kB 1
overhead/acrule/a+2 0.034 k allocs: 1.25 kB 0.034 k allocs: 1.25 kB 1
overhead/acrule/a+2+b 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/a+b 0.047 k allocs: 1.8 kB 0.047 k allocs: 1.8 kB 1
overhead/acrule/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/get_degrees/large_poly 2 allocs: 32 B 2 allocs: 32 B 1
overhead/rule/noop:Int 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Sym 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Term 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/ruleset/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/ruleset/noop:Sym 3 allocs: 0.109 kB 3 allocs: 0.109 kB 1
overhead/ruleset/noop:Term 12 allocs: 0.391 kB 12 allocs: 0.391 kB 1
overhead/simplify/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Term 0.298 k allocs: 11.6 kB 0.298 k allocs: 11.6 kB 1
overhead/simplify/randterm (+, *):serial 2.31 M allocs: 0.0883 GB 2.31 M allocs: 0.0883 GB 1
overhead/simplify/randterm (+, *):thread 2.35 M allocs: 0.246 GB 2.35 M allocs: 0.246 GB 1
overhead/simplify/randterm (/, *):serial 0.844 k allocs: 30.4 kB 0.844 k allocs: 30.4 kB 1
overhead/simplify/randterm (/, *):thread 0.879 k allocs: 31.5 kB 0.879 k allocs: 31.5 kB 1
overhead/substitute/a 0.22 k allocs: 8.42 kB 0.22 k allocs: 8.42 kB 1
overhead/substitute/a,b 0.267 k allocs: 10.1 kB 0.267 k allocs: 10.1 kB 1
overhead/substitute/a,b,c 0.238 k allocs: 8.62 kB 0.238 k allocs: 8.62 kB 1
polyform/easy_iszero 0.133 k allocs: 4.58 kB 0.133 k allocs: 4.58 kB 1
polyform/isone 8.34 k allocs: 0.567 MB 8.34 k allocs: 0.567 MB 1
polyform/isone:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/iszero 6.87 k allocs: 0.467 MB 6.87 k allocs: 0.467 MB 1
polyform/iszero:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/simplify_fractions 8.82 k allocs: 0.59 MB 8.82 k allocs: 0.59 MB 1
printing/large_poly 1.86 M allocs: 0.082 GB 1.86 M allocs: 0.082 GB 1
time_to_load 0.153 k allocs: 14.5 kB 0.153 k allocs: 14.5 kB 1

@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

Benchmark Results (Julia v1)

Time benchmarks
master ce3bfaa... master / ce3bfaa...
arithmetic/2-arg mul 10.9 ± 0.31 μs 10.7 ± 0.27 μs 1.02 ± 0.039
arithmetic/addition 0.0679 ± 0.0008 ms 0.0677 ± 0.00071 ms 1 ± 0.016
arithmetic/division 24.7 ± 0.63 μs 25 ± 0.55 μs 0.987 ± 0.033
arithmetic/multiplication 0.0499 ± 0.0019 ms 0.0519 ± 0.0016 ms 0.962 ± 0.046
overhead/acrule/a+2 2.18 ± 0.08 μs 2.17 ± 0.059 μs 1 ± 0.046
overhead/acrule/a+2+b 0.08 ± 0.001 μs 0.08 ± 0.001 μs 1 ± 0.018
overhead/acrule/a+b 3.78 ± 0.11 μs 3.74 ± 0.09 μs 1.01 ± 0.038
overhead/acrule/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/acrule/noop:Sym 0.07 ± 0.01 μs 0.07 ± 0.01 μs 1 ± 0.2
overhead/get_degrees/large_poly 0.09 ± 0 μs 0.08 ± 0.01 μs 1.12 ± 0.14
overhead/rule/noop:Int 0.07 ± 0.01 μs 0.07 ± 0.01 μs 1 ± 0.2
overhead/rule/noop:Sym 0.07 ± 0 μs 0.07 ± 0 μs 1 ± 0
overhead/rule/noop:Term 0.07 ± 0 μs 0.07 ± 0 μs 1 ± 0
overhead/ruleset/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/ruleset/noop:Sym 0.321 ± 0.03 μs 0.321 ± 0.03 μs 1 ± 0.13
overhead/ruleset/noop:Term 1.24 ± 0.03 μs 1.18 ± 0.029 μs 1.05 ± 0.036
overhead/simplify/noop:Int 30 ± 0 ns 30 ± 0 ns 1 ± 0
overhead/simplify/noop:Sym 30 ± 10 ns 30 ± 10 ns 1 ± 0.47
overhead/simplify/noop:Term 27.3 ± 0.7 μs 26.8 ± 0.67 μs 1.02 ± 0.036
overhead/simplify/randterm (+, *):serial 0.205 ± 0.027 s 0.19 ± 0.028 s 1.08 ± 0.21
overhead/simplify/randterm (+, *):thread 0.256 ± 0.027 s 0.262 ± 0.072 s 0.978 ± 0.29
overhead/simplify/randterm (/, *):serial 0.0861 ± 0.0045 ms 0.0865 ± 0.003 ms 0.996 ± 0.063
overhead/simplify/randterm (/, *):thread 0.0967 ± 0.008 ms 0.0966 ± 0.0086 ms 1 ± 0.12
overhead/substitute/a 0.0353 ± 0.0008 ms 0.0331 ± 0.00067 ms 1.07 ± 0.032
overhead/substitute/a,b 0.0431 ± 0.001 ms 0.0413 ± 0.00087 ms 1.04 ± 0.034
overhead/substitute/a,b,c 0.0416 ± 0.001 ms 0.0397 ± 0.00077 ms 1.05 ± 0.033
polyform/easy_iszero 19 ± 0.42 μs 18.7 ± 0.41 μs 1.02 ± 0.032
polyform/isone 0.92 ± 0.024 ms 0.898 ± 0.017 ms 1.02 ± 0.033
polyform/isone:noop 0.08 ± 0.001 μs 0.08 ± 0.01 μs 1 ± 0.13
polyform/iszero 0.798 ± 0.019 ms 0.784 ± 0.02 ms 1.02 ± 0.035
polyform/iszero:noop 0.08 ± 0 μs 0.08 ± 0 μs 1 ± 0
polyform/simplify_fractions 0.992 ± 0.035 ms 0.981 ± 0.043 ms 1.01 ± 0.057
printing/large_poly 0.195 ± 0.015 s 0.197 ± 0.014 s 0.991 ± 0.11
time_to_load 1.42 ± 0.025 s 1.41 ± 0.0053 s 1.01 ± 0.018
Memory benchmarks
master ce3bfaa... master / ce3bfaa...
arithmetic/2-arg mul 0.056 k allocs: 1.78 kB 0.056 k allocs: 1.78 kB 1
arithmetic/addition 0.3 k allocs: 10.3 kB 0.3 k allocs: 10.3 kB 1
arithmetic/division 0.132 k allocs: 4.77 kB 0.132 k allocs: 4.77 kB 1
arithmetic/multiplication 0.252 k allocs: 6.5 kB 0.252 k allocs: 6.5 kB 1
overhead/acrule/a+2 0.034 k allocs: 1.12 kB 0.034 k allocs: 1.12 kB 1
overhead/acrule/a+2+b 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/a+b 0.046 k allocs: 1.55 kB 0.046 k allocs: 1.55 kB 1
overhead/acrule/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/acrule/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/get_degrees/large_poly 2 allocs: 32 B 2 allocs: 32 B 1
overhead/rule/noop:Int 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Sym 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/rule/noop:Term 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
overhead/ruleset/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/ruleset/noop:Sym 3 allocs: 0.109 kB 3 allocs: 0.109 kB 1
overhead/ruleset/noop:Term 12 allocs: 0.391 kB 12 allocs: 0.391 kB 1
overhead/simplify/noop:Int 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Sym 0 allocs: 0 B 0 allocs: 0 B
overhead/simplify/noop:Term 0.284 k allocs: 10 kB 0.284 k allocs: 10 kB 1
overhead/simplify/randterm (+, *):serial 2.16 M allocs: 0.0754 GB 2.16 M allocs: 0.0754 GB 1
overhead/simplify/randterm (+, *):thread 2.32 M allocs: 0.237 GB 2.32 M allocs: 0.237 GB 1
overhead/simplify/randterm (/, *):serial 0.783 k allocs: 28.2 kB 0.783 k allocs: 28.2 kB 1
overhead/simplify/randterm (/, *):thread 0.918 k allocs: 0.0325 MB 0.918 k allocs: 0.0325 MB 1
overhead/substitute/a 0.172 k allocs: 6.05 kB 0.172 k allocs: 6.05 kB 1
overhead/substitute/a,b 0.223 k allocs: 7.69 kB 0.223 k allocs: 7.69 kB 1
overhead/substitute/a,b,c 0.229 k allocs: 7.81 kB 0.229 k allocs: 7.81 kB 1
polyform/easy_iszero 0.092 k allocs: 2.94 kB 0.092 k allocs: 2.94 kB 1
polyform/isone 10.9 k allocs: 0.579 MB 10.9 k allocs: 0.579 MB 1
polyform/isone:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/iszero 8.97 k allocs: 0.48 MB 8.97 k allocs: 0.48 MB 1
polyform/iszero:noop 1 allocs: 16 B 1 allocs: 16 B 1
polyform/simplify_fractions 11.4 k allocs: 0.596 MB 11.4 k allocs: 0.596 MB 1
printing/large_poly 2.15 M allocs: 0.079 GB 2.15 M allocs: 0.079 GB 1
time_to_load 0.145 k allocs: 11 kB 0.145 k allocs: 11 kB 1

where users provide abstract types that need default type parameters:
- `Complex` → `Complex{Real}`
"""
normalize_symtype(t::DataType) = t
Copy link
Member

Choose a reason for hiding this comment

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

Is this intended as public API for downstream users to add methods to?

Copy link
Author

Choose a reason for hiding this comment

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

I wouldn't think so. This is only used as a fallback when a concrete type wasn't specified

performance in internal operations.
"""
@inline function BSImpl.Sym{T}(name::Symbol; metadata = nothing, type, shape = default_shape(type), unsafe = false) where {T}
type = normalize_symtype(type)
Copy link
Member

Choose a reason for hiding this comment

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

This code path is very performance sensitive, and this change would add an unavoidable dynamic dispatch.

Copy link
Author

Choose a reason for hiding this comment

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

would you be okay with doing it in sym_from_parse_result instead? So working on result[:type] = :Complex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants