```
using Symbolics, LinearAlgebra
@variables q::Real
iden = collect(I(4) .* 1.0)
k = inv(iden .* q^2)
```

I get true/q^2 on the diagonal instead of 1/q^2

```
using Symbolics, LinearAlgebra
@variables q::Real
iden = collect(I(4) .* 1.0)
k = inv(iden .* q^2)
```

I get true/q^2 on the diagonal instead of 1/q^2

2 Likes

```
julia> true == 1
true
```

`true`

is the smallest value that represents the integer `1`

```
julia> true isa Integer
true
```

1 Like

This looks like a bug that is worth reporting. Even more extreme is

```
using Symbolics, LinearAlgebra
@variables q
inv(collect(q^2*2.0*I(4)))
```

giving

```
4Ă—4 Matrix{Num}:
true / (2.0(q^2)) 0 0 0
0 true / (2.0(q^2)) 0 0
0 0 true / (2.0(q^2)) 0
0 0 0 true / (2.0(q^2))
```

1 Like

What do you find problematic? What answer would you have expected, taking into account that `true == 1`

?

1 Like

With more complicated expressions it becomes difficult to read 1 instead of true. I tried â€śsimplifyâ€ť but it doesnâ€™t convert true to 1. Maybe there is an alternative? I am declaring q as Real and would not want a bool result.

There is only a `Bool`

in the symbolic expression, the result will be a floating-point value.

```
julia> q = rand();
julia> true/2q^2 === 1/2q^2 # Absolutely identical
true
julia> true/2q^2 # Result is a floating-point value
2.8977550256308775
julia> true/2q^2 |> typeof
Float64
```

The whole point is that `true == 1`

, just like `1.0 == 1`

, and it makes sense to use the smallest version of 1 possible to avoid type promotion if not required.

1 Like

Youâ€™re right, but I might want to use Symbolics to get a symbolic result without necessarily wanting to calculate it numerically.

In a symbolic expression I would like numbers, not equivalent quantities like Bool. Thank you.

1 Like

You could modify how `Bool`

is printed, but it may have unintended consequences

```
julia> Base.show(io::IO, b::Bool) = print(io, (b ? "1" : "0"))
julia> true
1
julia> false
0
```

1 Like

But they are not equivalent. `1.0 === 1`

is false and we can get different answers in subsequent computations

```
julia> x = sum(1.0 for i in range(1,2^16))
65536.0
julia> 2^48*x
1.8446744073709552e19
julia> x = sum(1 for i in range(1,2^16))
65536
julia> 2^48*x
0
```

1 Like

If you write the prompt more concisely, the result is more readable, too.

```
julia> using Symbolics, LinearAlgebra
julia> @variables q
1-element Vector{Num}:
q
julia> inv(collect(q^2*2I(4)))
4Ă—4 Matrix{Num}:
1 / (2(q^2)) 0 0 0
0 1 / (2(q^2)) 0 0
0 0 1 / (2(q^2)) 0
0 0 0 1 / (2(q^2))
```

1 Like

The computations you show here are unrelated to the expression `true/2q^2`

which is in fact identical to `1/2q^2`

. If you intend to make further numerical computations, you can always make sure you have a suitable type for the computations you want to perform.

1 Like

To elaborate on why `true`

is a good choice here, consider the following trivial function, if we define it using `false`

, we see that `false`

is *adaptive* in the sense that multiplying with `false`

will make the result have the same type as the input, irrespective of what the type is:

```
julia> multiply_by_zero(x) = false*x
multiply_by_zero (generic function with 1 method)
julia> multiply_by_zero(true)
false
julia> multiply_by_zero(1)
0
julia> multiply_by_zero(1f0)
0.0f0
julia> multiply_by_zero(1.0)
0.0
julia> multiply_by_zero(big"1.0")
0.0
```

Had we defined the function using a floating-point value, we see that the type of the result is different from the type of the input whenever the input type is *smaller* than `Float64`

```
julia> multiply_by_zero(x) = 0.0*x
multiply_by_zero (generic function with 1 method)
julia> multiply_by_zero(true)
0.0
julia> multiply_by_zero(1)
0.0
julia> multiply_by_zero(1f0)
0.0
julia> multiply_by_zero(1.0)
0.0
julia> multiply_by_zero(big"1.0")
0.0
julia>
```

3 Likes

With a float coefficient that is unfortunately not the case

```
julia> using Symbolics, LinearAlgebra
julia> @variables q
1-element Vector{Num}:
q
julia> z = inv(collect(q^2*2.0I(4)))
4Ă—4 Matrix{Num}:
true / (2.0(q^2)) 0 0 0
0 true / (2.0(q^2)) 0 0
0 0 true / (2.0(q^2)) 0
0 0 0 true / (2.0(q^2))
```

Going further with this example worries me

```
julia> y = z[1,1]
true / (2.0(q^2))
julia> x = sum(y for i in range(1,2^16))
65536(true / (2.0(q^2)))
julia> 2^48*x
0(true / (2.0(q^2)))
```

1 Like

simplifying or expanding doesnâ€™t seem to help either:

```
julia> simplify(y)
true / (2.0(q^2))
julia> simplify(x)
65536(true / (2.0(q^2)))
julia> expand(x)
65536 / (2.0(q^2))
julia> 2^48*expand(x)
0
julia> simplify(expand(x))
65536 / (2.0(q^2))
```

1 Like

This is simply integer overflow

```
julia> 2^48
281474976710656
julia> 65536 * 2^48
0
```

it is completely unrelated to Symbolics

1 Like

qed

```
julia> 2^48
281474976710656
julia> 65536 * 2^48
0
julia> 65536 * BigInt(2)^48
18446744073709551616
```

1 Like

Yes, that is how I constructed the example. If you reduce your float to an integer then you run in to the overflow problem in subsequent operations. If you keep it is a float, then that problem disappears, at the expense of the answer not being exactly representable. If you change 2.0 to 2.1 or 2.01063072 in the above examples the problems persist, and in the latter cases you would not expect simple replacements with integral or rational constants.

How does one get symbolics to reduce

```
true/(2.0*q^2)
```

to a more consistent form such as

```
0.5 q^(-2)
```

or

```
0.5 / q^2
```

?

2 Likes

I see what you mean; the overflow is hard to diagnose if it accumulates in different parts of the code.

First option I can think of: Use `BigInt`

everywhere; that should be okay in a symbolic computation.

Second option is to implement a `float`

method which recursively turns all numeric coeffiecients into floating-point numbers. see Symbolics.jl/num.jl at master Â· JuliaSymbolics/Symbolics.jl Â· GitHub

1 Like

The Num type has builtin choices for its zero element and its unit element given by

```
julia> using Symbolics
julia> zero(Num)
0
julia> typeof(zero(Num))
Num
julia> one(Num)
1
julia> typeof(one(Num))
Num
```

We have for example

```
julia> one(Num)/2.0
0.5
julia> one(Num)/(2.0*q^2)
1 / (2.0(q^2))
```

So why is this not used?

2 Likes

I would have expected either

```
0.5 / q^2
```

or

```
0.5 q^(-2)
```

rather than

```
true / (2.0(q^2))
```

1 Like