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.