# HG changeset patch
# User Georgios Ouzounis <ouzounis_georgios@hotmail.com>
# Date 1394194748 -7200
#      Fri Mar 07 14:19:08 2014 +0200
# Node ID 015eabcffeb1811af5b58d82615c321a15c2a490
# Parent  90d51df6222ae015cd105015d395cbab793795c0
Add udecode, uencode functions and update INDEX.

diff -r 90d51df6222a -r 015eabcffeb1 INDEX
--- a/INDEX	Sun Feb 16 22:41:27 2014 -0500
+++ b/INDEX	Fri Mar 07 14:19:08 2014 +0200
@@ -17,6 +17,8 @@
   specgram
   square
   tripuls
+  udecode
+  uencode
 Filtering
   filtfilt
   filtic
diff -r 90d51df6222a -r 015eabcffeb1 inst/udecode.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inst/udecode.m	Fri Mar 07 14:19:08 2014 +0200
@@ -0,0 +1,119 @@
+## Copyright (C) 2014 Georgios Ouzounis <ouzounis_georgios@hotmail.com>
+##
+## 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
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{out} =} udecode (@var{in}, @var{n})
+## @deftypefnx {Function File} {@var{out} =} udecode (@var{in}, @var{n}, @var{v})
+## @deftypefnx {Function File} {@var{out} =} udecode (@var{in}, @var{n}, @var{v}, @var{overflows})
+## Invert the operation of uencode.
+## @seealso{uencode}
+## @end deftypefn
+
+function out = udecode (in, n, v = 1, overflows = "saturate")
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (in != fix (in))
+    error ("udecode: IN must be matrix of integers.");
+  endif
+
+  if (n < 2 || n > 32 || n != fix (n))
+    error ("udecode: N must be an integer in [2 32].");
+  endif
+
+  if (v <= 0)
+    error ("udecode: V must be a possitive integer.");
+  endif
+
+  if (! (strcmp (overflows, "saturate") || strcmp (overflows, "wrap")))
+    error ("uencode: OVERFLOWS must be either \"saturate\" or \"wrap\".");
+  endif
+
+  if ( all (in >= 0))
+    signed = "unsigned";
+    lowerlevel = 0;
+    upperlevel = (2 ^ n) - 1;
+  else
+    signed = "signed";
+    lowerlevel = - 2 ^ (n - 1);
+    upperlevel = (2 ^ (n - 1)) - 1;
+  endif
+
+  if (strcmp (overflows, "saturate"))
+
+    if (strcmp (signed, "unsigned"))
+      in(in > upperlevel) = upperlevel;
+    elseif (strcmp (signed, "signed"))
+      in(in < lowerlevel) = lowerlevel;
+      in(in > upperlevel) = upperlevel;
+    endif
+
+  elseif (strcmp (overflows, "wrap"))
+
+    if (strcmp (signed, "unsigned"))
+      idx = in > upperlevel;
+      in(idx) = mod (in(idx), 2 ^ n);
+    elseif (strcmp (signed, "signed"))
+      idx = in < lowerlevel;
+      in(idx) = mod (in(idx) + 2 ^ (n - 1), 2 ^ n) - 2 ^ (n - 1);
+      idx = in > upperlevel;
+      in(idx) = mod (in(idx) + 2 ^ (n - 1), 2 ^ n) - 2 ^ (n - 1);
+    endif
+
+  endif
+
+  width = 2 * v / 2 ^ n;
+
+  out = double (in) .* width;
+  if (strcmp (signed, "unsigned"))
+    out = out - v;
+  endif
+
+endfunction
+
+%!test
+%! u = [0 0 0 0 0 1 2 3 3 3 3 3 3];
+%! y = udecode(u, 2);
+%! assert(y, [-1 -1 -1 -1 -1 -0.5 0 0.5 0.5 0.5 0.5 0.5 0.5]);
+
+%!test
+%! u = [0 1 2 3 4 5 6 7 8 9 10];
+%! y = udecode(u, 2, 1, "saturate");
+%! assert(y, [-1 -0.5 0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]);
+
+%!test
+%! u = [0 1 2 3 4 5 6 7 8 9 10];
+%! y = udecode(u, 2, 1, "wrap");
+%! assert(y, [-1 -0.5 0 0.5 -1 -0.5 0 0.5 -1 -0.5 0]);
+
+%!test
+%! u = [-4 -3 -2 -1 0 1 2 3];
+%! y = udecode(u, 3, 2);
+%! assert(y, [-2, -1.5 -1 -0.5 0 0.5 1 1.5]);
+
+%!test
+%! u = [-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7];
+%! y = udecode(u, 3, 2, "saturate");
+%! assert(y, [-2 -2 -2 -2 -1.5 -1 -0.5 0 0.5 1 1.5 1.5 1.5 1.5 1.5]);
+
+%!test
+%! u = [-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7];
+%! y = udecode(u, 3, 2, "wrap");
+%! assert(y, [0.5 1 1.5 -2 -1.5 -1 -0.5 0 0.5 1 1.5 -2 -1.5 -1 -0.5]);
diff -r 90d51df6222a -r 015eabcffeb1 inst/uencode.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inst/uencode.m	Fri Mar 07 14:19:08 2014 +0200
@@ -0,0 +1,76 @@
+## Copyright (C) 2014 Georgios Ouzounis <ouzounis_georgios@hotmail.com>
+##
+## 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
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{out} =} uencode (@var{in}, @var{n})
+## @deftypefnx {Function File} {@var{out} =} uencode (@var{in}, @var{n}, @var{v})
+## @deftypefnx {Function File} {@var{out} =} uencode (@var{in}, @var{n}, @var{v}, @var{signed})
+## Quantize the entries of the array @var{in} using 2^@var{n} quantization levels.
+## @seealso{udecode}
+## @end deftypefn
+
+function out = uencode (in, n, v = 1, signed = "unsigned")
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (n < 2 || n > 32 || n != fix (n))
+    error ("uencode: N must be an integer in [2 32].");
+  endif
+
+  if (v <= 0)
+    error ("uencode: V must be a possitive integer.");
+  endif
+
+  if (! (strcmp (signed, "signed") || strcmp (signed, "unsigned")))
+    error ("uencode: SIGNED must be either \"signed\" or \"unsigned\".");
+  endif
+
+  out = zeros (size (in));
+
+  width = 2 * v / 2 ^ n;
+
+  out(in >= v) = (2 ^ n) - 1;
+  idx = (in > -v) & (in < v);
+  out(idx) = floor ((in(idx) + v) ./ width);
+  if (strcmp (signed, "signed"))
+    out = out - 2 ^ (n - 1);
+  endif
+
+endfunction
+
+%!test
+%! u = [-3:0.5:3];
+%! y = uencode (u, 2);
+%! assert (y, [0 0 0 0 0 1 2 3 3 3 3 3 3]);
+
+%!test
+%! u = [-4:0.5:4];
+%! y = uencode (u, 3, 4);
+%! assert (y, [0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 7]);
+
+%!test
+%! u = [-8:0.5:8];
+%! y = uencode(u, 4, 8, "unsigned");
+%! assert (y, [0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 15];
+
+%!test
+%! u = [-8:0.5:8];
+%! y = uencode(u, 4, 8, "signed");
+%! assert (y, [-8 -8 -7 -7 -6 -6 -5 -5 -4 -4 -3 -3 -2 -2 -1 -1 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 7];
