458 views

Skip to first unread message

Nov 13, 2014, 12:19:07 AM11/13/14

to sage-...@googlegroups.com

Hi,

With Sage 6.3, I am getting:

sage: abs(x).diff(x)

x/abs(x)

sage: abs(I*x).diff(x)

-x/abs(I*x)

But abs(I*x) == abs(x). So also abs(x).diff(x) and abs(I*x).diff(x)

must be the same. But in the first case we get x/abs(x), and in the

second we got -x/abs(x).

In SymPy, the answer is:

In [1]: abs(x).diff(x)

Out[1]:

d d

re(x)⋅──(re(x)) + im(x)⋅──(im(x))

dx dx

─────────────────────────────────

│x│

In [2]: x = Symbol("x", real=True)

In [3]: abs(x).diff(x)

Out[3]: sign(x)

In [4]: abs(I*x).diff(x)

Out[4]: sign(x)

In [26]: var("x")

Out[26]: x

Which seems all correct --- in the complex case [1] we get a little

messy expression, but a correct one. For a real case, we get the

correct answer.

In Wolfram Alpha, the answer of abs(I*x).diff(x) is x/abs(x):

http://www.wolframalpha.com/input/?i=Diff%5BAbs%5Bi*x%5D%2C+x%5D

Which is only correct for real "x", but at least it is correct for

this special case.

The Sage result seems wrong for any "x".

Ondrej

With Sage 6.3, I am getting:

sage: abs(x).diff(x)

x/abs(x)

sage: abs(I*x).diff(x)

-x/abs(I*x)

But abs(I*x) == abs(x). So also abs(x).diff(x) and abs(I*x).diff(x)

must be the same. But in the first case we get x/abs(x), and in the

second we got -x/abs(x).

In SymPy, the answer is:

In [1]: abs(x).diff(x)

Out[1]:

d d

re(x)⋅──(re(x)) + im(x)⋅──(im(x))

dx dx

─────────────────────────────────

│x│

In [2]: x = Symbol("x", real=True)

In [3]: abs(x).diff(x)

Out[3]: sign(x)

In [4]: abs(I*x).diff(x)

Out[4]: sign(x)

In [26]: var("x")

Out[26]: x

Which seems all correct --- in the complex case [1] we get a little

messy expression, but a correct one. For a real case, we get the

correct answer.

In Wolfram Alpha, the answer of abs(I*x).diff(x) is x/abs(x):

http://www.wolframalpha.com/input/?i=Diff%5BAbs%5Bi*x%5D%2C+x%5D

Which is only correct for real "x", but at least it is correct for

this special case.

The Sage result seems wrong for any "x".

Ondrej

Nov 13, 2014, 2:18:02 AM11/13/14

to sage-...@googlegroups.com

possibly related to http://trac.sagemath.org/ticket/12588 ?

Regards, CH

Univ.-Prof. Dr. Clemens Heuberger Alpen-Adria-Universität Klagenfurt

Institut für Mathematik, Universitätsstraße 65-67, 9020 Klagenfurt, Austria

Tel: +43 463 2700 3121 Fax: +43 463 2700 99 3121

clemens....@aau.at http://wwwu.aau.at/cheuberg

Nov 13, 2014, 10:29:41 AM11/13/14

to sage-...@googlegroups.com

Yes. Note also here:

http://mathworld.wolfram.com/AbsoluteValue.html

which says that complex derivative of d|z|/dz does not exist, as

Cauchy-Riemann equations do not hold for Abs(z). And:

"As a result of the fact that computer algebra programs such as

Mathematica generically deal with complex variables (i.e., the

definition of derivative always means complex derivative), d|z|/dz

correctly returns unevaluated by such software."

So perhaps SymPy and Sage should return Derivative(Abs(x), x). Only

when user specifies that "x" is real, only then we can differentiate.

Ondrej

> --

> You received this message because you are subscribed to the Google Groups "sage-devel" group.

> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.

> To post to this group, send email to sage-...@googlegroups.com.

> Visit this group at http://groups.google.com/group/sage-devel.

> For more options, visit https://groups.google.com/d/optout.

http://mathworld.wolfram.com/AbsoluteValue.html

which says that complex derivative of d|z|/dz does not exist, as

Cauchy-Riemann equations do not hold for Abs(z). And:

"As a result of the fact that computer algebra programs such as

Mathematica generically deal with complex variables (i.e., the

definition of derivative always means complex derivative), d|z|/dz

correctly returns unevaluated by such software."

So perhaps SymPy and Sage should return Derivative(Abs(x), x). Only

when user specifies that "x" is real, only then we can differentiate.

Ondrej

> You received this message because you are subscribed to the Google Groups "sage-devel" group.

> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.

> To post to this group, send email to sage-...@googlegroups.com.

> Visit this group at http://groups.google.com/group/sage-devel.

> For more options, visit https://groups.google.com/d/optout.

Nov 13, 2014, 12:16:36 PM11/13/14

to sage-devel

It has always seemed very inconvenient to me that "computer algebra

programs such as Mathematica" choose to define derivative as

complex-derivative. I believe a reasonable alternative is what is

known as a Wirtinger derivative. Wirtinger derivatives exist for all

continuous complex-valued functions including non-holonomic functions

and permit the construction of a differential calculus for functions

of complex variables that is analogous to the ordinary differential

calculus for functions of real variables

http://en.wikipedia.org/wiki/Wirtinger_derivatives

Wirtinger derivatives come in conjugate pairs but we have

f(x).diff(conjugate(x)) = conjugate(conjugate(f(x).diff(x))

so we really only need one derivative given an appropriate conjugate

function. The Cauchy-Riemann equations reduce to

f(x).diff(conjugate(x)) = 0

I also like that abs is related to the sgn function

abs(x).diff(x) = x/abs(x)

This is consistent with

abs(x)=sqrt(x*conjugate(x))

The Wirtinger derivative of abs(x) is 1/2 x/abs(x). Its total

Wirtinger derivative is x/abs(x).

I have implemented conjugate and Wirtinger derivatives in FriCAS

http://axiom-wiki.newsynthesis.org/SandBoxWirtinger

Unfortunately I have not yet been able to convince the FriCAS

developers of the appropriateness of this approach. I would be happy

to find someone with whom to discuss this further, pro and con. The

discussion on the FriCAS email list consisted mostly of the related

proper treatment of conjugate without making explicit assumptions

about variables.

Regards,

Bill Page.

programs such as Mathematica" choose to define derivative as

complex-derivative. I believe a reasonable alternative is what is

known as a Wirtinger derivative. Wirtinger derivatives exist for all

continuous complex-valued functions including non-holonomic functions

and permit the construction of a differential calculus for functions

of complex variables that is analogous to the ordinary differential

calculus for functions of real variables

http://en.wikipedia.org/wiki/Wirtinger_derivatives

Wirtinger derivatives come in conjugate pairs but we have

f(x).diff(conjugate(x)) = conjugate(conjugate(f(x).diff(x))

so we really only need one derivative given an appropriate conjugate

function. The Cauchy-Riemann equations reduce to

f(x).diff(conjugate(x)) = 0

I also like that abs is related to the sgn function

abs(x).diff(x) = x/abs(x)

This is consistent with

abs(x)=sqrt(x*conjugate(x))

The Wirtinger derivative of abs(x) is 1/2 x/abs(x). Its total

Wirtinger derivative is x/abs(x).

I have implemented conjugate and Wirtinger derivatives in FriCAS

http://axiom-wiki.newsynthesis.org/SandBoxWirtinger

Unfortunately I have not yet been able to convince the FriCAS

developers of the appropriateness of this approach. I would be happy

to find someone with whom to discuss this further, pro and con. The

discussion on the FriCAS email list consisted mostly of the related

proper treatment of conjugate without making explicit assumptions

about variables.

Regards,

Bill Page.

Nov 13, 2014, 12:51:40 PM11/13/14

to sage-devel

On 13 November 2014 12:16, Bill Page <bill...@newsynthesis.org> wrote:

>

> The Wirtinger derivative of abs(x) is 1/2 x/abs(x). Its total

> Wirtinger derivative is x/abs(x).

>

Sorry, I should have written that the Wirtinger derivative of abs(x) is
>

> The Wirtinger derivative of abs(x) is 1/2 x/abs(x). Its total

> Wirtinger derivative is x/abs(x).

>

1/2 conjugate(x)/abs(x)

Bill.

Nov 13, 2014, 2:47:03 PM11/13/14

to sage-...@googlegroups.com

We had a similar problem with the complex derivative of logarithms in combination with the complex conjugate, where I also the

use of Wirtinger Operators would solve the problem: https://groups.google.com/forum/?hl=en#!topic/sage-support/bEMPMEYeZKU

Having them in Sage would be a great achievement!

Although this has some sense in complex analysis one should be careful with 'deriving' the absolute value, since

it results in the weak derivative ( http://en.wikipedia.org/wiki/Weak_derivative) , which is in a broader sense the derivative in the distribution sense.

Thus we have infinite possible derivatives

With this expression it is indirectly forbidden to asign a specific value to the unspecified value at zero:

sage: f = abs(x).diff(x)

sage: f(x=0)

---------------------------------------------------------------------------

ValueError Traceback (most recent call last)

<ipython-input-14-615bbebcb37c> in <module>()

----> 1 f(x=Integer(0))

/home/maldun/sage/sage-6.3/local/lib/python2.7/site-packages/sage/symbolic/expression.so in sage.symbolic.expression.Expression.__call__ (build/cythonized/sage/symbolic/expression.cpp:21933)()

/home/maldun/sage/sage-6.3/local/lib/python2.7/site-packages/sage/symbolic/ring.so in sage.symbolic.ring.SymbolicRing._call_element_ (build/cythonized/sage/symbolic/ring.cpp:8493)()

/home/maldun/sage/sage-6.3/local/lib/python2.7/site-packages/sage/symbolic/expression.so in sage.symbolic.expression.Expression.substitute (build/cythonized/sage/symbolic/expression.cpp:21183)()

ValueError: power::eval(): division by zero

This is in some sense good, since we don't have to care about the derivative at zero,

but in an other sense it is not so good, since the subdifferential ∂abs(0) = [0,1] is a bounded and with this definition one could come to the false conclusion that abs(x)

has a pole, althoug by taking limits one can easily see that it should be bounded at zero.

For symbolic purposes, of course one could live on with this.

Nov 13, 2014, 2:51:48 PM11/13/14

to sage-...@googlegroups.com

The only clean solution for this behaviour would be a warning e.g: "Warning: This Identity holds only almost everywhere!"

But I don't know if it's worth the effort ...

Nov 13, 2014, 3:04:14 PM11/13/14

to sage-...@googlegroups.com

This is in some sense good, since we don't have to care about the derivative at zero,but in an other sense it is not so good, since the subdifferential ∂abs(0) = [0,1] is a bounded and with this definition one could come to the false conclusion that abs(x)has a pole, althoug by taking limits one can easily see that it should be bounded at zero.

Sorry I meant ∂abs(0) = [-1,1] ...

And another thing to add: I think the only clean solution could be a warning like: "Warning: This is not a derivative in the classical sense!"

But I don't know if this is really worth the effort ...

Nov 13, 2014, 4:00:24 PM11/13/14

to sage-...@googlegroups.com

Hi Bill,

Thanks for your email! I haven't talked to you in a long time.

Literally just today I learned about Wirtinger derivatives. The

wikipedia page is *really* confusing to me. It took me a while to

realize, that Wirtinger derivatives is simply the derivative with

respect to z or conjugate(z). I.e.

z = x + i*y

conjugate(z) = x - i*y

From this it follows:

x = 1/2*(z + conjugate(z))

y = i/2*(-z+conjugate(z))

Then I take any function and write it in terms of z and conjugate(z),

some examples:

|z| = sqrt(z*conjugate(z))

Re z = x = 1/2 * (z + conjugate(z))

z^2 = (x+i*y)^2

And then I simply differentiate with respect to z or conjugate(z).

This is called the Wirtinger derivative. So:

d|z|/dz = d sqrt(z*conjugate(z)) / dz = 1/2*conjugate(z) / |z|

As you said, the function is analytic if it doesn't functionally

depend on conjugate(z), as can be shown easily. So |z| or Re z are not

analytic, while z^2 is. If the function is analytic, then df/d

conjugate(z) = 0, and df/dz is the complex derivative. Right?

So for analytic functions, Wirtinger derivative gives the same answer

as Mathematica. For non-analytic functions, Mathematica leaves it

unevaluated, but Wirtinger derivative gives you something.

How do you calculate the total Wirtinger derivative? How is that defined?

Because I would like to get

d|x| / d x = x / |x|

for real x. And I don't see currently how is this formula connected to

Wirtinger derivatives. Finally, the derivative operator in a CAS could

return Wirtinger derivatives, I think it's a great idea, if somehow we

can recover the usual formula for abs(x) with real "x".

What are the cons of this approach?

Ondrej

Literally just today I learned about Wirtinger derivatives. The

wikipedia page is *really* confusing to me. It took me a while to

realize, that Wirtinger derivatives is simply the derivative with

respect to z or conjugate(z). I.e.

z = x + i*y

conjugate(z) = x - i*y

From this it follows:

x = 1/2*(z + conjugate(z))

y = i/2*(-z+conjugate(z))

Then I take any function and write it in terms of z and conjugate(z),

some examples:

|z| = sqrt(z*conjugate(z))

Re z = x = 1/2 * (z + conjugate(z))

z^2 = (x+i*y)^2

And then I simply differentiate with respect to z or conjugate(z).

This is called the Wirtinger derivative. So:

d|z|/dz = d sqrt(z*conjugate(z)) / dz = 1/2*conjugate(z) / |z|

As you said, the function is analytic if it doesn't functionally

depend on conjugate(z), as can be shown easily. So |z| or Re z are not

analytic, while z^2 is. If the function is analytic, then df/d

conjugate(z) = 0, and df/dz is the complex derivative. Right?

So for analytic functions, Wirtinger derivative gives the same answer

as Mathematica. For non-analytic functions, Mathematica leaves it

unevaluated, but Wirtinger derivative gives you something.

How do you calculate the total Wirtinger derivative? How is that defined?

Because I would like to get

d|x| / d x = x / |x|

for real x. And I don't see currently how is this formula connected to

Wirtinger derivatives. Finally, the derivative operator in a CAS could

return Wirtinger derivatives, I think it's a great idea, if somehow we

can recover the usual formula for abs(x) with real "x".

What are the cons of this approach?

Ondrej

Nov 13, 2014, 7:24:05 PM11/13/14

to sage-...@googlegroups.com

(i.e. it is analytic),

then the complex derivative f'(z) = \partial f / \partial x. So to

calculate a complex derivative

with respect to z=x+i*y, we just need to differentiate with respect to x.

It can be shown, that the Wirtinger derivatives df/dz is equal to

\partial f / \partial x for analytic functions,

i.e. when df/d conjugate(z) = 0.

So in a CAS, we can simply define the derivative f'(z) as \partial f /

\partial x for any function, even if it doesn't have a complex

derivative.

For any function we can show that:

\partial f / \partial x = d f / d z + d f / d conjugate(z)

Bill, is this what you call the "total Wirtinger derivative"?

For example, for |z| we get:

|z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

Using our definition, this holds for any complex "z". Then, if "z" is

real, we get:

|z|' = z / |z|

Which is exactly the usual real derivative. Bill, is this what you had

in mind? That a CAS could return the derivative of abs(z)

as Re(z) / abs(z) ?

Ondrej

Nov 13, 2014, 8:12:55 PM11/13/14

to sage-devel

On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> As you said, the function is analytic if it doesn't functionally

>> depend on conjugate(z), as can be shown easily. So |z| or

>> Re z are not analytic, while z^2 is. If the function is analytic,

>> then df/d conjugate(z) = 0, and df/dz is the complex derivative.

>> Right?

>

Yes. In my email I notice that I wrote "holonomic" but what I meant
> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> As you said, the function is analytic if it doesn't functionally

>> depend on conjugate(z), as can be shown easily. So |z| or

>> Re z are not analytic, while z^2 is. If the function is analytic,

>> then df/d conjugate(z) = 0, and df/dz is the complex derivative.

>> Right?

>

was "holomorphic". Complex-analytic functions are holomorphic and

vice-versa.

> ...

> So in a CAS, we can simply define the derivative f'(z) as

> \partial f / \partial x for any function, even if it doesn't have a

> complex derivative.

Yes.
> \partial f / \partial x for any function, even if it doesn't have a

> complex derivative.

> For any function we can show that:

>

> \partial f / \partial x = d f / d z + d f / d conjugate(z)

>

> Bill, is this what you call the "total Wirtinger derivative"?

>

> For example, for |z| we get:

>

> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>

> Using our definition, this holds for any complex "z". Then, if "z" is

> real, we get:

>

> |z|' = z / |z|

>

> Which is exactly the usual real derivative. Bill, is this what you had

> in mind? That a CAS could return the derivative of abs(z)

> as Re(z) / abs(z) ?

>

> Ondrej

>

>>

>> So for analytic functions, Wirtinger derivative gives the same answer

>> as Mathematica. For non-analytic functions, Mathematica leaves it

>> unevaluated, but Wirtinger derivative gives you something.

>>

>> How do you calculate the total Wirtinger derivative? How is that defined?

>>

>> Because I would like to get

>>

>> d|x| / d x = x / |x|

>>

>> for real x. And I don't see currently how is this formula connected to

>> Wirtinger derivatives. Finally, the derivative operator in a CAS could

>> return Wirtinger derivatives, I think it's a great idea, if somehow we

>> can recover the usual formula for abs(x) with real "x".

>>

>> What are the cons of this approach?

>>

>> Ondrej

>

Nov 13, 2014, 8:56:24 PM11/13/14

to sage-devel

Sorry, I hit send before I was quite ready. To continue ...

On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

> ...

conjugate or Re as elementary.

>> ...

include the conjugate Wirtinger derivative where necessary.

Second, in principle problems can arise when defining a test for

constant functions. For example this is necessary as part of

rewriting expressions in terms of the smallest number of elementary

functions (normalize) as a kind of zero test for expressions in

FriCAS/Axiom. Usually we assume that

df(x)/dx = 0

is necessary and sufficient for f to be a constant function. But

requiring that the total derivative

d f / d z + d f / d conjugate(z) = 0

is not what we mean by constant. In fact it seems to be an open

question whether Richardson's theorem can be extended to include

conjugate as an elementary function in such a way that the zero test

is still computable. This is the last point of discussion on the

FriCAS email list.

Bill.

On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

> For example, for |z| we get:

>

> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>

> Using our definition, this holds for any complex "z". Then, if "z"

> is real, we get:

>

> |z|' = z / |z|

>

> Which is exactly the usual real derivative. Bill, is this what you

> had in mind? That a CAS could return the derivative of abs(z)

> as Re(z) / abs(z) ?

>

Yes, exactly. I think a question might arise whether we should treat
>

> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>

> Using our definition, this holds for any complex "z". Then, if "z"

> is real, we get:

>

> |z|' = z / |z|

>

> Which is exactly the usual real derivative. Bill, is this what you

> had in mind? That a CAS could return the derivative of abs(z)

> as Re(z) / abs(z) ?

>

conjugate or Re as elementary.

>> ...

>> What are the cons of this approach?

>>

First, care needs to be taken to properly extend the chain rule to
>>

include the conjugate Wirtinger derivative where necessary.

Second, in principle problems can arise when defining a test for

constant functions. For example this is necessary as part of

rewriting expressions in terms of the smallest number of elementary

functions (normalize) as a kind of zero test for expressions in

FriCAS/Axiom. Usually we assume that

df(x)/dx = 0

is necessary and sufficient for f to be a constant function. But

requiring that the total derivative

d f / d z + d f / d conjugate(z) = 0

is not what we mean by constant. In fact it seems to be an open

question whether Richardson's theorem can be extended to include

conjugate as an elementary function in such a way that the zero test

is still computable. This is the last point of discussion on the

FriCAS email list.

Bill.

Nov 14, 2014, 2:14:25 AM11/14/14

to sage-...@googlegroups.com

On Thu, Nov 13, 2014 at 6:56 PM, Bill Page <bill...@newsynthesis.org> wrote:

> Sorry, I hit send before I was quite ready. To continue ...

>

> On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> ...

>> For example, for |z| we get:

>>

>> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

>> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>>

>> Using our definition, this holds for any complex "z". Then, if "z"

>> is real, we get:

>>

>> |z|' = z / |z|

>>

>> Which is exactly the usual real derivative. Bill, is this what you

>> had in mind? That a CAS could return the derivative of abs(z)

>> as Re(z) / abs(z) ?

>>

>

> Yes, exactly. I think a question might arise whether we should treat

> conjugate or Re as elementary.

Ok, thanks for the confirmation.
> Sorry, I hit send before I was quite ready. To continue ...

>

> On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> ...

>> For example, for |z| we get:

>>

>> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

>> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>>

>> Using our definition, this holds for any complex "z". Then, if "z"

>> is real, we get:

>>

>> |z|' = z / |z|

>>

>> Which is exactly the usual real derivative. Bill, is this what you

>> had in mind? That a CAS could return the derivative of abs(z)

>> as Re(z) / abs(z) ?

>>

>

> Yes, exactly. I think a question might arise whether we should treat

> conjugate or Re as elementary.

There is an issue though --- since |z| is not analytic, the

derivatives depend on the direction. So along "x" you get

>

>>> ...

>>> What are the cons of this approach?

>>>

>

> First, care needs to be taken to properly extend the chain rule to

> include the conjugate Wirtinger derivative where necessary.

>

> Second, in principle problems can arise when defining a test for

> constant functions. For example this is necessary as part of

> rewriting expressions in terms of the smallest number of elementary

> functions (normalize) as a kind of zero test for expressions in

> FriCAS/Axiom. Usually we assume that

>

> df(x)/dx = 0

>

> is necessary and sufficient for f to be a constant function. But

> requiring that the total derivative

>

> d f / d z + d f / d conjugate(z) = 0

>

> is not what we mean by constant. In fact it seems to be an open

> question whether Richardson's theorem can be extended to include

> conjugate as an elementary function in such a way that the zero test

> is still computable. This is the last point of discussion on the

> FriCAS email list.

>

> Bill.

>

Nov 14, 2014, 2:19:56 AM11/14/14

to sage-...@googlegroups.com

On Fri, Nov 14, 2014 at 12:14 AM, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Thu, Nov 13, 2014 at 6:56 PM, Bill Page <bill...@newsynthesis.org> wrote:

>> Sorry, I hit send before I was quite ready. To continue ...

>>

>> On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>> ...

>>> For example, for |z| we get:

>>>

>>> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

>>> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>>>

>>> Using our definition, this holds for any complex "z". Then, if "z"

>>> is real, we get:

>>>

>>> |z|' = z / |z|

>>>

>>> Which is exactly the usual real derivative. Bill, is this what you

>>> had in mind? That a CAS could return the derivative of abs(z)

>>> as Re(z) / abs(z) ?

>>>

>>

>> Yes, exactly. I think a question might arise whether we should treat

>> conjugate or Re as elementary.

>

> Ok, thanks for the confirmation.

>

> There is an issue though --- since |z| is not analytic, the

> derivatives depend on the direction. So along "x" you get

Sorry, a bug in gmail sent the message....
> On Thu, Nov 13, 2014 at 6:56 PM, Bill Page <bill...@newsynthesis.org> wrote:

>> Sorry, I hit send before I was quite ready. To continue ...

>>

>> On 13 November 2014 19:24, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>> On Thu, Nov 13, 2014 at 2:00 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>> ...

>>> For example, for |z| we get:

>>>

>>> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

>>> conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>>>

>>> Using our definition, this holds for any complex "z". Then, if "z"

>>> is real, we get:

>>>

>>> |z|' = z / |z|

>>>

>>> Which is exactly the usual real derivative. Bill, is this what you

>>> had in mind? That a CAS could return the derivative of abs(z)

>>> as Re(z) / abs(z) ?

>>>

>>

>> Yes, exactly. I think a question might arise whether we should treat

>> conjugate or Re as elementary.

>

> Ok, thanks for the confirmation.

>

> There is an issue though --- since |z| is not analytic, the

> derivatives depend on the direction. So along "x" you get

along "x" you get:

|z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d

conjugate(z) = conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

|z|' = \partial |z| / \partial i*y = d |z| / d z - d |z| / d

conjugate(z) = conjugate(z) / (2*|z|) - z / (2*|z|) = i*Im(z) / |z|

So I get something completely different. So which direction should be preferred

in the CAS convention and why?

Ondrej

Nov 14, 2014, 9:43:18 AM11/14/14

to sage-devel

On 13 November 2014 14:47, maldun <dom...@gmx.net> wrote:

>

> Although this has some sense in complex analysis one should be careful

> with 'deriving' the absolute value, since it results in the weak derivative

> ( http://en.wikipedia.org/wiki/Weak_derivative) , which is in a broader sense

> the derivative in the distribution sense.

Yes, I first became interesting in Wirtinger derivatives in the
>

> Although this has some sense in complex analysis one should be careful

> with 'deriving' the absolute value, since it results in the weak derivative

> ( http://en.wikipedia.org/wiki/Weak_derivative) , which is in a broader sense

> the derivative in the distribution sense.

context of distributions.

> Thus we have infinite possible derivatives

>

i.e. just not defined everywhere.

> With this expression it is indirectly forbidden to assign a specific value to

> the unspecified value at zero:

>

Yes.
>

Nov 14, 2014, 10:57:58 AM11/14/14

to sage-devel

On 14 November 2014 02:19, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Fri, Nov 14, 2014 at 12:14 AM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> ...
> On Fri, Nov 14, 2014 at 12:14 AM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> Ok, thanks for the confirmation.

>>

>> There is an issue though --- since |z| is not analytic, the

>> derivatives depend on the direction. So along "x" you get

>

>>

>> There is an issue though --- since |z| is not analytic, the

>> derivatives depend on the direction. So along "x" you get

>

> |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d conjugate(z) =

> conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>

> but along "y" you get:

>

> |z|' = \partial |z| / \partial i*y = d |z| / d z - d |z| / d conjugate(z) =

> conjugate(z) / (2*|z|) - z / (2*|z|) = i*Im(z) / |z|

>

> So I get something completely different.

It seems to me that we should forget about x and y. All we really need is
> conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

>

> but along "y" you get:

>

> |z|' = \partial |z| / \partial i*y = d |z| / d z - d |z| / d conjugate(z) =

> conjugate(z) / (2*|z|) - z / (2*|z|) = i*Im(z) / |z|

>

> So I get something completely different.

|z|' = d |z| / d z = conjugate(z) / (2*|z|)

and the appropriate algebraic properties of conjugate.

> So which direction should be preferred in the CAS convention and why?

>

d|x| / d x = x / |x|

for real x".

Bill.

Nov 14, 2014, 1:18:36 PM11/14/14

to sage-...@googlegroups.com

On Nov 14, 2014 8:57 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>

> On 14 November 2014 02:19, Ondřej Čertík <ondrej...@gmail.com> wrote:

> > On Fri, Nov 14, 2014 at 12:14 AM, Ondřej Čertík <ondrej...@gmail.com> wrote:

> >> ...

> >> Ok, thanks for the confirmation.

> >>

> >> There is an issue though --- since |z| is not analytic, the

> >> derivatives depend on the direction. So along "x" you get

> >

> > |z|' = \partial |z| / \partial x = d |z| / d z + d |z| / d conjugate(z) =

> > conjugate(z) / (2*|z|) + z / (2*|z|) = Re(z) / |z|

> >

> > but along "y" you get:

> >

> > |z|' = \partial |z| / \partial i*y = d |z| / d z - d |z| / d conjugate(z) =

> > conjugate(z) / (2*|z|) - z / (2*|z|) = i*Im(z) / |z|

> >

> > So I get something completely different.

>

> It seems to me that we should forget about x and y. All we really need is

>

> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

>

> and the appropriate algebraic properties of conjugate.

Sure, we can make a CAS return this. But then you get the 1/2 there.

>

> > So which direction should be preferred in the CAS convention and why?

> >

>

> Well, um, you did write: "Because I would like to get

>

> d|x| / d x = x / |x|

>

> for real x".

>

> The constant 1/2 is irrelevant.

Well, but how do I recover the real derivative from the complex one if they differ by a factor of 1/2?

In other words, what is the utility of such a definition then?

I can see the utility of differentiating with respect to x, as at least you must recover the real derivative results.

Ondrej

Nov 14, 2014, 1:30:24 PM11/14/14

to sage-devel

On 14 November 2014 13:18, Ondřej Čertík <ondrej...@gmail.com> wrote:

>

> On Nov 14, 2014 8:57 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>>

>> It seems to me that we should forget about x and y. All we really need is

>>

>> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

>>

>> and the appropriate algebraic properties of conjugate.

>

> Sure, we can make a CAS return this. But then you get the 1/2 there.

>

Yes.
>

> On Nov 14, 2014 8:57 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>>

>> It seems to me that we should forget about x and y. All we really need is

>>

>> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

>>

>> and the appropriate algebraic properties of conjugate.

>

> Sure, we can make a CAS return this. But then you get the 1/2 there.

>

>> ...

>> The constant 1/2 is irrelevant.

>

> Well, but how do I recover the real derivative from the complex one if they

> differ by a factor of 1/2?

>

What do you mean by "the real derivative"? Perhaps we can just define that as
>

> Well, but how do I recover the real derivative from the complex one if they

> differ by a factor of 1/2?

>

d f / d z + d f / d conjugate(z)

> In other words, what is the utility of such a definition then?

>

> I can see the utility of differentiating with respect to x, as at least you

> must recover the real derivative results.

>

with respect to

(z+conjugate(z))/2

Bill.

Nov 14, 2014, 2:29:45 PM11/14/14

to sage-...@googlegroups.com

On Nov 14, 2014 11:30 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>

> On 14 November 2014 13:18, Ondřej Čertík <ondrej...@gmail.com> wrote:

> >

> > On Nov 14, 2014 8:57 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

> >>

> >> It seems to me that we should forget about x and y. All we really need is

> >>

> >> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

> >>

> >> and the appropriate algebraic properties of conjugate.

> >

> > Sure, we can make a CAS return this. But then you get the 1/2 there.

> >

>

> Yes.

>

> >> ...

> >> The constant 1/2 is irrelevant.

> >

> > Well, but how do I recover the real derivative from the complex one if they

> > differ by a factor of 1/2?

> >

>

> What do you mean by "the real derivative"?

The absolute value doesn't have a complex derivative, but it has a real derivative, over the real axis.

> Perhaps we can just define that as

>

> d f / d z + d f / d conjugate(z)

>

> > In other words, what is the utility of such a definition then?

> >

> > I can see the utility of differentiating with respect to x, as at least you

> > must recover the real derivative results.

> >

>

> You are not differentiating with respect to x, you are differentiating

> with respect to

>

> (z+conjugate(z))/2

Is that how you propose to define the derivatives for non-analytic functions? I am a little confused what exactly is your proposal.

I think one either leaves the derivatives of non analytic functions unevaluated, or defines them in such a way that one recovers the real derivative as a special case, as long as there are no inconsistencies.

Nov 15, 2014, 11:18:55 AM11/15/14

to sage-devel

On 14 November 2014 14:29, Ondřej Čertík <ondrej...@gmail.com> wrote:

>

> On Nov 14, 2014 11:30 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>>

>> What do you mean by "the real derivative"?

>

> The absolute value doesn't have a complex derivative, but it has a real

> derivative, over the real axis.

>

It seems to me that the concept of "real axis" is rather foreign to
>

> On Nov 14, 2014 11:30 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>>

>> What do you mean by "the real derivative"?

>

> The absolute value doesn't have a complex derivative, but it has a real

> derivative, over the real axis.

>

the algebra. Assuming conjugate is implemented properly, i.e.

"algebraically", what you are actually saying is just that

z = conjugate(z)

> ...

>> You are not differentiating with respect to x, you are differentiating

>> with respect to

>>

>> (z+conjugate(z))/2

>

> Is that how you propose to define the derivatives for non-analytic

> functions? I am a little confused what exactly is your proposal.

>

I am sorry for the confusion. What I am proposing is that the
>> with respect to

>>

>> (z+conjugate(z))/2

>

> Is that how you propose to define the derivatives for non-analytic

> functions? I am a little confused what exactly is your proposal.

>

Wirtinger derivative(s) be considered the fundamental case (valid for

complex or even quaternion variables). As you noted previously this is

fine and doesn't change anything for the case of analytic functions.

If someone wants the derivative of a non-analytic function over a

given domain that should be called something else.

> I think one either leaves the derivatives of non analytic functions

> unevaluated,

> or defines them in such a way that one recovers the real derivative

> as a special case, as long as there are no inconsistencies.

>

Bill.

Nov 17, 2014, 10:14:40 AM11/17/14

to sage-...@googlegroups.com

For reference (since Sage uses Ginac for most derivatives) see http://www.cebix.net/pipermail/ginac-devel/2014-April/002105.html

Nov 17, 2014, 11:17:41 AM11/17/14

to sage-devel

Vladimir V. Kisil kisilv's patch

http://www.ginac.de/pipermail/ginac-devel/2013-November/002053

looks like a good start to me especially if one doesn't want to

consider the issue of derivatives of non-analytic functions in

general.

On 17 November 2014 10:14, kcrisman <kcri...@gmail.com> wrote:

> For reference (since Sage uses Ginac for most derivatives) see

> http://www.cebix.net/pipermail/ginac-devel/2014-April/002105.html

>

http://www.ginac.de/pipermail/ginac-devel/2013-November/002053

looks like a good start to me especially if one doesn't want to

consider the issue of derivatives of non-analytic functions in

general.

On 17 November 2014 10:14, kcrisman <kcri...@gmail.com> wrote:

> For reference (since Sage uses Ginac for most derivatives) see

> http://www.cebix.net/pipermail/ginac-devel/2014-April/002105.html

>

Nov 17, 2014, 11:24:01 AM11/17/14

to sage-...@googlegroups.com

Vladimir V. Kisil kisilv's patch

http://www.ginac.de/pipermail/ginac-devel/2013-November/002053

looks like a good start to me especially if one doesn't want to

consider the issue of derivatives of non-analytic functions in

general.

Nov 17, 2014, 3:17:15 PM11/17/14

to sage-...@googlegroups.com

Hi Bill,

On Sat, Nov 15, 2014 at 9:18 AM, Bill Page <bill...@newsynthesis.org> wrote:

> On 14 November 2014 14:29, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> On Nov 14, 2014 11:30 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>>>

>>> What do you mean by "the real derivative"?

>>

>> The absolute value doesn't have a complex derivative, but it has a real

>> derivative, over the real axis.

>>

>

> It seems to me that the concept of "real axis" is rather foreign to

> the algebra. Assuming conjugate is implemented properly, i.e.

> "algebraically", what you are actually saying is just that

>

> z = conjugate(z)

That's fine.

>

>> ...

>>> You are not differentiating with respect to x, you are differentiating

>>> with respect to

>>>

>>> (z+conjugate(z))/2

>>

>> Is that how you propose to define the derivatives for non-analytic

>> functions? I am a little confused what exactly is your proposal.

>>

>

> I am sorry for the confusion. What I am proposing is that the

> Wirtinger derivative(s) be considered the fundamental case (valid for

> complex or even quaternion variables). As you noted previously this is

> fine and doesn't change anything for the case of analytic functions.

> If someone wants the derivative of a non-analytic function over a

> given domain that should be called something else.

I still don't understand exactly your proposal. We've played with a

few ideas above, in particular we have considered at least (below d/dz

is the Wirtinger derivative, d/dx and d/d(iy) are partial derivatives

with respect to "x" or "iy" in z=x+i*y) :

1) d/dz

2) d/dz + d/d conjugate(z) = d/dx

3) d/dz - d/d conjugate(z) = d/d(iy)

4) 2 * (d/dz + d/d conjugate(z))

5) 2 * d/dz

Which of these do you propose to use? For analytic functions, only 1)

and 2) reduce to the usual complex derivative. 4) and 5) will be off

by a factor of 2. For example, for a function z^2 we get:

1) 2*z

2) 2*z

3) 2*z

4) 4*z

5) 4*z

Since z^2 is analytic, the correct derivative is 2*z, so 1), 2) and 3)

give the right answer.

For abs(z), we get:

1) conjugate(z) / (2*|z|)

2) Re(z) / |z|

3) -i*Im(z) / |z|

4) 2*Re(z) / |z|

5) conjugate(z) / |z|

When "z" is real, then the (real) derivative of |z|' = z/|z|. We want

our complex formula to be equal to z/|z| if "z" is real. Of the above,

only 2) and 5) is equal to z/|z| when "z" is real. Note that I made a

sign mistake in my previous email regarding 3).

Comparing these two cases, options 1) and 3) are eliminated because

the results for abs(z) do not reduce to the correct real derivative.

Option 4) is eliminated, because it gives wrong results for analytic

functions, as well as it doesn't reduce to the correct real derivative

for abs(z). Option 5) is eliminated because it gives wrong results for

analytic functions.

As such, only option 2) is consistent. For all analytic functions, it

gives the correct complex derivative, and for non-analytic functions,

at least for abs(z) it reduces to the correct real derivative in the

special case when "z" is real, i.e. z = conjugate(z). Note that you

cannot apply z = conjugate(z) to the definition of 2) to obtain the

(incorrect) result 2*d/dz, you need to treat z and conjugate(z)

separately when differentiating and only at the end apply z =

conjugate(z).

It seems to work for other non-analytic functions, for example for

Re(z) = (z+conjugate(z))/2, we get:

2) 1

for Im(z) = (-z+conjugate(z))*i/2 we get:

2) 0

So that all works as expected. To prove that this works for all

non-analytic functions, we just use the fact that d/dz + d/d

conjugate(z) = d/dx, as we talked about above. So we are just

calculating the partial derivative with respect to "x" (we use the

notation z = x+i*y). When "z" is real, i.e. z = conjugate(z), it

follows that y = 0, and d/dx is just the usual (real) derivative. When

y is non-zero, we still calculate d/dx but using z and conjugate(z).

As shown above, for analytic functions this d/dx derivative is equal

to the complex derivative. For non-analytic functions the complex

derivative doesn't exist, so it's just our definition, but it reduces

to the usual real derivative (which is always equal to d/dx). In one

of my previous emails, I raised a question for non-analytic functions,

why we can't define it in some other way, perhaps d/d(iy), i.e. the

option 3) above. I think the answer is that we can, but it will not

reduce to the real derivative d/dx if "z" is real, simply because

d/d(iy) is not equal to d/dx, unless the function is analytic, i.e. 3)

works for analytic functions, but fails for abs(z), as shown above (as

well as in my previous email --- note again that I made a sign mistake

there).

>

>> I think one either leaves the derivatives of non analytic functions

>> unevaluated,

>

> No, this is just giving up. We should be able to do much better than that.

>

>> or defines them in such a way that one recovers the real derivative

>> as a special case, as long as there are no inconsistencies.

>>

>

> Yes exactly, the concept of "real derivative" is a special case.

Hopefully the above clarifies, that from everything that we have

considered so far, only the option 2) can work. It turns out that

that's also precisely what also ginac considered for abs(z)'. So the

conclusion seems clear --- simply use 2) for any function, be it

analytic or not.

However, Bill, from your emails, you seem to be giving conflicting

statements. It seems you agree that 2) is the way to go in some

Right in the next paragraph you wrote:

>

> The constant 1/2 is irrelevant.

What do you mean that the constant 1/2 is irrelevant? I think it is

very relevant, as it makes the answer incorrect.

Or:

> You are not differentiating with respect to x, you are differentiating

> with respect to

>

> (z+conjugate(z))/2

But differentiating with respect to (z+conjugate(z))/2 is just the

case 5) above, and it is shown that it doesn't work. While

differentiating with respect to "x" is the case 2) above and it is

shown that it works.

Finally, in your last email you wrote:

> I am sorry for the confusion. What I am proposing is that the

> Wirtinger derivative(s) be considered the fundamental case (valid for

> complex or even quaternion variables). As you noted previously this is

> fine and doesn't change anything for the case of analytic functions.

> If someone wants the derivative of a non-analytic function over a

> given domain that should be called something else.

I am completely confused with this paragraph. Let's try to clarify this.

When you say "I am proposing that the Wirtinger derivative(s) be

considered the fundamental case", which of the five cases above are

you proposing? Strictly speaking, Wirtinger derivative is the case 1),

but that doesn't work. Are you proposing the case 2) instead?

> As you noted previously this is

> fine and doesn't change anything for the case of analytic functions.

Correct, cases 1), 2) and 3) don't change anything for analytic functions.

> If someone wants the derivative of a non-analytic function over a

> given domain that should be called something else.

Are you proposing to only consider analytic functions? I thought the

whole conversation in this thread was about how to extend this to

non-analytic functions... If you only consider analytic functions,

then we don't need Wirtinger derivatives at all, since we can just use

the usual complex derivative, as is already the case in most CAS

systems. Of course, then we need to leave abs(z) unevaluated, as it is

not analytic.

I thought the goal was rather to extend the definition of "derivative"

to also apply for non-analytic functions, in the whole complex domain

in such a way, so that it reduces to a complex derivative for analytic

functions, and a real derivative if we restrict "z" to be real. It

seems that 2) above is one such definition that would allow that.

Bill, would you mind clarifying the above misunderstandings? I think

we are on the same page, probably we both just understood something

else with the terminology we used, but I want to make 100% sure.

Ondrej

On Sat, Nov 15, 2014 at 9:18 AM, Bill Page <bill...@newsynthesis.org> wrote:

> On 14 November 2014 14:29, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> On Nov 14, 2014 11:30 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

>>>

>>> What do you mean by "the real derivative"?

>>

>> The absolute value doesn't have a complex derivative, but it has a real

>> derivative, over the real axis.

>>

>

> It seems to me that the concept of "real axis" is rather foreign to

> the algebra. Assuming conjugate is implemented properly, i.e.

> "algebraically", what you are actually saying is just that

>

> z = conjugate(z)

>

>> ...

>>> You are not differentiating with respect to x, you are differentiating

>>> with respect to

>>>

>>> (z+conjugate(z))/2

>>

>> Is that how you propose to define the derivatives for non-analytic

>> functions? I am a little confused what exactly is your proposal.

>>

>

> I am sorry for the confusion. What I am proposing is that the

> Wirtinger derivative(s) be considered the fundamental case (valid for

> complex or even quaternion variables). As you noted previously this is

> fine and doesn't change anything for the case of analytic functions.

> If someone wants the derivative of a non-analytic function over a

> given domain that should be called something else.

few ideas above, in particular we have considered at least (below d/dz

is the Wirtinger derivative, d/dx and d/d(iy) are partial derivatives

with respect to "x" or "iy" in z=x+i*y) :

1) d/dz

2) d/dz + d/d conjugate(z) = d/dx

3) d/dz - d/d conjugate(z) = d/d(iy)

4) 2 * (d/dz + d/d conjugate(z))

5) 2 * d/dz

Which of these do you propose to use? For analytic functions, only 1)

and 2) reduce to the usual complex derivative. 4) and 5) will be off

by a factor of 2. For example, for a function z^2 we get:

1) 2*z

2) 2*z

3) 2*z

4) 4*z

5) 4*z

Since z^2 is analytic, the correct derivative is 2*z, so 1), 2) and 3)

give the right answer.

For abs(z), we get:

1) conjugate(z) / (2*|z|)

2) Re(z) / |z|

3) -i*Im(z) / |z|

4) 2*Re(z) / |z|

5) conjugate(z) / |z|

When "z" is real, then the (real) derivative of |z|' = z/|z|. We want

our complex formula to be equal to z/|z| if "z" is real. Of the above,

only 2) and 5) is equal to z/|z| when "z" is real. Note that I made a

sign mistake in my previous email regarding 3).

Comparing these two cases, options 1) and 3) are eliminated because

the results for abs(z) do not reduce to the correct real derivative.

Option 4) is eliminated, because it gives wrong results for analytic

functions, as well as it doesn't reduce to the correct real derivative

for abs(z). Option 5) is eliminated because it gives wrong results for

analytic functions.

As such, only option 2) is consistent. For all analytic functions, it

gives the correct complex derivative, and for non-analytic functions,

at least for abs(z) it reduces to the correct real derivative in the

special case when "z" is real, i.e. z = conjugate(z). Note that you

cannot apply z = conjugate(z) to the definition of 2) to obtain the

(incorrect) result 2*d/dz, you need to treat z and conjugate(z)

separately when differentiating and only at the end apply z =

conjugate(z).

It seems to work for other non-analytic functions, for example for

Re(z) = (z+conjugate(z))/2, we get:

2) 1

for Im(z) = (-z+conjugate(z))*i/2 we get:

2) 0

So that all works as expected. To prove that this works for all

non-analytic functions, we just use the fact that d/dz + d/d

conjugate(z) = d/dx, as we talked about above. So we are just

calculating the partial derivative with respect to "x" (we use the

notation z = x+i*y). When "z" is real, i.e. z = conjugate(z), it

follows that y = 0, and d/dx is just the usual (real) derivative. When

y is non-zero, we still calculate d/dx but using z and conjugate(z).

As shown above, for analytic functions this d/dx derivative is equal

to the complex derivative. For non-analytic functions the complex

derivative doesn't exist, so it's just our definition, but it reduces

to the usual real derivative (which is always equal to d/dx). In one

of my previous emails, I raised a question for non-analytic functions,

why we can't define it in some other way, perhaps d/d(iy), i.e. the

option 3) above. I think the answer is that we can, but it will not

reduce to the real derivative d/dx if "z" is real, simply because

d/d(iy) is not equal to d/dx, unless the function is analytic, i.e. 3)

works for analytic functions, but fails for abs(z), as shown above (as

well as in my previous email --- note again that I made a sign mistake

there).

>

>> I think one either leaves the derivatives of non analytic functions

>> unevaluated,

>

> No, this is just giving up. We should be able to do much better than that.

>

>> or defines them in such a way that one recovers the real derivative

>> as a special case, as long as there are no inconsistencies.

>>

>

> Yes exactly, the concept of "real derivative" is a special case.

considered so far, only the option 2) can work. It turns out that

that's also precisely what also ginac considered for abs(z)'. So the

conclusion seems clear --- simply use 2) for any function, be it

analytic or not.

However, Bill, from your emails, you seem to be giving conflicting

statements. It seems you agree that 2) is the way to go in some

emails, but then in some other emails you write:

> It seems to me that we should forget about x and y. All we really need is

>

> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

Which is the case 1) above, and it is shown that it doesn't work.
> It seems to me that we should forget about x and y. All we really need is

>

> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

Right in the next paragraph you wrote:

>

> The constant 1/2 is irrelevant.

very relevant, as it makes the answer incorrect.

Or:

> You are not differentiating with respect to x, you are differentiating

> with respect to

>

> (z+conjugate(z))/2

case 5) above, and it is shown that it doesn't work. While

differentiating with respect to "x" is the case 2) above and it is

shown that it works.

Finally, in your last email you wrote:

> I am sorry for the confusion. What I am proposing is that the

> Wirtinger derivative(s) be considered the fundamental case (valid for

> complex or even quaternion variables). As you noted previously this is

> fine and doesn't change anything for the case of analytic functions.

> If someone wants the derivative of a non-analytic function over a

> given domain that should be called something else.

When you say "I am proposing that the Wirtinger derivative(s) be

considered the fundamental case", which of the five cases above are

you proposing? Strictly speaking, Wirtinger derivative is the case 1),

but that doesn't work. Are you proposing the case 2) instead?

> As you noted previously this is

> fine and doesn't change anything for the case of analytic functions.

> If someone wants the derivative of a non-analytic function over a

> given domain that should be called something else.

whole conversation in this thread was about how to extend this to

non-analytic functions... If you only consider analytic functions,

then we don't need Wirtinger derivatives at all, since we can just use

the usual complex derivative, as is already the case in most CAS

systems. Of course, then we need to leave abs(z) unevaluated, as it is

not analytic.

I thought the goal was rather to extend the definition of "derivative"

to also apply for non-analytic functions, in the whole complex domain

in such a way, so that it reduces to a complex derivative for analytic

functions, and a real derivative if we restrict "z" to be real. It

seems that 2) above is one such definition that would allow that.

Bill, would you mind clarifying the above misunderstandings? I think

we are on the same page, probably we both just understood something

else with the terminology we used, but I want to make 100% sure.

Ondrej

Nov 17, 2014, 3:21:52 PM11/17/14

to sage-...@googlegroups.com

> I still don't understand exactly your proposal. We've played with a

> few ideas above, in particular we have considered at least (below d/dz

> is the Wirtinger derivative, d/dx and d/d(iy) are partial derivatives

> with respect to "x" or "iy" in z=x+i*y) :

>

> 1) d/dz

> 2) d/dz + d/d conjugate(z) = d/dx

> 3) d/dz - d/d conjugate(z) = d/d(iy)

> 4) 2 * (d/dz + d/d conjugate(z))

> 5) 2 * d/dz

>

> Which of these do you propose to use? For analytic functions, only 1)

> and 2) reduce to the usual complex derivative. 4) and 5) will be off

> by a factor of 2. For example, for a function z^2 we get:

Correction: For analytic functions, only 1), 2) and 3) reduce to the
> few ideas above, in particular we have considered at least (below d/dz

> is the Wirtinger derivative, d/dx and d/d(iy) are partial derivatives

> with respect to "x" or "iy" in z=x+i*y) :

>

> 1) d/dz

> 2) d/dz + d/d conjugate(z) = d/dx

> 3) d/dz - d/d conjugate(z) = d/d(iy)

> 4) 2 * (d/dz + d/d conjugate(z))

> 5) 2 * d/dz

>

> Which of these do you propose to use? For analytic functions, only 1)

> and 2) reduce to the usual complex derivative. 4) and 5) will be off

> by a factor of 2. For example, for a function z^2 we get:

usual complex derivative.

(As is shown below on particular examples.)

Nov 17, 2014, 9:52:47 PM11/17/14

to sage-devel

On 17 November 2014 15:17, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Sat, Nov 15, 2014 at 9:18 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>

>> I am sorry for the confusion. What I am proposing is that the

>> Wirtinger derivative(s) be considered the fundamental case (valid

>> for complex or even quaternion variables). As you noted previously

>> this is fine and doesn't change anything for the case of analytic

>> functions. If someone wants the derivative of a non-analytic

>> function over a given domain that should be called something

>> else.

>

> I still don't understand exactly your proposal. We've played with a

> few ideas above, in particular we have considered at least (below

> d/dz is the Wirtinger derivative, d/dx and d/d(iy) are partial derivatives

> with respect to "x" or "iy" in z=x+i*y) :

>

> 1) d/dz

> 2) d/dz + d/d conjugate(z) = d/dx

> 3) d/dz - d/d conjugate(z) = d/d(iy)

> 4) 2 * (d/dz + d/d conjugate(z))

> 5) 2 * d/dz

>

> Which of these do you propose to use?

Both d/dz and d/d conjugate(z), i.e. the Wirtinger derivatives.
> On Sat, Nov 15, 2014 at 9:18 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>

>> I am sorry for the confusion. What I am proposing is that the

>> Wirtinger derivative(s) be considered the fundamental case (valid

>> for complex or even quaternion variables). As you noted previously

>> this is fine and doesn't change anything for the case of analytic

>> functions. If someone wants the derivative of a non-analytic

>> function over a given domain that should be called something

>> else.

>

> I still don't understand exactly your proposal. We've played with a

> few ideas above, in particular we have considered at least (below

> d/dz is the Wirtinger derivative, d/dx and d/d(iy) are partial derivatives

> with respect to "x" or "iy" in z=x+i*y) :

>

> 1) d/dz

> 2) d/dz + d/d conjugate(z) = d/dx

> 3) d/dz - d/d conjugate(z) = d/d(iy)

> 4) 2 * (d/dz + d/d conjugate(z))

> 5) 2 * d/dz

>

> Which of these do you propose to use?

> ...

> When "z" is real, then the (real) derivative of |z|' = z/|z|. We want

> our complex formula to be equal to z/|z| if "z" is real.

Presumably you intend to choose only one of these? But this cannot
> our complex formula to be equal to z/|z| if "z" is real.

work in the general case.

> ...

> As such, only option 2) is consistent. For all analytic functions, it

> gives the correct complex derivative, and for non-analytic functions,

> at least for abs(z) it reduces to the correct real derivative in the

> special case when "z" is real, i.e. z = conjugate(z).

Yes.
> gives the correct complex derivative, and for non-analytic functions,

> at least for abs(z) it reduces to the correct real derivative in the

> special case when "z" is real, i.e. z = conjugate(z).

>> ...

>> Yes exactly, the concept of "real derivative" is a special case.

>

> Hopefully the above clarifies, that from everything that we have

> considered so far, only the option 2) can work. It turns out that

> that's also precisely what also ginac considered for abs(z)'. So

> the conclusion seems clear --- simply use 2) for any function, be

> it analytic or not.

>

If there is only one derivative, how will you handle the chain rule?
>

> Hopefully the above clarifies, that from everything that we have

> considered so far, only the option 2) can work. It turns out that

> that's also precisely what also ginac considered for abs(z)'. So

> the conclusion seems clear --- simply use 2) for any function, be

> it analytic or not.

>

>

> However, Bill, from your emails, you seem to be giving conflicting

> statements. It seems you agree that 2) is the way to go in some

> emails, but then in some other emails you write:

>

>> It seems to me that we should forget about x and y. All we really

>> need is

>>

>> |z|' = d |z| / d z = conjugate(z) / (2*|z|)

>

> Which is the case 1) above, and it is shown that it doesn't work.

>

> Right in the next paragraph you wrote:

>

>>

>> The constant 1/2 is irrelevant.

>

> What do you mean that the constant 1/2 is irrelevant? I think it is

> very relevant, as it makes the answer incorrect.

>

because the other can be expressed in terms of conjugate but I did not

mean to imply that it would meet your criteria of reducing to exactly

to the real case. It just happens that both Wirtinger derivatives are

the same in the case of abs.

>

> When you say "I am proposing that the Wirtinger derivative(s) be

> considered the fundamental case", which of the five cases above

> are you proposing? Strictly speaking, Wirtinger derivative is the case

> 1), but that doesn't work. Are you proposing the case 2) instead?

>

be obtained from the Wirtinger derivatives but not vice versa.

> ...

>> If someone wants the derivative of a non-analytic function over a

>> given domain that should be called something else.

>

> Are you proposing to only consider analytic functions?

No.
>> given domain that should be called something else.

>

> Are you proposing to only consider analytic functions?

> I thought the whole conversation in this thread was about how to

> extend this to non-analytic functions...

> ...

> I thought the goal was rather to extend the definition of "derivative"

> to also apply for non-analytic functions, in the whole complex domain

> in such a way, so that it reduces to a complex derivative for analytic

> functions, and a real derivative if we restrict "z" to be real. It

> seems that 2) above is one such definition that would allow that.

>

2) alone is not sufficient. In general for non-analytic functions two
> to also apply for non-analytic functions, in the whole complex domain

> in such a way, so that it reduces to a complex derivative for analytic

> functions, and a real derivative if we restrict "z" to be real. It

> seems that 2) above is one such definition that would allow that.

>

derivatives are required.

> Bill, would you mind clarifying the above misunderstandings?

> I think we are on the same page, probably we both just understood

> something else with the terminology we used, but I want to make

> 100% sure.

>

Bill.

Nov 17, 2014, 11:16:15 PM11/17/14

to sage-...@googlegroups.com

Hi Bill,

Thanks for the clarification. So your point is that 2) is not

sufficient, that we really need two Wirtinger derivatives --- it's

just that one can be expressed using the other and a conjugate, so

perhaps CAS can only return one, but a chain rule needs modification

and probably some other derivatives handling as well. I need to think

about this harder.

Here is a relation that I found today in [1] (see also the references

there), I don't know if you are aware of it:

D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

Where Df/Dz is the derivative in a complex plane along the direction

theta (the angle between the direction and the x-axis) and df/dz and

df/d conjugate(z) are the two Wirtinger derivatives. This formula

holds for any function. So all the derivatives no matter which

direction lie on a circle of radius df/d conjugate(z) and center

df/dz.

For analytic functions, we have df/d conjugate(z) = 0, and so the

above formula proves that all the derivatives are independent of

direction theta and equal to df/dz.

For non-analytic functions, the above formula gives all the possible

derivatives, and besides df/dz, the derivatives also depend on df/d

conjugate(z) and theta. But that's it. So as you said, the two

Wirtinger derivatives allow us to calculate the derivative along any

direction theta we want.

From my last email, the case 1) corresponds to df/d conjugate(z)=0,

i.e. analytic functions and the result is independent of theta. Case

2) is theta = 0, pi, 2*pi, ..., i.e. taking the derivative along the

x-axis. Case 3) is theta = pi/2, 3*pi/2, 5*pi/2, ..., i.e. taking the

derivative along the y-axis.

A real derivative of a real function g(x) is simply taken along the

x-axis. You can imagine that g(x) is also (arbitrarily) defined in the

whole complex plane and you are taking the Dg/gz derivative above with

theta = 0. The result is the same. So that's why the case 2), i.e.

theta=0, always reproduces the real derivative, because real

derivative is defined as theta=0.

For CAS, one could probably just say that theta=0 in our definition,

and then everything is consistent, and we only have one derivative,

2). The other option is to return both derivatives and make the

derivative Df/Dz of non-analytic function equal to the above formula,

i.e. depending on df/dz, df/d conjugate(z) and theta.

I need to think about the chain rule. I would simply introduce the

theta dependence into all formulas, as that gives all possible

derivatives and gives the exact functional dependence of all

possibilities. And then see whether we need to keep all formulas in

terms of theta, or perhaps if we can set theta = 0 for everything.

Ondrej

[1] Pyle, H. R., & Barker, B. M. (1946). A Vector Interpretation of

the Derivative Circle. The American Mathematical Monthly, 53(2), 79.

doi:10.2307/2305454

Thanks for the clarification. So your point is that 2) is not

sufficient, that we really need two Wirtinger derivatives --- it's

just that one can be expressed using the other and a conjugate, so

perhaps CAS can only return one, but a chain rule needs modification

and probably some other derivatives handling as well. I need to think

about this harder.

Here is a relation that I found today in [1] (see also the references

there), I don't know if you are aware of it:

D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

Where Df/Dz is the derivative in a complex plane along the direction

theta (the angle between the direction and the x-axis) and df/dz and

df/d conjugate(z) are the two Wirtinger derivatives. This formula

holds for any function. So all the derivatives no matter which

direction lie on a circle of radius df/d conjugate(z) and center

df/dz.

For analytic functions, we have df/d conjugate(z) = 0, and so the

above formula proves that all the derivatives are independent of

direction theta and equal to df/dz.

For non-analytic functions, the above formula gives all the possible

derivatives, and besides df/dz, the derivatives also depend on df/d

conjugate(z) and theta. But that's it. So as you said, the two

Wirtinger derivatives allow us to calculate the derivative along any

direction theta we want.

From my last email, the case 1) corresponds to df/d conjugate(z)=0,

i.e. analytic functions and the result is independent of theta. Case

2) is theta = 0, pi, 2*pi, ..., i.e. taking the derivative along the

x-axis. Case 3) is theta = pi/2, 3*pi/2, 5*pi/2, ..., i.e. taking the

derivative along the y-axis.

A real derivative of a real function g(x) is simply taken along the

x-axis. You can imagine that g(x) is also (arbitrarily) defined in the

whole complex plane and you are taking the Dg/gz derivative above with

theta = 0. The result is the same. So that's why the case 2), i.e.

theta=0, always reproduces the real derivative, because real

derivative is defined as theta=0.

For CAS, one could probably just say that theta=0 in our definition,

and then everything is consistent, and we only have one derivative,

2). The other option is to return both derivatives and make the

derivative Df/Dz of non-analytic function equal to the above formula,

i.e. depending on df/dz, df/d conjugate(z) and theta.

I need to think about the chain rule. I would simply introduce the

theta dependence into all formulas, as that gives all possible

derivatives and gives the exact functional dependence of all

possibilities. And then see whether we need to keep all formulas in

terms of theta, or perhaps if we can set theta = 0 for everything.

Ondrej

[1] Pyle, H. R., & Barker, B. M. (1946). A Vector Interpretation of

the Derivative Circle. The American Mathematical Monthly, 53(2), 79.

doi:10.2307/2305454

Nov 18, 2014, 8:57:11 AM11/18/14

to sage-devel

On 17 November 2014 23:16, Ondřej Čertík <ondrej...@gmail.com> wrote:

> Hi Bill,

>

> Thanks for the clarification. So your point is that 2) is not

> sufficient, that we really need two Wirtinger derivatives --- it's

> just that one can be expressed using the other and a conjugate,

> so perhaps CAS can only return one, but a chain rule needs

> modification and probably some other derivatives handling as

> well. I need to think about this harder.

>

Yes, that is a good summary. My tentative conclusion was that we
> Hi Bill,

>

> Thanks for the clarification. So your point is that 2) is not

> sufficient, that we really need two Wirtinger derivatives --- it's

> just that one can be expressed using the other and a conjugate,

> so perhaps CAS can only return one, but a chain rule needs

> modification and probably some other derivatives handling as

> well. I need to think about this harder.

>

could implement just one (Wirtinger) derivative, a modified chain rule

and a sufficiently strong conjugate operation. This derivative is the

same as the usual derivative in the case of analytic functions but we

would have to live with the fact that it is slightly different (factor

of 1/2) for the case of common real derivatives of non-analytic

functions such as abs. Introducing a factor of 2, such as in the case

of the definition of the sign function seems like a small price to

pay.

> Here is a relation that I found today in [1] (see also the references

> there), I don't know if you are aware of it:

>

> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>

> Where Df/Dz is the derivative in a complex plane along the direction

> theta (the angle between the direction and the x-axis) and df/dz and

> df/d conjugate(z) are the two Wirtinger derivatives. This formula

> holds for any function. So all the derivatives no matter which

> direction lie on a circle of radius df/d conjugate(z) and center

> df/dz.

>

> [1] Pyle, H. R., & Barker, B. M. (1946). A Vector Interpretation of

> the Derivative Circle. The American Mathematical Monthly, 53(2), 79.

> doi:10.2307/2305454

http://phdtree.org/pdf/36421281-a-vector-interpretation-of-the-derivative-circle/
> the Derivative Circle. The American Mathematical Monthly, 53(2), 79.

> doi:10.2307/2305454

Thank you. I was not aware of that specific publication. I think

their geometric interpretation is useful.

>

> For CAS, one could probably just say that theta=0 in our definition,

> and then everything is consistent, and we only have one derivative,

> 2). The other option is to return both derivatives and make the

> derivative Df/Dz of non-analytic function equal to the above formula,

> i.e. depending on df/dz, df/d conjugate(z) and theta.

reduces to the conventional derivative of non-analytic functions over

the reals.

>

> I need to think about the chain rule. I would simply introduce the

> theta dependence into all formulas, as that gives all possible

> derivatives and gives the exact functional dependence of all

> possibilities. And then see whether we need to keep all formulas

> in terms of theta, or perhaps if we can set theta = 0 for everything.

>

application of the chain rule.

Bill.

Nov 18, 2014, 9:02:55 AM11/18/14

to sage-devel

important that the derivative of abs(x) be sign(x) not 2*sign(x) or

1/2*sign(x).

If you use a different function, like f.wirtinger_derivative(), then

it doesn't matter so much.

David

>

>>

>> I need to think about the chain rule. I would simply introduce the

>> theta dependence into all formulas, as that gives all possible

>> derivatives and gives the exact functional dependence of all

>> possibilities. And then see whether we need to keep all formulas

>> in terms of theta, or perhaps if we can set theta = 0 for everything.

>>

>

> It is not clear to me how to use such as "generic" derivative in the

> application of the chain rule.

>

> Bill.

>

Nov 18, 2014, 10:11:10 AM11/18/14

to sage-...@googlegroups.com

> I think you are overly focused on trying to define a derivative that

> reduces to the conventional derivative of non-analytic functions over

> the reals.

I've just been casually following this conversation, but I think it's

important that the derivative of abs(x) be sign(x) not 2*sign(x) or

1/2*sign(x).

If you use a different function, like f.wirtinger_derivative(), then

it doesn't matter so much.

David

+1

That notwithstanding, this conversation is really great to see and I hope we get something that works for the usual cases in the original post too!

Nov 18, 2014, 11:05:54 AM11/18/14

to sage-devel

On 18 November 2014 09:02, David Roe <roed...@gmail.com> wrote:

> On Tue, Nov 18, 2014 at 5:57 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>

> On Tue, Nov 18, 2014 at 5:57 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>

>> > I think you are overly focused on trying to define a derivative that

>> > reduces to the conventional derivative of non-analytic functions

>> > over the reals.

>>

>> I've just been casually following this conversation, but I think it's

>> important that the derivative of abs(x) be sign(x) not 2*sign(x) or

>> 1/2*sign(x).

>>

What makes it important that "the" derivative of abs(x) be sign(x)?
>> > reduces to the conventional derivative of non-analytic functions

>> > over the reals.

>>

>> I've just been casually following this conversation, but I think it's

>> important that the derivative of abs(x) be sign(x) not 2*sign(x) or

>> 1/2*sign(x).

>>

An important point here is that there is no one single unique

derivative of non-analytic functions like abs, but rather than all of

their derivatives can be expressed in terms of just two. I am

seriously interested in reasons for retaining the status quo.

>> If you use a different function, like f.wirtinger_derivative(), then

>> it doesn't matter so much.

>> David

>>

>

> +1

>

Although I guess this would be consistent with the over all

"assimilation philosophy" adopted by Sage, I am rather strongly

against this in general. In my opinion it is in part what has lead to

the rather confusing situation in most other computer algebra systems.

I think rather that one should strive for the most general solution

consistent with the mathematics. I suppose that to some extent this

is conditioned by how the subject is taught. It came as a surprise to

me that a solution of this problem (Wirtinger calculus or CR-calculus)

was apparently "well-known" is some circles but considered only a

marginal curiosity in others (if at all).

> That notwithstanding, this conversation is really great to see and I hope

> we get something that works for the usual cases in the original post

> too!

>

proposed by Vladimir V. Kisil for ginac and in more generality by

Ondrej is quite good. I don't think a new name for this is desirable.

Bill.

Nov 18, 2014, 11:28:41 AM11/18/14

to sage-devel

On Tue, Nov 18, 2014 at 8:05 AM, Bill Page <bill...@newsynthesis.org> wrote:

> On 18 November 2014 09:02, David Roe <roed...@gmail.com> wrote:

>> On Tue, Nov 18, 2014 at 5:57 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>>

>>> > I think you are overly focused on trying to define a derivative that

>>> > reduces to the conventional derivative of non-analytic functions

>>> > over the reals.

>>>

>>> I've just been casually following this conversation, but I think it's

>>> important that the derivative of abs(x) be sign(x) not 2*sign(x) or

>>> 1/2*sign(x).

>>>

>

> What makes it important that "the" derivative of abs(x) be sign(x)?

> An important point here is that there is no one single unique

> derivative of non-analytic functions like abs, but rather than all of

> their derivatives can be expressed in terms of just two. I am

> seriously interested in reasons for retaining the status quo.

Because derivative is not just used in the context of functions of a
> On 18 November 2014 09:02, David Roe <roed...@gmail.com> wrote:

>> On Tue, Nov 18, 2014 at 5:57 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>>

>>> > I think you are overly focused on trying to define a derivative that

>>> > reduces to the conventional derivative of non-analytic functions

>>> > over the reals.

>>>

>>> I've just been casually following this conversation, but I think it's

>>> important that the derivative of abs(x) be sign(x) not 2*sign(x) or

>>> 1/2*sign(x).

>>>

>

> What makes it important that "the" derivative of abs(x) be sign(x)?

> An important point here is that there is no one single unique

> derivative of non-analytic functions like abs, but rather than all of

> their derivatives can be expressed in terms of just two. I am

> seriously interested in reasons for retaining the status quo.

complex variable (whether they are analytic or not). Probably more

than 90% of Sage users don't know any complex analysis (as frequently

lamented by rtf). I will certainly acknowledge that people get things

wrong with regard to sqrt and log by not knowing about branch cuts.

But when it comes to the definition of derivative, we need to stay

consistent with the standard definition of lim_{h -> 0} (f(x + h) -

f(x))/h for functions of a real variable (or functions that many

people interpret as just functions of a real variable). Any other

decision will cause frustration for the vast majority of our users.

David

>

>>> If you use a different function, like f.wirtinger_derivative(), then

>>> it doesn't matter so much.

>>> David

>>>

>

> On 18 November 2014 10:11, kcrisman <kcri...@gmail.com> wrote:

>>

>> +1

>>

>

> Although I guess this would be consistent with the over all

> "assimilation philosophy" adopted by Sage, I am rather strongly

> against this in general. In my opinion it is in part what has lead to

> the rather confusing situation in most other computer algebra systems.

> I think rather that one should strive for the most general solution

> consistent with the mathematics. I suppose that to some extent this

> is conditioned by how the subject is taught. It came as a surprise to

> me that a solution of this problem (Wirtinger calculus or CR-calculus)

> was apparently "well-known" is some circles but considered only a

> marginal curiosity in others (if at all).

>

>> That notwithstanding, this conversation is really great to see and I hope

>> we get something that works for the usual cases in the original post

>> too!

>>

>

> Provided that one realizes its limitations I think the solution

> proposed by Vladimir V. Kisil for ginac and in more generality by

> Ondrej is quite good. I don't think a new name for this is desirable.

>

> Bill.

>

Nov 18, 2014, 12:29:26 PM11/18/14

to sage-...@googlegroups.com

The point is rather that there is a real derivative and a complex

derivative. The complex derivative being a generalization of the real

one (http://en.wikipedia.org/wiki/Derivative#Generalizations,

http://en.wikipedia.org/wiki/Generalizations_of_the_derivative#Complex_analysis).

As such, it must reduce to the real derivative as a special case when

all variables are real, otherwise you get inconsistencies.

For example for real numbers, you get:

|x|' = x / |x| = sign(x)

and you can do this numerically. Here is a function that does this for

any angle theta in the complex plane:

def diff(f, z0, theta, eps=1e-8):

h = eps*exp(I*theta)

return (f(z0+h)-f(z0)) / h

For real numbers, you need to set theta=0. This then obviously becomes

the standard definition of a real derivative. So any other definition

than |x|' = sign(x) gives wrong answers. No matter if you know complex

analysis or not.

As far as the derivative of abs(x) in the complex plane for any theta,

the above "diff" function is just the directional derivative, i.e.

derivative in the direction theta. Based on my previous email, the

(only) correct analytic answer is, using Python notation:

x.conjugate()/(2*abs(x)) + x/(2*abs(x)) * exp(-2*I*theta)

And you can check numerically using the function "diff" above that

this is indeed the correct answer (just plug in various complex or

real values for "x" and check that "diff" and the above formula gives

the same numerical answer for all theta).

Bill, you wrote "I think rather that one should strive for the most

general solution

consistent with the mathematics.". Well, the above (i.e.

x.conjugate()/(2*abs(x)) + x/(2*abs(x)) * exp(-2*I*theta)) is the most

general solution consistent with mathematics.

Of these options, only theta=0 gives the real derivative as a special

case, that's what the GiNaC proposal does.

Ondrej

Nov 18, 2014, 1:08:36 PM11/18/14

to sage-devel

On 18 November 2014 12:29, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Tue, Nov 18, 2014 at 9:28 AM, David Roe <roed...@gmail.com> wrote:

>> ...
> On Tue, Nov 18, 2014 at 9:28 AM, David Roe <roed...@gmail.com> wrote:

>> Because derivative is not just used in the context of functions of a

>> complex variable (whether they are analytic or not). Probably more

>> than 90% of Sage users don't know any complex analysis (as frequently

>> lamented by rtf). I will certainly acknowledge that people get things

>> wrong with regard to sqrt and log by not knowing about branch cuts.

>> But when it comes to the definition of derivative, we need to stay

>> consistent with the standard definition of lim_{h -> 0} (f(x + h) -

>> f(x))/h for functions of a real variable (or functions that many

>> people interpret as just functions of a real variable). Any other

>> decision will cause frustration for the vast majority of our users.

>

> Well, I think it doesn't matter if you know complex analysis or not.

I agree, but apparently for a different reason.
>> complex variable (whether they are analytic or not). Probably more

>> than 90% of Sage users don't know any complex analysis (as frequently

>> lamented by rtf). I will certainly acknowledge that people get things

>> wrong with regard to sqrt and log by not knowing about branch cuts.

>> But when it comes to the definition of derivative, we need to stay

>> consistent with the standard definition of lim_{h -> 0} (f(x + h) -

>> f(x))/h for functions of a real variable (or functions that many

>> people interpret as just functions of a real variable). Any other

>> decision will cause frustration for the vast majority of our users.

>

> Well, I think it doesn't matter if you know complex analysis or not.

> The point is rather that there is a real derivative and a complex

> derivative. The complex derivative being a generalization of the

> real one (http://en.wikipedia.org/wiki/Derivative#Generalizations,

> http://en.wikipedia.org/wiki/Generalizations_of_the_derivative#Complex_analysis).

> As such, it must reduce to the real derivative as a special case when

> all variables are real, otherwise you get inconsistencies.

>

education and experience. Although I admit that it is very common

(almost ubiquitous) to teach calculus starting from the notion of

continuity and limits, I my opinion these references on wikipedia are

especially biased. To me from the point of view of computer algebra,

the algebraic properties of derivatives are more important.

For the sake of continuing the argument, from the point of view of

algebra why should we consider derivatives of complex functions as a

generalization of the real one rather than the real derivative as a

defined in terms of something more general? In particular notice that

the so called Wirtinger derivatives also make sense in the case of

quaternion analysis, so should we be expecting to view quaternion

calculus also as a "generalization' of real derivatives?

OK, maybe I am pushing this a little too far. I admit that the

argument from the point of view of limits and without any reference to

conjugate is quite convincing.

> ...

> Bill, you wrote "I think rather that one should strive for the most

> general solution

> consistent with the mathematics.". Well, the above (i.e.

> x.conjugate()/(2*abs(x)) + x/(2*abs(x)) * exp(-2*I*theta)) is the

> most general solution consistent with mathematics.

>

> Of these options, only theta=0 gives the real derivative as a special

> case, that's what the GiNaC proposal does.

>

Have you had a chance to consider the issue of the chain-rule yet?
> general solution

> consistent with the mathematics.". Well, the above (i.e.

> x.conjugate()/(2*abs(x)) + x/(2*abs(x)) * exp(-2*I*theta)) is the

> most general solution consistent with mathematics.

>

> Of these options, only theta=0 gives the real derivative as a special

> case, that's what the GiNaC proposal does.

>

Bill.

Nov 18, 2014, 1:42:01 PM11/18/14

to sage-...@googlegroups.com

analysis is essentially a subset of complex analysis. Is that true

that complex analysis is a subset of quaternion analysis? But I think

it's true that quaternion analysis is a generalization of a real

analysis, so I would definitely expect the quaternion derivatives to

match the real ones.

>

> OK, maybe I am pushing this a little too far. I admit that the

> argument from the point of view of limits and without any reference to

> conjugate is quite convincing.

>

>> ...

>> Bill, you wrote "I think rather that one should strive for the most

>> general solution

>> consistent with the mathematics.". Well, the above (i.e.

>> x.conjugate()/(2*abs(x)) + x/(2*abs(x)) * exp(-2*I*theta)) is the

>> most general solution consistent with mathematics.

>>

>> Of these options, only theta=0 gives the real derivative as a special

>> case, that's what the GiNaC proposal does.

>>

>

> Have you had a chance to consider the issue of the chain-rule yet?

D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

(http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

I am sure that can be proven quite easily. Then you just calculate

directly:

D f(g) / D z = df(g)/dz + df(g)/d conjugate(z) * e^{-2*i*theta} =

= (df/dg * dg/dz + df/d conjugate(g) * d conjugate(g) / dz) + (df/dg *

dg/d conjugate(z) + df/d conjugate(g) * d conjugate(g) / d

conjugate(z)) * e^{-2*i*theta} =

= df/dg * (dg/dz + dg/d conjugate(z) * e^{-2*i*theta}) + df/d

conjugate(g) * (d conjugate(g)/dz + d conjugate(g)/d conjugate(z) *

e^{-2*i*theta}) =

= df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

So at the end, the theta dependence got absorbed into Dg/Dz and D

conjugate(g) / Dz, but it assumes that these directional derivatives

are taken with the same angle theta.

You can now use it to do the example from GiNaC:

cout << abs(log(z)).diff(z) << endl;

// (before) -> D[0](abs)(log(z))*z^(-1)

// (now) -> 1/2*(z^(-1)*conjugate(log(z))+log(z)*conjugate(z)^(-1))*abs(log(z))^(-1)

I.e. f(g) = |g|, g(z) = log(z) and you get:

D |log(z)| / D z = conjugate(g)/(2*|g|) * D log(z) / Dz + g / (2*|g|)

* D conjugate(log(z)) / Dz =

= conjugate(log(z)) / (2*|log(z)|) * 1/z + log(z) / (2*|log(z)|) *

1/conjugate(z) * e^{-2*i*theta})

= 1/(2*|log(z)|) * (conjugate(log(z)) / z + log(z) / conjugate(z) *

e^{-2*i*theta})

So it exactly agrees, except that there is a theta dependence in the

final answer and GiNaC implicitly chose theta=0. Everything in this

example should be straightforward except perhaps:

D conjugate(log(z)) / Dz = d conjugate(log(z)) / dz + d

conjugate(log(z)) / d conjugate(z) * e^{-2*i*theta}

where we first write conjugate(log(z)) = log|z| - I*arg(z) =

log|conjugate(z)| + I*arg(conjugate(z)) = log(conjugate(z)) and then

we can see that the first Wirtinger derivative is zero (no functional

dependence on "z"), and the second one is 1/conjugate(z). So the

answer is:

D conjugate(log(z)) / Dz = 1/conjugate(z) * e^{-2*i*theta}

I hope I didn't make some mistake somewhere, but it looks all

straightforward to me.

Ondrej

Nov 18, 2014, 2:14:40 PM11/18/14

to sage-devel

On 18 November 2014 13:41, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Tue, Nov 18, 2014 at 11:08 AM, Bill Page <bill...@newsynthesis.org> wrote:

>> ...
> On Tue, Nov 18, 2014 at 11:08 AM, Bill Page <bill...@newsynthesis.org> wrote:

>> Have you had a chance to consider the issue of the chain-rule yet?

>

> Yes. Very straightforward, as I suggested in my last email. Just start with:

>

> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>

> and then consider the chain rule for Wirtinger derivatives

> (http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

> I am sure that can be proven quite easily.

Let me make sure I understand your proposal. Are you saying that you
>

> Yes. Very straightforward, as I suggested in my last email. Just start with:

>

> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>

> and then consider the chain rule for Wirtinger derivatives

> (http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

> I am sure that can be proven quite easily.

would introduce the symbolic expression

e^{-2*i*theta}

with theta undefined in the result of all derivatives? So that

diff(x) is always the sum of two terms. In particular

abs(x).diff(x)

would return the symbolic expression

conjugate(x)/(2*abs(x)) + conjugate(x)/(2*abs(x))* e^{-2*i*theta}

If you are, then clearly one can recover both Wirtinger derivatives

from this expression and the rest holds.

> Then you just calculate directly:

> So it exactly agrees, except that there is a theta dependence in the

> final answer and GiNaC implicitly chose theta=0.

>...
> final answer and GiNaC implicitly chose theta=0.

> I hope I didn't make some mistake somewhere, but it looks all

> straightforward to me.

>

It looks OK to me but I must say, it probably seems rather peculiar
> straightforward to me.

>

from the point of view expressed earlier by David Roe.

How can you explain the presence of the e^theta term to someone

without experience in complex analysis or at least multi-variable

calculus?

I thought rather that what you were proposing was to set theta=0 from

the start. If you did that, then I think you still have problems with

the chain rule.

Bill.

Nov 18, 2014, 2:38:12 PM11/18/14

to sage-devel

On 18 November 2014 14:14, Bill Page <bill...@newsynthesis.org> wrote:

> On 18 November 2014 13:41, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> On Tue, Nov 18, 2014 at 11:08 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>> ...

>>> Have you had a chance to consider the issue of the chain-rule yet?

>>

>> Yes. Very straightforward, as I suggested in my last email. Just start with:

>>

>> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>>

>> and then consider the chain rule for Wirtinger derivatives

>> (http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

>> I am sure that can be proven quite easily.

> ...
> On 18 November 2014 13:41, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> On Tue, Nov 18, 2014 at 11:08 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>> ...

>>> Have you had a chance to consider the issue of the chain-rule yet?

>>

>> Yes. Very straightforward, as I suggested in my last email. Just start with:

>>

>> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>>

>> and then consider the chain rule for Wirtinger derivatives

>> (http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

>> I am sure that can be proven quite easily.

> I thought rather that what you were proposing was to set theta=0 from

> the start. If you did that, then I think you still have problems with

> the chain rule.

>

Let me add that the kind of solution to this problem that I did
> the start. If you did that, then I think you still have problems with

> the chain rule.

>

imagine was to implement two derivatives, for example both

f.diff(z) = df/dz + df/d conjugate(z)

and

f.diff2(z) = df/dz - df/d conjugate(z)

diff(z) would equal diff2(z) for all analytic functions and diff would

reduce to the derivative of real non-analytic functions as you desire.

Note that for abs we have

abs(z).diff2(z) = 0

but not in general. There would be no need to discuss this 2nd

derivative with less experienced users until they were ready to

consider more "advanced" mathematics.

Clearly we could implement the chain rule given these two derivatives.

Bill.

Nov 18, 2014, 3:19:20 PM11/18/14

to sage-...@googlegroups.com

On Tue, Nov 18, 2014 at 12:14 PM, Bill Page <bill...@newsynthesis.org> wrote:

> On 18 November 2014 13:41, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> On Tue, Nov 18, 2014 at 11:08 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>> ...

>>> Have you had a chance to consider the issue of the chain-rule yet?

>>

>> Yes. Very straightforward, as I suggested in my last email. Just start with:

>>

>> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>>

>> and then consider the chain rule for Wirtinger derivatives

>> (http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

>> I am sure that can be proven quite easily.

>

> Let me make sure I understand your proposal. Are you saying that you

> would introduce the symbolic expression

>

> e^{-2*i*theta}

>

> with theta undefined in the result of all derivatives? So that

> diff(x) is always the sum of two terms. In particular

>

> abs(x).diff(x)

>

> would return the symbolic expression

>

> conjugate(x)/(2*abs(x)) + conjugate(x)/(2*abs(x))* e^{-2*i*theta}

I think you made a mistake, the correct expression is:
> On 18 November 2014 13:41, Ondřej Čertík <ondrej...@gmail.com> wrote:

>> On Tue, Nov 18, 2014 at 11:08 AM, Bill Page <bill...@newsynthesis.org> wrote:

>>> ...

>>> Have you had a chance to consider the issue of the chain-rule yet?

>>

>> Yes. Very straightforward, as I suggested in my last email. Just start with:

>>

>> D f / D z = df/dz + df/d conjugate(z) * e^{-2*i*theta}

>>

>> and then consider the chain rule for Wirtinger derivatives

>> (http://en.wikipedia.org/wiki/Wirtinger_derivatives#Functions_of_one_complex_variable_2),

>> I am sure that can be proven quite easily.

>

> Let me make sure I understand your proposal. Are you saying that you

> would introduce the symbolic expression

>

> e^{-2*i*theta}

>

> with theta undefined in the result of all derivatives? So that

> diff(x) is always the sum of two terms. In particular

>

> abs(x).diff(x)

>

> would return the symbolic expression

>

> conjugate(x)/(2*abs(x)) + conjugate(x)/(2*abs(x))* e^{-2*i*theta}

conjugate(x)/(2*abs(x)) + x/(2*abs(x)) * e^{-2*i*theta}

>

> If you are, then clearly one can recover both Wirtinger derivatives

> from this expression and the rest holds.

I wasn't even considering what a CAS should do.

>

>> Then you just calculate directly:

>> ...

>> So it exactly agrees, except that there is a theta dependence in the

>> final answer and GiNaC implicitly chose theta=0.

>>...

>> I hope I didn't make some mistake somewhere, but it looks all

>> straightforward to me.

>>

>

> It looks OK to me but I must say, it probably seems rather peculiar

> from the point of view expressed earlier by David Roe.

>

> How can you explain the presence of the e^theta term to someone

> without experience in complex analysis or at least multi-variable

> calculus?

>

> I thought rather that what you were proposing was to set theta=0 from

> the start. If you did that, then I think you still have problems with

> the chain rule.

objections, I first needed to figure out the most general case that

covers everything. I think that's now sufficiently clarified.

> Let me add that the kind of solution to this problem that I did

> imagine was to implement two derivatives, for example both

>

> f.diff(z) = df/dz + df/d conjugate(z)

>

> and

>

> f.diff2(z) = df/dz - df/d conjugate(z)

>

> diff(z) would equal diff2(z) for all analytic functions and diff would

> reduce to the derivative of real non-analytic functions as you desire.

the derivative along the imaginary axis.

> Note that for abs we have

>

> abs(z).diff2(z) = 0

abs(z).diff2(z) = (conjugate(z)-z)/(2*abs(z))

> but not in general. There would be no need to discuss this 2nd

> derivative with less experienced users until they were ready to

> consider more "advanced" mathematics.

>

> Clearly we could implement the chain rule given these two derivatives.

example analytic functions just return the unique complex derivative,

for example:

log(z).diff(z) = 1/z

This holds for all cases. Non-analytic functions like abs(f) can return:

abs(f).diff(z) = (conjugate(f)*f.diff(z) +

f*conjugate(f).diff(z)*e^{-2*i*theta}) / (2*abs(f))

I think that's the correct application of the chain rule. We can set

theta=0, so we would just return:

abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

Which for real "f" (i.e. conjugate(f)=f) simplifies to (as a special case):

abs(f).diff(z) = (f*f.diff(z) + f*f.diff(z)) / (2*abs(f)) = f/abs(f) *

f.diff(z) = sign(f) * f.diff(z)

So it all works.

Unless there is some issue that I don't see, it seems to me we just

need to have one diff(z) function, no need for diff2().

Ondrej

Nov 18, 2014, 3:46:37 PM11/18/14

to sage-...@googlegroups.com

the most general case. We use:

D f(g) / D z =

= df/dg * (dg/dz + dg/d conjugate(z) * e^{-2*i*theta}) + df/d

conjugate(g) * (d conjugate(g)/dz + d conjugate(g)/d conjugate(z) *

e^{-2*i*theta}) =

= df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

Which we derived above. We have f(g) -> |g| and g(z) -> f(z). So we get:
conjugate(g) * (d conjugate(g)/dz + d conjugate(g)/d conjugate(z) *

e^{-2*i*theta}) =

= df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

D |f| / Dz = d|f|/df * Df/Dz + d|f|/d conjugate(f) * D conjugate(f) / Dz =

= (conjugate(f) * Df/Dz + f * D conjugate(f) / Dz) / (2*abs(f))

And then:

Df/Dz = f.diff(z)

D conjugate(f) / Dz = conjugate(f).diff(z)

So I think the formula:

abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

in conjugate(f).diff(z), since if "f" is analytic, like f=log(z), the

conjugate(f) is

not analytic, and so the derivative is theta dependent.

The below holds though:

Nov 18, 2014, 4:50:20 PM11/18/14

to sage-devel

On 18 November 2014 15:19, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Tue, Nov 18, 2014 at 12:14 PM, Bill Page <bill...@newsynthesis.org> wrote:

>>

>> abs(x).diff(x)

>>

>> would return the symbolic expression

>>

>> conjugate(x)/(2*abs(x)) + conjugate(x)/(2*abs(x))* e^{-2*i*theta}

>

> I think you made a mistake, the correct expression is:

>

> conjugate(x)/(2*abs(x)) + x/(2*abs(x)) * e^{-2*i*theta}

>

Yes, sorry.
> On Tue, Nov 18, 2014 at 12:14 PM, Bill Page <bill...@newsynthesis.org> wrote:

>>

>> abs(x).diff(x)

>>

>> would return the symbolic expression

>>

>> conjugate(x)/(2*abs(x)) + conjugate(x)/(2*abs(x))* e^{-2*i*theta}

>

> I think you made a mistake, the correct expression is:

>

> conjugate(x)/(2*abs(x)) + x/(2*abs(x)) * e^{-2*i*theta}

>

>> ...

>> I thought rather that what you were proposing was to set theta=0

>> from the start. If you did that, then I think you still have problems

>> with the chain rule.

>

> For a CAS, I was leaning towards using theta=0. But given your

> objections, I first needed to figure out the most general case that

> covers everything. I think that's now sufficiently clarified.

>

OK.
>> from the start. If you did that, then I think you still have problems

>> with the chain rule.

>

> For a CAS, I was leaning towards using theta=0. But given your

> objections, I first needed to figure out the most general case that

> covers everything. I think that's now sufficiently clarified.

>

>> Let me add that the kind of solution to this problem that I did

>> imagine was to implement two derivatives, for example both

>>

>> f.diff(z) = df/dz + df/d conjugate(z)

>>

>> and

>>

>> f.diff2(z) = df/dz - df/d conjugate(z)

>>

>> diff(z) would equal diff2(z) for all analytic functions and diff would

>> reduce to the derivative of real non-analytic functions as you desire.

>

> Right, diff() is for theta = 0. diff2() is for theta=pi/2, i.e. taking

> the derivative along the imaginary axis.

>

>> Note that for abs we have

>>

>> abs(z).diff2(z) = 0

>

> Actually, for abs you have:

>

> abs(z).diff2(z) = (conjugate(z)-z)/(2*abs(z))

>

>> but not in general. There would be no need to discuss this 2nd

>> derivative with less experienced users until they were ready to

>> consider more "advanced" mathematics.

>>

>> Clearly we could implement the chain rule given these two derivatives.

On 18 November 2014 15:46, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Tue, Nov 18, 2014 at 1:19 PM, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> So I think that functions can return their own correct derivative, for

>> example analytic functions just return the unique complex derivative,

>> for example:

>>

>> log(z).diff(z) = 1/z

>>

>> This holds for all cases. Non-analytic functions like abs(f) can return:

>>

>> abs(f).diff(z) = (conjugate(f)*f.diff(z) +

>> f*conjugate(f).diff(z)*e^{-2*i*theta}) / (2*abs(f))

>

>> So I think that functions can return their own correct derivative, for

>> example analytic functions just return the unique complex derivative,

>> for example:

>>

>> log(z).diff(z) = 1/z

>>

>> This holds for all cases. Non-analytic functions like abs(f) can return:

>>

>> abs(f).diff(z) = (conjugate(f)*f.diff(z) +

>> f*conjugate(f).diff(z)*e^{-2*i*theta}) / (2*abs(f))

>

> Actually, I think I made a mistake. Let's do abs(f).diff(x) again for

> the most general case. We use:

>

> the most general case. We use:

>

> D f(g) / D z =

>

>

> = df/dg * (dg/dz + dg/d conjugate(z) * e^{-2*i*theta}) + df/d

> conjugate(g) * (d conjugate(g)/dz + d conjugate(g)/d conjugate(z) *

> e^{-2*i*theta}) =

>

> = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>

> conjugate(g) * (d conjugate(g)/dz + d conjugate(g)/d conjugate(z) *

> e^{-2*i*theta}) =

>

> = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>

> Which we derived above. We have f(g) -> |g| and g(z) -> f(z). So we get:

>

> D |f| / Dz = d|f|/df * Df/Dz + d|f|/d conjugate(f) * D conjugate(f) / Dz =

>

> = (conjugate(f) * Df/Dz + f * D conjugate(f) / Dz) / (2*abs(f))

>

> And then:

>

> Df/Dz = f.diff(z)

> D conjugate(f) / Dz = conjugate(f).diff(z)

>

> So I think the formula:

>

>

> D |f| / Dz = d|f|/df * Df/Dz + d|f|/d conjugate(f) * D conjugate(f) / Dz =

>

> = (conjugate(f) * Df/Dz + f * D conjugate(f) / Dz) / (2*abs(f))

>

> And then:

>

> Df/Dz = f.diff(z)

> D conjugate(f) / Dz = conjugate(f).diff(z)

>

> So I think the formula:

>

> abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

>

>

> is the most general formula for any theta. The theta dependence is hidden

> in conjugate(f).diff(z), since if "f" is analytic, like f=log(z), the

> conjugate(f) is not analytic, and so the derivative is theta dependent.

>

> The below holds though:

>

>>

> in conjugate(f).diff(z), since if "f" is analytic, like f=log(z), the

> conjugate(f) is not analytic, and so the derivative is theta dependent.

>

> The below holds though:

>

>>

>> I think that's the correct application of the chain rule. We can set

>> theta=0, so we would just return:

>>

>> abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

>>

>> Which for real "f" (i.e. conjugate(f)=f) simplifies to (as a special case):

>>

>> abs(f).diff(z) = (f*f.diff(z) + f*f.diff(z)) / (2*abs(f)) = f/abs(f) *

>> f.diff(z) = sign(f) * f.diff(z)

>>

>> So it all works.

>>

>> Unless there is some issue that I don't see, it seems to me we just

>> need to have one diff(z) function, no need for diff2().

>>

Hmmm... So given only f(z).diff(z) as you have defined it above, how
>> theta=0, so we would just return:

>>

>> abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

>>

>> Which for real "f" (i.e. conjugate(f)=f) simplifies to (as a special case):

>>

>> abs(f).diff(z) = (f*f.diff(z) + f*f.diff(z)) / (2*abs(f)) = f/abs(f) *

>> f.diff(z) = sign(f) * f.diff(z)

>>

>> So it all works.

>>

>> Unless there is some issue that I don't see, it seems to me we just

>> need to have one diff(z) function, no need for diff2().

>>

do I get Df(z)/D conjugate(z), i.e. the other Wirtinger derivative?

Or are you claiming that this is not necessary in general in spite of

the Wirtinger formula for the chain rule?

Bill.

Nov 18, 2014, 5:40:04 PM11/18/14

to sage-...@googlegroups.com

d conjugate(z). The Df(z) / Dz is the complex derivative taking in

direction theta (where it could be theta=0). Given the chain rule, as

I derived above using chain rules for the Wirtinger derivative:

D f(g) / D z = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

I don't see why you would need the isolated Wirtinger derivatives. The

method that implements the derivative of the given function, like

log(z) or abs(z) would simply return the correct formula, as I said

above, e.g.

log(z).diff(z) = 1/z

abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

implemented, maybe some CASes have a general machinery for

derivatives. But I am pretty sure you can simply implemented it as I

outlined.

Let me know if you found any issue with this.

Ondrej

Nov 18, 2014, 8:43:05 PM11/18/14

to sage-...@googlegroups.com

Hi,

With Sage 6.3, I am getting:

sage: abs(x).diff(x)

x/abs(x)

sage: abs(I*x).diff(x)

-x/abs(I*x)

But abs(I*x) == abs(x). So also abs(x).diff(x) and abs(I*x).diff(x)

must be the same. But in the first case we get x/abs(x), and in the

second we got -x/abs(x).

In SymPy, the answer is:

------///

www.mathHandbook.com show

http://www.mathHandbook.com/input/?guess=d(abs(x))

With Sage 6.3, I am getting:

sage: abs(x).diff(x)

x/abs(x)

sage: abs(I*x).diff(x)

-x/abs(I*x)

But abs(I*x) == abs(x). So also abs(x).diff(x) and abs(I*x).diff(x)

must be the same. But in the first case we get x/abs(x), and in the

second we got -x/abs(x).

In SymPy, the answer is:

------///

www.mathHandbook.com show

http://www.mathHandbook.com/input/?guess=d(abs(x))

Nov 18, 2014, 8:51:18 PM11/18/14

to sage-devel

On 18 November 2014 17:40, Ondřej Čertík <ondrej...@gmail.com> wrote:

>

> In my notation, the Wirtinger derivative is d f(z) / d z and d f(z) /

> d conjugate(z). The Df(z) / Dz is the complex derivative taking in

> direction theta (where it could be theta=0). Given the chain rule, as

> I derived above using chain rules for the Wirtinger derivative:

>

> D f(g) / D z = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>

> I don't see why you would need the isolated Wirtinger derivatives.

You mean that only the function being differentiated needs to the
>

> In my notation, the Wirtinger derivative is d f(z) / d z and d f(z) /

> d conjugate(z). The Df(z) / Dz is the complex derivative taking in

> direction theta (where it could be theta=0). Given the chain rule, as

> I derived above using chain rules for the Wirtinger derivative:

>

> D f(g) / D z = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>

> I don't see why you would need the isolated Wirtinger derivatives.

Writinger derivatives (as part of the "formula" that it implements for

the chain rule)?

> The

> method that implements the derivative of the given function, like

> log(z) or abs(z) would simply return the correct formula, as I said

> above, e.g.

>

> log(z).diff(z) = 1/z

>

> abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

>

that you also have

log(f).diff(z) = f.diff(z) / z

right?

> Both formulas hold for any theta.

> I guess it depends on how the CAS is implemented, maybe

> some CASes have a general machinery for derivatives. But

> I am pretty sure you can simply implemented it as I outlined.

>

> Let me know if you found any issue with this.

>

Bill.

Nov 18, 2014, 9:22:10 PM11/18/14

to sage-...@googlegroups.com

On Tue, Nov 18, 2014 at 6:51 PM, Bill Page <bill...@newsynthesis.org> wrote:

> On 18 November 2014 17:40, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> In my notation, the Wirtinger derivative is d f(z) / d z and d f(z) /

>> d conjugate(z). The Df(z) / Dz is the complex derivative taking in

>> direction theta (where it could be theta=0). Given the chain rule, as

>> I derived above using chain rules for the Wirtinger derivative:

>>

>> D f(g) / D z = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>>

>> I don't see why you would need the isolated Wirtinger derivatives.

>

> You mean that only the function being differentiated needs to the

> Writinger derivatives (as part of the "formula" that it implements for

> the chain rule)?

Did you mean to write "You mean that only the function being
> On 18 November 2014 17:40, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>

>> In my notation, the Wirtinger derivative is d f(z) / d z and d f(z) /

>> d conjugate(z). The Df(z) / Dz is the complex derivative taking in

>> direction theta (where it could be theta=0). Given the chain rule, as

>> I derived above using chain rules for the Wirtinger derivative:

>>

>> D f(g) / D z = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>>

>> I don't see why you would need the isolated Wirtinger derivatives.

>

> You mean that only the function being differentiated needs to the

> Writinger derivatives (as part of the "formula" that it implements for

> the chain rule)?

differentiated needs to do the

Writinger derivatives..."?

Yes.

>

>> The

>> method that implements the derivative of the given function, like

>> log(z) or abs(z) would simply return the correct formula, as I said

>> above, e.g.

>>

>> log(z).diff(z) = 1/z

>>

>> abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

>>

>

> If the chain rule must be implemented by each function then I suppose

> that you also have

>

> log(f).diff(z) = f.diff(z) / z

>

> right?

>

>> Both formulas hold for any theta.

>

> The generality provided by theta seems not be be of much interest.

the option 2) in my email above.

>

>> I guess it depends on how the CAS is implemented, maybe

>> some CASes have a general machinery for derivatives. But

>> I am pretty sure you can simply implemented it as I outlined.

>>

>> Let me know if you found any issue with this.

>>

>

> Is this how derivatives are implemented in sympy?

are implemented in csympy (https://github.com/sympy/csympy).

Ondrej

Nov 19, 2014, 9:36:29 AM11/19/14

to sage-devel

On 18 November 2014 21:22, Ondřej Čertík <ondrej...@gmail.com> wrote:

> On Tue, Nov 18, 2014 at 6:51 PM, Bill Page <bill...@newsynthesis.org> wrote:

>> On 18 November 2014 17:40, Ondřej Čertík <ondrej...@gmail.com> wrote:

>>>

>>> In my notation, the Wirtinger derivative is d f(z) / d z and d f(z) /

>>> d conjugate(z). The Df(z) / Dz is the complex derivative taking in

>>> direction theta (where it could be theta=0). Given the chain rule, as

>>> I derived above using chain rules for the Wirtinger derivative:

>>>

>>> D f(g) / D z = df/dg Dg/Dz + df/d conjugate(g) D conjugate(g) / Dz

>>>

>>>

>>> abs(f).diff(z) = (conjugate(f)*f.diff(z) + f*conjugate(f).diff(z)) / (2*abs(f))

>>>

>>

>>>

>>>

>>

>>>

>>> Let me know if you found any issue with this.

>>>

>>>

I implemented this in FriCAS and tried a few examples, e.g.

(4) -> D(abs(f(z,conjugate(z))),z)

_ _ _ _

f(z,z)f (z,z) + f(z,z)f (z,z)

,2 ,1

(4) -------------------------------

_

2abs(f(z,z))

Type: Expression(Integer)

where the ,1 and ,2 notation represents the derivative with respect the the first and second variable of f, respectively.

Then I noticed that if we have f=z we get

conjugate(z).diff(z)

which is 0. So the 2nd term is 0 and the result is just the first Wirtinger derivative.

(4) -> D(abs(f(z,conjugate(z))),z)

_ _ _ _

f(z,z)f (z,z) + f(z,z)f (z,z)

,2 ,1

(4) -------------------------------

_

2abs(f(z,z))

Type: Expression(Integer)

where the ,1 and ,2 notation represents the derivative with respect the the first and second variable of f, respectively.

Then I noticed that if we have f=z we get

conjugate(z).diff(z)

which is 0. So the 2nd term is 0 and the result is just the first Wirtinger derivative.

Perhaps I am misinterpreting something?

Nov 19, 2014, 10:19:07 AM11/19/14

to sage-devel

On 2014-11-19 9:36 AM, "Bill Page" <bill...@newsynthesis.org> wrote:

> ...

> Then I noticed that if we have f=z we get

>

> conjugate(z).diff(z)

>

> which is 0. So the 2nd term is 0 and the result is just the first Wirtinger derivative.

>

> Perhaps I am misinterpreting something?

>

Oops, my fault. According to your definition

conjugate(z).diff(z) = 1

Bill.

Nov 19, 2014, 11:32:22 AM11/19/14

to sage-devel

OK, this looks better!

(1) -> D(abs(x),x)

_

x + x

(1) -------

2abs(x)

Type: Expression(Integer)

(2) -> D(conjugate(x),y)

(2) 0

Type: Expression(Integer)

(3) -> D(conjugate(x),x)

(3) 1

Type: Expression(Integer)

(4) -> f:=operator 'f

(4) f

Type: BasicOperator

(5) -> D(abs(f(x)),x)

, _ _ ,

f(x)f (x) + f(x)f (x)

(5) ---------------------

2abs(f(x))

Type: Expression(Integer)

(6) -> D(abs(log(x)),x)

_ _

xlog(x) + x log(x)

(6) ------------------

_

2xxabs(log(x))

Type: Expression(Integer)

(1) -> D(abs(x),x)

_

x + x

(1) -------

2abs(x)

Type: Expression(Integer)

(2) -> D(conjugate(x),y)

(2) 0

Type: Expression(Integer)

(3) -> D(conjugate(x),x)

(3) 1

Type: Expression(Integer)

(4) -> f:=operator 'f

(4) f

Type: BasicOperator

(5) -> D(abs(f(x)),x)

, _ _ ,

f(x)f (x) + f(x)f (x)

(5) ---------------------

2abs(f(x))

Type: Expression(Integer)

(6) -> D(abs(log(x)),x)

_ _

xlog(x) + x log(x)

(6) ------------------

_

2xxabs(log(x))

Type: Expression(Integer)

Nov 19, 2014, 11:39:57 AM11/19/14

to sage-...@googlegroups.com

theta, so the first Wirtinger derivative is 0, the second one is 1 and

you get:

0 + 1*e^{-2*i*theta})

and if you implicitly set theta=0, then you get 1.

Ondrej

Nov 19, 2014, 11:42:27 AM11/19/14

to sage-...@googlegroups.com

derivatives of arg(z)? Do you have other examples of non-analytic

functions?

Would you mind posting your patch to FriCAS somewhere? I would be

interested in how you implemented it.

Ondrej

Nov 19, 2014, 11:51:21 AM11/19/14

to sage-...@googlegroups.com

play with it. Can you also try:

abs(I*x)

1/abs(x)

1/abs(x)^2

x/abs(x)^3

abs(x)^2

The x/abs(x)^3 is a Coulomb's law in 1D.

Ondrej

Nov 19, 2014, 12:29:37 PM11/19/14

to sage-devel, fricas-devel

Since this mostly concerns FriCAS I am cross posting to that group. I will also post the patch there. For FriCAS list reference the original email thread is here:

https://groups.google.com/forum/#!topic/sage-devel/6j-LcC6tpkE

Here is the result of compiling the patch against the current SourceForge svn trunk:

wspage@opensuse:~> fricas

The directory for FriCAS, /usr/local/lib/fricas/target/x86_64-suse-linux, does not exist.

Goodbye.

wspage@opensuse:~> fricas

Checking for foreign routines

AXIOM="/usr/local/lib64/fricas/target/x86_64-suse-linux"

spad-lib="/usr/local/lib64/fricas/target/x86_64-suse-linux/lib/libspad.so"

foreign routines found

openServer result 0

FriCAS Computer Algebra System

Version: FriCAS 2014-11-14

Timestamp: Wed Nov 19 11:57:49 EST 2014

-----------------------------------------------------------------------------

Issue )copyright to view copyright notices.

Issue )summary for a summary of useful system commands.

Issue )quit to leave FriCAS and return to shell.

-----------------------------------------------------------------------------

https://groups.google.com/forum/#!topic/sage-devel/6j-LcC6tpkE

Here is the result of compiling the patch against the current SourceForge svn trunk:

wspage@opensuse:~> fricas

The directory for FriCAS, /usr/local/lib/fricas/target/x86_64-suse-linux, does not exist.

Goodbye.

wspage@opensuse:~> fricas

Checking for foreign routines

AXIOM="/usr/local/lib64/fricas/target/x86_64-suse-linux"

spad-lib="/usr/local/lib64/fricas/target/x86_64-suse-linux/lib/libspad.so"

foreign routines found

openServer result 0

FriCAS Computer Algebra System

Version: FriCAS 2014-11-14

Timestamp: Wed Nov 19 11:57:49 EST 2014

-----------------------------------------------------------------------------

Issue )copyright to view copyright notices.

Issue )summary for a summary of useful system commands.

Issue )quit to leave FriCAS and return to shell.

-----------------------------------------------------------------------------

(1) -> D(abs(x),x)

_

x + x

(1) -------

2abs(x)

Type: Expression(Integer)

(2) -> D(conjugate(x),x)

(2) 1

Type: Expression(Integer)

(3) -> f:=operator 'f

(3) f

Type: BasicOperator

(4) -> D(abs(f(x)),x)

(2) 1

Type: Expression(Integer)

(3) -> f:=operator 'f

(3) f

Type: BasicOperator

(4) -> D(abs(f(x)),x)

, _ _ ,

f(x)f (x) + f(x)f (x)

(4) ---------------------

2abs(f(x))

Type: Expression(Integer)

(5) -> D(abs(log(x)),x)

2abs(f(x))

Type: Expression(Integer)

(5) -> D(abs(log(x)),x)

_ _

xlog(x) + x log(x)

(5) ------------------

_

2xxabs(log(x))

Type: Expression(Integer)

(6) -> D(log(abs(x)),x)

_

x + x

(6) --------

2

2abs(x)

Type: Expression(Integer)

(7) -> D(abs(%i*x),x)

_

x + x

(7) ----------

2abs(%i x)

Type: Expression(Complex(Integer))

(8) -> D(1/abs(x),x)

_

- x - x

(8) --------

3

2abs(x)

Type: Expression(Integer)

(9) -> D(1/abs(x)^2,x)

_

- x - x

(9) -------

4

abs(x)

Type: Expression(Integer)

(10) -> D(x/abs(x)^3,x)

_ 2 2

- 3xx + 2abs(x) - 3x

(10) ----------------------

5

2abs(x)

Type: Expression(Integer)

(11) -> D(abs(x)^2,x)

_

(11) x + x

Type: Expression(Integer)

_

2xxabs(log(x))

Type: Expression(Integer)

(6) -> D(log(abs(x)),x)

_

x + x

(6) --------

2

2abs(x)

Type: Expression(Integer)

(7) -> D(abs(%i*x),x)

_

x + x

(7) ----------

2abs(%i x)

Type: Expression(Complex(Integer))

(8) -> D(1/abs(x),x)

_

- x - x

(8) --------

3

2abs(x)

Type: Expression(Integer)

(9) -> D(1/abs(x)^2,x)

_

- x - x

(9) -------

4

abs(x)

Type: Expression(Integer)

(10) -> D(x/abs(x)^3,x)

_ 2 2

- 3xx + 2abs(x) - 3x

(10) ----------------------

5

2abs(x)

Type: Expression(Integer)

(11) -> D(abs(x)^2,x)

_

(11) x + x

Type: Expression(Integer)

Bill.

Nov 19, 2014, 9:23:57 PM11/19/14

to sage-...@googlegroups.com

Since this mostly concerns FriCAS I am cross posting to that group. I will also post the patch there. For FriCAS list reference the original email thread is here:

But if you come up with a solution Sage (or Ginac, or whatever) can implement too, please let us know!

Nov 19, 2014, 9:36:25 PM11/19/14

to sage-devel

On 19 November 2014 21:23, kcrisman <kcri...@gmail.com> wrote:

>

>

>> Since this mostly concerns FriCAS I am cross posting to that group. I will also post the patch there. For FriCAS list reference the original email thread is here:

>>

>

> But if you come up with a solution Sage (or Ginac, or whatever) can implement too, please let us know!

>

Right now Ondrej's proposed definition is looking pretty good to me
>

>

>> Since this mostly concerns FriCAS I am cross posting to that group. I will also post the patch there. For FriCAS list reference the original email thread is here:

>>

>

> But if you come up with a solution Sage (or Ginac, or whatever) can implement too, please let us know!

>

but I think it needs more extensive testing. Apparently Ginac with

Vladimir V. Kisil's patch is able to compute at least some of the

results I showed with FriCAS. If someone has used Ginac and is able

to compile it with the patch, it would be good to have these results

for comparison.

Yes, certainly. We can also continue this thread.

Bill.

Nov 20, 2014, 1:54:32 AM11/20/14

to sage-...@googlegroups.com

im(z) and any other non-analytic function that we can find.

Ondrej

Nov 20, 2014, 9:41:09 AM11/20/14

to sage-devel

On 20 November 2014 01:54, Ondřej Čertík <ondrej...@gmail.com> wrote:

>

> What you posted looks good. But we need to test it for arg(z), re(z),

> im(z) and any other non-analytic function that we can find.

>

>

> What you posted looks good. But we need to test it for arg(z), re(z),

> im(z) and any other non-analytic function that we can find.

>

(1) -> re(x)==(conjugate(x)+x)/2

Type: Void

(2) -> im(x)==%i*(conjugate(x)-x)/2

Type: Void

(3) -> arg(x)==log(x/abs(x))/%i

Type: Void

(4) -> re %i

Compiling function re with type Complex(Integer) -> Fraction(Complex

(Integer))

(4) 0

Type: Fraction(Complex(Integer))

(5) -> im %i

Compiling function im with type Complex(Integer) -> Fraction(Complex

(Integer))

(5) 1

Type: Fraction(Complex(Integer))

(6) -> arg %i

Compiling function arg with type Complex(Integer) -> Expression(

Complex(Integer))

(6) - %i log(%i)

Type: Expression(Complex(Integer))

(7) -> complexNumeric %

(7) 1.5707963267_948966192

Type: Complex(Float)

(8) -> D(re(x),x)

Compiling function re with type Variable(x) -> Expression(Integer)

(8) 1

Type: Expression(Integer)

(9) -> D(im(x),x)

Compiling function im with type Variable(x) -> Expression(Complex(

Integer))

(9) 0

Type: Expression(Complex(Integer))

(10) -> D(arg(x),x)

Compiling function arg with type Variable(x) -> Expression(Complex(

Integer))

_ 2 2

%i xx - 2%i abs(x) + %i x

(10) ---------------------------

2

2x abs(x)

Type: Expression(Complex(Integer))

I had a thought. I suppose that all non-analytic (nonholomorphic) functions of interest can be written in terms of conjugate and some analytic functions, e.g.

abs(x)=sqrt(x*conjugate(x))

so perhaps all we really need is to know how to differentiate conjugate properly?

Bill

Nov 20, 2014, 9:53:05 AM11/20/14

to sage-devel

So here (20) is a simpler expression for derivative of arg:

(16) -> abs(x)==sqrt(x*conjugate(x))

Compiled code for abs has been cleared.

Compiled code for arg has been cleared.

1 old definition(s) deleted for function or rule abs

Type: Void

(17) -> arg(x)==log(x/abs(x))/%i

1 old definition(s) deleted for function or rule arg

Type: Void

(18) -> arg %i

Compiling function abs with type Complex(Integer) -> Expression(

(16) -> abs(x)==sqrt(x*conjugate(x))

Compiled code for abs has been cleared.

Compiled code for arg has been cleared.

1 old definition(s) deleted for function or rule abs

Type: Void

(17) -> arg(x)==log(x/abs(x))/%i

1 old definition(s) deleted for function or rule arg

Type: Void

(18) -> arg %i

Compiling function abs with type Complex(Integer) -> Expression(

Complex(Integer))

Compiling function arg with type Complex(Integer) -> Expression(

Complex(Integer))

(18) - %i log(%i)

Type: Expression(Complex(Integer))

(19) -> complexNumeric %

(19) 1.5707963267_948966192

Type: Complex(Float)

(20) -> D(arg(x),x)

Compiling function abs with type Variable(x) -> Expression(Integer)

Type: Expression(Complex(Integer))

(19) -> complexNumeric %

(19) 1.5707963267_948966192

Type: Complex(Float)

(20) -> D(arg(x),x)

Compiling function abs with type Variable(x) -> Expression(Integer)

Compiling function arg with type Variable(x) -> Expression(Complex(

Integer))

_

- %ix + %i x

(20) ------------

_

2xx

Type: Expression(Complex(Integer))

In general I am a little uncertain if, how and when to deal with simplifications of expressions like abs that can be expressed in terms of more fundamental/elementary functions. What do you think?

Bill.(20) ------------

_

2xx

Type: Expression(Complex(Integer))

In general I am a little uncertain if, how and when to deal with simplifications of expressions like abs that can be expressed in terms of more fundamental/elementary functions. What do you think?

Nov 20, 2014, 11:08:01 AM11/20/14

to sage-...@googlegroups.com

true for abs(x), arg(x), re(x), im(x) and conjugate(x). Other

non-analytic functions are combinations of those. The only other way

to create some non-analytic functions is to define their real and

complex parts using "x" and "y", e.g.

f(x+iy) = (x^2+y^2) + i*(2*x*y)

You can imagine arbitrary complicated expressions. But then you just

substitute z, conjugate(z) for x, y.

So I think that for most things that people would use a CAS for, this is true.

>

> Bill

Nov 20, 2014, 11:16:39 AM11/20/14