changelog shortlog tags changeset files revisions annotate raw

scripts/general/mod.m

changeset 10289: 4b124317dc38
parent:c1fff751b5a8
author: John W. Eaton <jwe@octave.org>
date: Tue Feb 09 20:58:55 2010 -0500 (51 minutes ago)
permissions: -rw-r--r--
description: base_properties::set_children: account for hidden children
1## Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008,
2## 2009 Paul Kienzle
3##
4## This file is part of Octave.
5##
6## Octave is free software; you can redistribute it and/or modify it
7## under the terms of the GNU General Public License as published by
8## the Free Software Foundation; either version 3 of the License, or (at
9## your option) any later version.
10##
11## Octave is distributed in the hope that it will be useful, but
12## WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14## General Public License for more details.
15##
16## You should have received a copy of the GNU General Public License
17## along with Octave; see the file COPYING. If not, see
18## <http://www.gnu.org/licenses/>.
19
20## -*- texinfo -*-
21## @deftypefn {Mapping Function} {} mod (@var{x}, @var{y})
22## Compute the modulo of @var{x} and @var{y}. Conceptually this is given by
23##
24## @example
25## x - y .* floor (x ./ y)
26## @end example
27##
28## and is written such that the correct modulus is returned for
29## integer types. This function handles negative values correctly. That
30## is, @code{mod (-1, 3)} is 2, not -1, as @code{rem (-1, 3)} returns.
31## @code{mod (@var{x}, 0)} returns @var{x}.
32##
33## An error results if the dimensions of the arguments do not agree, or if
34## either of the arguments is complex.
35## @seealso{rem, fmod}
36## @end deftypefn
37
38## Author: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
39## Modified by: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
40## Adapted by: jwe
41
42function r = mod (x, y)
43
44 if (nargin != 2)
45 print_usage ();
46 endif
47
48 if (! size_equal (x, y) && ! (isscalar (x) || isscalar (y)))
49 error ("mod: argument sizes must agree");
50 endif
51
52 if (isreal (x) && isreal (y))
53 nz = y != 0.0;
54 if (all (nz(:)))
55 ## No elements of y are zero.
56 if (isinteger(x) || isinteger(y))
57 if (isinteger (x))
58 typ = class (x);
59 else
60 typ = class (y);
61 endif
62 r = x - y .* cast (floor (double(x) ./ double(y)), typ);
63 else
64 r = x - y .* floor (x ./ y);
65 endif
66 elseif (isscalar (y))
67 ## y must be zero.
68 r = x;
69 else
70 ## Some elements of y are zero.
71 if (isscalar (x))
72 r = x * ones (size(y), class(y));
73 else
74 r = x;
75 x = x(nz);
76 endif
77 y = y(nz);
78 if (isinteger(x) || isinteger(y))
79 if (isinteger (x))
80 typ = class (x);
81 else
82 typ = class (y);
83 endif
84 r(nz) = x - y .* floor (double(x) ./ double(y));
85 else
86 r(nz) = x - y .* floor (x ./ y);
87 endif
88 endif
89 else
90 error ("mod: complex arguments are not allowed");
91 endif
92
93endfunction
94
95## empty input test
96%!assert (isempty(mod([], [])));
97
98## x mod y, y != 0 tests
99%!assert (mod(5, 3), 2);
100%!assert (mod(-5, 3), 1);
101%!assert (mod(0, 3), 0);
102%!assert (mod([-5, 5, 0], [3, 3, 3]), [1, 2, 0]);
103%!assert (mod([-5; 5; 0], [3; 3; 3]), [1; 2; 0]);
104%!assert (mod([-5, 5; 0, 3], [3, 3 ; 3, 1]), [1, 2 ; 0, 0]);
105
106## x mod 0 tests
107%!assert (mod(5, 0), 5);
108%!assert (mod(-5, 0), -5);
109%!assert (mod([-5, 5, 0], [3, 0, 3]), [1, 5, 0]);
110%!assert (mod([-5; 5; 0], [3; 0; 3]), [1; 5; 0]);
111%!assert (mod([-5, 5; 0, 3], [3, 0 ; 3, 1]), [1, 5 ; 0, 0]);
112%!assert (mod([-5, 5; 0, 3], [0, 0 ; 0, 0]), [-5, 5; 0, 3]);
113
114## mixed scalar/matrix tests
115%!assert (mod([-5, 5; 0, 3], 0), [-5, 5; 0, 3]);
116%!assert (mod([-5, 5; 0, 3], 3), [1, 2; 0, 0]);
117%!assert (mod(-5,[0,0; 0,0]), [-5, -5; -5, -5]);
118%!assert (mod(-5,[3,0; 3,1]), [1, -5; 1, 0]);
119%!assert (mod(-5,[3,2; 3,1]), [1, 1; 1, 0]);
120
121## integer types
122%!assert (mod(uint8(5),uint8(4)),uint8(1))
123%!assert (mod(uint8([1:5]),uint8(4)),uint8([1,2,3,0,1]))
124%!assert (mod(uint8([1:5]),uint8(0)),uint8([1:5]))
125%!error (mod(uint8(5),int8(4)))
126
127## mixed integer/real types
128%!assert (mod(uint8(5),4),uint8(1))
129%!assert (mod(5,uint8(4)),uint8(1))
130%!assert (mod(uint8([1:5]),4),uint8([1,2,3,0,1]))