Hello Richard, On Fri, Aug 5, 2011 at 11:34 PM, Richard B. Kreckel <kreckel@xxxxxxxx> wrote: > Hi everybody, > > On 11/27/2010 08:37 AM, Michael Kerrisk wrote: >> >> Hi Andries, >> >> Since you are the mathematician, can you comment? >> >> Thanks, >> >> Michael >> >> On Fri, Nov 26, 2010 at 9:57 AM, Richard B. Kreckel<kreckel@xxxxxxxx> >> wrote: >>> >>> Hi! >>> >>> The man pages for cacos, cacosf, cacosl, catan, catanf, catanl, cacosh, >>> cacoshf, cacoshl, catanh, catanhf, and catanhl contain wrong maths. >>> >>> cacos, cacosf, cacosl: >>> The formula given in the man page >>> cacos(z) = -i clog(z + csqrt(z * z - 1)) >>> gives wrong results in second and fourth quadrant of complex plain. >>> The formula >>> cacos(z) = -i clog(z + I*csqrt(1 - z * z)) >>> gives correct results. >>> >>> catan, catanf, catanl: >>> The formula given in the man page >>> catan(z) = 1 / 2i clog((1 + iz) / (1 - iz)) >>> gives wrong results on the negative imaginary axis beginning at -I >>> (along one of the two branch cuts). Besides, the formula is written >>> in an ambiguous way. >>> The formula >>> catan(z) = (clog(1 + iz) - clog(1 - iz)) / 2i >>> gives correct results. >>> >>> cacosh, cacoshf, cacoshl: >>> The formula given in the man page >>> cacosh(z) = (0.5) * clog((1 + z) / (1 - z)) >>> gives wrong results everywhere in the complex plain. (The formula >>> seems to be copied from the one for catanh, where it is sometimes >>> correct.) >>> The formula >>> cacosh(z) = 2 * clog(csqrt((z + 1)/2) + csqrt((z - 1)/2)) >>> gives correct results. >>> >>> catanh, catanhf, catanhl: >>> The formula given in the man page >>> catanh(z) = 0.5 * clog((1 + z) / (1 - z)) >>> gives wrong results on the positive real axis beginning at 1 (along >>> one of the two branch cuts). >>> The formula >>> catanh(z) = 0.5 * (clog(1 + z) - clog(1 - z)) >>> gives correct results. >>> >>> I've also checked casin, casinf, casinl, casinh, casinhf, and casinhl and >>> the formulae given there >>> casin(z) = -i clog(iz + csqrt(1 - z * z)) >>> casinh(z) = clog(z + csqrt(z * z + 1)) >>> are actually correct. >>> >>> I suspect that some of these errors are due to somebody trying to >>> "simplify" >>> these formulae. Since this can ruin the behavior, I recommend to add a >>> comment to the upstream sources that warns against attempt of >>> simplification. >>> >>> For the sake of reference, I am looking at manpages-dev 3.25-1 on >>> Debian/squeeze. >>> >>> Bye! >>> -richy. >>> -- >>> Richard B. Kreckel >>> <http://www.ginac.de/~kreckel/> > > This doesn't have seem to have been fixed in the Linux man pages, does it? Sorry -- no, not yet. > May I suggest a non-mathematical approach to moving forward? > > Just write a little C program and compare the complex results of > a) the library implementation of catan, cacos, etc., > b) the formula written in the man page, and > c) the formula I proposed above. > If you include a couple of values from all four quadrants, you'll see that > my formula always agrees with the implementation while the one from the man > page doesn't. Now there's a good idea ;-). It would have been even better if you'd sent me a program--I don't mess round with complex numbers every day of the week... > Is there anything else I can do to convince you that this should be fixed? > If yes, pretty please, let me know! I would really appreciate getting this > fixed. So, I eventually ironed out my complex math problems and came up with the below: === /* Link with "-lm" */ #include <complex.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char *argv[]) { double complex z, c, f1, f2; double complex i = I; if (argc != 3) { fprintf(stderr, "Usage: %s <real> <imag>\n"); exit(EXIT_FAILURE); } z = atof(argv[1]) + atof(argv[2]) * I; c = cacos(z); printf("cacos() = %6.3f %6.3f*i\n", creal(c), cimag(c)); f1 = -i * clog(z + csqrt(z * z - 1)); f2 = -i * clog(z + i * csqrt(1 - z * z)); printf("f1 = %6.3f %6.3f*i\n", creal(f1), cimag(f1)); printf("f2 = %6.3f %6.3f*i\n", creal(f2), cimag(f2)); exit(EXIT_SUCCESS); } === Some sample runs certainly seem to prove your point for that function at least: $ ./cacos 1 1 cacos() = 0.905 -1.061*i f1 = 0.905 -1.061*i f2 = 0.905 -1.061*i $ ./cacos -1 -1 cacos() = 2.237 1.061*i f1 = 2.237 1.061*i f2 = 2.237 1.061*i $ ./cacos -1 1 cacos() = 2.237 -1.061*i f1 = -2.237 1.061*i f2 = 2.237 -1.061*i $ ./cacos 1 -1 cacos() = 0.905 1.061*i f1 = -0.905 -1.061*i f2 = 0.905 1.061*i The above is what you meant, right? Thanks, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface"; http://man7.org/tlpi/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html