# \[ANN\] Conjugates.jl

**URL:** https://discourse.julialang.org/t/ann-conjugates-jl/36921
**Category:** Package Announcements
**Created:** [April 2, 2020, 9:51pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921 "2020-04-02T21:51:42Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [April 2, 2020, 9:51pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/1 "2020-04-02T21:51:42Z")

</div>

Edit: The package has been renamed to Conjugates.jl from PlusHC.jl

Here’s a snippet I’ve been using in some code for the past little while that I decided to roll up into a tiny package: [Conjugates.jl](https://github.com/MasonProtter/Conjugates.jl)

```julia
julia> using Conjugates

julia> (1 + im) + hc
2

julia> randn(ComplexF64, 3, 3) + hc
3×3 Hermitian{Complex{Float64},Array{Complex{Float64},2}}:
   0.86551+0.0im 1.38105+0.506667im -0.761315-0.211322im
   1.38105-0.506667im 0.826828+0.0im -0.764402-0.579842im
 -0.761315+0.211322im -0.764402+0.579842im -0.629772+0.0im

julia> randn(ComplexF64, 3, 3) * tp
3×3 Symmetric{Complex{Float64},Array{Complex{Float64},2}}:
   2.43339+0.0im -1.48393-0.247791im 0.0867097+0.53651im
  -1.48393-0.247791im 1.38745+0.0im 0.0606936-0.470711im
 0.0867097+0.53651im 0.0606936-0.470711im 2.14239+0.0im

```

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

If you feel a burning desire for this, you can do

```julia
]add Conjugates

```

at the repl to get the package.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 3, 2020, 5:25am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/2 "2020-04-03T05:25:41Z")

</div>

I did something similar for AA' in

> **[GitHub - tpapp/SymmetricProducts.jl: Calculate A\*A', wrapping the result in...](https://github.com/tpapp/SymmetricProducts.jl)**
>
> Calculate A\*A', wrapping the result in the narrowest type. - GitHub - tpapp/SymmetricProducts.jl: Calculate A\*A', wrapping the result in the narrowest type.

(unregistered), but I like your approach better.

It would be great if the package contained a placeholder for products with the transpose — perhaps generalizing the package name a bit.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [April 3, 2020, 6:02am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/3 "2020-04-03T06:02:12Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [April 3, 2020, 6:52am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/4 "2020-04-03T06:52:58Z")

</div>

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

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

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [April 3, 2020, 7:25am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/5 "2020-04-03T07:25:27Z")

</div>

I had a related idea in [[1]](https://github.com/JuliaLang/julia/issues/23919#issuecomment-441829549). For some of these operation, their _formula_ is almost the clearest name for the operation it self. I prefer

```julia
x + x'
A*A'
α*A*B + β*C

```

over

```julia
addhc(x)
symprod(A)
addmul(α, A, B, β, C)

```

So a macro for “speaking function names”

```julia
@call C = α*A*B + β*C

```

expanding to a canonical function name and call

```julia
var"_1 = _2 * _3 * _4 + _5 * _1"(C, α, A, B, β, C)

```

would be nice. `+ hc` avoids that issue in a different way, nice!

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 3, 2020, 7:31am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/6 "2020-04-03T07:31:25Z")

</div>

> [@Per](#):
>
> This would be type piracy, since both `adjoint` and `+` are in `Base` , so even better would be to also make it a PR there.

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

```julia
x + ADJOINT
x * ADJOINT
ADJOINT * x

```

etc.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [April 3, 2020, 9:15am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/7 "2020-04-03T09:15:09Z")

</div>

It could, but I would _love_ to have this in Base.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [April 3, 2020, 9:25am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/8 "2020-04-03T09:25:03Z")

</div>

Also: The name `Adjoint` is already exported by `LinearAlgebra`.

---

<div class="post-metadata">

### Author: ![francesco.alemanno](https://avatars.discourse-cdn.com/v4/letter/f/e8c25b/32.png) [@francesco.alemanno](https://discourse.julialang.org/u/francesco.alemanno)
#### Post date: [April 3, 2020, 11:55am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/9 "2020-04-03T11:55:18Z")

</div>

@Mason this is lovely!

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [April 3, 2020, 7:43pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/10 "2020-04-03T19:43:52Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [April 3, 2020, 7:49pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/11 "2020-04-03T19:49:10Z")

</div>

> [@Per](#):
>
> If I may bikeshed a little: How about using `adjoint` instead of `hc` ? Something like

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`

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [April 3, 2020, 8:02pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/12 "2020-04-03T20:02:39Z")

</div>

Maybe it’d be kind of nice to use `◻'` or something?

```julia
struct Hole end
const ◻ = Hole()
Base.adjoint(::Hole) = hc

julia> (1 + im) + ◻'
2

```

---

<div class="post-metadata">

### Author: ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)
#### Post date: [April 3, 2020, 9:18pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/13 "2020-04-03T21:18:23Z")

</div>

> [@tkf](#):
>
> `◻`

This is also a symbol used for the [d’Alembert operator](https://en.wikipedia.org/wiki/D%27Alembert_operator), so probably not that symbol

---

<div class="post-metadata">

### Author: ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)
#### Post date: [April 3, 2020, 9:29pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/14 "2020-04-03T21:29:13Z")

</div>

is there anyway to get the dagger in Julia?

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [April 3, 2020, 9:30pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/15 "2020-04-03T21:30:45Z")

</div>

`\dagger` is reserved syntax.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [April 4, 2020, 10:19am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/16 "2020-04-04T10:19:14Z")

</div>

Generalizing the the idea of @tkf a bit:

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

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 5, 2020, 6:33am UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/17 "2020-04-05T06:33:30Z")

</div>

> [@Per](#):
>
> Also: The name `Adjoint` is already exported by `LinearAlgebra` .

I was suggesting that the constant `ADJOINT` is used. The API does not need to have the type itself exported, which could be anything.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [April 7, 2020, 4:47pm UTC](https://discourse.julialang.org/t/ann-conjugates-jl/36921/18 "2020-04-07T16:47:39Z")

</div>

Okay, conjugates is now on the general registry!
