On May 17, 2005, at 07:01 am, Prof Brian Ripley wrote:
On Mon, 16 May 2005 r.hankin@noc.soton.ac.uk wrote:
The complex versions of atain(), asin(), acos() are not documented except in the source code.
Thank you, but your patch does not address that so they would become undocumented (they no longer follow the comment in the source code, which BTW is regarded as documentation). Could you please supply documentation to match this change, including the exact definition you have implemented. Also: have you looked at atan2?
OK, this follows PR#7871, discussing branch cuts of inverse trig
functions.
In this email, I provide a context diff between complex.c (R-2.1.0) and
a version that
moves the branch cuts to the standard places. The changes are
documented in the code.
I also give updated Trig.Rd and Hyperbolic.Rd files which document the
behaviour
of the new functions. R-2.1.0 passes "make check" with the new files
(after editing
Rdutils.Rd, which caused a problem).
I have not attempted to alter z_atan2(): there appear to be unrelated
issues here.
For example, atan2(0,0) gives 0 as documented, but atan2(0i,0i) gives
NA.
Also, atan2(0,1i) returns an error (I would expect a zero here too).
I feel it is better to consider z_atan2() as a separate issue. I will
file a separate bugreport
for this.
diff -c <old complex.c> <new complex.c>
*** /Users/rksh/downloads/R-2.1.0/src/main/complex.c Mon Apr 18
22:30:00 2005
--- complex.c Tue May 17 13:35:27 2005
***************
*** 355,360 ****
--- 355,365 ----
/* Complex Arcsin and Arccos Functions */
/* Equation (4.4.37) Abramowitz and Stegun */
+ /* with additional terms to force the branch
+ /* to agree with figure 4.4, p79. Continuity */
+ /* on the branch cuts (real axis; y==0, |x| > 1) is */
+ /* standard: z_asin() is continuous from below if x >= 1 */
+ /* and continuous from above if x <= -1. */
static void z_asin(Rcomplex *r, Rcomplex *z)
{
***************
*** 367,372 ****
--- 372,382 ----
bet = t1 - t2;
r->r = asin(bet);
r->i = log(alpha + sqrt(alpha*alpha - 1));
+
+ if(y<0 || (y==0 && x > 1)){
+ r->i *= -1;
+ }
+
}
static void z_acos(Rcomplex *r, Rcomplex *z)
***************
*** 379,384 ****
--- 389,399 ----
/* Complex Arctangent Function */
/* Equation (4.4.39) Abramowitz and Stegun */
+ /* with additional terms to force the branch cuts */
+ /* to agree with figure 4.4, p79. Continuity */
+ /* on the branch cuts (pure imaginary axis; x==0, |y|>1) */
+ /* is standard: z_asin() is continuous from the right */
+ /* if y >= 1, and continuous from the left if y <= -1. */
static void z_atan(Rcomplex *r, Rcomplex *z)
{
***************
*** 388,393 ****
--- 403,416 ----
r->r = 0.5 * atan(2 * x / ( 1 - x * x - y * y));
r->i = 0.25 * log((x * x + (y + 1) * (y + 1)) /
(x * x + (y - 1) * (y - 1)));
+
+ if(x*x + y*y > 1){
+ r->r += M_PI_2;
+ if(x < 0 || (x==0 && y<0)){
+ r->r -= M_PI;
+ }
+ }
+
}
static void z_atan2(Rcomplex *r, Rcomplex *csn, Rcomplex *ccs)
====FILE Hyperbolic.Rd STARTS====
\name{Hyperbolic}
\title{Hyperbolic Functions}
\usage{
cosh(x)
sinh(x)
tanh(x)
acosh(x)
asinh(x)
atanh(x)
}
\alias{cosh}
\alias{sinh}
\alias{tanh}
\alias{acosh}
\alias{asinh}
\alias{atanh}
\description{
These functions give the obvious hyperbolic functions. They
respectively compute the hyperbolic cosine, sine, tangent, and their
inverses, arc-cosine, arc-sine, arc-tangent (or \dQuote{\emph{area
cosine}},
etc).
}
\arguments{
\item{x}{a numeric or complex vector}
}
\details{
These are generic functions: methods can be defined for them
individually or via the \code{\link{Math}} group generic.
Branch cuts are consistent with the inverse trigonometric functions
\code{asin()} et seq, and agree with those defined in Abramowitz and
Stegun, figure 4.7, page 86.
}
\seealso{
The trigonometric functions, \code{\link{cos}}, \code{\link{sin}},
\code{\link{tan}}, and their inverses
\code{\link{acos}}, \code{\link{asin}}, \code{\link{atan}}.
The logistic distribution function \code{\link{plogis}} is a shifted
version of \code{tanh()}.
}
\keyword{math}
====FILE Hyperbolic.Rd ENDS====
====File Trig.Rd STARTS====
\name{Trig}
\alias{Trig}
\alias{cos}
\alias{sin}
\alias{tan}
\alias{acos}
\alias{asin}
\alias{atan}
\alias{atan2}
\title{Trigonometric Functions}
\description{
These functions give the obvious trigonometric functions. They
respectively compute the cosine, sine, tangent, arc-cosine, arc-sine,
arc-tangent, and the two-argument arc-tangent.
}
\usage{
cos(x)
sin(x)
tan(x)
acos(x)
asin(x)
atan(x)
atan2(y, x)
}
\arguments{
\item{x, y}{numeric or complex vector}
}
\details{
The arc-tangent of two arguments \code{atan2(y,x)} returns the angle
between the x-axis and the vector from the origin to \eqn{(x,y)},
i.e., for positive arguments \code{atan2(y,x) == atan(y/x)}.
Angles are in radians, not degrees (i.e., a right angle is
\eqn{\pi/2}).
All except \code{atan2} are generic functions: methods can be defined
for them individually or via the \code{\link{Math}} group generic.
For the inverse trigonometric functions, branch cuts are defined as in
Abramowitz and Stegun, figure 4.4, page 79. Continuity on the
branch cuts is standard.
\item For \code{asin()} and \code{acos()}, there are two cuts, both
along the real axis: \eqn{\left(-\infty,-1\right]}{\(-infinity,1\]}
and \eqn{\left[1,\infty\right)}{\[1,infinity\)}. Functions
\code{asin()} and \code{acos()} are continuous from above on the
interval \eqn{\left(-\infty,-1\right]}{\(-infinity,1\]} and
continuous from below on
\eqn{\left[1,\infty\right)}{\[1,infinity\)}.
\item For \code{atan()} there are two cuts, both along the pure
imaginary axis: \eqn{\left(-i\infty,-i\right]}{\(-i*infinity,-i\]}
and \eqn{\left[i,i\infty\right)}{\[i,i*infinity\)}. Function
\code{atan()} is continuous from the left on the interval
\eqn{\left(-i\infty,-i\right]}{\(-i*infinity,-i\]} and from the
right on the interval
\eqn{\left[i,i\infty\right)}{\[i,i*infinity\)}.
}
\references{
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988)
\emph{The New S Language}.
Wadsworth \& Brooks/Cole.
Abramowitz, M. and Stegun, I. (1964). \emph{Handbook of
Mathematical Functions}, Dover.
}
\examples{
#Visualize branch cuts:
x <- seq(from = -4, to = 4, len = 100)
z <- outer(x,1i*x,"+")
persp(x,x,Im(asin(z)),theta= 40,phi=40,r=1e9, expand=0.6,
ticktype="detailed")
persp(x,x,Re(atan(z)),theta=-40,phi=40,r=1e9, expand=0.6,
ticktype="detailed")
#check continuity on branch cuts:
asin( 3+ 1e-9i*(-1:1))
asin(-3+ 1e-9i*(-1:1))
atan( 3i + 1e-9*(-1:1))
atan(-3i + 1e-9*(-1:1))
}
\keyword{math}
====FILE Trig.Rd ENDS====
--
Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
tel 023-8059-7743