On Mon, Nov 24, 2014 at 10:23 PM, Bill Page <bill.p...@newsynthesis.org> wrote:
> On 24 November 2014 at 17:43, Ondřej Čertík <ondrej.cer...@gmail.com> wrote:
>> On Mon, Nov 24, 2014 at 1:57 PM, Bill Page <bill.p...@newsynthesis.org> 
>> wrote:
>> ...
>>>
>>> In FriCAS 'abs' is already a kernel function and it implemented the
>>> derivative of 'abs' even before my proposed patch but I think the
>>> current definition is wrong:
>>>
>>> (14) -> D(abs(x),x)
>>>
>>>          abs(x)
>>>    (14)  ------
>>>             x
>>>                                                     Type: 
>>> Expression(Integer)
>>
>> I think that's correct for real numbers, i.e. x/abs(x) = abs(x) / x.
>>
>
> I am not very interested in real numbers.  I am interested in the
> algebra.  Would you say that
>
>   sqrt(x^2).diff(x) = sqrt(x^2)/x
>
> is OK?

I think so, using the following calculation:

sqrt(x^2).diff(x) = exp(1/2*log(x^2)).diff(x) = exp(1/2*log(x^2)) *
1/2 * 1/x^2 * 2*x = sqrt(x^2)/x

The function exp(1/2*log(x^2)) that we differentiate is analytic, so I
don't see any issue here.

>
>>> Rather, I think the correct definition of 'log(z)' is the solution of
>>>
>>>   z = exp(?)
>>>
>>> So we can write z=exp(log(z)) by definition.
>>
>> Indeed, exp(log(z))=z always,
>
> Not just "true always". It is the definition of 'log(z)'.
>
>>
>> In both (A) and (B),
>> it is true that z = exp(log(z)). However, these are different:
>>
>> (A) log(exp(z)) = z + 2*pi*i*n
>> (B) log(exp(z)) = z + 2*pi*i*floor((pi-Im z) / 2*pi)
>>
>> In (B), you get a single value, but in (A) you get multiple values,
>> one for each "n".
>>
>
> Better to say (A) is true "\forall n \in Integer"

Yes.

>
>> I am very familiar with the approach (B) and I think I understand
>> exactly what follows from what and how to derive all the formulas.
>
> (B) is about choosing a particular "branch" of 'log' - the principal
> value.

Correct.

> But I don't want to be forced to make a choice of branch until
> I actually need to evaluate an expression numerically.

I understand that's what you want. I am just trying to understand how
exactly this works.

>
>> But I am not 100% sure with (A), I was hoping you can help, since
>> that's the approach that you want to use in FriCAS.
>
> (A) is not quite the approach I want to use for 'Expression' in
> FriCAS.  I want 'log(exp(z))' to be the solution of
>
>   exp(z) = exp(?)
>
> The best way to say that algebraically (symbolically) is just
> 'log(exp(z))', i.e. without evaluation.  This is what FriCAS already
> does in the case of
>
> (1) -> z:Expression Complex Integer
>                                                                    Type: Void
> (2) -> exp(log(z))
>
>    (2)  z
>                                            Type: Expression(Complex(Integer))
> (3) -> log(exp(z))
>
>               z
>    (3)  log(%e )
>                                            Type: Expression(Complex(Integer))
>
> but unfortunately not in the case of 'Expression Integer'.
>
> (4) -> z:Expression Integer
>                                                                    Type: Void
> (5) -> log(exp(z))
>
>    (5)  z
>                                                     Type: Expression(Integer)
>
> I think that what it currently does for 'Expression Integer' should be
> considered a bug.
>
>> I think what I wrote is correct for (A), but please correct me if I am wrong.
>>
>>> This is exactly analogous
>>> to the treatment of 'sqrt(z)' as the solution to
>>>
>>>   z = ? * ?
>>>
>
> We have
>
>   sqrt(z)^2 = z
>
> but
>
>   sqrt(z^2) = sqrt(z^2)
>
>>>> However, this definition quickly becomes impractical, because you
>>>> need to be able to numerically evaluate symbolic expressions, and
>>>> you would need to carry the symbolic term 2*pi*i*n around.
>>>
>>> We do not need an extra term.  We only need axioms for the correct
>>> behavior of the expression 'log(z)'. But 'log(z)' does not denote a
>>> function in the sense of a many-to-one mapping.  The inverse of a
>>> function is only a function (possibly partial) if the function is
>>> injective (one-to-one).
>>
>> Sure, that's why you have "n" in the formula for log(z) in (A), and
>> the function is multivalued over all "n".
>>
>
> No.  As you have written it, it is a function of two variables with
> one value for each z and n.
>
>   f(z,n) = z + 2*pi*i*n
>
> I think what you are trying to say is
>
>  (A) log(exp(z)) = { z + 2*pi*i*n | for all n in Integer}

Exactly, that's what I meant.

>
> and
>
>   sqrt(z) = {  x | x^2 =z }

Sure, though I would just define

sqrt(z) = exp(1/2 * log(z))

>
> Although it may seem simple in this case, in general implementing sets
> with comprehension like this requires logic and takes us outside of
> algebra as such into the realm of theorem proving.

Sure. But that's what you want, correct?

>
>>>
>>> The Riemann surface is an important tool in complex analysis but I
>>> have yet to see it used explicitly in any computer algebra system as
>>> a representation of complex functions.
>>
>> I thought the Riemann surface gives you a way to couple "n" in
>> log(a*b), log(a) and log(b) in such a way that you get exactly
>> log(a*b)-log(a)-log(b)=0. I.e. that the Riemann surface is (A).
>> I agree that I haven't seen it used in CAS. But I think it must be
>> implicitly used in FriCAS somehow. Maybe you can clarify that.
>
> I don't think it is used in FriCAS at all.  A Riemann surface is a
> manifold. At each point in the manifold we need to evaluate a
> function, but how would you propose to represent this surface
> algebraically?  For example, the surface of a sphere is a manifold.
> For that we need a co-ordinate system that labels each point on the
> surface.  In a sense the important thing about a Riemann surface is
> its global topology and this is different for each complex holomorphic
> function.  For 'exp' it might make sense to include 'n' as one of
> these co-ordinates.  But this is not what FriCAS does.

Ok. I don't know what FriCAS does.

>
>>> ...
>>> In order to numerically evaluate a symbolic expression it is indeed
>>> necessary to choose a branch in the case of "multi-valued functions",
>>> i.e. expressions like 'sqrt(x)' and 'log(x)'.  But this choice should
>>> not effect the axiomatic properties of these expressions.
>>
>> I see. I think in the definition:
>>
>> (A) log(z) = log|z| + i*arg(z) + 2*pi*i*n
>>
>> the result is multivalued, and you obtain all the numerical values by
>> plugging different integers for "n".
>>
>
> Sure but "plugging different integers for n" makes n a parameter.

We clarified this above, what I meant is a set of all values when n is integer.

>
>>>
>>> In FrCAS we have
>>>
>>> (2) -> normalize(log(a*b)-log(a)-log(b))
>>>
>>>    (2)  0
>>>                                                     Type: 
>>> Expression(Integer)
>>>
>>> and with my proposed patch we also have 'conjugate(log(z)) =
>>> log(conjugate(z))' by definition. So this is like your (A).
>>
>> What does Expression(Integer) mean? Does it mean that "a" and "b"
>>are integers? I.e. does the above hold if a=b=-1?
>
> No. Integer is the domain of the coefficients of the rational
> function.  In other words Expression Integer is a ratio of two
> polynomials with coefficients from Integer and variables from Symbol
> or a kernels over Expression Integer (recursively).

Ok.

>
>>
>> This is precisely the part that I don't understand with the approach
>> (A). log(a*b), log(a) and log(b) are all multivalued, so you would
>> naively think, that log(a*b)-log(a)-log(b) = 0 + 2*pi*i*n, for all
>> "n". But I think this is not the case, I think the "n" in log(a*b) is
>> coupled to the implicit "n" in log(a) and log(b) in such a way, that
>> the result is exactly 0. Can you clarify exactly how this works?
>
> Try it this way:
>
>   a*b = exp(?1)
>   a = exp(?2)
>   b = exp(?3)
>
> I think 'normalize' is saying that there is a solution that makes
>
>   ?1 - ?2 - ?3  = 0.

Ok, but why wouldn't normalize return 2*pi*i instead? Or 4*pi*i?
Surely there is a solution so that

?1 - ?2 - ?3  = 2*pi*i

and a different solution so that

?1 - ?2 - ?3  = 4*pi*i

In other words, how exactly are the operations on the multivalued sets
log(x) defined? Things like log(a*b) - log(a) in this case. In the
case (B), it is defined exactly by the branch cut, so there is no
ambiguity.

>
> Maybe there is a way to think of this as a kind of coupling of n's if
> that was the way that log was represented but I am quite sure that
> this is not what 'normalize' is doing.
>
>>>
>>> Now I am a little unclear on what you are proposing.  Are you
>>> suggesting that symbolic computations (such as those using
>>> 'Expression' in FriCAS) should somehow introduce an independent
>>> 'argument' function instead of defining it as
>>>
>>>   argument(x) = log(x/abs(x))/%i
>> ...
>>>
>>> or that 'abs' is somehow an important part of these equalities?
>>
>> I am not sure what you mean by this question.
>>
>
> I meant that I did not understand what you are proposing for how to
> represent the value of 'log(z)' symbolically, i.e. when the value of z
> is unknown.

Ah ok. I would represent it by the approach (B). But then, as we
talked about, it's not true that
conjugate(log(z)) = log(conjugate(z)). Since you want this property to
hold, then the approach (B)
does not work for you, obviously. So I am trying to understand how
exactly are all the operations
defined in your approach. You said your approach is not (A) exactly.
So I am just trying to understand.

>
>>> Note
>>> that 'normalize' does not have to introduce these sort of terms to
>>> in order to return 0 in result  (2) above.
>>
>> See my questions above about this.
>>
>
> 'normalize' re-writes Expression using the minimum number of
> algebraically independent transcendental kernels.  In the case above
> that is just 0.
>
> --
>
> Let's take a step back:  Is this discussion going any place useful for
> you?  We seem to be talking mostly about FriCAS.  Does this discussion
> really belong here on the sage-devel mailing list?

This discussion is about how a CAS should handle (complex)
differentiation. Since it started here, I would finish it here, so
that the whole thread is in one mailinglist for future reference.

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+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at http://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to