Writing x + h.c. is pretty common, at least in physics circles, to mean x + x^\dagger, and I often find myself wanting to manually symmetrize expressions in this way, so I figured why not?
hc stands for Hermitian Conjugate, and tp stands for transpose.
Mhm yeah, multiying with the conjugate is often useful too. Maybe I should just rename it something like Conjugates.jl and then have hc And maybe tc or something for transpose, allowing elementary operations like addition, subtraction, multiplication, etc.
This is really nice! (I’ve been writing |> x->x+x', but this is much better.)
If I may bikeshed a little: How about using adjoint instead of hc? Something like
Base.:+(x, ::typeof(adjoint)) = x + x'
I think that somebody who is not a physicist (but is familiar with Julia) would more easily be able to guess what (1 + im) + adjoint does.
(This would be type piracy, since both adjoint and + are in Base, so even better would be to also make it a PR there. Once the PR is accepted, the package would be modified to do nothing for Julia versions where the functionality already exists.)
I think that your proposal is a great idea, but the package might as well just export a singleton Adjoint type with the constant ADJOINT and avoid all these issues. Eg
Okay, to I enlarged the scope of the package a bit, renamed it to Conjugates.jl, added tp which is to transpose as hc is to adjoint and added support for subtraction and multiplication.
I like this, but I didn’t want to commit piracy here, and I strongly suspect that a PR adding this to Base will get shot down, though it may be worth a shot.
I might eventually try adding a macro so that a user can do something like @pirate adjoint transpose to get the methods you suggest put in.
I’m not really a fan of using something like ADJOINT, but if someone is, it’s easy enough to just write const ADJOINT = hc; TRANSPOSE = tp
struct Idem{F}
f::F
end
for f in (:adjoint, :transpose)
@eval Base.$f(id::Idem{typeof(identity)}) = Idem($f)
end
for op in (:+, :*)
@eval Base.$op(x, id::Idem{F}) where {F} = $op(x, id.f(x))
@eval Base.$op(id::Idem{F}, x) where {F} = $op(id.f(x), x)
end
const idem = Idem(identity)
const hc = idem'
const tp = transpose(idem)
The lists of unary and binary operators could be extended as needed.