I trying to modify the behaviour of the built-in Conjugate[] operator on a particular function I have defined, to take into account that some of its variables are real.

ClearAll[f];
f /: Conjugate[f[k_]] := Conjugate[F[r]] Exp[I k r]
f[k_] := F[r] Exp[-I k r]

The problem with using UpValues in this way is that the DownValues for f[k] are evaluated before, resulting in:

Conjugate[f[k]]=Exp[I Conjugate[k r]] Conjugate[F[r]]

Using non-standard evaluation seems to do the trick

Conjugate[Unevaluated[f[k]]]=Exp[I k r] Conjugate[F[r]]

However, I want to use my function inside expressions like

f[k1] + f[k2] + Conjugate[f[k3]]

without having to manually replace f[_] by Unevaluated[f[_]].

-

One possibility would be to define a new Conjugate function, myConjugate, the behaves in the same way as Conjugate, except when it encounters a phase of the type Exp[+(-)I k r], it transforms it to Exp[-(+)I k r], leaving k and r as real variables.

Another possibility (and the one I ended up using) is to go along the lines of this stack overflow answer and use UpValues to explicitly define k and r as being real:

ClearAll[makeReal];
makeReal[a__Symbol] := (# /: Conjugate[#] := #) & /@ List[a]

makeReal[k, r]

Then one gets the expected

Conjugate[F[r] Exp[-I k r]]= Exp[I k r] Conjugate[F[r]]
-
I always find it amusing when my old answers resurface. :) – rcollyer Jun 18 '13 at 18:43
This is a wonderful resolution to get rid of the annoying Conjugate! – Leo Fang Jul 3 '13 at 16:09

I don't think you need to define upvalues for f nor for your own myConjugate function. Using your definitions:

ClearAll[F,f];
f[k_] := F[r] Exp[-I k r]

all you need to do is tell Conjugate to distribute over addition and then Refine it by letting Mathematica know which variables are real. So, say you have an expression:

Conjugate[f[k1] + f[k2] - Conjugate[f[k3]]]

by calling

Assuming[{k1 ∈ Reals, k2 ∈ Reals,
k3 ∈  Reals, r ∈ Reals}, Refine[Distribute /@ %]]

you get the desired (?)

E^(I k1 r) Conjugate[F[r]] + E^(I k2 r) Conjugate[F[r]] -
E^(-I k3 r) F[r]

If F is behaving with a known pattern under conjugation you can account for it by changing its UpValues, i.e.

F /: Conjugate[F[r_]] := F[-r]

and the above would still work.

-
I am aware that I can use assumptions, but this is not what I want. – Andrei May 17 '13 at 9:26
Can you please edit the question to explain a little better what you want then? I can edit my answer to include a myConjugate function that ignores phases but you need to be more specific as to how you want it to behave. – gpap May 17 '13 at 9:41
Thanks for accepting but if my answer didn't answer your question the way you intended you really don't have to accept it! In fact there is no harm (I'd say it's encouraged) to write down your own answer and accept it if nobody else comes up with something better within some time. It seems you can write an answer incorporating both your edits. – gpap May 17 '13 at 11:18
Ok @gpap, I followed your advice, hope you don't mind! :) – Andrei May 19 '13 at 17:58