15

Wirtinger derivatives ( also called Cauchy operators) in complex analysis are widely used tools. They are defined in the case of one dimensional complex plane as follows

$$\frac{\partial}{\partial z}=\frac12\left(\frac{\partial}{\partial x}-i\frac{\partial}{\partial y}\right),\quad \frac{\partial}{\partial \bar{z}}=\frac12\left(\frac{\partial}{\partial x}+i\frac{\partial}{\partial y}\right)$$

Where $z=x+i y$ and x,y are real variables. Apparently Mathematica does not support directly these operators. For instance, as it is pointed in my question; Defining a complex partial differential operator, D[ , ] don't support a complex argument #2.

What is the best way to generalize D such that it supports complex variable z = x + I y, such that it is homogeneous with derivatives of the real part x and imaginary part y in a fashion where results of formal computations can be given in terms of x and y, or in terms of z and Conjugate[z]


Update :

Following the suggestion of @xzczd, let me articulate about the concept I have in my head. But the details here are not all requirements for an answer on my question above. It is indeed the converse. As a beginner on Mathematica, any insight can be very helpful for me

Let denote by Dc The wanted generalization of D. The first argument of Dc will be a complex function, expressed in term of a variable z := x + I y. The second argument will be x OR y OR z OR Conjugate[z] (in general real or complex). The third argument will contain a rule of the form Coordinates->"Complex" or "real" which depends of the wanted output whether in terms of $\partial_z$ and $\partial_{\bar{z}}$ or in terms of $\partial_x$ and $\partial_{y}$. note that $\partial_z$ and $\partial_{\bar{z}}$ are defined by the formulas given above. Let's suppose that "Complex" is the default value.

Examples: (I denote by === the output, I use some TeX code, hope it is clear)

Basic identities

Dc[z,z] === 1
Dc[Conjugate[z],z] === 0
Dc[Abs[z],Conjugate[z]] === z
Dc[x,z] === 1/2

General identities

Dc[f[z],z] === \partial_z[f[z]]
Dc[f[z],z,Coordinates->"Real"] === 1/2 \partial_x[f[z]] - 1/2 I \partial_y[f[z]]
x Dc[f[z],x] + y Dc[f[z],y] === z\partial_z[f[z]] + \bar{z} \partial_{\bar{z}} [f[z]]

I hope it is more clear now, and the concept makes some sense. Let me know if you need further explanations.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Aymane Fihadi
  • 363
  • 1
  • 9

2 Answers2

11

Here is one idea for supporting derivatives with respect to $z$ and $z^*$. First, we need to use SetSystemOptions to avoid differentiating Conjugate/Abs. Something like:

old = "ExcludedFunctions" /. 
    ("DifferentiationOptions" /. SystemOptions["DifferentiationOptions"]);
SetSystemOptions["DifferentiationOptions" -> 
    "ExcludedFunctions" -> Union@Join[old,{Abs, Conjugate}]
];

Then, we need to teach D how to differentiate Conjugate/Abs the way we want. To do this we need to make use of the NonConstants option of D so that derivatives of functions with a hidden dependence on Conjugate[z] with respect to Conjugate[z] do not automatically evaluate to 0.

Unprotect[Conjugate, Abs];
Conjugate /: D[z, Conjugate[z], NonConstants->{z}] := 0;
Conjugate /: D[Conjugate[f_], w_, NonConstants->{z}] := Conjugate[D[f, Conjugate[w], NonConstants->{z}]];
Abs /: D[Abs[f_], w_, NonConstants->{z}] := 1/(2Abs[f]) D[Conjugate[f]f, w, NonConstants->{z}]

Without the NonConstants->{z} option, something like D[Abs[z]^2, Conjugate[z]] will evaluate to 0.

D[Abs[z]^2, Conjugate[z]]
D[Abs[z]^2, Conjugate[z], NonConstants->{z}]

0

z

Here are some examples:

D[z, z, NonConstants->{z}]
D[Conjugate[z], z, NonConstants->{z}]
D[Abs[z]^2, Conjugate[z],NonConstants->{z}]
D[(z+Conjugate[z])/2, z, NonConstants->{z}]

1

0

z

1/2

It might be convenient to create a function to package up everything up:

ComplexD[expr_, z__] := With[
    {
    v = Union @ Cases[{z}, s_Symbol | Conjugate[s_Symbol] | {s_Symbol | Conjugate[s_Symbol], _} :> s],
    old = "ExcludedFunctions" /. ("DifferentiationOptions" /. SystemOptions["DifferentiationOptions"])
    },
    Internal`WithLocalSettings[
        SetSystemOptions["DifferentiationOptions" -> "ExcludedFunctions" -> Join[old, {Abs, Conjugate}]];
        Unprotect[Conjugate, Abs];
        Conjugate /: D[w_, Conjugate[w_], NonConstants->v] := 0;
        Conjugate /: D[Conjugate[f_], w_, NonConstants->v] := Conjugate[D[f, Conjugate[w], NonConstants->v]];
        Abs /: D[Abs[f_], w_, NonConstants->v] := 1/(2Abs[f]) D[Conjugate[f]f, w, NonConstants->v],

        D[expr, z, NonConstants->v],

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

The function ComplexD will temporarily change the system options and give Conjugate/Abs the desired D behavior. An example:

ComplexD[Conjugate@Sin[z Conjugate[z]^2], z]
ComplexD[Exp[Conjugate[w] z], Conjugate[w]] 

2 z Conjugate[z] Cos[z^2 Conjugate[z]]

E^(z Conjugate[w]) z

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
0
Dw[f_, var_, RealVar_, CmplxVar_] := Module[
  {fn},
  fn = ComplexExpand[Simplify[f /. {var -> RealVar + CmplxVar*I}, Assumptions -> {RealVar \[Element] Reals, CmplxVar \[Element] Reals}]];
  1/2 {
    Simplify[ComplexExpand[D[fn, RealVar] - I*D[fn, CmplxVar]], Assumptions -> {RealVar \[Element] Reals, CmplxVar \[Element] Reals}],
    Simplify[ComplexExpand[D[fn, RealVar] + I*D[fn, CmplxVar]], Assumptions -> {RealVar \[Element] Reals, CmplxVar \[Element] Reals}]
  }
]

This will get you both Wirtinger derivatives as a list. Var sets the complex variable (often z) RealVar is the real part variable of z (often x or a) CmplxVar is the complex part variable of z (often y or b) -> z = a + bi = x + yi

someone
  • 1
  • 1
  • BTW You might switch simplify and complexExpand if you'd like real and imaginary parts to be visually separated. – someone Nov 14 '17 at 17:52