changeset 29166:b58e3a04fab3

sinpi.m, cospi.m: New trigonometric functions (bug #59615) * scripts/elfun/cospi.m, scripts/elfun/sinpi.m: New functions. * scripts/elfun/module.mk: Add cospi.m, sinpi.m to build system. * NEWS: Add sinpi, cospi to list of new functions for 7.1. * arith.txi: Add @DOCSTRING entries for new functions to manual.
author Rik <rik@octave.org>
date Tue, 08 Dec 2020 11:13:26 -0800
parents ee20ff0ceb60
children bb6bb306b8a6
files NEWS doc/interpreter/arith.txi scripts/elfun/cospi.m scripts/elfun/module.mk scripts/elfun/sinpi.m
diffstat 5 files changed, 161 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Dec 07 17:32:04 2020 -0800
+++ b/NEWS	Tue Dec 08 11:13:26 2020 -0800
@@ -178,6 +178,7 @@
 
 ### Alphabetical list of new functions added in Octave 7
 
+* `cospi`
 * `getpixelposition`
 * `endsWith`
 * `jsondecode`
@@ -188,6 +189,7 @@
 * `memory`
 * `ordqz`
 * `rng`
+* `sinpi`
 * `startsWith`
 * `streamribbon`
 * `xtickangle`
--- a/doc/interpreter/arith.txi	Mon Dec 07 17:32:04 2020 -0800
+++ b/doc/interpreter/arith.txi	Tue Dec 08 11:13:26 2020 -0800
@@ -198,6 +198,12 @@
 @DOCSTRING(acscd)
 @DOCSTRING(acotd)
 
+Finally, there are two trigonometric functions that calculate special
+arguments with increased accuracy.
+
+@DOCSTRING(sinpi)
+@DOCSTRING(cospi)
+
 @node Sums and Products
 @section Sums and Products
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/elfun/cospi.m	Tue Dec 08 11:13:26 2020 -0800
@@ -0,0 +1,76 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{y} =} cospi (@var{x})
+## Compute cosine (@var{x} * pi) for each element of @var{x} accurately.
+##
+## The ordinary @code{cos} function uses IEEE floating point numbers and may
+## produce results that are very close (within a few eps) of the correct
+## value, but which are not exact.  The @code{cospi} function is more accurate
+## and returns 0 exactly for half-integer values of @var{x} (e.g., @dots{},
+## -3/2, -1/2, 1/2, 3/2, @dots{}), and +1/-1 for integer values.
+##
+## Example @*
+## comparison of @code{cos} and @code{cospi} for half-integer values of @var{x}
+##
+## @example
+## @group
+## cos ([-3/2, -1/2, 1/2, 3/2] * pi)
+## @result{}
+##      -1.8370e-16   6.1232e-17   6.1232e-17  -1.8370e-16
+##
+## cospi ([-3/2, -1/2, 1/2, 3/2])
+## @result{}
+##        0   0   0   0
+## @end group
+## @end example
+##
+## @seealso{sinpi, cos}
+## @end deftypefn
+
+function y = cospi (x)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  ## Advance phase by pi/2 so that algorithm from sinpi can be used.
+  ## Unwrap integer multiples so that new domain is [0, 2).
+  x = mod (x + 0.5, 2);
+
+  ## Integer multiples of pi must be exactly zero.
+  x(x == 1) = 0;
+
+  y = sin (x * pi);
+
+endfunction
+
+
+%!assert (cospi ([-3/2, -1/2, 1/2, 3/2]) == 0)
+%!assert (cospi ([-2, -1, 0, 1, 2]), [1, -1, 1, -1, 1])
+%!assert (cospi (100 + [0.1:0.1:0.9]), cos ([0.1:0.1:0.9]*pi), 2*eps (100))
+
+%!error <Invalid call> cospi ()
--- a/scripts/elfun/module.mk	Mon Dec 07 17:32:04 2020 -0800
+++ b/scripts/elfun/module.mk	Tue Dec 08 11:13:26 2020 -0800
@@ -16,6 +16,7 @@
   %reldir%/atan2d.m \
   %reldir%/atand.m \
   %reldir%/cosd.m \
+  %reldir%/cospi.m \
   %reldir%/cot.m \
   %reldir%/cotd.m \
   %reldir%/coth.m \
@@ -26,6 +27,7 @@
   %reldir%/secd.m \
   %reldir%/sech.m \
   %reldir%/sind.m \
+  %reldir%/sinpi.m \
   %reldir%/tand.m
 
 %canon_reldir%dir = $(fcnfiledir)/elfun
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/elfun/sinpi.m	Tue Dec 08 11:13:26 2020 -0800
@@ -0,0 +1,75 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{y} =} sinpi (@var{x})
+## Compute sine (@var{x} * pi) for each element of @var{x} accurately.
+##
+## The ordinary @code{sin} function uses IEEE floating point numbers and may
+## produce results that are very close (within a few eps) of the correct
+## value, but which are not exact.  The @code{sinpi} function is more accurate
+## and returns 0 exactly for integer values of @var{x} and +1/-1 for
+## half-integer values (e.g., @dots{}, -3/2, -1/2, 1/2, 3/2, @dots{}).
+##
+## Example @*
+## comparison of @code{sin} and @code{sinpi} for integer values of @var{x}
+##
+## @example
+## @group
+## sin ([0, 1, 2, 3] * pi)
+## @result{}
+##      0   1.2246e-16  -2.4493e-16   3.6739e-16
+##
+## sinpi ([0, 1, 2, 3])
+## @result{}
+##        0   0   0   0
+## @end group
+## @end example
+##
+## @seealso{cospi, sin}
+## @end deftypefn
+
+function y = sinpi (x)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  ## Unwrap integer multiples so that new domain is [0, 2)
+  x = mod (x, 2);
+
+  ## Integer multiples of pi must be exactly zero
+  x(x == 1) = 0;
+
+  y = sin (x * pi);
+
+endfunction
+
+
+%!assert (sinpi ([-1, -2, 0, 1, 2]) == 0)
+%!assert (sinpi ([-3/2, -1/2, 1/2, 3/2]), [1, -1, 1, -1])
+%!assert (sinpi (100 + [0.1:0.1:0.9]), sin ([0.1:0.1:0.9]*pi), 2*eps (100))
+
+%!error <Invalid call> sinpi ()