Specialize adding/subtracting mixed Upper/LowerTriangular (#56149)
Fixes https://github.com/JuliaLang/julia/issues/56134
After this,
```julia
julia> using LinearAlgebra
julia> A = hermitianpart(rand(4, 4))
4×4 Hermitian{Float64, Matrix{Float64}}:
0.387617 0.277226 0.67629 0.60678
0.277226 0.894101 0.388416 0.489141
0.67629 0.388416 0.100907 0.619955
0.60678 0.489141 0.619955 0.452605
julia> B = UpperTriangular(A)
4×4 UpperTriangular{Float64, Hermitian{Float64, Matrix{Float64}}}:
0.387617 0.277226 0.67629 0.60678
⋅ 0.894101 0.388416 0.489141
⋅ ⋅ 0.100907 0.619955
⋅ ⋅ ⋅ 0.452605
julia> B - B'
4×4 Matrix{Float64}:
0.0 0.277226 0.67629 0.60678
-0.277226 0.0 0.388416 0.489141
-0.67629 -0.388416 0.0 0.619955
-0.60678 -0.489141 -0.619955 0.0
```
This preserves the band structure of the parent, if any:
```julia
julia> U = UpperTriangular(Diagonal(ones(4)))
4×4 UpperTriangular{Float64, Diagonal{Float64, Vector{Float64}}}:
1.0 0.0 0.0 0.0
⋅ 1.0 0.0 0.0
⋅ ⋅ 1.0 0.0
⋅ ⋅ ⋅ 1.0
julia> U - U'
4×4 Diagonal{Float64, Vector{Float64}}:
0.0 ⋅ ⋅ ⋅
⋅ 0.0 ⋅ ⋅
⋅ ⋅ 0.0 ⋅
⋅ ⋅ ⋅ 0.0
```
This doesn't fully work with partly initialized matrices, and would need
https://github.com/JuliaLang/julia/pull/55312 for that.
The abstract triangular methods now construct matrices using
`similar(parent(U), size(U))` so that the destinations are fully
mutable.
```julia
julia> @invoke B::LinearAlgebra.AbstractTriangular - B'::LinearAlgebra.AbstractTriangular
4×4 Matrix{Float64}:
0.0 0.277226 0.67629 0.60678
-0.277226 0.0 0.388416 0.489141
-0.67629 -0.388416 0.0 0.619955
-0.60678 -0.489141 -0.619955 0.0
```
---------
Co-authored-by: Daniel Karrasch <daniel.karrasch@posteo.de>