I recently ran into something that should be straight forward, but seems to be incredibly complex.

If I define some function,


I wish to take the derivative of the complex conjugate. I have found some workarounds, such as here.

excluded=OptionValue[SystemOptions[], "DifferentiationOptions"->"ExcludedFunctions"];

Conjugate /: D[Conjugate[f_], x__] := Conjugate[D[f, x]]

However, let's say I choose the variable to differentiate to be the complex conjugate. If I set y to some constant

D[Conjugate[f[x, 1]], Conjugate[x]] (*1*)

I get the desired result. However, if I set y as a variable

 D[Conjugate[f[x, y]], Conjugate[x]] (*0*)

I get the wrong result, while

  D[Conjugate[f[x, y]], x] (*1*)

It appears that when I have two or more variables, the result doesn't work because the conjugate isn't expanded.I have used the FunctionExpand function, which yields the correct results, but I am more interested in why the disconnect occurs

  • $\begingroup$ This is also (1) D[Conjugate[f[x, 2 y]], Conjugate[x]]. Have you considered something line f[x_, y_] := Cos[x] + Sin[y]? It looks like results are pretty much wrong anyways. $\endgroup$ Commented May 30, 2018 at 20:51

2 Answers 2


You could use my ComplexD function, which I repeat here (slightly modified):

ComplexD[expr_, z__] := With[
    nc = NonConstants -> Union @ Cases[{z},
        s_Symbol | Conjugate[s_Symbol] | {s_Symbol | Conjugate[s_Symbol], _} :> s
    old = OptionValue[
        "DifferentiationOptions" -> "ExcludedFunctions"]

        With[{new = Join[old, {Abs, Conjugate}]},
            SetSystemOptions["DifferentiationOptions"->"ExcludedFunctions" -> new]
        Unprotect[Conjugate, Abs];
        Conjugate /: D[w_, Conjugate[w_], nc] := 0;
        Conjugate /: D[Conjugate[f_], w_, nc] := Conjugate[D[f, Conjugate[w], nc]];
        Abs /: D[Abs[f_], w_, nc] := D[Conjugate[f]f, w, nc]/(2 Abs[f]),

        D[expr, z, nc],

        SetSystemOptions["DifferentiationOptions" -> "ExcludedFunctions" -> old];
        Conjugate /: D[w_, Conjugate[w_], nc] =.;
        Conjugate /: D[Conjugate[f_], w_, nc] =.;
        Abs /: D[Abs[f_], w_, nc] =.;
        Protect[Conjugate, Abs];


ComplexD[Conjugate[x+y], Conjugate[x]]
ComplexD[Conjugate[Sin[x y]], Conjugate[x]]


Conjugate[y Cos[x y]]

f[x_, y_] := x + y

It just needs a look at the return value of

Conjugate[f[x, y]]

Conjugate[x + y]

to see why D[Conjugate[f[x, y]], Conjugate[x]] returns 0. There is no Conjugate[x] involved in the expression. When calling D[arg1, arg2], Mathematica has to look for literal occurrences of arg2 within arg1.

So, the problem is that Conjugate did propagate over Plus[x,y]. In this case, we can enforce that with Distribute:

Distribute@Conjugate[f[x, y]]
D[Distribute@Conjugate[f[x, y]], Conjugate[x]]

Conjugate[x] + Conjugate[y]


If you add the following rule to Conjugate, then it will always try to propagate into holomorphic functions

Conjugate[f_[x__]] := f[Sequence @@ Conjugate /@ {x}] /; ComplexAnalysis`HolomorphicQ[f]

Now we can even deal with the following:

D[Conjugate[Sin[x y]], Conjugate[x]]

Conjugate[y] Cos[Conjugate[x] Conjugate[y]]


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.