# HG changeset patch # User Rik # Date 1607391124 28800 # Node ID ee20ff0ceb607c5290b34edd082d3ed044461f5d # Parent a88f6107acebea5ebbdc861e5418d58bd353f0b3 sind.m: Overhaul function for improved accuracy with large inputs. * sind.m: More explicitly describe the advantage of sind() in documentation. Unwrap input in to domain [0, 360) which improves accuracy for large arguments. Zero out inputs which are a multiple of 180 degrees before calling sin() function for improved performance. Expand BIST tests. diff -r a88f6107aceb -r ee20ff0ceb60 scripts/elfun/sind.m --- a/scripts/elfun/sind.m Mon Dec 07 13:34:49 2020 -0800 +++ b/scripts/elfun/sind.m Mon Dec 07 17:32:04 2020 -0800 @@ -27,7 +27,8 @@ ## @deftypefn {} {} sind (@var{x}) ## Compute the sine for each element of @var{x} in degrees. ## -## Returns zero for elements where @code{@var{x}/180} is an integer. +## The function is more exact than @code{sin} for multiples of 180 degrees and +## returns zero rather than a small value on the order of eps. ## @seealso{asind, sin} ## @end deftypefn @@ -37,15 +38,19 @@ print_usage (); endif - I = x / 180; - y = sin (I .* pi); - y(I == fix (I) & isfinite (I)) = 0; + ## Unwrap multiples so that new domain is [0, 360) + x = mod (x, 360); + + ## Integer multiples of pi must be exactly zero + x(x == 180) = 0; + + y = sin (x / 180 * pi); endfunction -%!assert (sind (10:10:90), sin (pi*[10:10:90]/180), -10*eps) -%!assert (sind ([0, 180, 360]) == 0) -%!assert (sind ([90, 270]) != 0) +%!assert (sind (10:20:360), sin ([10:20:360] * pi/180), 5*eps) +%!assert (sind ([-360, -180, 0, 180, 360]) == 0) +%!assert (sind ([-270, -90, 90, 270]), [1, -1, 1, -1]) %!error sind ()