Thanks Waldek. As usual I appreciate your thorough look at what I
wrote for conjugate.

On 11 September 2014 07:28, Waldek Hebisch <[email protected]> wrote:
>> > Bill Page wrote:
>>
>> The code that I wrote for conjugate assumes that operators always
>> represent holomorphic functions, while conjugate itself is explicitly
>> not holomorphic so a substitution such as you suggest does not make
>> sense.
>
> You clearly allow non-holomorphic arguments to conjugate, otherwise
> 'conjugate(conjugate(x))' would be illegal.

Yes.  What I meant was the conjugate assumes the an *user-defined*
operator and *most* built-in functions are holomorphic.  conjugate
itself, as well as abs are non-holomorphic.  Maybe there are others?

> Rather, you assume
> that conjugate will be always pushed onto variables/parameters
> and that _in context of differentiation_ we will substitute
> only holomorphic functions for variables.

I assume that conjugate commutes with (most) other functions.

It is not my intention to make assumptions about what functions
(holomorphic or non-holomorphic) witll be substituted for variables.
Can you give me an example where I seem to be doing that?

>  But in other
> context you allow non-holomorphic things.

I want to allow non-holomorphic things where ever possible.

> Pushing conjugate
> to variables in itself is debatable:
>
> (14) -> conjugate(log(-1))
>
>          ________
>    (14)  log(- 1)
>                                                     Type: Expression(Integer)
> (15) -> eval(conjugate(log(x)), x = -1)
>
>    (15)  log(- 1)
>                                                     Type: Expression(Integer)
>
> you get different result depending on when exactly we plug in
> constant argument to logarithm.
>

This was an error in my code that I have fixed in the most recent
version on the wiki.

The new code in FunctionalSpecialFunction is the following:

    evaluate(opconjugate, iiconjugate)$BasicOperatorFunctions1(F)
--
    dconjugate(lo : List OF) : OF == overbar lo.1
    display(opconjugate,dconjugate)
--
    derivative(opconjugate, (x : F) : F +-> 0)
--
    iiconjugate(x:F):F ==
      is?(x, opconjugate) => argument(retract(x)@K)(1)
      is?(x, opabs) => x
      retractIfCan(x)@Union(Symbol, "failed") case Symbol => iconjugate(x)
      x:=eval(x,kernels(x), _
        map((k:Kernel F):F +-> _
          ( (height(k)=0 or height(k)=1 and
retractIfCan(k::F)@Union(Symbol, "failed") case Symbol)
=>iconjugate(k::F);map(iiconjugate,k)), _
          kernels(x))$ListFunctions2(Kernel F,F))
      if R has conjugate : R -> R then
        x:=map(conjugate$R,numer x)::F / _
          map(conjugate$R,denom x)::F
      return x
--
    iconjugate x ==
      zero? x => 0
      is?(x, opconjugate) => argument(retract(x)@K)(1)
      is?(x, opabs) => x
      kernel(opconjugate, x)
--
    if R has abs : R -> R then
      import from Polynomial R
      iiabs x ==
        (r := retractIfCan(x)@Union(Fraction Polynomial R, "failed"))
          case "failed" => iabs x
        f := r::Fraction Polynomial R
        (a := retractIfCan(numer f)@Union(R, "failed")) case "failed" or
          (b := retractIfCan(denom f)@Union(R,"failed")) case "failed" => iabs x
        abs(a::R)::F / abs(b::R)::F
    else iiabs x == iabs x
--
    iabs x ==
      zero? x => 0
      one? x => 1
      is?(x, opabs) => x
      is?(x, opconjugate) => kernel(opabs, argument(retract(x)@K)(1))
      if R has abs : R -> R then
        a := retractIfCan(x)@Union(R, "failed")
        a case R => abs(a::R)::F
      smaller?(x, 0) => kernel(opabs, -x)
      kernel(opabs, x)
--

I am still a little uncomfortable with how I wrote the recursion in
iiconjugate. In the most recent version I changed slightly how I use
height(k).  I did not realized that variables (symbols) and kernels
like log(-1) are both said to have height of 1 in the
expression/kernel tree structure..  Maybe there is a better way?

> You have:
>
> (21) -> conjugate(log(conjugate(x) + x))
>                    _
>    (21)  log(x + x)
>                                                     Type: Expression(Integer)
>
> but when real part of x is negative we are on the conventional
> branch cut of logarithm and some folks may be upset by such
> simplification (not that unlike previous example where problem
> set was of lower dimension here we have problem on open set).

I don't understand your comment.  If log is holomorphic I do not see a
problem with this result.  Could you explain?

>
>>
>> The reason that I wanted D(conjugate(x), x) = 0 is to have D
>> correspond to the first Wirtinger derivative that I mentioned in
>> another email chain.  It is not clear to me that this could result in
>> nasty bugs.  Maybe this is possible in the cases where the chain rule
>> is applied since in that case the conjugate Wirtinger derivative would
>> be required.
>
> But chain rule is applied automatically when computing derivatives.

Yes, I admit that might be a problem.

> Consider:
>
> (13) -> D(abs(x + conjugate(x)), x)
>
>             _
>             x + x
>    (13)  -----------
>               _
>          2abs(x + x)
>                                                     Type: Expression(Integer)
>
> complex (Wirtinger) derivative of the above is twice of the above.
>

As I understand it the Wirtinger derivative is normally distinguished
from what is called "complex derivative".  It is apparently also
sometimes called CR-calculus in North America.

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

Wikipedia:

"permits the construction of a differential calculus for such
functions that is entirely analogous to the ordinary differential
calculus for functions of real variables"

>
> Actually, it seems that even leaving derivatives of conjugate
> unevaluated we need to be careful.  Namely, given
> a differential Ring R_0 and any formal operation f we can form
> differential ring R_1 where f and all its derivative remain
> unevaluated.  But we want to have _some_ simplification
> so we divide R_1 by appropriate equivalence relation.
> For the result to be a differential ring equivalence
> classes should be cosets of a differential ideal, in
> particular set of elements of R_1 equivalent to 0
> should be a differential ideal.  So we need to make
> sure that simplifications are consistent with
> derivative.
>

OK

>>
>> I would like to collect some examples of such errors.
>

Thank you very much for these!

>
> With your current code:
>
> (24) -> normalize(exp(conjugate(x)+x)+exp(x) + exp(conjugate(x)))
>    _
>
>    >> Error detected within library code:
>    Hidden constant detected
>
> With derivative of 'conjugate' changes to error:
>
> (1) -> integrate(exp(conjugate(y)*x), x)
>
>    >> Error detected within library code:
>    differentiating conjugate
>
> (3) -> normalize(exp(conjugate(y)*x)+exp(x))
>
>    >> Error detected within library code:
>    differentiating conjugate
>
> (3) -> limit(exp(conjugate(y)*x), x=%plusInfinity)
>
>    >> Error detected within library code:
>    differentiating conjugate
>
> (3) -> series(conjugate(x), x=1)
>
>
>    >> Error detected within library code:
>    differentiating conjugate
>

The last example produces a result using the version of FriCAS
currently installed on the wiki.  Is it correct?

Bill.

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/fricas-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to