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.
