# Inverse of symbolic matrix

**URL:** <https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764>\
**Category:** Modelling & Simulations\
**Tags:** linearalgebra, symbolics\
**Created:** [August 15, 2022, 9:16am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764 "2022-08-15T09:16:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![qwerty](https://avatars.discourse-cdn.com/v4/letter/q/4491bb/32.png) [@qwerty](https://discourse.julialang.org/u/qwerty)\
**Post date:** [August 15, 2022, 9:16am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/1 "2022-08-15T09:16:28Z")

</div>

```julia
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

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 15, 2022, 9:39am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/2 "2022-08-15T09:39:01Z")

</div>

```julia
julia> true == 1
true

```

`true` is the smallest value that represents the integer `1`

```julia
julia> true isa Integer
true

```

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 15, 2022, 10:00am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/3 "2022-08-15T10:00:39Z")

</div>

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

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

```

giving

```julia
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))

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 15, 2022, 10:21am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/4 "2022-08-15T10:21:09Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![qwerty](https://avatars.discourse-cdn.com/v4/letter/q/4491bb/32.png) [@qwerty](https://discourse.julialang.org/u/qwerty)\
**Post date:** [August 15, 2022, 10:25am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/5 "2022-08-15T10:25:57Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 15, 2022, 10:29am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/6 "2022-08-15T10:29:11Z")

</div>

There is only a `Bool` in the symbolic expression, the result will be a floating-point value.

```julia
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.

---

<div class="post-metadata">

**Author:** ![qwerty](https://avatars.discourse-cdn.com/v4/letter/q/4491bb/32.png) [@qwerty](https://discourse.julialang.org/u/qwerty)\
**Post date:** [August 15, 2022, 10:33am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/7 "2022-08-15T10:33:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 15, 2022, 10:33am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/8 "2022-08-15T10:33:36Z")

</div>

You could modify how `Bool` is printed, but it may have unintended consequences

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

julia> true
1

julia> false
0

```

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 15, 2022, 10:53am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/9 "2022-08-15T10:53:17Z")

</div>

But they are not equivalent. `1.0 === 1` is false and we can get different answers in subsequent computations

```julia
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

```

---

<div class="post-metadata">

**Author:** ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)\
**Post date:** [August 15, 2022, 10:56am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/10 "2022-08-15T10:56:08Z")

</div>

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

```julia
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))

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 15, 2022, 10:56am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/11 "2022-08-15T10:56:28Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 15, 2022, 11:01am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/12 "2022-08-15T11:01:13Z")

</div>

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
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
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> 

```

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 15, 2022, 1:43pm UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/13 "2022-08-15T13:43:52Z")

</div>

With a float coefficient that is unfortunately not the case

```julia
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
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)))

```

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 15, 2022, 1:47pm UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/14 "2022-08-15T13:47:42Z")

</div>

simplifying or expanding doesn’t seem to help either:

```julia
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))

```

---

<div class="post-metadata">

**Author:** ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)\
**Post date:** [August 15, 2022, 2:47pm UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/15 "2022-08-15T14:47:00Z")

</div>

This is simply integer overflow

```julia
julia> 2^48
281474976710656

julia> 65536 * 2^48
0

```

it is completely unrelated to Symbolics

---

<div class="post-metadata">

**Author:** ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)\
**Post date:** [August 15, 2022, 2:47pm UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/16 "2022-08-15T14:47:32Z")

</div>

qed

```julia
julia> 2^48
281474976710656

julia> 65536 * 2^48
0

julia> 65536 * BigInt(2)^48
18446744073709551616

```

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 15, 2022, 3:25pm UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/17 "2022-08-15T15:25:47Z")

</div>

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

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

```

to a more consistent form such as

```julia
0.5 q^(-2)  

```

or

```julia
0.5 / q^2

```

?

---

<div class="post-metadata">

**Author:** ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)\
**Post date:** [August 15, 2022, 3:44pm UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/18 "2022-08-15T15:44:01Z")

</div>

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](https://github.com/JuliaSymbolics/Symbolics.jl/blob/master/src/num.jl#L35)

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 16, 2022, 6:20am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/19 "2022-08-16T06:20:01Z")

</div>

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

```julia
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
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?

---

<div class="post-metadata">

**Author:** ![Andrew\_Swann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrew_swann/32/32106_2.png) [@Andrew\_Swann](https://discourse.julialang.org/u/Andrew_Swann)\
**Post date:** [August 16, 2022, 6:33am UTC](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764/20 "2022-08-16T06:33:07Z")

</div>

I would have expected either

```julia
0.5 / q^2

```

or

```julia
0.5 q^(-2)

```

rather than

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

```

[Next page](https://discourse.julialang.org/t/inverse-of-symbolic-matrix/85764.md?page=2)
