# HG changeset patch # User Rik # Date 1607454806 28800 # Node ID b58e3a04fab3cdf4ba348f425f11e2ec6f8bcff1 # Parent ee20ff0ceb607c5290b34edd082d3ed044461f5d 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. diff -r ee20ff0ceb60 -r b58e3a04fab3 NEWS --- 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` diff -r ee20ff0ceb60 -r b58e3a04fab3 doc/interpreter/arith.txi --- 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 diff -r ee20ff0ceb60 -r b58e3a04fab3 scripts/elfun/cospi.m --- /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 . +## +## 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 +## . +## +######################################################################## + +## -*- 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 cospi () diff -r ee20ff0ceb60 -r b58e3a04fab3 scripts/elfun/module.mk --- 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 diff -r ee20ff0ceb60 -r b58e3a04fab3 scripts/elfun/sinpi.m --- /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 . +## +## 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 +## . +## +######################################################################## + +## -*- 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 sinpi ()