# Using superscript ⁻¹ as a postfix operator for inv?

Nice. I see they’re using the latest unicode.
Does anyone know if it will be possible (an supported by Julia) to express negative one “-1” as a superscript w/ unicode?
X^{-1} is a lot leaner than inv(X) or X^-1

1 Like

Slightly off topic, but the real answer is to never use inv. It is almost never the right answer.

7 Likes

Off-topic, but you can already do that with X\^-\^1 but the ⁻¹ is part of the variable name so you can write  X⁻¹ = [...], same as the more common σ² = .... It would be a breaking change to make these into operators, and the idea was previously rejected: https://github.com/JuliaLang/julia/issues/9806 .

5 Likes

See an article claiming that inv(A)'s bad reputation is not deserved. At the end of section 2, the author writes:

It appears that this easy-to-derive but loose bound gave the matrix inverse its bad reputation.

2 Likes

More serious is the expense, IMO.

Solving a linear system by Gaussian elimination is a constant factor 4 faster than finding the inverse [Trefethen, Numerical Linear Algebra].

2 Likes

The original author did not suggest to use inv() for solving linear systems. There are perfectly valid reasons for inverting matrices other than solving linear systems. E.g. if you need to compute its trace, or you need the inverse of a Hessian as a covariance matrix in a likelihood optimization, or a Fisher information matrix, or to compute the projection matrix on a column space, or … whatever.

Also, inv() is not a matrix-thing, it can equally well be used for things like finite fields, where its implementation can be via power operators or a generalized gcd.

Personally I do not like filling programs with utf8. It looks nice, but the next programmer may not be able to find all the funny symbols on the keyboard (like guessing that å is written \aa, which every Dane or Norwegian born before 1870 will easily guess). Or it may even be ambiguous because the glyphs look similar for two different utf8-symbols. Like m and \ttm looks different with my current font setup, but looks exactly the same with another font setup, and will of course be two different variables. And things like \epsilon in the ess julia mode in emacs is \varepsilon in the REPL.

4 Likes

I think Unicode in text files is great (when used within reason, as all things). Mostly, because it can significantly improve readability, and that is more important than writeability.

No guessing required!

help?> å
"å" can be typed by \aa<tab>


Well, that’s if you can copy-paste from the source of course. But if you’re looking at code in a picture or on paper, it doesn’t matter anyway, you can choose the symbols when writing your own code, as usual.

Totally agree. In this case Unicode actually hurts readability. That’s where “within reason” comes in. Note that this has always been a problem, not specific to Unicode symbols: maybe I and l, or O and 0 are easily distinguishable in your font but not in your collaborator’s bad font. But Unicode can definitely take this problem to a new level.

That’s a rather minor issue… Surely Emacs has a mode for writing Julia code using the same symbol names as in the REPL? In any case it is unfortunate that Emacs binds \epsilon to ϵ in the so-called “TeX input mode”.

1 Like

I am aware that both countries have outstanding life expectancy, but I would guess that the set of such people is empty in 2020.

4 Likes

If ⁻¹  is an operator, you can’t use it as part of a variable name:

X⁻¹ = inv(X)
use(X⁻¹ )
reuse(X⁻¹ )
and_again(X⁻¹ )


vs

X_inv = X⁻¹
use(X_inv)
reuse(X_inv)
and_again(X_inv)


In general I think it is more valuable to be able to use unicode super/subscripts as part of variable names, then for operator names.

2 Likes

As a side note, I learned typewriting quite some years ago, on a real typewriter. It didn’t have 0 and 1, to save mechanical costs. It was quite common at the time. We were instructed to write O and l instead. It created some unexpected problems in the computer science course the following year, it turned out that the ROM based Basic-interpreter differentiated between 0 and O, and 1 and l.

2 Likes

You can actually do this with no language changes if you’re willing to write (A)⁻¹ rather than A⁻¹. Here’s an example at the REPL:

julia> begin
struct Inverter end
const ⁻¹ = Inverter()
Base.:(*)(A, ::Inverter) = inv(A)
end

julia> A = rand(3,3)
3×3 Array{Float64,2}:
0.51549   0.0616877  0.530502
0.783366  0.0598045  0.697045
0.381722  0.833891   0.632847

julia> (A)⁻¹
3×3 Array{Float64,2}:
-13.5368    10.0475    0.280811
-5.72129    3.08199   1.4014
15.704    -10.1216   -0.435822

julia> ((A)⁻¹)*A ≈ I(3)
true


This works because (a)b is parsed as a * b:

julia> quote (a)b end
quote
#= REPL[7]:1 =#
a * b
end


so we need only define an object ⁻¹ which when multiplied by A on the left produces inv(A), trivially easy with multiple dispatch.

One could do the same with ² to make an squaring operator if they were unable to stomach reading x^2 or x*x

8 Likes