./PaxHeaders.3802/communications-1.2.10000644000000000000000000000013212510010473014265 xustar0030 mtime=1428164923.938510295 30 atime=1428164983.712815029 30 ctime=1428164983.712815029 communications-1.2.1/0000755000000000000000000000000012510010473014532 5ustar00rootroot00000000000000communications-1.2.1/PaxHeaders.3802/src0000644000000000000000000000013212510010567014723 xustar0030 mtime=1428164983.708815162 30 atime=1428164983.712815029 30 ctime=1428164983.712815029 communications-1.2.1/src/0000755000000000000000000000000012510010567015325 5ustar00rootroot00000000000000communications-1.2.1/src/PaxHeaders.3802/op-gm-m.cc0000644000000000000000000000013212510010473016554 xustar0030 mtime=1428164923.954509931 30 atime=1428164924.034508105 30 ctime=1428164983.712815029 communications-1.2.1/src/op-gm-m.cc0000644000000000000000000000741712510010473017112 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include "galois.h" #include "ov-galois.h" #include "galois-ops.h" // galois by matrix ops. DEFBINOP_OP_G (add, galois, matrix, +) DEFBINOP_OP_G (sub, galois, matrix, -) DEFBINOP_OP_G (mul, galois, matrix, *) DEFBINOP_FN_G (div, galois, matrix, xdiv) DEFBINOPX (pow, galois, matrix) { error ("for A^x, A must be square and x scalar"); return octave_value (); } DEFBINOP_FN_G (ldiv, galois, matrix, xleftdiv) DEFBINOP_FN (lt, galois, matrix, mx_el_lt) DEFBINOP_FN (le, galois, matrix, mx_el_le) DEFBINOP_FN (eq, galois, matrix, mx_el_eq) DEFBINOP_FN (ge, galois, matrix, mx_el_ge) DEFBINOP_FN (gt, galois, matrix, mx_el_gt) DEFBINOP_FN (ne, galois, matrix, mx_el_ne) DEFBINOP_FN_G (el_mul, galois, matrix, product) DEFBINOP_FN_G (el_div, galois, matrix, quotient) DEFBINOP_FN_G (el_pow, galois, matrix, elem_pow) DEFBINOP (el_ldiv, galois, matrix) { CAST_BINOP_ARGS (const octave_galois&, const octave_matrix&); return new octave_galois (quotient (v2.matrix_value (), v1.galois_value ())); } DEFBINOP_FN (el_and, galois, matrix, mx_el_and) DEFBINOP_FN (el_or, galois, matrix, mx_el_or) DEFCATOP_G_METHOD (gm_m, galois, matrix, concat) // Need to create temporary Galois array so that matrix values are checked DEFASSIGNOP (assign, galois, matrix) { CAST_BINOP_ARGS (octave_galois&, const octave_matrix&); v1.assign (idx, galois (v2.matrix_value (), v1.galois_value ().m (), v1.galois_value ().primpoly ())); return octave_value (); } void install_gm_m_ops (void) { INSTALL_BINOP (op_add, octave_galois, octave_matrix, add); INSTALL_BINOP (op_sub, octave_galois, octave_matrix, sub); INSTALL_BINOP (op_mul, octave_galois, octave_matrix, mul); INSTALL_BINOP (op_div, octave_galois, octave_matrix, div); INSTALL_BINOP (op_pow, octave_galois, octave_matrix, pow); INSTALL_BINOP (op_ldiv, octave_galois, octave_matrix, ldiv); INSTALL_BINOP (op_lt, octave_galois, octave_matrix, lt); INSTALL_BINOP (op_le, octave_galois, octave_matrix, le); INSTALL_BINOP (op_eq, octave_galois, octave_matrix, eq); INSTALL_BINOP (op_ge, octave_galois, octave_matrix, ge); INSTALL_BINOP (op_gt, octave_galois, octave_matrix, gt); INSTALL_BINOP (op_ne, octave_galois, octave_matrix, ne); INSTALL_BINOP (op_el_mul, octave_galois, octave_matrix, el_mul); INSTALL_BINOP (op_el_div, octave_galois, octave_matrix, el_div); INSTALL_BINOP (op_el_pow, octave_galois, octave_matrix, el_pow); INSTALL_BINOP (op_el_ldiv, octave_galois, octave_matrix, el_ldiv); INSTALL_BINOP (op_el_and, octave_galois, octave_matrix, el_and); INSTALL_BINOP (op_el_or, octave_galois, octave_matrix, el_or); INSTALL_G_CATOP (octave_galois, octave_matrix, gm_m); INSTALL_ASSIGNOP (op_asn_eq, octave_galois, octave_matrix, assign); INSTALL_ASSIGNCONV (octave_base_value, octave_galois, octave_matrix); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/op-gm-s.cc0000644000000000000000000000013112510010473016561 xustar0029 mtime=1428164923.95850984 30 atime=1428164924.034508105 30 ctime=1428164983.712815029 communications-1.2.1/src/op-gm-s.cc0000644000000000000000000000770012510010473017113 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include "galois.h" #include "ov-galois.h" #include "galois-ops.h" // galois by scalar ops. DEFBINOP_OP_G_S2 (add, galois, scalar, +) DEFBINOP_OP_G_S2 (sub, galois, scalar, -) DEFBINOP_FN_G_S2 (mul, galois, scalar, product) DEFBINOP_FN_G_S2 (div, galois, scalar, quotient) DEFBINOP (pow, galois, scalar) { CAST_BINOP_ARGS (const octave_galois&, const octave_scalar&); return new octave_galois (pow (v1.galois_value (), v2.double_value ())); } DEFBINOP_FN_G_S2 (ldiv, galois, scalar, xleftdiv) DEFBINOP_FN_B_S2 (lt, galois, scalar, mx_el_lt) DEFBINOP_FN_B_S2 (le, galois, scalar, mx_el_le) DEFBINOP_FN_B_S2 (eq, galois, scalar, mx_el_eq) DEFBINOP_FN_B_S2 (ge, galois, scalar, mx_el_ge) DEFBINOP_FN_B_S2 (gt, galois, scalar, mx_el_gt) DEFBINOP_FN_B_S2 (ne, galois, scalar, mx_el_ne) DEFBINOP_FN_G_S2 (el_mul, galois, scalar, product) DEFBINOP_FN_G_S2 (el_div, galois, scalar, quotient) DEFBINOP_FN_G (el_pow, galois, scalar, elem_pow) DEFBINOP (el_ldiv, galois, scalar) { CAST_BINOP_ARGS (const octave_galois&, const octave_scalar&); return new octave_galois (quotient (v2.matrix_value (), v1.galois_value ())); } DEFBINOP_FN_B_S2 (el_and, galois, scalar, mx_el_and) DEFBINOP_FN_B_S2 (el_or, galois, scalar, mx_el_or) DEFCATOP (gm_s, galois, scalar) { CAST_BINOP_ARGS (octave_galois&, const octave_scalar&); return new octave_galois (v1.galois_value (). concat (v2.matrix_value (), ra_idx)); } DEFASSIGNOP (assign, galois, scalar) { CAST_BINOP_ARGS (octave_galois&, const octave_scalar&); v1.assign (idx, galois (1, 1, v2.scalar_value (), v1.galois_value ().m (), v1.galois_value ().primpoly ())); return octave_value (); } void install_gm_s_ops (void) { INSTALL_BINOP (op_add, octave_galois, octave_scalar, add); INSTALL_BINOP (op_sub, octave_galois, octave_scalar, sub); INSTALL_BINOP (op_mul, octave_galois, octave_scalar, mul); INSTALL_BINOP (op_div, octave_galois, octave_scalar, div); INSTALL_BINOP (op_pow, octave_galois, octave_scalar, pow); INSTALL_BINOP (op_ldiv, octave_galois, octave_scalar, ldiv); INSTALL_BINOP (op_lt, octave_galois, octave_scalar, lt); INSTALL_BINOP (op_le, octave_galois, octave_scalar, le); INSTALL_BINOP (op_eq, octave_galois, octave_scalar, eq); INSTALL_BINOP (op_ge, octave_galois, octave_scalar, ge); INSTALL_BINOP (op_gt, octave_galois, octave_scalar, gt); INSTALL_BINOP (op_ne, octave_galois, octave_scalar, ne); INSTALL_BINOP (op_el_mul, octave_galois, octave_scalar, el_mul); INSTALL_BINOP (op_el_div, octave_galois, octave_scalar, el_div); INSTALL_BINOP (op_el_pow, octave_galois, octave_scalar, el_pow); INSTALL_BINOP (op_el_ldiv, octave_galois, octave_scalar, el_ldiv); INSTALL_BINOP (op_el_and, octave_galois, octave_scalar, el_and); INSTALL_BINOP (op_el_or, octave_galois, octave_scalar, el_or); INSTALL_G_CATOP (octave_galois, octave_scalar, gm_s); INSTALL_ASSIGNOP (op_asn_eq, octave_galois, octave_scalar, assign); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/cyclpoly.cc0000644000000000000000000000013212510010473017141 xustar0030 mtime=1428164923.942510204 30 atime=1428164924.034508105 30 ctime=1428164983.712815029 communications-1.2.1/src/cyclpoly.cc0000644000000000000000000001733712510010473017501 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include enum cyclic_poly_type { CYCLIC_POLY_MIN=0, CYCLIC_POLY_MAX, CYCLIC_POLY_ALL, CYCLIC_POLY_L }; // A simplified version of the filter function for specific lengths of // a and b in the Galois field GF(2) Array filter_gf2 (const Array& b, const Array& a, const Array& x, const int& n) { int x_len = x.length (); Array si (dim_vector (n, 1), 0); Array y (dim_vector (x_len, 1), 0); for (int i = 0; i < x_len; i++) { y(i) = si(0); if (b(0) && x(i)) y(i) ^= 1; for (int j = 0; j < n - 1; j++) { si(j) = si(j+1); if (a(j+1) && y(i)) si(j) ^= 1; if (b(j+1) && x(i)) si(j) ^= 1; } si(n-1) = 0; if (a(n) && y(i)) si(n-1) ^= 1; if (b(n) && x(i)) si(n-1) ^= 1; } return y; } // Cyclic polynomial is irreducible. I.E. it divides into x^n-1 // without remainder There must surely be an easier way of doing this // as the polynomials are over GF(2). static bool do_is_cyclic_polynomial (const unsigned long long& a1, const int& n, const int& m) { Array a (dim_vector (n+1, 1), 0); Array y (dim_vector (n+1, 1), 0); Array x (dim_vector (n-m+2, 1), 0); y(0) = 1; y(n) = 1; x(0) = 1; for (int i=0; i < m+1; i++) a(i) = (a1 & (1UL << i) ? 1 : 0); Array b = filter_gf2 (y, a, x, n); b.resize(dim_vector (n+1, 1), 0); Array p (dim_vector (m+1, 1), 0); p(0) = 1; Array q = filter_gf2 (a, p, b, m); for (int i=0; i < n+1; i++) if (y(i) ^ q(i)) return false; return true; } DEFUN_DLD (cyclpoly, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{y} =} cyclpoly (@var{n}, @var{k})\n\ @deftypefnx {Loadable Function} {@var{y} =} cyclpoly (@var{n}, @var{k}, @var{opt})\n\ @deftypefnx {Loadable Function} {@var{y} =} cyclpoly (@var{n}, @var{k}, @var{opt}, @var{rep})\n\ This function returns the cyclic generator polynomials of the code\n\ [@var{n},@var{k}]. By default the polynomial with the smallest weight\n\ is returned. However this behavior can be overridden with the @var{opt}\n\ flag. Valid values of @var{opt} are:\n\ \n\ @table @asis\n\ @item @code{\"all\"}\n\ Returns all of the polynomials of the code [@var{n},@var{k}]\n\ @item @code{\"min\"}\n\ Returns the polynomial of minimum weight of the code [@var{n},@var{k}]\n\ @item @code{\"max\"}\n\ Returns the polynomial of the maximum weight of the code [@var{n},@var{k}]\n\ @item @var{l}\n\ Returns the polynomials having exactly the weight @var{l}\n\ @end table\n\ \n\ The polynomials are returns as row-vectors in the variable @var{y}. Each\n\ row of @var{y} represents a polynomial with the least-significant term\n\ first. The polynomials can be returned with an integer representation\n\ if @var{rep} is @code{\"integer\"}. The default behavior is given if @var{rep}\n\ is @code{\"polynomial\"}.\n\ @seealso{gf, isprimitive}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); bool polyrep = true; enum cyclic_poly_type type = CYCLIC_POLY_MIN; RowVector cyclic_polys; int l=0; if (nargin < 2 || nargin > 4) { print_usage (); return retval; } int n = args(0).int_value (); int k = args(1).int_value ();; if (n < 1) { error ("cyclpoly: n must be 1 or greater"); return retval; } if (n <= k) { error ("cyclpoly: k must be less than n"); return retval; } for (int i = 2; i < nargin; i++) { if (args(i).is_scalar_type ()) { l = args(i).int_value (); type = CYCLIC_POLY_L; } else if (args(i).is_string ()) { std::string s_arg = args(i).string_value (); if (s_arg == "integer") polyrep = false; else if (s_arg == "polynomial") polyrep = true; else if (s_arg == "min") type = CYCLIC_POLY_MIN; else if (s_arg == "max") type = CYCLIC_POLY_MAX; else if (s_arg == "all") type = CYCLIC_POLY_ALL; else { error ("cyclpoly: invalid argument"); return retval; } } else { error ("cyclpoly: incorrect argument type"); return retval; } } int m = n - k; // Matlab code seems to think that 1+x+x^3 is of larger weight than // 1+x^2+x^3. So for matlab compatiability the list of polynomials // should be reversed by replacing "i+=2" with "i-=2" and visa-versa. // Thats not going to happen!!! switch (type) { case CYCLIC_POLY_MIN: cyclic_polys.resize (1); for (unsigned long long i = (1UL< (1UL<. // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include DEFUN_DLD (__errcore__, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{c} =} __errcore__ (@var{a}, @var{b})\n\ Returns the number of bit errors comparing the matrices @var{a} and\n\ @var{b}. These matrices must be of the same size. The return matrix @var{c}\n\ will also be of the same size.\n\ \n\ This is an internal function of @code{biterr} and @code{symerr}. You should\n\ use these functions instead.\n\ @seealso{biterr, symerr}\n\ @end deftypefn") { octave_value retval; if (args.length () != 2) { print_usage (); return retval; } Matrix a = args(0).matrix_value (); Matrix b = args(1).matrix_value (); if ((a.rows () != b.rows ()) || (a.cols () != b.cols ())) { error ("__errcore__: Matrix mismatch"); return retval; } unsigned int sz = (sizeof (unsigned int) << 3); Matrix c (a.rows (), a.cols (), 0); for (int i = 0; i < a.rows (); i++) for (int j = 0; j < a.cols (); j++) { unsigned int tmp = (unsigned int)a(i,j) ^ (unsigned int)b(i,j); if (tmp != 0) for (unsigned int k=0; k < sz; k++) if (tmp & (1<. // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include static int get_weight (const Array& codeword, const Matrix& gen, int weight, int depth, int start, int n, int k) { int retval = weight; for (int i = start; i < k ; i++) { OCTAVE_QUIT; Array new_codeword (codeword); int tmp = 0; for (int j = 0; j < n; j++) if (new_codeword (j) ^= (char)gen(i,j)) tmp++; if (tmp < retval) retval = tmp; if (depth < retval) retval = get_weight (new_codeword, gen, retval, depth+1, i+1, n, k); } return retval; } DEFUN_DLD (__gfweight__, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{w} =} __gfweight__ (@var{gen})\n\ Returns the minimum distance @var{w} of the generator matrix @var{gen}.\n\ The codeword length is @var{k}.\n\ \n\ This is an internal function of @code{gfweight}. You should use\n\ @code{gfweight} rather than use this function directly.\n\ @seealso{gfweight}\n\ @end deftypefn") { if (args.length () != 1) { print_usage (); return octave_value (); } Matrix gen = args(0).matrix_value (); int k = gen.rows (); int n = gen.columns (); if (k > 128) { octave_stdout << "__gfweight__: this is likely to take a very long time!!\n"; flush_octave_stdout (); } Array codeword (dim_vector (n, 1), 0); return octave_value ((double)get_weight (codeword, gen, n - k + 1, 1, 0, n, k)); } /* %% Test input validation %!error __gfweight__ () %!error __gfweight__ (1, 2) */ /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/op-m-gm.cc0000644000000000000000000000013112510010473016553 xustar0029 mtime=1428164923.95850984 30 atime=1428164924.034508105 30 ctime=1428164983.712815029 communications-1.2.1/src/op-m-gm.cc0000644000000000000000000000741712510010473017112 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include "galois.h" #include "ov-galois.h" #include "galois-ops.h" // matrix by galois ops. DEFBINOP_OP_G (add, matrix, galois, +) DEFBINOP_OP_G (sub, matrix, galois, -) DEFBINOP_OP_G (mul, matrix, galois, *) DEFBINOP_FN_G (div, matrix, galois, xdiv) DEFBINOP (pow, matrix, galois) { CAST_BINOP_ARGS (const octave_matrix&, const octave_galois&); galois tmp (v1.matrix_value (), v2.m (), v2.primpoly ()); return new octave_galois (pow (tmp, v2.galois_value ())); } DEFBINOP_FN_G (ldiv, matrix, galois, xleftdiv) DEFBINOP_FN (lt, matrix, galois, mx_el_lt) DEFBINOP_FN (le, matrix, galois, mx_el_le) DEFBINOP_FN (eq, matrix, galois, mx_el_eq) DEFBINOP_FN (ge, matrix, galois, mx_el_ge) DEFBINOP_FN (gt, matrix, galois, mx_el_gt) DEFBINOP_FN (ne, matrix, galois, mx_el_ne) DEFBINOP_FN_G (el_mul, matrix, galois, product) DEFBINOP_FN_G (el_div, matrix, galois, quotient) DEFBINOP (el_pow, matrix, galois) { CAST_BINOP_ARGS (const octave_matrix&, const octave_galois&); galois tmp (v1.matrix_value (), v2.m (), v2.primpoly ()); return new octave_galois (elem_pow (tmp, v2.galois_value ())); } DEFBINOP (el_ldiv, matrix, galois) { CAST_BINOP_ARGS (const octave_matrix&, const octave_galois&); return new octave_galois (quotient (v2.galois_value (), v1.matrix_value ())); } DEFBINOP_FN (el_and, matrix, galois, mx_el_and) DEFBINOP_FN (el_or, matrix, galois, mx_el_or) DEFCATOP_G_FN (m_gm, matrix, galois, concat) DEFASSIGNOP_FN (assign, matrix, galois, assign) void install_m_gm_ops (void) { INSTALL_BINOP (op_add, octave_matrix, octave_galois, add); INSTALL_BINOP (op_sub, octave_matrix, octave_galois, sub); INSTALL_BINOP (op_mul, octave_matrix, octave_galois, mul); INSTALL_BINOP (op_div, octave_matrix, octave_galois, div); INSTALL_BINOP (op_pow, octave_matrix, octave_galois, pow); INSTALL_BINOP (op_ldiv, octave_matrix, octave_galois, ldiv); INSTALL_BINOP (op_lt, octave_matrix, octave_galois, lt); INSTALL_BINOP (op_le, octave_matrix, octave_galois, le); INSTALL_BINOP (op_eq, octave_matrix, octave_galois, eq); INSTALL_BINOP (op_ge, octave_matrix, octave_galois, ge); INSTALL_BINOP (op_gt, octave_matrix, octave_galois, gt); INSTALL_BINOP (op_ne, octave_matrix, octave_galois, ne); INSTALL_BINOP (op_el_mul, octave_matrix, octave_galois, el_mul); INSTALL_BINOP (op_el_div, octave_matrix, octave_galois, el_div); INSTALL_BINOP (op_el_pow, octave_matrix, octave_galois, el_pow); INSTALL_BINOP (op_el_ldiv, octave_matrix, octave_galois, el_ldiv); INSTALL_BINOP (op_el_and, octave_matrix, octave_galois, el_and); INSTALL_BINOP (op_el_or, octave_matrix, octave_galois, el_or); INSTALL_G_CATOP (octave_matrix, octave_galois, m_gm); INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_galois, assign); //INSTALL_ASSIGNCONV (octave_base_value, octave_matrix, octave_galois); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/gf.cc0000644000000000000000000000013212510010473015677 xustar0030 mtime=1428164923.954509931 30 atime=1428164924.034508105 30 ctime=1428164983.712815029 communications-1.2.1/src/gf.cc0000644000000000000000000024232212510010473016231 0ustar00rootroot00000000000000// Copyright (C) 1994-1997 Robert Morelos-Zaragoza // Copyright (C) 2002 Phil Karn // Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) /* Part of the function rsenc and the function decode_rs are from Phil Karn. See the website http://www.ka9q.net/code/fec for more details. Parts of the function bchenco and bchdeco are from Robert Morelos-Zaragoza. See the website http://www.eccpage.com for more details. Permission has been granted for a GPL release of his code */ #include #include #include #include #include #include #include #include "galois.h" #include "ov-galois.h" static bool galois_type_loaded = false; // PKG_ADD: autoload ("isgalois", "gf.oct"); // PKG_DEL: autoload ("isgalois", "gf.oct", "remove"); DEFUN_DLD (isgalois, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} isgalois (@var{expr})\n\ Return 1 if the value of the expression @var{expr} is a Galois Field.\n\ @end deftypefn") { if (args.length () != 1) print_usage (); else if (!galois_type_loaded) // Can be of Galois type if the type isn't load :-/ return octave_value (0.); else return octave_value (args(0).type_id () == octave_galois::static_type_id ()); return octave_value (); } /* %% Test input validation %!error isgalois () %!error isgalois (1, 2) */ // FIXME: // I want to replace the "16" below with __OCTAVE_GALOIS_MAX_M_AS_STRING, // but as I don't run the preprocessor when getting the help from the // functions, this can't be done at the point. So if more default primitive // polynomials are added to galoisfield.cc, need to update the "16" here // as well!! DEFUN_DLD (gf, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{y} =} gf (@var{x})\n\ @deftypefnx {Loadable Function} {@var{y} =} gf (@var{x}, @var{m})\n\ @deftypefnx {Loadable Function} {@var{y} =} gf (@var{x}, @var{m}, @var{primpoly})\n\ Creates a Galois field array GF(2^@var{m}) from the matrix @var{x}. The\n\ Galois field has 2^@var{m} elements, where @var{m} must be between 1 and 16.\n\ The elements of @var{x} must be between 0 and 2^@var{m} - 1. If @var{m} is\n\ undefined it defaults to the value 1.\n\ \n\ The primitive polynomial to use in the creation of Galois field can be\n\ specified with the @var{primpoly} variable. If this is undefined a default\n\ primitive polynomial is used. It should be noted that the primitive\n\ polynomial must be of the degree @var{m} and it must be irreducible.\n\ \n\ The output of this function is recognized as a Galois field by Octave and\n\ other matrices will be converted to the same Galois field when used in an\n\ arithmetic operation with a Galois field.\n\ \n\ @seealso{isprimitive, primpoly}\n\ @end deftypefn") { Matrix data; octave_value retval; int nargin = args.length (); int m = 1; int primpoly = 0; if (nargin < 1 || nargin > 3) { print_usage (); return retval; } data = args(0).matrix_value (); if (nargin > 1) m = args(1).int_value (); if (nargin > 2) primpoly = args(2).int_value (); if (!galois_type_loaded) { octave_galois::register_type (); install_gm_gm_ops (); install_m_gm_ops (); install_gm_m_ops (); install_s_gm_ops (); install_gm_s_ops (); galois_type_loaded = true; mlock (); } retval = new octave_galois (data, m, primpoly); return retval; } /* %% Test input validation %!error gf () %!error gf (1, 2, 3, 4) */ static octave_value make_gdiag (const octave_value& a, const octave_value& b) { octave_value retval; if ((!galois_type_loaded) || (a.type_id () != octave_galois::static_type_id ())) gripe_wrong_type_arg ("gdiag", a); else { galois m = ((const octave_galois&) a.get_rep ()).galois_value (); int k = b.nint_value (); if (! error_state) { int nr = m.rows (); int nc = m.columns (); if (nr == 0 || nc == 0) retval = new octave_galois (m); else if (nr == 1 || nc == 1) { int roff = 0; int coff = 0; if (k > 0) { roff = 0; coff = k; } else if (k < 0) { k = -k; roff = k; coff = 0; } if (nr == 1) { int n = nc + k; galois r (n, n, 0, m.m (), m.primpoly ()); for (int i = 0; i < nc; i++) r (i+roff, i+coff) = m (0, i); retval = new octave_galois (r); } else { int n = nr + k; galois r (n, n, 0, m.m (), m.primpoly ()); for (int i = 0; i < nr; i++) r (i+roff, i+coff) = m (i, 0); retval = new octave_galois (r); } } else { galois r = m.diag (k); if (r.capacity () > 0) retval = new octave_galois (r); } } else gripe_wrong_type_arg ("gdiag", a); } return retval; } // PKG_ADD: autoload ("gdiag", "gf.oct"); // PKG_DEL: autoload ("gdiag", "gf.oct", "remove"); DEFUN_DLD (gdiag, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gdiag (@var{v}, @var{k})\n\ Return a diagonal matrix with Galois vector @var{v} on diagonal @var{k}.\n\ The second argument is optional. If it is positive, the vector is placed on\n\ the @var{k}-th super-diagonal. If it is negative, it is placed on the\n\ @var{-k}-th sub-diagonal. The default value of @var{k} is 0, and the\n\ vector is placed on the main diagonal. For example,\n\ \n\ @example\n\ gdiag (gf ([1, 2, 3], 2), 1)\n\ ans =\n\ GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7)\n\ \n\ Array elements =\n\ \n\ 0 1 0 0\n\ 0 0 2 0\n\ 0 0 0 3\n\ 0 0 0 0\n\ \n\ @end example\n\ @seealso{diag}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin == 1 && args(0).is_defined ()) retval = make_gdiag (args(0), octave_value (0.)); else if (nargin == 2 && args(0).is_defined () && args(1).is_defined ()) retval = make_gdiag (args(0), args(1)); else print_usage (); return retval; } /* %% Test input validation %!error gdiag () %!error gdiag (1, 2, 3) */ // PKG_ADD: autoload ("greshape", "gf.oct"); // PKG_DEL: autoload ("greshape", "gf.oct", "remove"); DEFUN_DLD (greshape, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} greshape (@var{a}, @var{m}, @var{n})\n\ Return a matrix with @var{m} rows and @var{n} columns whose elements are\n\ taken from the Galois array @var{a}. To decide how to order the elements,\n\ Octave pretends that the elements of a matrix are stored in column-major\n\ order (like Fortran arrays are stored).\n\ \n\ For example,\n\ \n\ @example\n\ greshape (gf ([1, 2, 3, 4], 3), 2, 2)\n\ ans =\n\ GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11)\n\ \n\ Array elements =\n\ \n\ 1 3\n\ 2 4\n\ \n\ @end example\n\ \n\ The @code{greshape} function is equivalent to\n\ \n\ @example\n\ @group\n\ retval = gf (zeros (m, n), a.m, a.prim_poly);\n\ retval(:) = a;\n\ @end group\n\ @end example\n\ \n\ @noindent\n\ but it is somewhat less cryptic to use @code{reshape} instead of the\n\ colon operator. Note that the total number of elements in the original\n\ matrix must match the total number of elements in the new matrix.\n\ @seealso{reshape, :}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin != 2 && nargin != 3) { print_usage (); } else { int mr = 0, mc = 0; if ((!galois_type_loaded) || (args(0).type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("greshape", args(0)); return retval; } galois a = ((const octave_galois&) args(0).get_rep ()).galois_value (); if (nargin == 2) { RowVector tmp = args(1).row_vector_value (); mr = (int)tmp(0); mc = (int)tmp(1); } else if (nargin == 3) { mr = args(1).nint_value (); mc = args(2).nint_value (); } int nr = a.rows (); int nc = a.cols (); if ((nr * nc) != (mr * mc)) error ("greshape: sizes must match"); else { RowVector tmp1 (mr*mc); for (int i = 0; i < nr; i++) for (int j = 0; j < nc; j++) tmp1(i+j*nr) = (double)a(i, j); galois tmp2 (mr, mc, 0, a.m (), a.primpoly ()); for (int i = 0; i < mr; i++) for (int j = 0; j < mc; j++) tmp2(i, j) = (int)tmp1(i+j*mr); retval = new octave_galois (tmp2); } } return retval; } /* %% Test input validation %!error greshape () %!error greshape (1) %!error greshape (1, 2, 3, 4) */ #define DATA_REDUCTION(FCN) \ \ octave_value_list retval; \ \ int nargin = args.length (); \ \ if (nargin == 1 || nargin == 2) \ { \ octave_value arg = args(0); \ \ int dim = (nargin == 1 ? -1 : args(1).int_value (true) - 1); \ \ if (! error_state) \ { \ if (dim <= 1 && dim >= -1) \ { \ if (galois_type_loaded && (arg.type_id () == \ octave_galois::static_type_id ())) \ { \ galois tmp = ((const octave_galois&)arg.get_rep ()).galois_value (); \ \ if (! error_state) \ retval(0) = new octave_galois (tmp.FCN (dim)); \ } \ else \ { \ gripe_wrong_type_arg (#FCN, arg); \ return retval; \ } \ } \ else \ error (#FCN ": invalid dimension argument = %d", dim + 1); \ } \ } \ else \ print_usage (); \ \ return retval // PKG_ADD: autoload ("gprod", "gf.oct"); // PKG_DEL: autoload ("gprod", "gf.oct", "remove"); DEFUN_DLD (gprod, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gprod (@var{x}, @var{dim})\n\ Product of elements along dimension @var{dim} of Galois array. If\n\ @var{dim} is omitted, it defaults to 1 (column-wise products).\n\ @seealso{prod}\n\ @end deftypefn") { DATA_REDUCTION (prod); } /* %% Test input validation %!error gprod () %!error gprod (1, 2, 3) */ // PKG_ADD: autoload ("gsum", "gf.oct"); // PKG_DEL: autoload ("gsum", "gf.oct", "remove"); DEFUN_DLD (gsum, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gsum (@var{x}, @var{dim})\n\ Sum of elements along dimension @var{dim} of Galois array. If @var{dim}\n\ is omitted, it defaults to 1 (column-wise sum).\n\ @seealso{sum}\n\ @end deftypefn") { DATA_REDUCTION (sum); } /* %% Test input validation %!error gsum () %!error gsum (1, 2, 3) */ // PKG_ADD: autoload ("gsumsq", "gf.oct"); // PKG_DEL: autoload ("gsumsq", "gf.oct", "remove"); DEFUN_DLD (gsumsq, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gsumsq (@var{x}, @var{dim})\n\ Sum of squares of elements along dimension @var{dim} of Galois array.\n\ If @var{dim} is omitted, it defaults to 1 (column-wise sum of squares).\n\ \n\ This function is equivalent to computing\n\ @example\n\ gsum (x .* conj (x), dim)\n\ @end example\n\ but it uses less memory.\n\ @seealso{sumsq}\n\ @end deftypefn") { DATA_REDUCTION (sumsq); } /* %% Test input validation %!error gsumsq () %!error gsumsq (1, 2, 3) */ // PKG_ADD: autoload ("gsqrt", "gf.oct"); // PKG_DEL: autoload ("gsqrt", "gf.oct", "remove"); DEFUN_DLD (gsqrt, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gsqrt (@var{x})\n\ Compute the square root of @var{x}, element by element, in a Galois Field.\n\ @seealso{exp}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin != 1) { print_usage (); return retval; } if (!galois_type_loaded || (args(0).type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("gsqrt", args(0)); return retval; } galois a = ((const octave_galois&) args(0).get_rep ()).galois_value (); retval = new octave_galois (a.sqrt ()); return retval; } /* %% Test input validation %!error gsqrt () %!error gsqrt (1, 2) */ // PKG_ADD: autoload ("glog", "gf.oct"); // PKG_DEL: autoload ("glog", "gf.oct", "remove"); DEFUN_DLD (glog, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} glog (@var{x})\n\ Compute the natural logarithm for each element of @var{x} for a Galois\n\ array.\n\ @seealso{log}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin != 1) { print_usage (); return retval; } if (!galois_type_loaded || (args(0).type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("glog", args(0)); return retval; } galois a = ((const octave_galois&) args(0).get_rep ()).galois_value (); retval = new octave_galois (a.log ()); return retval; } /* %% Test input validation %!error glog () %!error glog (1, 2) */ // PKG_ADD: autoload ("gexp", "gf.oct"); // PKG_DEL: autoload ("gexp", "gf.oct", "remove"); DEFUN_DLD (gexp, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} gexp (@var{x})\n\ Compute the anti-logarithm for each element of @var{x} for a Galois\n\ array.\n\ @seealso{exp}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin != 1) { print_usage (); return retval; } if (!galois_type_loaded || (args(0).type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("gexp", args(0)); return retval; } galois a = ((const octave_galois&) args(0).get_rep ()).galois_value (); retval = new octave_galois (a.exp ()); return retval; } /* %% Test input validation %!error gexp () %!error gexp (1, 2) */ static inline int modn (int x, int m, int n) { while (x >= n) { x -= n; x = (x >> m) + (x & n); } return x; } galois filter (galois& b, galois& a, galois& x, galois& si) { int ab_len = (a.length () > b.length () ? a.length () : b.length ()); b.resize (dim_vector (ab_len, 1), 0); galois retval (x.length (), 1, 0, b.m (), b.primpoly ()); int norm = a(0, 0); if (norm == 0) { error ("gfilter: the first element of a must be non-zero"); return galois (); } if (si.length () != ab_len - 1) { error ("gfilter: si must be a vector of length max(length(a), length(b)) - 1"); return galois (); } if (norm != 1) { int idx_norm = b.index_of (norm); for (int i = 0; i < b.length (); i++) { if (b(i, 0) != 0) b(i, 0) = b.alpha_to (modn (b.index_of (b(i, 0))-idx_norm+b.n (), b.m (), b.n ())); } } if (a.length () > 1) { a.resize (dim_vector (ab_len, 1), 0); if (norm != 1) { int idx_norm = a.index_of (norm); for (int i = 0; i < a.length (); i++) if (a(i, 0) != 0) a(i, 0) = a.alpha_to (modn (a.index_of (a(i, 0))-idx_norm+a.n (), a.m (), a.n ())); } for (int i = 0; i < x.length (); i++) { retval(i, 0) = si(0, 0); if ((b(0, 0) != 0) && (x(i, 0) != 0)) retval(i, 0) ^= b.alpha_to (modn (b.index_of (b(0, 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); if (si.length () > 1) { for (int j = 0; j < si.length () - 1; j++) { si(j, 0) = si(j+1, 0); if ((a(j+1, 0) != 0) && (retval(i, 0) != 0)) si(j, 0) ^= a.alpha_to (modn (a.index_of (a(j+1, 0)) + a.index_of (retval(i, 0)), a.m (), a.n ())); if ((b(j+1, 0) != 0) && (x(i, 0) != 0)) si(j, 0) ^= b.alpha_to (modn (b.index_of (b(j+1, 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); } si(si.length ()-1, 0) = 0; if ((a(si.length (), 0) != 0) && (retval(i, 0) != 0)) si(si.length ()-1, 0) ^= a.alpha_to (modn (a.index_of (a(si.length (), 0)) + a.index_of (retval(i, 0)), a.m (), a.n ())); if ((b(si.length (), 0) != 0) && (x(i, 0) != 0)) si(si.length ()-1, 0) ^= b.alpha_to (modn (b.index_of (b(si.length (), 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); } else { si(0, 0) = 0; if ((a(1, 0) != 0) && (retval(i, 0) != 0)) si(0, 0) ^= a.alpha_to (modn (a.index_of (a(1, 0))+ a.index_of (retval(i, 0)), a.m (), a.n ())); if ((b(1, 0) != 0) && (x(i, 0) != 0)) si(0, 0) ^= b.alpha_to (modn (b.index_of (b(1, 0))+ b.index_of (x(i, 0)), b.m (), b.n ())); } } } else if (si.length () > 0) { for (int i = 0; i < x.length (); i++) { retval(i, 0) = si(0, 0); if ((b(0, 0) != 0) && (x(i, 0) != 0)) retval(i, 0) ^= b.alpha_to (modn (b.index_of (b(0, 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); if (si.length () > 1) { for (int j = 0; j < si.length () - 1; j++) { si(j, 0) = si(j+1, 0); if ((b(j+1, 0) != 0) && (x(i, 0) != 0)) si(j, 0) ^= b.alpha_to (modn (b.index_of (b(j+1, 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); } si(si.length ()-1, 0) = 0; if ((b(si.length (), 0) != 0) && (x(i, 0) != 0)) si(si.length ()-1, 0) ^= b.alpha_to (modn (b.index_of (b(si.length (), 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); } else { si(0, 0) = 0; if ((b(1, 0) != 0) && (x(i, 0) != 0)) si(0, 0) ^= b.alpha_to (modn (b.index_of (b(1, 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); } } } else for (int i = 0; i < x.length (); i++) if ((b(0, 0) != 0) && (x(i, 0) != 0)) retval(i, 0) = b.alpha_to (modn (b.index_of (b(0, 0)) + b.index_of (x(i, 0)), b.m (), b.n ())); return retval; } // PKG_ADD: autoload ("gfilter", "gf.oct"); // PKG_DEL: autoload ("gfilter", "gf.oct", "remove"); DEFUN_DLD (gfilter, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {y =} gfilter (@var{b}, @var{a}, @var{x})\n\ @deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} gfilter (@var{b}, @var{a}, @var{x}, @var{si})\n\ Digital filtering of vectors in a Galois Field. Returns the solution to\n\ the following linear, time-invariant difference equation over a Galois\n\ Field:\n\ @tex\n\ $$\n\ \\sum_{k=0}^N a_{k+1} y_{n-k} = \\sum_{k=0}^M b_{k+1} x_{n-k}, \\qquad\n\ 1 \\le n \\le P\n\ $$\n\ @end tex\n\ @ifnottex\n\ \n\ @smallexample\n\ @group\n\ N M\n\ SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k) for 1<=n<=length(x)\n\ k=0 k=0\n\ @end group\n\ @end smallexample\n\ @end ifnottex\n\ \n\ @noindent\n\ where\n\ @tex\n\ $a \\in \\Re^{N-1}$, $b \\in \\Re^{M-1}$, and $x \\in \\Re^P$.\n\ @end tex\n\ @ifnottex\n\ N=length(a)-1 and M=length(b)-1.\n\ @end ifnottex\n\ An equivalent form of this equation is:\n\ @tex\n\ $$\n\ y_n = -\\sum_{k=1}^N c_{k+1} y_{n-k} + \\sum_{k=0}^M d_{k+1} x_{n-k}, \\qquad\n\ 1 \\le n \\le P\n\ $$\n\ @end tex\n\ @ifnottex\n\ \n\ @smallexample\n\ @group\n\ N M\n\ y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k) for 1<=n<=length(x)\n\ k=1 k=0\n\ @end group\n\ @end smallexample\n\ @end ifnottex\n\ \n\ @noindent\n\ where\n\ @tex\n\ $c = a/a_1$ and $d = b/a_1$.\n\ @end tex\n\ @ifnottex\n\ c = a/a(1) and d = b/a(1).\n\ @end ifnottex\n\ \n\ If the fourth argument @var{si} is provided, it is taken as the initial\n\ state of the system and the final state is returned as @var{sf}. The\n\ state vector is a column vector whose length is equal to the length of\n\ the longest coefficient vector minus one. If @var{si} is not supplied,\n\ the initial state vector is set to all zeros.\n\ @seealso{filter}\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin < 3 || nargin > 4) { print_usage (); return retval; } if (!galois_type_loaded) { error ("gfilter: wrong argument types"); return retval; } bool x_is_row_vector = (args(2).rows () == 1); bool si_is_row_vector = (nargin == 4 && args(3).rows () == 1); galois b, a, x, si; bool ib=false, ia=false, ix = false, isi=false; if (args(0).type_id () == octave_galois::static_type_id ()) { b = ((const octave_galois&) args(0).get_rep ()).galois_value (); ib = true; } if (args(1).type_id () == octave_galois::static_type_id ()) { a = ((const octave_galois&) args(1).get_rep ()).galois_value (); ia = true; } if (args(2).type_id () == octave_galois::static_type_id ()) { x = ((const octave_galois&) args(2).get_rep ()).galois_value (); ix = true; } if (nargin == 4) { if (args(3).type_id () == octave_galois::static_type_id ()) { si = ((const octave_galois&) args(3).get_rep ()).galois_value (); isi = true; } } if (!ib && !ia && !ix && !isi) { error ("gfilter: wrong argument types"); return retval; } if (!ib) { if (ia) b = galois (args(0).matrix_value (), a.m (), a.primpoly ()); else if (ix) b = galois (args(0).matrix_value (), x.m (), x.primpoly ()); else if (isi) b = galois (args(0).matrix_value (), si.m (), si.primpoly ()); } if (!ia) a = galois (args(1).matrix_value (), b.m (), b.primpoly ()); if (!ix) x = galois (args(2).matrix_value (), b.m (), b.primpoly ()); if (nargin == 4) { if (!isi) si = galois (args(3).matrix_value (), b.m (), b.primpoly ()); } else { int a_len = a.length (); int b_len = b.length (); int si_len = (a_len > b_len ? a_len : b_len) - 1; si = galois (si_len, 1, 0, b.m (), b.primpoly ()); } if ((b.m () != a.m ()) || (b.m () != x.m ()) || (b.m () != si.m ()) || (b.primpoly () != a.primpoly ()) || (b.primpoly () != x.primpoly ()) || (b.primpoly () != si.primpoly ())) { error ("gfilter: arguments must be in same galois field"); return retval; } if (b.cols () > 1) b = b.transpose (); if (a.cols () > 1) a = a.transpose (); if (x.cols () > 1) x = x.transpose (); if (si.cols () > 1) si = si.transpose (); if (b.cols () > 1 || a.cols () > 1 || x.cols () > 1 || si.cols () > 1) { error ("gfilter: arguments must be vectors"); return retval; } galois y (filter (b, a, x, si)); if (nargout == 2) { if (si_is_row_vector) retval(1) = new octave_galois (si.transpose ()); else retval(1) = new octave_galois (si); } if (x_is_row_vector) retval(0) = new octave_galois (y.transpose ()); else retval(0) = new octave_galois (y); return retval; } /* %% Test input validation %!error gfilter () %!error gfilter (1) %!error gfilter (1, 2) %!error gfilter (1, 2, 3, 4, 5) */ // PKG_ADD: autoload ("glu", "gf.oct"); // PKG_DEL: autoload ("glu", "gf.oct", "remove"); DEFUN_DLD (glu, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}] =} glu (@var{a})\n\ @cindex LU decomposition of Galois matrix\n\ Compute the LU decomposition of @var{a} in a Galois Field. The result is\n\ returned in a permuted form, according to the optional return value\n\ @var{p}. For example, given the matrix\n\ @code{a = gf ([1, 2; 3, 4], 3)},\n\ \n\ @example\n\ [l, u, p] = glu (a)\n\ @end example\n\ \n\ @noindent\n\ returns\n\ \n\ @example\n\ l =\n\ GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11)\n\ \n\ Array elements =\n\ \n\ 1 0\n\ 6 1\n\ \n\ u =\n\ GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11)\n\ \n\ Array elements =\n\ \n\ 3 4\n\ 0 7\n\ \n\ p =\n\ \n\ Permutation Matrix\n\ \n\ 0 1\n\ 1 0\n\ \n\ @end example\n\ \n\ Such that @code{@var{p} * @var{a} = @var{l} * @var{u}}. If the argument\n\ @var{p} is not included then the permutations are applied to @var{l}\n\ so that @code{@var{a} = @var{l} * @var{u}}. @var{l} is then a pseudo-\n\ lower triangular matrix. The matrix @var{a} can be rectangular.\n\ @seealso{lu}\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin != 1 || nargout > 3) { print_usage (); return retval; } octave_value arg = args(0); if (!galois_type_loaded || (arg.type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("glu", arg); return retval; } galois m = ((const octave_galois&) arg.get_rep ()).galois_value (); int nr = arg.rows (); int nc = arg.columns (); int arg_is_empty = empty_arg ("glu", nr, nc); if (arg_is_empty < 0) return retval; else if (arg_is_empty > 0) { retval(0) = new octave_galois (galois (0, 0, 0, m.m (), m.primpoly ())); retval(1) = new octave_galois (galois (0, 0, 0, m.m (), m.primpoly ())); retval(2) = new octave_galois (galois (0, 0, 0, m.m (), m.primpoly ())); return retval; } if (! error_state) { galoisLU fact (m); switch (nargout) { case 0: case 1: case 2: { // While we don't have sparse galois matrices converting the // permutation matrix to a full matrix is the best we can do. Matrix P = Matrix (fact.P ()); galois L = P.transpose () * fact.L (); retval(1) = new octave_galois (fact.U ()); retval(0) = new octave_galois (L); } break; case 3: default: retval(2) = fact.P (); retval(1) = new octave_galois (fact.U ()); retval(0) = new octave_galois (fact.L ()); break; } } return retval; } /* %% Test input validation %!error glu () %!error glu (1, 2) */ // PKG_ADD: autoload ("ginv", "gf.oct"); // PKG_DEL: autoload ("ginv", "gf.oct", "remove"); DEFUN_DLD (ginv, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} ginv (@var{a})\n\ Compute the inverse of the square matrix @var{a}. Return an estimate\n\ of the reciprocal condition number if requested, otherwise warn of an\n\ ill-conditioned matrix if the reciprocal condition number is small.\n\ @seealso{inv}\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin != 1) { print_usage (); return retval; } octave_value arg = args(0); int nr = arg.rows (); int nc = arg.columns (); if (!galois_type_loaded || (arg.type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("ginverse", arg); return retval; } galois m = ((const octave_galois&) arg.get_rep ()).galois_value (); int arg_is_empty = empty_arg ("ginverse", nr, nc); if (arg_is_empty < 0) return retval; else if (arg_is_empty > 0) { retval(0) = new octave_galois (galois (0, 0, 0, m.m (), m.primpoly ())); return retval; } if (nr != nc) { gripe_square_matrix_required ("ginverse"); return retval; } if (! error_state) { int info; double rcond = 0.0; galois result = m.inverse (info, 1); if (nargout > 1) retval(1) = rcond; retval(0) = new octave_galois (result); if (nargout < 2 && info == -1) warning ("inverse: matrix singular to machine precision, rcond = %g", rcond); } return retval; } /* %% Test input validation %!error ginv () %!error ginv (1, 2) */ // FIXME: this should really be done with an alias, but // alias_builtin() won't do the right thing if we are actually using // dynamic linking. // PKG_ADD: autoload ("ginverse", "gf.oct"); // PKG_DEL: autoload ("ginverse", "gf.oct", "remove"); DEFUN_DLD (ginverse, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {} ginverse (@var{a})\n\ Compute the inverse of the square matrix @var{a}. Return an estimate\n\ of the reciprocal condition number if requested, otherwise warn of an\n\ ill-conditioned matrix if the reciprocal condition number is small.\n\ @seealso{ginv}\n\ @end deftypefn") { return Fginv (args, nargout); } /* %% Test input validation %!error ginverse () %!error ginverse (1, 2) */ // PKG_ADD: autoload ("gdet", "gf.oct"); // PKG_DEL: autoload ("gdet", "gf.oct", "remove"); DEFUN_DLD (gdet, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{d} =} gdet (@var{a})\n\ Compute the determinant of the Galois array @var{a}.\n\ @seealso{det}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin != 1) { print_usage (); return retval; } octave_value arg = args(0); if (!galois_type_loaded || (arg.type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("gdet", arg); return retval; } int nr = arg.rows (); int nc = arg.columns (); galois m = ((const octave_galois&) arg.get_rep ()).galois_value (); int arg_is_empty = empty_arg ("gdet", nr, nc); if (arg_is_empty < 0) return retval; else if (arg_is_empty > 0) { retval = new octave_galois (galois (1, 1, 1, m.m (), m.primpoly ())); return retval; } if (nr != nc) { gripe_square_matrix_required ("det"); return retval; } retval = new octave_galois (m.determinant ()); return retval; } /* %% Test input validation %!error gdet () %!error gdet (1, 2) */ // PKG_ADD: autoload ("grank", "gf.oct"); // PKG_DEL: autoload ("grank", "gf.oct", "remove"); DEFUN_DLD (grank, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{d} =} grank (@var{a})\n\ Compute the rank of the Galois array @var{a} by counting the independent\n\ rows and columns.\n\ @seealso{rank}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin != 1) { print_usage (); return retval; } octave_value arg = args(0); if (!galois_type_loaded || (arg.type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("grank", arg); return retval; } int nr = arg.rows (); int nc = arg.columns (); galois m = ((const octave_galois&) arg.get_rep ()).galois_value (); int arg_is_empty = empty_arg ("grank", nr, nc); if (arg_is_empty > 0) retval = 0.0; else if (arg_is_empty == 0) { int d = 0; int mm = m.m (); int mn = m.n (); OCTAVE_LOCAL_BUFFER (int, ci, nr); for (int i = 0; i < nc; i++) { int idx = -1; int iel = 0; for (int j = 0; j < nr; j++) { ci[j] = m.elem (j, i); if (ci[j] != 0 && idx == -1) { iel = ci[j]; idx = j; } } if (idx != -1) { d++; int indx = m.index_of (iel); for (int j = 0; j < nr; j++) if (ci[j] != 0) ci[j] = m.alpha_to (modn (m.index_of (ci[j]) - indx + mn, mm, mn)); for (int j = i+1; j < nc; j++) { if (m.elem (idx, j) != 0) { indx = m.index_of (m.elem (idx, j)); for (int k = 0; k < nr; k++) if (ci[k] != 0) m.elem (k, j) ^= m.alpha_to (modn (m.index_of (ci[k]) + indx + mn, mm, mn)); } } } } retval = (double)d; } return retval; } /* %% Test input validation %!error grank () %!error grank (1, 2) */ // PKG_ADD: autoload ("rsenc", "gf.oct"); // PKG_DEL: autoload ("rsenc", "gf.oct", "remove"); DEFUN_DLD (rsenc, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{code} =} rsenc (@var{msg}, @var{n}, @var{k})\n\ @deftypefnx {Loadable Function} {@var{code} =} rsenc (@var{msg}, @var{n}, @var{k}, @var{g})\n\ @deftypefnx {Loadable Function} {@var{code} =} rsenc (@var{msg}, @var{n}, @var{k}, @var{fcr}, @var{prim})\n\ @deftypefnx {Loadable Function} {@var{code} =} rsenc (@dots{}, @var{parpos})\n\ Encodes the message @var{msg} using a [@var{n},@var{k}] Reed-Solomon coding.\n\ The variable @var{msg} is a Galois array with @var{k} columns and an arbitrary\n\ number of rows. Each row of @var{msg} represents a single block to be coded\n\ by the Reed-Solomon coder. The coded message is returned in the Galois\n\ array @var{code} containing @var{n} columns and the same number of rows as\n\ @var{msg}.\n\ \n\ The use of @code{rsenc} can be seen in the following short example.\n\ \n\ @example\n\ m = 3; n = 2^m -1; k = 3;\n\ msg = gf ([1 2 3; 4 5 6], m);\n\ code = rsenc (msg, n, k);\n\ @end example\n\ \n\ If @var{n} does not equal @code{2^@var{m}-1}, where m is an integer, then a\n\ shorten Reed-Solomon coding is used where zeros are added to the start of\n\ each row to obtain an allowable codeword length. The returned @var{code}\n\ has these prepending zeros stripped.\n\ \n\ By default the generator polynomial used in the Reed-Solomon coding is based\n\ on the properties of the Galois Field in which @var{msg} is given. This\n\ default generator polynomial can be overridden by a polynomial in @var{g}.\n\ Suitable generator polynomials can be constructed with @code{rsgenpoly}.\n\ @var{fcr} is an integer value, and it is taken to be the first consecutive\n\ root of the generator polynomial. The variable @var{prim} is then the\n\ primitive element used to construct the generator polynomial, such that\n\ @tex\n\ $g = (x - A^b) (x - A^{b+p}) \\cdots (x - A ^{b+2tp-1})$.\n\ @end tex\n\ @ifnottex\n\ \n\ @var{g} = (@var{x} - A^@var{b}) * (@var{x} - A^(@var{b}+@var{prim})) * ... * (@var{x} - A^(@var{b}+2*@var{t}*@var{prim}-1)).\n\ @end ifnottex\n\ \n\ where @var{b} is equal to @code{@var{fcr} * @var{prim}}. By default @var{fcr}\n\ and @var{prim} are both 1.\n\ \n\ By default the parity symbols are placed at the end of the coded message.\n\ The variable @var{parpos} controls this positioning and can take the values\n\ @code{\"beginning\"} or @code{\"end\"}.\n\ @seealso{gf, rsdec, rsgenpoly}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin < 3 || nargin > 5) { print_usage (); return retval; } if (!galois_type_loaded || (args(0).type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("rsenc", args(0)); return retval; } galois msg = ((const octave_galois&) args(0).get_rep ()).galois_value (); int nsym = msg.rows (); int primpoly = msg.primpoly (); int n = args(1).nint_value (); int k = args(2).nint_value (); int m = 1; while (n > (1< __OCTAVE_GALOIS_MAX_M)) { error ("rsenc: invalid values of message and codeword length"); return retval; } if ((n-k) & 1) { error ("rsenc: difference of message and codeword length must be even"); return retval; } int nroots = n-k; galois genpoly; bool have_genpoly = false; bool parity_at_end = true; int fcr = 0; int prim = 0; for (int i = 3; i < nargin; i++) { if (args(i).is_string ()) { std::string parstr = args(i).string_value (); for (int j = 0; j < (int)parstr.length (); j++) parstr[j] = toupper (parstr[j]); if (!parstr.compare("END")) { parity_at_end = true; } else if (!parstr.compare("BEGINNING")) { parity_at_end = false; } else { error ("rsenc: unrecoginized parity position"); return retval; } } else { if (args(i).type_id () == octave_galois::static_type_id ()) { if (have_genpoly) { print_usage (); return retval; } genpoly = ((const octave_galois&) args(i).get_rep ()).galois_value (); if (genpoly.cols () > genpoly.rows ()) genpoly = genpoly.transpose (); } else { if (have_genpoly) { if (prim != 0) { print_usage (); return retval; } prim = args(i).nint_value (); } else fcr = args(i).nint_value (); } have_genpoly = true; } } if ((genpoly.rows () == 0) || (genpoly.cols () == 0)) { if (fcr == 0) fcr = 1; if (prim == 0) prim = 1; // Create polynomial of right length. genpoly = galois (nroots+1, 1, 0, m, primpoly); genpoly(nroots, 0) = 1; int i, root; for (i = 0, root=fcr*prim; i < nroots; i++, root += prim) { genpoly(nroots-i-1, 0) = 1; // Multiply genpoly by @**(root + x) for (int j = i; j > 0; j--) { int k = nroots - j; if (genpoly(k, 0) != 0) genpoly(k, 0) = genpoly(k+1, 0) ^ genpoly.alpha_to (modn (genpoly.index_of (genpoly(k, 0)) + root, m, n)); else genpoly(k, 0) = genpoly(k+1, 0); } // genpoly(nroots,0) can never be zero genpoly(nroots, 0) = genpoly.alpha_to (modn (genpoly.index_of (genpoly(nroots, 0)) + root, m, n)); } } else { if (genpoly.cols () != 1) { error ("rsenc: the generator polynomial must be a vector"); return retval; } if (genpoly.primpoly () != primpoly) { error ("rsenc: the generator polynomial must be same galois field " "as the message"); return retval; } if (genpoly.rows () != nroots+1) { error ("rsenc: generator polynomial has incorrect order"); return retval; } } int norm = genpoly(0, 0); // Take logarithm of generator polynomial, for faster coding for (int i = 0; i < nroots+1; i++) genpoly(i, 0) = genpoly.index_of (genpoly(i, 0)); // Add space for parity block msg.resize (dim_vector (nsym, n), 0); // The code below basically finds the parity bits by treating the // message as a polynomial and dividing it by the generator polynomial. // The parity bits are then the remainder of this division. If the parity // is at the end the polynomial is treat MSB first, otherwise it is // treated LSB first // // This code could just as easily be written as // [ignore par] = gdeconv(msg, genpoly); // But the code below has the advantage of being 20 times faster :-) if (parity_at_end) { for (int l = 0; l < nsym; l++) { galois par (nroots, 1, 0, m, primpoly); for (int i = 0; i < k; i++) { int feedback = par.index_of (par(0, 0) ^ msg(l, i)); if (feedback != nn) { if (norm != 1) feedback = modn (nn-genpoly(0, 0)+feedback, m, nn); for (int j = 1; j < nroots; j++) par(j, 0) ^= par.alpha_to (modn (feedback + genpoly(j, 0), m, nn)); } for (int j = 1; j < nroots; j++) par(j-1, 0) = par(j, 0); if (feedback != nn) par(nroots-1, 0) = par.alpha_to (modn (feedback+ genpoly(nroots, 0), m, nn)); else par(nroots-1, 0) = 0; } for (int j = 0; j < nroots; j++) msg(l, k+j) = par(j, 0); } } else { for (int l = 0; l < nsym; l++) { for (int i=k; i > 0; i--) msg(l, i+nroots-1) = msg(l, i-1); for (int i = 0; i nroots; i--) { int feedback = par.index_of (par(0, 0) ^ msg(l, i-1)); if (feedback != nn) { if (norm != 1) feedback = modn (nn-genpoly(0, 0)+feedback, m, nn); for (int j = 1; j < nroots; j++) par(j, 0) ^= par.alpha_to (modn (feedback + genpoly(j, 0), m, nn)); } for (int j = 1; j < nroots; j++) par(j-1, 0) = par(j, 0); if (feedback != nn) par(nroots-1, 0) = par.alpha_to (modn (feedback+ genpoly(nroots, 0), m, nn)); else par(nroots-1, 0) = 0; } for (int j = 0; j < nroots; j++) msg(l, j) = par(nroots-j-1, 0); } } retval = new octave_galois (msg); return retval; } /* %% Test input validation %!error rsenc () %!error rsenc (1) %!error rsenc (1, 2) %!error rsenc (1, 2, 3, 4, 5, 6) */ int decode_rs(galois& data, const int prim, const int iprim, const int nroots, const int fcr, const int drow, const bool msb_first) { int deg_lambda, el, deg_omega; int i, j, r, k; int q, tmp, num1, num2, den, discr_r; int syn_error, count; int m = data.m (); int n = data.n (); int A0 = n; /* Err Locator and syndrome poly */ OCTAVE_LOCAL_BUFFER (int, lambda, nroots+1); OCTAVE_LOCAL_BUFFER (int, s, nroots); OCTAVE_LOCAL_BUFFER (int, b, nroots+1); OCTAVE_LOCAL_BUFFER (int, t, nroots+1); OCTAVE_LOCAL_BUFFER (int, omega, nroots+1); OCTAVE_LOCAL_BUFFER (int, root, nroots); OCTAVE_LOCAL_BUFFER (int, reg, nroots+1); OCTAVE_LOCAL_BUFFER (int, loc, nroots); /* form the syndromes; i.e., evaluate data(x) at roots of g(x) */ if (msb_first) { for (i = 0; i < nroots; i++) s[i] = data(drow, 0); for (j = 1; j < n; j++) for (i = 0; i0; j--) for (i = 0; i < nroots; i++) if(s[i] == 0) s[i] = data(drow, j-1); else s[i] = data(drow, j-1) ^ data.alpha_to (modn (data.index_of (s[i]) + (fcr+i)*prim, m, n)); } /* Convert syndromes to index form, checking for nonzero condition */ syn_error = 0; for (i = 0; i < nroots; i++) { syn_error |= s[i]; s[i] = data.index_of (s[i]); } if (!syn_error) /* if syndrome is zero, data(drow,:) is a codeword and there are no * errors to correct. So return data(drow,:) unmodified */ return 0; memset(&lambda[1], 0, nroots*sizeof (lambda[0])); lambda[0] = 1; for (i = 0; i < nroots+1; i++) b[i] = data.index_of (lambda[i]); /* * Begin Berlekamp-Massey algorithm to determine error locator polynomial */ r = 0; el = 0; while (++r <= nroots) {/* r is the step number */ /* Compute discrepancy at the r-th step in poly-form */ discr_r = 0; for (i = 0; i < r; i++) { if ((lambda[i] != 0) && (s[r-i-1] != A0)) { discr_r ^= data.alpha_to (modn (data.index_of (lambda[i]) + s[r-i-1], m, n)); } } discr_r = data.index_of (discr_r); /* Index form */ if (discr_r == A0) { /* 2 lines below: B(x) <-- x*B(x) */ memmove(&b[1], b, nroots*sizeof (b[0])); b[0] = A0; } else { /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */ t[0] = lambda[0]; for (i = 0 ; i < nroots; i++) { if(b[i] != A0) t[i+1] = lambda[i+1] ^ data.alpha_to (modn (discr_r + b[i], m, n)); else t[i+1] = lambda[i+1]; } if (2 * el <= r - 1) { el = r - el; /* * 2 lines below: B(x) <-- inv(discr_r) * * lambda(x) */ for (i = 0; i <= nroots; i++) b[i] = (lambda[i] == 0) ? A0 : modn (data.index_of (lambda[i]) - discr_r + n, m, n); } else { /* 2 lines below: B(x) <-- x*B(x) */ memmove(&b[1], b, nroots*sizeof (b[0])); b[0] = A0; } memcpy(lambda, t, (nroots+1)*sizeof (t[0])); } } /* Convert lambda to index form and compute deg(lambda(x)) */ deg_lambda = 0; for (i = 0; i < nroots+1; i++) { lambda[i] = data.index_of (lambda[i]); if(lambda[i] != A0) deg_lambda = i; } /* Find roots of the error locator polynomial by Chien search */ memcpy(®[1], &lambda[1], nroots*sizeof (reg[0])); count = 0; /* Number of roots of lambda(x) */ for (i = 1, k = iprim-1; i <= n; i++, k = modn (k+iprim, m, n)) { q = 1; /* lambda[0] is always 0 */ for (j = deg_lambda; j > 0; j--) { if (reg[j] != A0) { reg[j] = modn (reg[j] + j, m, n); q ^= data.alpha_to (reg[j]); } } if (q != 0) continue; /* Not a root */ /* store root (index-form) and error location number */ root[count] = i; loc[count] = k; /* If we've already found max possible roots, * abort the search to save time */ if(++count == deg_lambda) break; } if (deg_lambda != count) { /* * deg(lambda) unequal to number of roots => uncorrectable * error detected */ return -1; } /* * Compute err evaluator poly omega(x) = s(x)*lambda(x) (modulo * x**nroots). in index form. Also find deg(omega). */ deg_omega = 0; for (i = 0; i < nroots; i++) { tmp = 0; j = (deg_lambda < i) ? deg_lambda : i; for (; j >= 0; j--) { if ((s[i - j] != A0) && (lambda[j] != A0)) tmp ^= data.alpha_to (modn (s[i - j] + lambda[j], m, n)); } if(tmp != 0) deg_omega = i; omega[i] = data.index_of (tmp); } omega[nroots] = A0; /* * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = * inv(X(l))**(fcr-1) and den = lambda_pr(inv(X(l))) all in poly-form */ for (j = count-1; j >= 0; j--) { num1 = 0; for (i = deg_omega; i >= 0; i--) { if (omega[i] != A0) num1 ^= data.alpha_to (modn (omega[i] + i * root[j], m, n)); } num2 = data.alpha_to (modn (root[j] * (fcr - 1) + n, m, n)); den = 0; /* lambda[i+1] for i even is the formal deriv lambda_pr of lambda[i] */ for (i = (deg_lambda < nroots-1 ? deg_lambda : nroots-1) & ~1; i >= 0; i -=2) { if(lambda[i+1] != A0) den ^= data.alpha_to (modn (lambda[i+1] + i * root[j], m, n)); } if (den == 0) { count = -1; break; } /* Apply error to data */ if (num1 != 0) { if (msb_first) data(drow, loc[j]) ^= data.alpha_to (modn (data.index_of (num1) + data.index_of (num2) + n - data.index_of (den), m, n)); else data(drow, n-loc[j]-1) ^= data.alpha_to (modn (data.index_of (num1) + data.index_of (num2) + n - data.index_of (den), m, n)); } } return count; } // PKG_ADD: autoload ("rsdec", "gf.oct"); // PKG_DEL: autoload ("rsdec", "gf.oct", "remove"); DEFUN_DLD (rsdec, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{msg} =} rsdec (@var{code}, @var{n}, @var{k})\n\ @deftypefnx {Loadable Function} {@var{msg} =} rsdec (@var{code}, @var{n}, @var{k}, @var{g})\n\ @deftypefnx {Loadable Function} {@var{msg} =} rsdec (@var{code}, @var{n}, @var{k}, @var{fcr}, @var{prim})\n\ @deftypefnx {Loadable Function} {@var{msg} =} rsdec (@dots{}, @var{parpos})\n\ @deftypefnx {Loadable Function} {[@var{msg}, @var{nerr}] =} rsdec (@dots{})\n\ @deftypefnx {Loadable Function} {[@var{msg}, @var{nerr}, @var{ccode}] =} rsdec (@dots{})\n\ Decodes the message contained in @var{code} using a [@var{n},@var{k}]\n\ Reed-Solomon code. The variable @var{code} must be a Galois array with\n\ @var{n} columns and an arbitrary number of rows. Each row of @var{code}\n\ represents a single block to be decoded by the Reed-Solomon coder. The\n\ decoded message is returned in the variable @var{msg} containing @var{k}\n\ columns and the same number of rows as @var{code}.\n\ \n\ If @var{n} does not equal @code{2^@var{m}-1}, where m is an integer, then a\n\ shorten Reed-Solomon decoding is used where zeros are added to the start of\n\ each row to obtain an allowable codeword length. The returned @var{msg}\n\ has these prepending zeros stripped.\n\ \n\ By default the generator polynomial used in the Reed-Solomon coding is based\n\ on the properties of the Galois Field in which @var{msg} is given. This\n\ default generator polynomial can be overridden by a polynomial in @var{g}.\n\ Suitable generator polynomials can be constructed with @code{rsgenpoly}.\n\ @var{fcr} is an integer value, and it is taken to be the first consecutive\n\ root of the generator polynomial. The variable @var{prim} is then the\n\ primitive element used to construct the generator polynomial. By default\n\ @var{fcr} and @var{prim} are both 1. It is significantly faster to specify\n\ the generator polynomial in terms of @var{fcr} and @var{prim}, since @var{g}\n\ is converted to this form in any case.\n\ \n\ By default the parity symbols are placed at the end of the coded message.\n\ The variable @var{parpos} controls this positioning and can take the values\n\ @code{\"beginning\"} or @code{\"end\"}. If the parity symbols are at the end, the message is\n\ treated with the most-significant symbol first, otherwise the message is\n\ treated with the least-significant symbol first.\n\ @seealso{gf, rsenc, rsgenpoly}\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin < 3 || nargin > 5) { print_usage (); return retval; } if (!galois_type_loaded || (args(0).type_id () != octave_galois::static_type_id ())) { gripe_wrong_type_arg ("rsdec", args(0)); return retval; } galois code = ((const octave_galois&) args(0).get_rep ()).galois_value (); int nsym = code.rows (); int primpoly = code.primpoly (); int n = args(1).nint_value (); int k = args(2).nint_value (); int m = 1; while (n > (1< __OCTAVE_GALOIS_MAX_M)) { error ("rsdec: invalid values of message and codeword length"); return retval; } if ((n-k) & 1) { error ("rsdec: difference of message and codeword length must be even"); return retval; } int nroots = n-k; galois genpoly; bool have_genpoly = false; bool parity_at_end = true; int fcr = 0; int prim = 0; int iprim; for (int i = 3; i < 6; i++) { if (nargin > i) { if (args(i).is_string ()) { std::string parstr = args(i).string_value (); for (int j = 0; j < (int)parstr.length (); j++) parstr[j] = toupper (parstr[j]); if (!parstr.compare("END")) { parity_at_end = true; } else if (!parstr.compare("BEGINNING")) { parity_at_end = false; } else { error ("rsdec: unrecoginized parrity position"); return retval; } } else { if (args(i).type_id () == octave_galois::static_type_id ()) { if (have_genpoly) { print_usage (); return retval; } genpoly = ((const octave_galois&) args(i).get_rep ()).galois_value (); } else { if (have_genpoly) { if (prim != 0) { print_usage (); return retval; } prim = args(i).nint_value (); } else fcr = args(i).nint_value (); } have_genpoly = true; } } } if (have_genpoly) { if (fcr != 0) { if ((fcr < 1) || (fcr > nn)) { error ("rsdec: invalid first consecutive root of generator polynomial"); return retval; } if ((prim < 1) || (prim > nn)) { error ("rsdec: invalid primitive element of generator polynomial"); return retval; } } else { if (genpoly.cols () > genpoly.rows ()) genpoly = genpoly.transpose (); if (genpoly.cols () != 1) { error ("rsdec: the generator polynomial must be a vector"); return retval; } if (genpoly.primpoly () != primpoly) { error ("rsdec: the generator polynomial must be same galois " "field as the message"); return retval; } if (genpoly.rows () != nroots+1) { error ("rsdec: generator polynomial has incorrect order"); return retval; } // Find the roots of the generator polynomial int count = 0; OCTAVE_LOCAL_BUFFER (int, roots, nroots); for (int j = 0; j <= nn; j++) { // Evaluate generator polynomial at j int val = genpoly(0, 0); int indx = genpoly.index_of (j); for (int i = 0; i 0; i--) code(l, i+nn-n-1) = code(l, i-1); } for (int l = 0; l < nsym; l++) nerr(l) = decode_rs (code, prim, iprim, nroots, fcr, l, parity_at_end); if (nn != n) { if (parity_at_end) for (int l = 0; l < nsym; l++) for (int i = 0; i > n; i--) code(l, i) = code(l, i+nn-n); code.resize (dim_vector (nsym, n), 0); } if (parity_at_end) { for (int l = 0; l < nsym; l++) for (int i = 0; i < k; i++) msg(l, i) = code(l, i); } else { for (int l = 0; l < nsym; l++) for (int i = 0; i < k; i++) msg(l, i) = code(l, nroots+i); } retval(0) = new octave_galois (msg); retval(1) = octave_value (nerr); retval(2) = new octave_galois (code); return retval; } /* %% Test input validation %!error rsdec () %!error rsdec (1) %!error rsdec (1, 2) %!error rsdec (1, 2, 3, 4, 5, 6) */ // PKG_ADD: autoload ("bchenco", "gf.oct"); // PKG_DEL: autoload ("bchenco", "gf.oct", "remove"); DEFUN_DLD (bchenco, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{code} =} bchenco (@var{msg}, @var{n}, @var{k})\n\ @deftypefnx {Loadable Function} {@var{code} =} bchenco (@var{msg}, @var{n}, @var{k}, @var{g})\n\ @deftypefnx {Loadable Function} {@var{code} =} bchenco (@dots{}, @var{parpos})\n\ Encodes the message @var{msg} using a [@var{n},@var{k}] BCH coding.\n\ The variable @var{msg} is a binary array with @var{k} columns and an\n\ arbitrary number of rows. Each row of @var{msg} represents a single symbol\n\ to be coded by the BCH coder. The coded message is returned in the binary\n\ array @var{code} containing @var{n} columns and the same number of rows as\n\ @var{msg}.\n\ \n\ The use of @code{bchenco} can be seen in the following short example.\n\ \n\ @example\n\ m = 3; n = 2^m -1; k = 4;\n\ msg = randint (10,k);\n\ code = bchenco (msg, n, k);\n\ @end example\n\ \n\ Valid codes can be found using @code{bchpoly}. In general the codeword\n\ length @var{n} should be of the form @code{2^@var{m}-1}, where m is an\n\ integer. However, shortened BCH codes can be used such that if\n\ @code{[2^@var{m}-1,@var{k}]} is a valid code\n\ @code{[2^@var{m}-1-@var{x},@var{k}-@var{x}]}\n is also a valid code using\n\ the same generator polynomial.\n\ \n\ By default the generator polynomial used in the BCH coding is\n\ based on the properties of the Galois Field GF(2^@var{m}). This\n\ default generator polynomial can be overridden by a polynomial in @var{g}.\n\ Suitable generator polynomials can be constructed with @code{bchpoly}.\n\ \n\ By default the parity symbols are placed at the beginning of the coded\n\ message. The variable @var{parpos} controls this positioning and can take\n\ the values @code{\"beginning\"} or @code{\"end\"}.\n\ @seealso{bchpoly, bchdeco, encode}\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin < 3 || nargin > 5) { print_usage (); return retval; } Matrix msg = args(0).matrix_value (); int nsym = msg.rows (); int nn = args(1).nint_value (); int k = args(2).nint_value (); int m = 1; while (nn > (1< __OCTAVE_GALOIS_MAX_M)) { error ("bchenco: invalid values of message or codeword length"); return retval; } galois genpoly; bool have_genpoly = false; bool parity_at_end = false; for (int i = 3; i < nargin; i++) { if (args(i).is_string ()) { std::string parstr = args(i).string_value (); for (int j = 0; j < (int)parstr.length (); j++) parstr[j] = toupper (parstr[j]); if (!parstr.compare("END")) { parity_at_end = true; } else if (!parstr.compare("BEGINNING")) { parity_at_end = false; } else { error ("bchenco: unrecoginized parity position"); return retval; } } else { have_genpoly = true; genpoly = galois (args(i).matrix_value (), m); if (genpoly.cols () > genpoly.rows ()) genpoly = genpoly.transpose (); if (genpoly.cols () != 1) { error ("bchenco: the generator polynomial must be a vector"); return retval; } if (genpoly.rows () != nn-k+1) { error ("bchenco: generator polynomial has incorrect order"); return retval; } } } if (!have_genpoly) { // The code below is basically bchpoly.m in C++, so if there is a need // it can be used to rewrite bchpoly as an oct-file... RowVector found (n, 0); found(0) = 1; galois c (1, m, 0, m); c(0, 0) = c.index_of (1); Array cs (dim_vector (1, 1), 1); int nc = 1; // Find the cyclotomic cosets of GF(2^m) while (found.min () == 0) { int idx = n; for (int i = 0; i idx) { c(nc, cs(nc)) = r; found(c.alpha_to (r)-1) = 1; cs(nc) += 1; } nc++; } // Re-use the found vector with 1==not-found !!! found.resize (nc); galois f (1, 0, 0, m); int t = 0; int nf = 0; do { t++; for (int i = 0; i < nc; i++) { if (found(i) == 1) { for (int j = 2*(t-1); j<2*t; j++) { int flag = 0; for (int l = 0; l < cs(i); l++) { if (c(i, l) == j+1) { f.resize (dim_vector (1, nf+cs(i))); for (int ll = 0; ll < cs(i); ll++) f(0, nf+ll) = c(i, ll); found(i) = 0; nf += cs(i); flag = 1; break; } } if (flag) break; } } } } while (nf < nn - k); if (nf != nn - k) { error ("bchenco: can not find valid generator polynomial for parameters"); return retval; } // Create polynomial of right length. genpoly = galois (nf+1, 1, 0, m); genpoly(0, 0) = 1; for (int i = 0; i < nf; i++) { genpoly(i+1, 0) = 1; // Multiply genpoly by @**(root + x) for (int l = i; l > 0; l--) { if (genpoly(l, 0) != 0) genpoly(l, 0) = genpoly(l-1, 0) ^ genpoly.alpha_to (modn (genpoly.index_of (genpoly(l, 0)) + f(0, i), m, n)); else genpoly(l, 0) = genpoly(l-1, 0); } // genpoly(0,0) can never be zero genpoly(0, 0) = genpoly.alpha_to (modn (genpoly.index_of (genpoly(0, 0)) + f(0, i), m, n)); } } // Add space for parity block msg.resize (nsym, nn, 0); // The code below basically finds the parity bits by treating the // message as a polynomial and dividing it by the generator polynomial. // The parity bits are then the remainder of this division. // // This code could just as easily be written as // [ignore par] = gdeconv(gf(msg), gf(genpoly)); // But the code below has the advantage of being 20 times faster :-) if (parity_at_end) { for (int l = 0; l < nsym; l++) { for (int i = 0; i < k; i++) { int feedback = (int)msg(l, i) ^ (int)msg(l, k); if (feedback != 0) { for (int j = 0; j < nn-k-1; j++) if (genpoly(nn-k-j-1, 0) != 0) msg(l, k+j) = (int)msg(l, k+j+1) ^ feedback; else msg(l, k+j) = msg(l, k+j+1); msg(l, nn-1) = genpoly(0, 0) & feedback; } else { for (int j = k; j < nn-1; j++) msg(l, j) = msg(l, j+1); msg(l, nn-1) = 0; } } } } else { for (int l = 0; l < nsym; l++) { for (int i=k; i > 0; i--) msg(l, i+nn-k-1) = msg(l, i-1); for (int i = 0; i= 0; i--) { int feedback = (int)msg(l, nn-k+i) ^ (int)msg(l, nn-k-1); if (feedback != 0) { for (int j = nn - k -1; j > 0; j--) if (genpoly(j, 0) != 0) msg(l, j) = (int)msg(l, j-1) ^ feedback; else msg(l, j) = msg(l, j-1); msg(l, 0) = genpoly(0, 0) & feedback; } else { for (int j = nn - k - 1; j > 0; j--) msg(l, j) = msg(l, j-1); msg(l, 0) = 0; } } } } retval = msg; return retval; } /* %% Test input validation %!error bchenco () %!error bchenco (1) %!error bchenco (1, 2) %!error bchenco (1, 2, 3, 4, 5, 6) */ // PKG_ADD: autoload ("bchdeco", "gf.oct"); // PKG_DEL: autoload ("bchdeco", "gf.oct", "remove"); DEFUN_DLD (bchdeco, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{msg} =} bchdeco (@var{code}, @var{k}, @var{t})\n\ @deftypefnx {Loadable Function} {@var{msg} =} bchdeco (@var{code}, @var{k}, @var{t}, @var{prim})\n\ @deftypefnx {Loadable Function} {@var{msg} =} bchdeco (@dots{}, @var{parpos})\n\ @deftypefnx {Loadable Function} {[@var{msg}, @var{err}] =} bchdeco (@dots{})\n\ @deftypefnx {Loadable Function} {[@var{msg}, @var{err}, @var{ccode}] =} bchdeco (@dots{})\n\ Decodes the coded message @var{code} using a BCH coder. The message length\n\ of the coder is defined in variable @var{k}, and the error correction\n\ capability of the code is defined in @var{t}.\n\ \n\ The variable @var{code} is a binary array with @var{n} columns and an\n\ arbitrary number of rows. Each row of @var{code} represents a single symbol\n\ to be decoded by the BCH coder. The decoded message is returned in the\n\ binary array @var{msg} containing @var{k} columns and the same number of\n\ rows as @var{code}.\n\ \n\ The use of @code{bchdeco} can be seen in the following short example.\n\ \n\ @example\n\ m = 3; n = 2^m -1; k = 4; t = 1;\n\ msg = randint (10, k);\n\ code = bchenco (msg, n, k);\n\ noisy = mod (randerr (10,n) + code, 2);\n\ [dec, err] = bchdeco (msg, k, t);\n\ @end example\n\ \n\ Valid codes can be found using @code{bchpoly}. In general the codeword\n\ length @var{n} should be of the form @code{2^@var{m}-1}, where m is an\n\ integer. However, shortened BCH codes can be used such that if\n\ @code{[2^@var{m}-1,@var{k}]} is a valid code\n\ @code{[2^@var{m}-1-@var{x},@var{k}-@var{x}]}\n is also a valid code using\n\ the same generator polynomial.\n\ \n\ By default the BCH coding is based on the properties of the Galois\n\ Field GF(2^@var{m}). The primitive polynomial used in the Galois\n\ can be overridden by a primitive polynomial in @var{prim}. Suitable\n\ primitive polynomials can be constructed with @code{primpoly}. The form\n\ of @var{prim} maybe be either a integer representation of the primitive\n\ polynomial as given by @code{primpoly}, or a binary representation that\n\ might be constructed like\n\ \n\ @example\n\ m = 3;\n\ prim = de2bi (primpoly (m));\n\ @end example\n\ \n\ By default the parity symbols are assumed to be placed at the beginning of\n\ the coded message. The variable @var{parpos} controls this positioning and\n\ can take the values @code{\"beginning\"} or @code{\"end\"}.\n\ @seealso{bchpoly, bchenco, decode, primpoly}\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin < 3 || nargin > 5) { print_usage (); return retval; } Matrix code = args(0).matrix_value (); int nsym = code.rows (); int nn = code.cols (); int k = args(1).nint_value (); int t = args(2).nint_value (); int t2 = t << 1; int m = 1; while (nn > (1< __OCTAVE_GALOIS_MAX_M)) { error ("bchdeco: invalid values of message or codeword length"); return retval; } int prim = 0; // primitve polynomial of zero flags default bool parity_at_end = false; for (int i = 3; i < nargin; i++) { if (args(i).is_string ()) { std::string parstr = args(i).string_value (); for (int j = 0; j < (int)parstr.length (); j++) parstr[j] = toupper (parstr[j]); if (!parstr.compare("END")) { parity_at_end = true; } else if (!parstr.compare("BEGINNING")) { parity_at_end = false; } else { error ("bchdeco: unrecoginized parity position"); return retval; } } else { if (args(i).is_real_scalar ()) prim = args(i).int_value (); else { Matrix tmp = args(i).matrix_value (); if (tmp.cols () > tmp.rows ()) tmp = tmp.transpose (); if (tmp.cols () != 1) { error ("bchdeco: the primitve polynomial must be a scalar " "or a vector"); return retval; } prim = 0; for (int i = 0; i < tmp.rows (); i++) if ((int)tmp(i, 0) & 1) prim |= (1< s (dim_vector(t2+1, 1), 0); bool syn_error = false; for (int i = 1; i <= t2; i++) { for (int j = 0; j < nn; j++) { if (parity_at_end) { if (code(lsym, nn-j-1) != 0) s(i) ^= tables.alpha_to (modn (i*j, m, n)); } else { if (code(lsym, j) != 0) s(i) ^= tables.alpha_to (modn (i*j, m, n)); } } if (s(i) != 0) syn_error = true; /* set error flag if non-zero syndrome */ } if (syn_error) { /* if there are errors, try to correct them */ int q, u; Array d (dim_vector (t2+2, 1)), l(dim_vector (t2+2, 1)), u_lu(dim_vector (t2+2, 1)), reg(dim_vector (t2+2, 1)), elp(dim_vector (t2+2, t2+2)); /* convert syndrome from polynomial form to index form */ for (int i = 1; i <= t2; i++) s(i) = tables.index_of (s(i)); /* * Compute the error location polynomial via the Berlekamp * iterative algorithm. Following the terminology of Lin and * Costello's book : d(u) is the 'mu'th discrepancy, where * u='mu'+1 and 'mu' (the Greek letter!) is the step number * ranging from -1 to 2*t (see L&C), l(u) is the degree of * the elp at that step, and u_l(u) is the difference between * the step number and the degree of the elp. */ /* initialise table entries */ d(0) = 0; /* index form */ d(1) = s(1); /* index form */ elp(0, 0) = 0; /* index form */ elp(1, 0) = 1; /* polynomial form */ for (int i = 1; i < t2; i++) { elp(0, i) = n; /* index form */ elp(1, i) = 0; /* polynomial form */ } l(0) = 0; l(1) = 0; u_lu(0) = -1; u_lu(1) = 0; u = 0; do { u++; if (d(u) == n) { l(u + 1) = l(u); for (int i = 0; i <= l(u); i++) { elp(u + 1, i) = elp(u, i); elp(u, i) = tables.index_of (elp(u, i)); } } else /* * search for words with greatest u_lu(q) for * which d(q)!=0 */ { q = u - 1; while ((d(q) == n) && (q > 0)) q--; /* have found first non-zero d(q) */ if (q > 0) { int j = q; do { j--; if ((d(j) != n) && (u_lu(q) < u_lu(j))) q = j; } while (j > 0); } /* * have now found q such that d(u)!=0 and * u_lu(q) is maximum */ /* store degree of new elp polynomial */ if (l(u) > l(q) + u - q) l(u + 1) = l(u); else l(u + 1) = l(q) + u - q; /* form new elp(x) */ for (int i = 0; i < t2; i++) elp(u + 1, i) = 0; for (int i = 0; i <= l(q); i++) if (elp(q, i) != n) elp(u + 1, i + u - q) = tables.alpha_to (modn ((d(u) + n - d(q) + elp(q, i)), m, n)); for (int i = 0; i <= l(u); i++) { elp(u + 1, i) ^= elp(u, i); elp(u, i) = tables.index_of (elp(u, i)); } } u_lu(u + 1) = u - l(u + 1); /* form (u+1)th discrepancy */ if (u < t2) { /* no discrepancy computed on last iteration */ d(u + 1) = tables.alpha_to (s(u + 1)); for (int i = 1; i <= l(u + 1); i++) if ((s(u + 1 - i) != n) && (elp(u + 1, i) != 0)) d(u + 1) ^= tables.alpha_to (modn (s(u + 1 - i) + tables.index_of (elp(u + 1, i)), m, n)); /* put d(u+1) into index form */ d(u + 1) = tables.index_of (d(u + 1)); } } while ((u < t2) && (l(u + 1) <= t)); u++; if (l(u) <= t) {/* Can correct errors */ int count; Array loc (dim_vector (t+2, 1)); /* put elp into index form */ for (int i = 0; i <= l(u); i++) elp(u, i) = tables.index_of (elp(u, i)); /* Chien search: find roots of the error location polynomial */ for (int i = 1; i <= l(u); i++) reg(i) = elp(u, i); count = 0; for (int i = 1; i <= n; i++) { q = 1; for (int j = 1; j <= l(u); j++) if (reg(j) != n) { reg(j) = modn ((reg(j) + j), m, n); q ^= tables.alpha_to (reg(j)); } if (!q) { /* store root and error * location number indices */ loc(count) = n - i; count++; if (count > l(u)) break; } } if (count == l(u)) { /* no. roots = degree of elp hence <= t errors */ nerr(lsym) = l(u); for (int i = 0; i < l(u); i++) if (parity_at_end) code(lsym, nn-loc(i)-1) = (int)code(lsym, nn-loc(i)-1) ^ 1; else code(lsym, loc(i)) = (int)code(lsym, loc(i)) ^ 1; } else /* elp has degree >t hence cannot solve */ nerr(lsym) = -1; } else nerr(lsym) = -1; } } Matrix msg (nsym, k); if (parity_at_end) { for (int l = 0; l < nsym; l++) for (int i = 0; i < k; i++) msg(l, i) = code(l, i); } else { for (int l = 0; l < nsym; l++) for (int i = 0; i < k; i++) msg(l, i) = code(l, nn-k+i); } retval(0) = octave_value (msg); retval(1) = octave_value (nerr); retval(2) = octave_value (code); return retval; } /* %% Test input validation %!error bchdeco () %!error bchdeco (1) %!error bchdeco (1, 2) %!error bchdeco (1, 2, 3, 4, 5, 6) */ communications-1.2.1/src/PaxHeaders.3802/syndtable.cc0000644000000000000000000000013112510010473017267 xustar0029 mtime=1428164923.96250975 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/syndtable.cc0000644000000000000000000001144712510010473017624 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #define COL_MAJ(N) (N / (SIZEOF_INT << 3)) #define COL_MIN(N) (N % (SIZEOF_INT << 3)) Array get_errs (const int& nmin, const int& nmax, const int &nerrs) { Array pos; int cols = COL_MAJ (nmax)+1; OCTAVE_QUIT; if (nerrs == 1) { pos.resize (dim_vector (nmax-nmin, cols), 0); for (int i = nmin; i < nmax; i++) { pos(i-nmin, COL_MAJ (i)) = (1< new_pos = get_errs (i+1, nmax, nerrs-1); int l = pos.rows (); pos.resize (dim_vector (l+new_pos.rows (), cols), 0); for (int j=0; j (int)(sizeof (int) << 3)) { error ("syndtable: codeword minus message length must be less than %d", (sizeof (int) << 3)); return retval; } // Check that the data in h is valid in GF(2) for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) if (((h(i, j) != 0) && (h(i, j) != 1)) || ((h(i, j) - (double)((int)h(i, j))) != 0)) { error ("syndtable: parity check matrix contains invalid data"); return retval; } RowVector filled (nrows, 0); Matrix table (nrows, n, 0); unsigned int nfilled = nrows; int nerrs = 1; // The first row of the table is for no errors nfilled--; filled(0) = 1; while (nfilled != 0) { // Get all possible combinations of nerrs bit errors in n bits Array errpos = get_errs (0, n, nerrs); // Calculate the syndrome with the error vectors just calculated for (int j = 0; j < errpos.rows (); j++) { int syndrome = 0; for (int i = 0; i < m; i++) { for (int k = 0; k < n; k++) syndrome ^= (errpos(j, COL_MAJ (k)) & ((unsigned int)h(i, k) << COL_MIN (k)) ? ((unsigned int)1<<(m-i-1)) : 0); } // Now use the syndrome as the rows indices to put the error vectors // in place if (((unsigned int)syndrome < nrows) && !filled(syndrome)) { filled(syndrome) = 1; nfilled--; for (int i = 0; i < n; i++) table(syndrome, i) = ((errpos(j, COL_MAJ (i)) & ((unsigned int)1 << COL_MIN (i))) != 0); } } nerrs++; } retval = octave_value (table); return retval; } /* %% Test input validation %!error syndtable () %!error syndtable (1, 2) %!error syndtable ([1 2]) */ communications-1.2.1/src/PaxHeaders.3802/galois-ops.h0000644000000000000000000000013212510010473017222 xustar0030 mtime=1428164923.946510113 30 atime=1428164923.946510113 30 ctime=1428164983.712815029 communications-1.2.1/src/galois-ops.h0000644000000000000000000000761612510010473017561 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #if !defined (galois_octave_ops_h) #define galois_octave_ops_h 1 // Override the operator and function definition defines from Octave #define DEFBINOP_OP_G(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois \ (v1.t1 ## _value () op v2.t2 ## _value ()); \ } #define DEFBINOP_FN_G(name, t1, t2, f) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois (f (v1.t1 ## _value (), v2.t2 ## _value ())); \ } #define DEFBINOP_OP_B_S1(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return octave_value \ (v1.matrix_value () op v2.t2 ##_value ()); \ } #define DEFBINOP_FN_B_S1(name, t1, t2, f) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return octave_value (f (v1.matrix_value (), v2.t2 ## _value ())); \ } #define DEFBINOP_OP_G_S1(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois \ (v1.matrix_value () op v2.t2 ## _value ()); \ } #define DEFBINOP_FN_G_S1(name, t1, t2, f) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois (f (v1.matrix_value (), v2.t2 ## _value ())); \ } #define DEFBINOP_OP_B_S2(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return octave_value \ (v1.t1 ## _value () op v2.matrix_value ()); \ } #define DEFBINOP_FN_B_S2(name, t1, t2, f) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return octave_value (f (v1.t1 ## _value (), v2.matrix_value ())); \ } #define DEFBINOP_OP_G_S2(name, t1, t2, op) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois \ (v1.t1 ## _value () op v2.matrix_value ()); \ } #define DEFBINOP_FN_G_S2(name, t1, t2, f) \ BINOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois (f (v1.t1 ## _value (), v2.matrix_value ())); \ } #define DEFCATOP_G_FN(name, t1, t2, f) \ CATOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois (f (v1.t1 ## _value (), v2.t2 ## _value (), \ ra_idx)); \ } #define DEFCATOP_G_METHOD(name, t1, t2, f) \ CATOPDECL (name, a1, a2) \ { \ CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ return new octave_galois (v1.t1 ## _value (). f (v2.t2 ## _value (), \ ra_idx)); \ } #define INSTALL_G_CATOP(t1, t2, f) INSTALL_CATOP (t1, t2, f) #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/ov-galois.cc0000644000000000000000000000013112510010473017202 xustar0029 mtime=1428164923.95850984 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/ov-galois.cc0000644000000000000000000004442512510010473017541 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include #include #include #include #include #include #include #include #include "galois.h" #include "ov-galois.h" #if defined (DEFINE_OCTAVE_ALLOCATOR) DEFINE_OCTAVE_ALLOCATOR (octave_galois); #endif DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_galois, "galois", "galois"); octave_value octave_galois::resize (const dim_vector& dv, bool) const { if (dv.length () > 2) { error ("Can not resize galois structure to NDArray"); return octave_value (); } galois retval (gval); retval.resize (dv); return new octave_galois (retval); } octave_value_list octave_galois::dotref (const octave_value_list& idx) { octave_value_list retval; assert (idx.length () == 1); std::string nm = idx(0).string_value (); if (nm == __GALOIS_PRIMPOLY_STR) retval(0) = octave_value ((double)gval.primpoly ()); else if (nm == __GALOIS_ORDER_STR) retval(0) = octave_value ((double)gval.m ()); else if (nm == __GALOIS_DATA_STR) { int r = gval.rows (); int c = gval.columns (); Matrix data (r, c); for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) data(i, j) = (double)gval(i, j); retval(0) = octave_value (data); } #ifdef GALOIS_DISP_PRIVATES else if (nm == __GALOIS_LENGTH_STR) retval(0) = octave_value ((double)gval.n ()); else if (nm == __GALOIS_ALPHA_TO_STR) { int n = gval.n (); Matrix data (n+1, 1); for (int i = 0; i < n+1; i++) data(i, 0) = (double)gval.alpha_to (i); retval(0) = octave_value (data); } else if (nm == __GALOIS_INDEX_OF_STR) { int n = gval.n (); Matrix data (n+1, 1); for (int i = 0; i < n+1; i++) data(i, 0) = (double)gval.index_of (i); retval(0) = octave_value (data); } #endif else error ("galois structure has no member `%s'", nm.c_str ()); return retval; } octave_value octave_galois::do_index_op (const octave_value_list& idx, bool resize_ok) { octave_value retval; int len = idx.length (); switch (len) { case 2: { idx_vector i = idx (0).index_vector (); idx_vector j = idx (1).index_vector (); retval = new octave_galois (gval.index (i, j, resize_ok)); } break; case 1: { idx_vector i = idx (0).index_vector (); retval = new octave_galois (gval.index (i, resize_ok)); } break; default: { std::string n = type_name (); error ("invalid number of indices (%d) for %s value", len, n.c_str ()); } break; } return retval; } octave_value octave_galois::subsref (const std::string &type, const std::list& idx) { octave_value retval; int skip = 1; switch (type[0]) { case '(': retval = do_index_op (idx.front (), true); break; case '.': { octave_value_list t = dotref (idx.front ()); retval = (t.length () == 1) ? t(0) : octave_value (t); } break; case '{': error ("%s cannot be indexed with %c", type_name ().c_str (), type[0]); break; default: panic_impossible (); } if (! error_state) retval = retval.next_subsref (type, idx, skip); return retval; } bool octave_galois::is_true (void) const { bool retval = false; if (rows () > 0 && columns () > 0) { boolMatrix m = (gval.all () . all ()); retval = (m.rows () == 1 && m.columns () == 1 && m(0, 0)); } return retval; } bool octave_galois::print_as_scalar (void) const { int nr = rows (); int nc = columns (); return ((nr == 1 && nc == 1) || (nr == 0 || nc == 0)); } void #if defined (HAVE_OCTAVE_BASE_VALUE_PRINT_CONST) octave_galois::print (std::ostream& os, bool) const #else octave_galois::print (std::ostream& os, bool) #endif { print_raw (os); } void octave_galois::print_raw (std::ostream& os, bool) const { bool first = true; int m = gval.m (); int primpoly = gval.primpoly (); Matrix data (gval.rows (), gval.cols ()); indent (os); if (m == 1) os << "GF(2) array."; else { os << "GF(2^" << m << ") array. Primitive Polynomial = "; for (int i = m; i >= 0; i--) { if (primpoly & (1< 0) { if (first) { first = false; os << "D"; } else os << "+D"; if (i != 1) os << "^" << i; } else { if (first) { first = false; os << "1"; } else os << "+1"; } } } os << " (decimal " << primpoly << ")"; } newline (os); newline (os); indent (os); os << "Array elements = "; newline (os); newline (os); for (int i = 0; i < gval.rows (); i++) for (int j = 0; j < gval.columns (); j++) data(i, j) = (double)gval(i, j); octave_print_internal (os, data, false, current_print_indent_level ()); newline (os); } bool octave_galois::print_name_tag (std::ostream& os, const std::string& name) const { bool retval = false; indent (os); // Vstruct_levels_to_print was made static in Octave 3.4, which means // the name_tag might be printed on a seperate line when it shouldn't be. #if 0 if (Vstruct_levels_to_print < 0) #else if (false) #endif os << name << " = "; else { os << name << " ="; newline (os); retval = true; } return retval; } void octave_galois::print_info (std::ostream& os, const std::string& prefix) const { gval.print_info (os, prefix); } double octave_galois::double_value (bool) const { double retval = octave_NaN; if (rows () > 0 && columns () > 0) { gripe_implicit_conversion ("Octave:array-as-scalar", "real matrix", "real scalar"); retval = (double) gval (0, 0); } else gripe_invalid_conversion ("galois", "real scalar"); return retval; } Complex octave_galois::complex_value (bool) const { double tmp = octave_NaN; Complex retval (tmp, tmp); if (rows () > 0 && columns () > 0) { gripe_implicit_conversion ("Octave:array-as-scalar", "real matrix", "real scalar"); retval = (double) gval (0, 0); } else gripe_invalid_conversion ("galois", "complex scalar"); return retval; } Matrix octave_galois::matrix_value (bool) const { Matrix retval; retval.resize (rows (), columns ()); for (int i = 0; i < rows (); i++) for (int j = 0; j < columns (); j++) retval(i, j) = gval(i, j); return retval; } NDArray octave_galois::array_value (bool) const { int nr = rows (); int nc = columns (); dim_vector dv (nr, nc); NDArray retval (dv); for (int i = 0; i < nr; i++) for (int j = 0; j < nc; j++) retval(i + j*nr) = gval(i, j); return retval; } void octave_galois::assign (const octave_value_list& idx, const galois& rhs) { int len = idx.length (); if (gval.have_field () && rhs.have_field ()) { if ((gval.m () != rhs.m ()) || (gval.primpoly () != rhs.primpoly ())) { (*current_liboctave_error_handler) ("can not assign data between two different Galois Fields"); return; } } switch (len) { case 2: { idx_vector i = idx (0).index_vector (); if (! error_state) { idx_vector j = idx (1).index_vector (); if (! error_state) gval.assign (i, j, rhs); } } break; case 1: { idx_vector i = idx (0).index_vector (); if (! error_state) gval.assign (i, rhs); } break; default: error ("invalid number of indices (%d) for galois assignment", len); break; } } bool octave_galois::save_ascii (std::ostream& os) { dim_vector d = dims (); Matrix tmp = matrix_value (); // Note use N-D way of writing matrix for eventual conversion // of octave_galois to handle N-D arrays os << "# m: " << m () << "\n"; os << "# prim: " << primpoly () << "\n"; os << "# ndims: " << d.length () << "\n"; for (int i = 0; i < d.length (); i++) os << " " << d (i); os << "\n" << tmp; return true; } bool octave_galois::load_ascii (std::istream& is) { int mord, prim, mdims; bool success = true; if (extract_keyword (is, "m", mord) && extract_keyword (is, "prim", prim) && extract_keyword (is, "ndims", mdims)) { dim_vector dv; dv.resize (mdims); for (int i = 0; i < mdims; i++) is >> dv(i); if (dv.length () != 2) { error ("load: N-D galois matrix not supported"); success = false; } else { Matrix tmp (dv(0), dv(1)); is >> tmp; if (!is) { error ("load: failed to load matrix constant"); success = false; } gval = galois (tmp, mord, prim); } } else { error ("load: failed to extract galois field order, primitive and/or imension"); success = false; } return success;; } bool octave_galois::save_binary (std::ostream& os, bool& save_as_floats) { char tmp = m (); os.write (X_CAST (char *, &tmp), 1); int32_t itmp = primpoly (); os.write (X_CAST (char *, &itmp), 4); dim_vector d = dims (); // Don't handle N-D arrays yet if (d.length () != 2) return false; // Use negative value for ndims to be consistent with other formats itmp = - d.length (); os.write (X_CAST (char *, &itmp), 4); for (int i = 0; i < d.length (); i++) { itmp = d(i); os.write (X_CAST (char *, &itmp), 4); } Matrix m = matrix_value (); save_type st; if (tmp < 8) st = LS_U_CHAR; else if (tmp < 16) st = LS_U_SHORT; else st = LS_U_INT; const double *mtmp = m.data (); write_doubles (os, mtmp, st, d.numel ()); return true; } bool octave_galois::load_binary (std::istream& is, bool swap, oct_mach_info::float_format fmt) { char mord; int32_t prim, mdims; if (! is.read (X_CAST (char *, &mord), 1)) return false; if (! is.read (X_CAST (char *, &prim), 4)) return false; if (swap) swap_bytes <4> (X_CAST (char *, &prim)); if (! is.read (X_CAST (char *, &mdims), 4)) return false; if (swap) swap_bytes <4> (X_CAST (char *, &mdims)); // Don't treat N-D arrays yet if (mdims == -2) { mdims = - mdims; int32_t di; dim_vector dv; dv.resize (mdims); for (int i = 0; i < mdims; i++) { if (! is.read (X_CAST (char *, &di), 4)) return false; if (swap) swap_bytes <4> (X_CAST (char *, &di)); dv(i) = di; } char tmp; if (! is.read (X_CAST (char *, &tmp), 1)) return false; Matrix m (dv(0), dv(1)); double *re = m.fortran_vec (); read_doubles (is, re, X_CAST (save_type, tmp), dv.numel (), swap, fmt); if (error_state || ! is) return false; gval = galois (m, mord, prim); } return true; } bool octave_galois::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats) { bool retval = true; #if defined (HAVE_HDF5) Matrix mval = matrix_value (); hid_t group_hid = -1; #if HAVE_HDF5_18 group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); #else group_hid = H5Gcreate (loc_id, name, 0); #endif if (group_hid < 0 ) return false; dim_vector d = dims (); OCTAVE_LOCAL_BUFFER (hsize_t, hdims, d.length () > 2 ? d.length () : 3); hid_t space_hid = -1, data_hid = -1; char tmp; int32_t itmp; space_hid = H5Screate_simple (0, hdims, (hsize_t*) 0); if (space_hid < 0) { H5Gclose (group_hid); return false; } #if HAVE_HDF5_18 data_hid = H5Dcreate (group_hid, "m", H5T_NATIVE_UCHAR, space_hid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); #else data_hid = H5Dcreate (group_hid, "m", H5T_NATIVE_UCHAR, space_hid, H5P_DEFAULT); #endif if (data_hid < 0) { H5Sclose (space_hid); H5Gclose (group_hid); return false; } tmp = m (); retval = H5Dwrite (data_hid, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void*) &tmp) >= 0; H5Dclose (data_hid); if (!retval) { H5Sclose (space_hid); H5Gclose (group_hid); return false; } #if HAVE_HDF5_18 data_hid = H5Dcreate (group_hid, "prim", H5T_NATIVE_UINT, space_hid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); #else data_hid = H5Dcreate (group_hid, "prim", H5T_NATIVE_UINT, space_hid, H5P_DEFAULT); #endif if (data_hid < 0) { H5Sclose (space_hid); H5Gclose (group_hid); return false; } itmp = primpoly (); retval = H5Dwrite (data_hid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void*) &itmp) >= 0; H5Dclose (data_hid); if (!retval) { H5Sclose (space_hid); H5Gclose (group_hid); return false; } H5Sclose (space_hid); // Octave uses column-major, while HDF5 uses row-major ordering for (int i = 0, j = d.length () - 1; i < d.length (); i++, j--) hdims[i] = d (j); space_hid = H5Screate_simple (d.length (), hdims, (hsize_t*) 0); if (space_hid < 0) return false; double *mtmp = mval.fortran_vec (); OCTAVE_LOCAL_BUFFER (uint32_t, vtmp, d.numel ()); hid_t save_type_hid = H5T_NATIVE_UINT; if (tmp <= 8) { save_type_hid = H5T_NATIVE_UCHAR; char *wtmp = (char *)vtmp; for (int i = 0; i < d.numel (); i++) wtmp[i] = (char) mtmp[i]; } else if (tmp <= 16) { save_type_hid = H5T_NATIVE_USHORT; uint16_t *wtmp = (uint16_t *)vtmp; for (int i = 0; i < d.numel (); i++) wtmp[i] = (uint16_t) mtmp[i]; } else { for (int i = 0; i < d.numel (); i++) vtmp[i] = (uint32_t) mtmp[i]; } #if HAVE_HDF5_18 data_hid = H5Dcreate (group_hid, "val", save_type_hid, space_hid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); #else data_hid = H5Dcreate (group_hid, "val", save_type_hid, space_hid, H5P_DEFAULT); #endif if (data_hid < 0) { H5Sclose (space_hid); H5Gclose (group_hid); return false; } retval = H5Dwrite (data_hid, save_type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void*) vtmp) >= 0; H5Dclose (data_hid); H5Sclose (space_hid); H5Gclose (group_hid); #elif defined (HAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE) gripe_save ("hdf5"); #else warning ("galois: saving hdf5 files not available"); #endif return retval; } bool octave_galois::load_hdf5 (octave_hdf5_id loc_id, const char *name) { bool retval = false; #if defined (HAVE_HDF5) char mord; unsigned int prim; hid_t group_hid, data_hid, space_id; hsize_t rank; #if HAVE_HDF5_18 group_hid = H5Gopen (loc_id, name, H5P_DEFAULT); #else group_hid = H5Gopen (loc_id, name); #endif if (group_hid < 0 ) return false; #if HAVE_HDF5_18 data_hid = H5Dopen (group_hid, "m", H5P_DEFAULT); #else data_hid = H5Dopen (group_hid, "m"); #endif space_id = H5Dget_space (data_hid); rank = H5Sget_simple_extent_ndims (space_id); if (rank != 0) { H5Dclose (data_hid); H5Gclose (group_hid); return false; } if (H5Dread (data_hid, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *) &mord) < 0) { H5Dclose (data_hid); H5Gclose (group_hid); return false; } H5Dclose (data_hid); #if HAVE_HDF5_18 data_hid = H5Dopen (group_hid, "prim", H5P_DEFAULT); #else data_hid = H5Dopen (group_hid, "prim"); #endif space_id = H5Dget_space (data_hid); rank = H5Sget_simple_extent_ndims (space_id); if (rank != 0) { H5Dclose (data_hid); H5Gclose (group_hid); return false; } if (H5Dread (data_hid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *) &prim) < 0) { H5Dclose (data_hid); H5Gclose (group_hid); return false; } H5Dclose (data_hid); #if HAVE_HDF5_18 data_hid = H5Dopen (group_hid, "val", H5P_DEFAULT); #else data_hid = H5Dopen (group_hid, "val"); #endif space_id = H5Dget_space (data_hid); rank = H5Sget_simple_extent_ndims (space_id); // Only handle matrices for now if (rank != 2) { H5Sclose (space_id); H5Dclose (data_hid); H5Gclose (group_hid); return false; } OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank); H5Sget_simple_extent_dims (space_id, hdims, maxdims); MArray m (dim_vector (hdims[1], hdims[0])); int *re = m.fortran_vec (); if (H5Dread (data_hid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *) re) >= 0) { retval = true; gval = galois (m, mord, prim); } H5Sclose (space_id); H5Dclose (data_hid); #elif defined (HAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE) gripe_load ("hdf5"); #else warning ("galois: loading hdf5 files not available"); #endif return retval; } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/galois.h0000644000000000000000000000013212510010473016423 xustar0030 mtime=1428164923.946510113 30 atime=1428164923.946510113 30 ctime=1428164983.712815029 communications-1.2.1/src/galois.h0000644000000000000000000001254112510010473016753 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #if !defined (octave_galois_int_h) #define octave_galois_int_h 1 #include #include #include #include "galoisfield.h" typedef void (*solve_singularity_handler) (double rcond); class galois : public MArray { public: galois (void) : field (NULL) { } galois (const Array& a, const int& m=1, const int& primpoly=0); galois (const MArray& a, const int& m=1, const int& primpoly=0); galois (const Matrix& a, const int& m=1, const int& primpoly=0); galois (int nr, int nc, const int& val=0, const int& _m=1, const int& _primpoly=0); galois (int nr, int nc, double val=0., const int& _m=1, const int& _primpoly=0); galois (const galois& a); ~galois (void); galois index (idx_vector& i, int resize_ok = 0, const int& rfv = 0) const; galois index (idx_vector& i, idx_vector& j, int resize_ok = 0, const int& rfv = 0) const; // unary operations boolMatrix operator ! (void) const; galois transpose (void) const; // other operations boolMatrix all (int dim = -1) const; boolMatrix any (int dim = -1) const; galois concat (const galois& rb, const Array& ra_idx); galois concat (const Matrix& rb, const Array& ra_idx); friend galois concat (const Matrix& ra, const galois& rb, const Array& ra_idx); galois& insert (const galois& a, int r, int c); galois diag (void) const; galois diag (int k) const; galois prod (int dim) const; galois sum (int dim) const; galois sumsq (int dim) const; galois sqrt (void) const; galois log (void) const; galois exp (void) const; galois inverse (void) const; galois inverse (int &info, int force = 0) const; galois solve (const galois& b) const; galois solve (const galois& b, int& info) const; galois solve (const galois& b, int& info, solve_singularity_handler sing_handler) const; galois determinant (void) const; galois determinant (int& info) const; galois &operator = (const galois& t); galois &operator += (const galois& a); galois &operator -= (const galois& a); private: // Pointer to the Galois field structure used galois_field_node *field; public: // Is the variable initialized?? bool have_field (void) const { return (field ? true : false); }; // Access to Galois field structures int m (void) const { return (field->m); } int primpoly (void) const { return (field->primpoly); } int n (void) const { return (field->n); } int alpha_to (const int& idx) const { return (field->alpha_to (idx)); } int index_of (const int& idx) const { return (field->index_of (idx)); } }; class galoisLU : public base_lu { friend class galois; public: enum pivot_type { ROW, COL }; galoisLU (void) : base_lu () { } galoisLU (const galois& a, const pivot_type& typ) { factor (a, typ); } galoisLU (const galois& a) { factor (a, galoisLU::ROW); } galoisLU (const galoisLU& a) : base_lu (a) { } galoisLU& operator = (const galoisLU& a) { if (this != &a) base_lu :: operator = (a); return *this; } ~galoisLU (void) { } galois L (void) const; galois U (void) const; bool singular (void) const { return info != 0; } pivot_type type (void) const { return ptype; } private: void factor (const galois& a, const pivot_type& typ); int info; pivot_type ptype; }; void install_gm_gm_ops (void); void install_gm_m_ops (void); void install_m_gm_ops (void); void install_gm_s_ops (void); void install_s_gm_ops (void); void install_fil_gm_ops (void); galois elem_pow (const galois& a, const galois& b); galois elem_pow (const galois& a, const Matrix& b); galois elem_pow (const galois& a, double b); galois elem_pow (const galois& a, int b); galois pow (const galois& a, const galois& b); galois pow (const galois& a, double b); galois pow (const galois& a, int b); galois xdiv (const galois& a, const galois& b); galois xdiv (const galois& a, const Matrix& b); galois xdiv (const Matrix& a, const galois& b); galois xleftdiv (const galois& a, const galois& b); galois xleftdiv (const galois& a, const Matrix& b); galois xleftdiv (const Matrix& a, const galois& b); galois operator * (const galois& a, const galois& b); galois operator * (const galois& a, const Matrix& b); galois operator * (const Matrix& a, const galois& b); MM_OP_DECLS (galois, galois, galois, ); MM_OP_DECLS (galois, galois, Matrix, ); MM_OP_DECLS (galois, Matrix, galois, ); #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/isprimitive.cc0000644000000000000000000000013212510010473017647 xustar0030 mtime=1428164923.954509931 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/isprimitive.cc0000644000000000000000000000707112510010473020201 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include static bool do_isprimitive (const int& a, const int& m) { // Fast return since primitive polynomial can't be even if (!(a & 1)) return false; RowVector repr (1< 24) { error ("isprimitive: order of the primitive polynomial must " "be less than 22"); return retval; } Matrix b (a.rows (), 1); for (int i = 0; i < a.rows (); i++) { int tmp = (int)a(i, 0); for (int j = 1; j < a.columns (); j++) tmp = (tmp << 1) | (int)a(i, j); int m = 1; while (tmp > (1<<(m+1))) m++; b(i, 0) = do_isprimitive (tmp, m); } retval = octave_value (b); } else { for (int i = 0; i < a.rows (); i++) for (int j = 0; j < a.columns (); j++) if (a(i, j) > (1<<23)) { error ("isprimitive: order of the primitive polynomial must " "be less than 22"); return retval; } Matrix b (a.rows (), a.columns ()); for (int i = 0; i < a.rows (); i++) { for (int j = 0; j < a.columns (); j++) { int m = 1; while (a(i, j) > (1<<(m+1))) m++; b(i, j) = do_isprimitive ((int)a(i, j), m); } } retval = octave_value (b); } return retval; } /* %% Test input validation %!error isprimitive () %!error isprimitive (1, 2) */ /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/galoisfield.h0000644000000000000000000000013212510010473017427 xustar0030 mtime=1428164923.950510022 30 atime=1428164923.950510022 30 ctime=1428164983.712815029 communications-1.2.1/src/galoisfield.h0000644000000000000000000000420412510010473017754 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #if !defined (octave_galois_field_int_h) #define octave_galois_field_int_h 1 #include // Maximum value of m #define __OCTAVE_GALOIS_MAX_M 16 // Maximum value of m. If you change the above, change here also #define __OCTAVE_GALOIS_MAX_M_AS_STRING "16" // A0 flag -inf value #define __OCTAVE_GALOIS_A0 (n) // The default primitive polynomials for GF(2^(indx+1)) extern int default_galois_primpoly[]; class galois_field_node { friend class galois_field_list; friend class galois; private: int m; int primpoly; int n; MArray alpha_to; MArray index_of; galois_field_node *next; galois_field_node *prev; int count; public: galois_field_node (void); galois_field_node (const int& _m = 1, const int& _primpoly = 0); galois_field_node & operator = (const galois_field_node &t); }; class galois_field_list { private: galois_field_node *first; galois_field_node *last; public: galois_field_list (void) : first (NULL), last (NULL) { } ~galois_field_list (void); galois_field_node * find_galois_field (const int& m, const int& primpoly); galois_field_node * create_galois_field (const int& m, const int& primpoly); int delete_galois_field (galois_field_node *field); }; #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/configure.ac0000644000000000000000000000013212510010473017262 xustar0030 mtime=1428164923.938510295 30 atime=1428164983.572819657 30 ctime=1428164983.712815029 communications-1.2.1/src/configure.ac0000644000000000000000000000705212510010473017613 0ustar00rootroot00000000000000AC_PREREQ([2.60]) AC_INIT([Octave-Forge communications package], [0]) AC_ARG_VAR([MKOCTFILE], [mkoctfile compiler helper command]) AC_ARG_VAR([OCTAVE], [Octave interpreter command]) AC_CHECK_PROG([MKOCTFILE], mkoctfile, mkoctfile, []) AC_CHECK_PROG([OCTAVE], octave, octave, []) AC_PROG_CXX AC_PROG_SED comm_OCT_EVAL="$OCTAVE --norc --no-history --silent --eval" AC_CACHE_CHECK([for Octave HDF5 preprocessor flags], [comm_cv_hdf5_cppflags], [comm_cv_hdf5_cppflags=`$comm_OCT_EVAL 'disp(octave_config_info.HDF5_CPPFLAGS)' 2>/dev/null`]) AC_CACHE_CHECK([for Octave HDF5 linker flags], [comm_cv_hdf5_ldflags], [comm_cv_hdf5_ldflags=`$comm_OCT_EVAL 'disp(octave_config_info.HDF5_LDFLAGS)' 2>/dev/null`]) AC_CACHE_CHECK([for Octave HDF5 libraries], [comm_cv_hdf5_libs], [comm_cv_hdf5_libs=`$comm_OCT_EVAL 'disp(octave_config_info.HDF5_LIBS)' 2>/dev/null`]) AC_SUBST([HDF5_CPPFLAGS], [$comm_cv_hdf5_cppflags]) AC_SUBST([HDF5_LDFLAGS], [$comm_cv_hdf5_ldflags]) AC_SUBST([HDF5_LIBS], [$comm_cv_hdf5_libs]) AC_SUBST([PKG_CPPFLAGS], ["-DGALOIS_DISP_PRIVATES"]) comm_CXXFLAGS=`$MKOCTFILE -p ALL_CXXFLAGS` AC_CACHE_CHECK([for octave_hdf5_id type], [comm_cv_octave_hdf5_id_type], [comm_save_CPPFLAGS=$CPPFLAGS comm_save_CXXFLAGS=$CXXFLAGS CPPFLAGS="$CPPFLAGS $HDF5_CPPFLAGS" CXXFLAGS="$CXXFLAGS $comm_CXXFLAGS" AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ octave_hdf5_id x; ]])], [comm_cv_octave_hdf5_id_type=yes], [comm_cv_octave_hdf5_id_type=no]) AC_LANG_POP(C++) CPPFLAGS=$comm_save_CPPFLAGS CXXFLAGS=$comm_save_CXXFLAGS]) if test $comm_cv_octave_hdf5_id_type = yes; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_OCTAVE_HDF5_ID_TYPE=1" fi AC_CACHE_CHECK([for octave_base_value::gripe_load and octave_base_value::gripe_save], [comm_cv_octave_base_value_gripe_load_save], [comm_save_CPPFLAGS=$CPPFLAGS comm_save_CXXFLAGS=$CXXFLAGS CPPFLAGS="$CPPFLAGS $HDF5_CPPFLAGS" CXXFLAGS="$CXXFLAGS $comm_CXXFLAGS" AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include class foo : public octave_base_value { public: foo () {} void func () { gripe_load ("func"); gripe_save ("func"); } }; ]], [[ foo x; ]])], [comm_cv_octave_base_value_gripe_load_save=yes], [comm_cv_octave_base_value_gripe_load_save=no]) AC_LANG_POP(C++) CPPFLAGS=$comm_save_CPPFLAGS CXXFLAGS=$comm_save_CXXFLAGS]) if test $comm_cv_octave_base_value_gripe_load_save = yes; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE=1" fi AC_CACHE_CHECK([whether octave_base_value::print is const-qualified], [comm_cv_octave_base_value_print_const_qualified], [comm_save_CPPFLAGS=$CPPFLAGS comm_save_CXXFLAGS=$CXXFLAGS CPPFLAGS="$CPPFLAGS $HDF5_CPPFLAGS" CXXFLAGS="$CXXFLAGS $comm_CXXFLAGS" AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]], [[ const octave_base_value x; x.print (std::cout); ]])], [comm_cv_octave_base_value_print_const_qualified=yes], [comm_cv_octave_base_value_print_const_qualified=no]) AC_LANG_POP(C++) CPPFLAGS=$comm_save_CPPFLAGS CXXFLAGS=$comm_save_CXXFLAGS]) if test $comm_cv_octave_base_value_print_const_qualified = yes; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_OCTAVE_BASE_VALUE_PRINT_CONST=1" fi AC_CONFIG_FILES([Makefile]) AC_OUTPUT communications-1.2.1/src/PaxHeaders.3802/op-s-gm.cc0000644000000000000000000000013112510010473016561 xustar0029 mtime=1428164923.95850984 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/op-s-gm.cc0000644000000000000000000001000612510010473017104 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include "galois.h" #include "ov-galois.h" #include "galois-ops.h" // scalar by galois ops. DEFBINOP_OP_G_S1 (add, scalar, galois, +) DEFBINOP_OP_G_S1 (sub, scalar, galois, -) DEFBINOP_FN_G_S1 (mul, scalar, galois, product) DEFBINOP_FN_G_S1 (div, scalar, galois, xdiv) DEFBINOP (pow, scalar, galois) { CAST_BINOP_ARGS (const octave_scalar&, const octave_galois&); galois tmp (v1.matrix_value (), v2.m (), v2.primpoly ()); return new octave_galois (pow (tmp, v2.galois_value ())); } DEFBINOP (ldiv, scalar, galois) { CAST_BINOP_ARGS (const octave_scalar&, const octave_galois&); \ return new octave_galois (quotient (v2.galois_value (), v1.matrix_value ())); } DEFBINOP_FN_B_S1 (lt, scalar, galois, mx_el_lt) DEFBINOP_FN_B_S1 (le, scalar, galois, mx_el_le) DEFBINOP_FN_B_S1 (eq, scalar, galois, mx_el_eq) DEFBINOP_FN_B_S1 (ge, scalar, galois, mx_el_ge) DEFBINOP_FN_B_S1 (gt, scalar, galois, mx_el_gt) DEFBINOP_FN_B_S1 (ne, scalar, galois, mx_el_ne) DEFBINOP_FN_G_S1 (el_mul, scalar, galois, product) DEFBINOP_FN_G_S1 (el_div, scalar, galois, quotient) DEFBINOP (el_pow, scalar, galois) { CAST_BINOP_ARGS (const octave_scalar&, const octave_galois&); \ galois tmp (v1.matrix_value (), v2.m (), v2.primpoly ()); return new octave_galois (elem_pow (tmp, v2.galois_value ())); } DEFBINOP (el_ldiv, scalar, galois) { CAST_BINOP_ARGS (const octave_scalar&, const octave_galois&); return new octave_galois (quotient (v2.galois_value (), v1.matrix_value ())); } DEFBINOP_FN_B_S1 (el_and, scalar, galois, mx_el_and) DEFBINOP_FN_B_S1 (el_or, scalar, galois, mx_el_or) DEFCATOP (s_gm, scalar, galois) { CAST_BINOP_ARGS (octave_scalar&, const octave_galois&); return new octave_galois (concat (v1.matrix_value (), v2.galois_value (), ra_idx)); } void install_s_gm_ops (void) { INSTALL_BINOP (op_add, octave_scalar, octave_galois, add); INSTALL_BINOP (op_sub, octave_scalar, octave_galois, sub); INSTALL_BINOP (op_mul, octave_scalar, octave_galois, mul); INSTALL_BINOP (op_div, octave_scalar, octave_galois, div); INSTALL_BINOP (op_pow, octave_scalar, octave_galois, pow); INSTALL_BINOP (op_ldiv, octave_scalar, octave_galois, ldiv); INSTALL_BINOP (op_lt, octave_scalar, octave_galois, lt); INSTALL_BINOP (op_le, octave_scalar, octave_galois, le); INSTALL_BINOP (op_eq, octave_scalar, octave_galois, eq); INSTALL_BINOP (op_ge, octave_scalar, octave_galois, ge); INSTALL_BINOP (op_gt, octave_scalar, octave_galois, gt); INSTALL_BINOP (op_ne, octave_scalar, octave_galois, ne); INSTALL_BINOP (op_el_mul, octave_scalar, octave_galois, el_mul); INSTALL_BINOP (op_el_div, octave_scalar, octave_galois, el_div); INSTALL_BINOP (op_el_pow, octave_scalar, octave_galois, el_pow); INSTALL_BINOP (op_el_ldiv, octave_scalar, octave_galois, el_ldiv); INSTALL_BINOP (op_el_and, octave_scalar, octave_galois, el_and); INSTALL_BINOP (op_el_or, octave_scalar, octave_galois, el_or); INSTALL_G_CATOP (octave_scalar, octave_galois, s_gm); INSTALL_ASSIGNCONV (octave_scalar, octave_galois, octave_galois); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/Makefile.in0000644000000000000000000000013212510010473017041 xustar0030 mtime=1428164923.938510295 30 atime=1428164923.938510295 30 ctime=1428164983.712815029 communications-1.2.1/src/Makefile.in0000644000000000000000000000230212510010473017363 0ustar00rootroot00000000000000MKOCTFILE ?= @MKOCTFILE@ OCTAVE ?= @OCTAVE@ SED ?= @SED@ HDF5_CPPFLAGS = @HDF5_CPPFLAGS@ HDF5_LDFLAGS = @HDF5_LDFLAGS@ HDF5_LIBS = @HDF5_LIBS@ PKG_CPPFLAGS = @PKG_CPPFLAGS@ OCT_FILES = \ __errcore__.oct \ __gfweight__.oct \ cyclgen.oct \ cyclpoly.oct \ genqamdemod.oct \ gf.oct \ isprimitive.oct \ primpoly.oct \ syndtable.oct GF_OBJECTS = \ galois-def.o \ galois.o \ galoisfield.o \ gf.o \ op-gm-gm.o \ op-gm-m.o \ op-gm-s.o \ op-m-gm.o \ op-s-gm.o \ ov-galois.o GF_HEADERS = \ galois-def.h \ galois-ops.h \ galois.h \ galoisfield.h \ ov-galois.h OCT_SOURCES = $(patsubst %.oct,%.cc,$(OCT_FILES)) all: $(OCT_FILES) %.o: %.cc $(MKOCTFILE) $(PKG_CPPFLAGS) -c $< -o $@ %.oct: %.cc $(MKOCTFILE) $(PKG_CPPFLAGS) $< -o $@ gf.oct: $(GF_OBJECTS) $(MKOCTFILE) $(HDF5_LDFLAGS) $^ $(HDF5_LIBS) -o $@ ov-galois.o: PKG_CPPFLAGS += $(HDF5_CPPFLAGS) $(GF_OBJECTS): $(GF_HEADERS) PKG_ADD PKG_DEL: $(OCT_SOURCES) $(SED) -n -e 's/.*$@: \(.*\)/\1/p' $^ > $@-t mv $@-t $@ clean: -rm -f *.o *.oct PKG_* distclean: clean -rm -f Makefile config.* maintainer-clean: distclean -rm -rf autom4te.cache configure .PHONY: all clean distclean maintainer-clean communications-1.2.1/src/PaxHeaders.3802/galoisfield.cc0000644000000000000000000000013212510010473017565 xustar0030 mtime=1428164923.950510022 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/galoisfield.cc0000644000000000000000000001130612510010473020113 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include "galois.h" #include "galoisfield.h" #include "galois-def.h" // The default primitive polynomials for GF(2^(indx+1)) int default_galois_primpoly[] = { 0x3, 0x7, 0xb, 0x13, 0x25, 0x43, 0x89, 0x11d, 0x211, 0x409, 0x805, 0x1053, 0x201b, 0x4443, 0x8003, 0x1100b}; galois_field_node::galois_field_node (void) : m (0), primpoly (0), n (0), next (NULL), prev (NULL), count (0) { } galois_field_node::galois_field_node (const int& _m, const int& _primpoly) { int mask; next = NULL; prev = NULL; count = 0; // Flag that field is currently bad... // Initialize order of GF(2^m) m = _m; if ((m < 1) || (m > __OCTAVE_GALOIS_MAX_M)) { gripe_order_galois (m); return; } n = (1< n) { gripe_irred_galois (primpoly); return; } count = 1; // Field is good now !! return; } galois_field_node & galois_field_node::operator = (const galois_field_node &t) { m = t.m; primpoly = t.primpoly; n = t.n; alpha_to = t.alpha_to; index_of = t.index_of; next = NULL; prev = NULL; count = 1; return *this; } galois_field_list::~galois_field_list (void) { while (first) { galois_field_node * tmp = first->next; delete first; first = tmp; } } galois_field_node* galois_field_list::find_galois_field (const int& m, const int& primpoly) { galois_field_node* ptr = first; while (ptr) { if ((ptr->m == m) && (ptr->primpoly == primpoly)) return ptr; ptr = ptr->next; } return NULL; } galois_field_node* galois_field_list::create_galois_field (const int& m, const int& primpoly) { galois_field_node* ptr = find_galois_field (m, primpoly); if (ptr) { // We already have this field. Bump counter and return ptr->count++; return ptr; } // Create a new field and add it to the list ptr = new galois_field_node (m, primpoly); if (ptr->count == 0) { gripe_init_galois (); return ptr; } if (first) { ptr->next = first; first->prev = ptr; } else last = ptr; first = ptr; return ptr; } int galois_field_list::delete_galois_field (galois_field_node* field) { if (!field) return 0; field->count--; if (field->count == 0) { if (field == first) { first = field->next; if (first) first->prev = NULL; } else if (field == last) { last = field->prev; if (last) last->next = NULL; } else { field->prev->next = field->next; field->next->prev = field->prev; } delete field; return 1; } else return 0; } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/galois-def.cc0000644000000000000000000000013212510010473017315 xustar0030 mtime=1428164923.942510204 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/galois-def.cc0000644000000000000000000000614512510010473017650 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include "galois.h" void gripe_nonconformant_galois (const char *op, int op1_m, int op1_primpoly, int op2_m, int op2_primpoly) { (*current_liboctave_error_handler) ("%s: nonconformant arguments. op1 is GF(2^%d) " "(primitive polynomial %d), op2 is GF(2^%d) (primitive polynomial %d)", op, op1_m, op1_primpoly, op2_m, op2_primpoly); } void gripe_nonconformant_galois (const char *op, int m) { (*current_liboctave_error_handler) ("%s: element exceeds range of galois field GF(2^%d)", op, m); } void gripe_divzero_galois (const char *op) { (*current_liboctave_error_handler) ("%s: division by zero in galois field", op); } void gripe_invalid_galois (void) { (*current_liboctave_error_handler) ("invalid data in Galois Field"); } void gripe_range_galois (int m) { (*current_liboctave_error_handler) ("data outside range of Galois Field GF(2^%d)", m); } void gripe_integer_galois (void) { (*current_liboctave_error_handler) ("data in Galois Field must be integer"); } void gripe_copy_invalid_galois (void) { (*current_liboctave_error_handler) ("trying to copy invalid Galois Field"); } void gripe_differ_galois (void) { (*current_liboctave_error_handler) ("can not assign data between two different Galois Fields"); } void gripe_invalid_table_galois (void) { (*current_liboctave_error_handler) ("invalid lookup table in Galois Field"); } void gripe_square_galois (void) { (*current_liboctave_error_handler) ("for A^x, A must be square and x scalar"); } void gripe_integer_power_galois (void) { (*current_liboctave_error_handler) ("exponent must be integer for binary operator '^' with galois field"); } void gripe_order_galois (int m) { (*current_liboctave_error_handler) ("invalid order %d for Galois Field", m); } void gripe_degree_galois (int m) { (*current_liboctave_error_handler) ("invalid degree for primitive polynomial (%d) of Galois Field", m); } void gripe_irred_galois (int m) { (*current_liboctave_error_handler) ("primitive polynomial (%d) of Galois Field must be irreducible", m); } void gripe_init_galois (void) { (*current_liboctave_error_handler) ("unable to initialize Galois Field"); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/cyclgen.cc0000644000000000000000000000013212510010473016727 xustar0030 mtime=1428164923.942510204 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/cyclgen.cc0000644000000000000000000001651412510010473017263 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include // A simplified version of the filter function for specific lengths of a and b // in the Galois field GF(2) Array filter_gf2 (const Array& b, const Array& a, const Array& x, const int& n) { int x_len = x.length (); Array si (dim_vector (n, 1), 0); Array y (dim_vector (x_len, 1), 0); for (int i = 0; i < x_len; i++) { y(i) = si(0); if (b(0) && x(i)) y(i) ^= 1; for (int j = 0; j < n - 1; j++) { si(j) = si(j+1); if (a(j+1) && y(i)) si(j) ^= 1; if (b(j+1) && x(i)) si(j) ^= 1; } si(n-1) = 0; if (a(n) && y(i)) si(n-1) ^= 1; if (b(n) && x(i)) si(n-1) ^= 1; } return y; } // Cyclic polynomial is irreducible. I.E. it divides into x^n-1 // without remainder There must surely be an easier way of doing this // as the polynomials are over GF(2). static bool do_is_cyclic_polynomial (const Array& a, const int& n, const int& m) { Array y (dim_vector (n+1, 1), 0); Array x (dim_vector (n-m+2, 1), 0); y(0) = 1; y(n) = 1; x(0) = 1; Array b = filter_gf2 (y, a, x, n); b.resize (dim_vector (n+1, 1), 0); Array p (dim_vector (m+1, 1), 0); p(0) = 1; Array q = filter_gf2 (a, p, b, m); for (int i = 0; i < n+1; i++) if (y(i) ^ q(i)) return false; return true; } DEFUN_DLD (cyclgen, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{h} =} cyclgen (@var{n}, @var{p})\n\ @deftypefnx {Loadable Function} {@var{h} =} cyclgen (@var{n}, @var{p}, @var{typ})\n\ @deftypefnx {Loadable Function} {[@var{h}, @var{g}] =} cyclgen (@dots{})\n\ @deftypefnx {Loadable Function} {[@var{h}, @var{g}, @var{k}] =} cyclgen (@dots{})\n\ Produce the parity check and generator matrix of a cyclic code. The parity\n\ check matrix is returned as a @var{m} by @var{n} matrix, representing the\n\ [@var{n},@var{k}] cyclic code. @var{m} is the order of the generator\n\ polynomial @var{p} and the message length @var{k} is given by\n\ @code{@var{n} - @var{m}}.\n\ \n\ The generator polynomial can either be a vector of ones and zeros,\n\ and length @var{m} representing,\n\ @tex\n\ $$ p_0 + p_1 x + p_2 x^2 + \\cdots + p_m x^{m-1} $$\n\ @end tex\n\ @ifnottex\n\ \n\ @example\n\ @var{p}(1) + @var{p}(2) * x + @var{p}(3) * x^2 + ... + @var{p}(@var{m}) * x^(m-1)\n\ @end example\n\ @end ifnottex\n\ \n\ The terms of the polynomial are stored least-significant term first.\n\ Alternatively, @var{p} can be an integer representation of the same\n\ polynomial.\n\ \n\ The form of the parity check matrix is determined by @var{typ}. If\n\ @var{typ} is 'system', a systematic parity check matrix is produced. If\n\ @var{typ} is 'nosys' and non-systematic parity check matrix is produced.\n\ \n\ If requested @code{cyclgen} also returns the @var{k} by @var{n} generator\n\ matrix @var{g}.\ \n\ @seealso{hammgen, gen2par, cyclpoly}\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); unsigned long long p = 0; int n, m, k, mm; bool system = true; Array pp; if (nargin < 2 || nargin > 3) { print_usage (); return retval; } n = args(0).int_value (); m = 1; while (n > (1<<(m+1))) m++; pp.resize (dim_vector (n+1, 1), 0); if (args(1).is_scalar_type ()) { p = (unsigned long long)(args(1).int_value ()); mm = 1; while (p > ((unsigned long long)1<<(mm+1))) mm++; for (int i = 0; i < mm+1; i++) pp(i) = (p & (1< 2) { if (args(2).is_string ()) { std::string s_arg = args(2).string_value (); if (s_arg == "system") system = true; else if (s_arg == "nosys") system = false; else { error ("cyclgen: illegal argument"); return retval; } } else { error ("cyclgen: illegal argument"); return retval; } } // Haven't implemented this since I'm not sure what matlab wants here if (!system) { error ("cyclgen: non-systematic generator matrices not implemented"); return retval; } if (!do_is_cyclic_polynomial (pp, n, mm)) { error ("cyclgen: generator polynomial does not produce cyclic code"); return retval; } unsigned long long mask = 1; unsigned long long *alpha_to = (unsigned long long *)malloc (sizeof (unsigned long long) * n); for (int i = 0; i < n; i++) { alpha_to[i] = mask; mask <<= 1; if (mask & ((unsigned long long)1< 1) { Matrix generator (k, n, 0); for (int i = 0; i < (int)k; i++) for (int j = 0; j < (int)mm; j++) generator(i, j) = parity(j, i+mm); for (int i = 0; i < (int)k; i++) generator(i, i+mm) = 1; retval(1) = octave_value (generator); retval(2) = octave_value ((double)k); } return retval; } /* %% Test input validation %!error cyclgen () %!error cyclgen (1) %!error cyclgen (1, 2, 3, 4) */ /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/primpoly.cc0000644000000000000000000000013112510010473017155 xustar0029 mtime=1428164923.96250975 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/primpoly.cc0000644000000000000000000002026512510010473017510 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include enum primpoly_type { PRIMPOLY_MIN=0, PRIMPOLY_MAX, PRIMPOLY_ALL, PRIMPOLY_K }; static bool do_isprimitive (const int& a, const int& m) { // Fast return since primitive polynomial can't be even if (!(a & 1)) return false; RowVector repr (1< 3) { print_usage (); return retval; } m = args(0).int_value (); // The upper limit is an artifical limit caused by memory requirements // in do_is_primitive. m=22 uses an array of 32MBytes!! if ((m < 1) || (m > 22)) { error ("primpoly: m must be greater than 1 and less than 22"); return retval; } if (nargin > 1) { if (args(1).is_scalar_type ()) { k = args(1).int_value (); type = PRIMPOLY_K; } else if (args(1).is_string ()) { std::string s_arg = args(1).string_value (); if (s_arg == "nodisplay") disp = false; else if (s_arg == "min") type = PRIMPOLY_MIN; else if (s_arg == "max") type = PRIMPOLY_MAX; else if (s_arg == "all") type = PRIMPOLY_ALL; else { error ("primpoly: invalid argument"); return retval; } } else { error ("primpoly: incorrect argument type"); return retval; } } if (nargin > 2) { if (args(2).is_scalar_type ()) { if (type == PRIMPOLY_K) { error ("primpoly: invalid arguments"); return retval; } k = args(2).int_value (); type = PRIMPOLY_K; } else if (args(2).is_string ()) { std::string s_arg = args(2).string_value (); if (s_arg == "nodisplay") { if (!disp) { error ("primpoly: invalid arguments"); return retval; } disp = false; } else if (!disp) { if (s_arg == "min") type = PRIMPOLY_MIN; else if (s_arg == "max") type = PRIMPOLY_MAX; else if (s_arg == "all") type = PRIMPOLY_ALL; else { error ("primpoly: invalid argument"); return retval; } } else { error ("primpoly: invalid arguments"); return retval; } } else { error ("primpoly: incorrect argument type"); return retval; } } switch (type) { case PRIMPOLY_MIN: primpolys.resize (1); for (int i = (1< (1<. #include DEFUN_DLD (genqamdemod, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{y} =} genqamdemod (@var{x}, @var{C})\n\ General quadrature amplitude demodulation. The complex envelope\n\ quadrature amplitude modulated signal @var{x} is demodulated using a\n\ constellation mapping specified by the 1D vector @var{C}.\n\ @end deftypefn") { octave_value retval; int i, j, m; double tmp1, tmp2; if (args.length () != 2) { print_usage (); return retval; } int nr1 (args(0).rows ()); int nc1 (args(0).columns ()); int arg_is_empty1 = empty_arg ("genqamdemod", nr1, nc1); Matrix y (nr1,nc1); int nr2 (args(1).rows ()); int nc2 (args(1).columns ()); int M = (nr2>nc2)?nr2:nc2; if (arg_is_empty1 < 0) return retval; if (arg_is_empty1 > 0) return octave_value (Matrix ()); if (args(0).is_real_type () && args(1).is_real_type ()) { // Real-valued signal & constellation Matrix x (args(0).matrix_value ()); ColumnVector constellation (args(1).vector_value ()); for (i = 0;i < nr1;i++) { for (j = 0;j < nc1;j++) { tmp1 = fabs (x(i,j)-constellation(0)); y(i,j) = 0; for (m = 1; m < M;m++) { tmp2 = fabs (x(i,j)-constellation(m)); if (tmp2 < tmp1) { y(i,j) = m; tmp1 = tmp2; } } } } } else if (args(0).is_complex_type () || args(1).is_complex_type ()) { // Complex-valued input & constellation ComplexMatrix x (args(0).complex_matrix_value ()); ComplexColumnVector constellation (args(1).complex_vector_value ()); if (!error_state) { for (i = 0;i < nr1;i++) { for (j = 0;j < nc1;j++) { tmp1 = abs (x(i,j)-constellation(0)); y(i,j) = 0; for (m = 1;m < M;m++) { tmp2 = abs (x(i,j)-constellation(m)); if (tmp2 < tmp1) { y(i,j) = m; tmp1 = tmp2; } } } } } else print_usage (); } else { print_usage (); } return retval = y; } /* %!assert (genqamdemod ([-7:2:7], [-7:2:7]), [0:7]) %!assert (genqamdemod ([-7 -5 -1 -3 7 5 1 3], [-7 -5 -1 -3 7 5 1 3]), [0:7]) %% Test input validation %!error genqamdemod () %!error genqamdemod (1) %!error genqamdemod (1, 2, 3) */ communications-1.2.1/src/PaxHeaders.3802/configure0000644000000000000000000000013212510010567016704 xustar0030 mtime=1428164983.708815162 30 atime=1428164983.652817013 30 ctime=1428164983.712815029 communications-1.2.1/src/configure0000755000000000000000000033131512510010567017242 0ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Octave-Forge communications package 0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Octave-Forge communications package' PACKAGE_TARNAME='octave-forge-communications-package' PACKAGE_VERSION='0' PACKAGE_STRING='Octave-Forge communications package 0' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS PKG_CPPFLAGS HDF5_LIBS HDF5_LDFLAGS HDF5_CPPFLAGS SED OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX OCTAVE MKOCTFILE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking ' ac_precious_vars='build_alias host_alias target_alias MKOCTFILE OCTAVE CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Octave-Forge communications package 0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/octave-forge-communications-package] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Octave-Forge communications package 0:";; esac cat <<\_ACEOF Some influential environment variables: MKOCTFILE mkoctfile compiler helper command OCTAVE Octave interpreter command CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Octave-Forge communications package configure 0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Octave-Forge communications package $as_me 0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Extract the first word of "mkoctfile", so it can be a program name with args. set dummy mkoctfile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MKOCTFILE+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MKOCTFILE"; then ac_cv_prog_MKOCTFILE="$MKOCTFILE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MKOCTFILE="mkoctfile" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MKOCTFILE=$ac_cv_prog_MKOCTFILE if test -n "$MKOCTFILE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKOCTFILE" >&5 $as_echo "$MKOCTFILE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "octave", so it can be a program name with args. set dummy octave; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OCTAVE+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OCTAVE"; then ac_cv_prog_OCTAVE="$OCTAVE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OCTAVE="octave" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OCTAVE=$ac_cv_prog_OCTAVE if test -n "$OCTAVE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE" >&5 $as_echo "$OCTAVE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed comm_OCT_EVAL="$OCTAVE --norc --no-history --silent --eval" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Octave HDF5 preprocessor flags" >&5 $as_echo_n "checking for Octave HDF5 preprocessor flags... " >&6; } if ${comm_cv_hdf5_cppflags+:} false; then : $as_echo_n "(cached) " >&6 else comm_cv_hdf5_cppflags=`$comm_OCT_EVAL 'disp(octave_config_info.HDF5_CPPFLAGS)' 2>/dev/null` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $comm_cv_hdf5_cppflags" >&5 $as_echo "$comm_cv_hdf5_cppflags" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Octave HDF5 linker flags" >&5 $as_echo_n "checking for Octave HDF5 linker flags... " >&6; } if ${comm_cv_hdf5_ldflags+:} false; then : $as_echo_n "(cached) " >&6 else comm_cv_hdf5_ldflags=`$comm_OCT_EVAL 'disp(octave_config_info.HDF5_LDFLAGS)' 2>/dev/null` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $comm_cv_hdf5_ldflags" >&5 $as_echo "$comm_cv_hdf5_ldflags" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Octave HDF5 libraries" >&5 $as_echo_n "checking for Octave HDF5 libraries... " >&6; } if ${comm_cv_hdf5_libs+:} false; then : $as_echo_n "(cached) " >&6 else comm_cv_hdf5_libs=`$comm_OCT_EVAL 'disp(octave_config_info.HDF5_LIBS)' 2>/dev/null` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $comm_cv_hdf5_libs" >&5 $as_echo "$comm_cv_hdf5_libs" >&6; } HDF5_CPPFLAGS=$comm_cv_hdf5_cppflags HDF5_LDFLAGS=$comm_cv_hdf5_ldflags HDF5_LIBS=$comm_cv_hdf5_libs PKG_CPPFLAGS="-DGALOIS_DISP_PRIVATES" comm_CXXFLAGS=`$MKOCTFILE -p ALL_CXXFLAGS` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for octave_hdf5_id type" >&5 $as_echo_n "checking for octave_hdf5_id type... " >&6; } if ${comm_cv_octave_hdf5_id_type+:} false; then : $as_echo_n "(cached) " >&6 else comm_save_CPPFLAGS=$CPPFLAGS comm_save_CXXFLAGS=$CXXFLAGS CPPFLAGS="$CPPFLAGS $HDF5_CPPFLAGS" CXXFLAGS="$CXXFLAGS $comm_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { octave_hdf5_id x; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : comm_cv_octave_hdf5_id_type=yes else comm_cv_octave_hdf5_id_type=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CPPFLAGS=$comm_save_CPPFLAGS CXXFLAGS=$comm_save_CXXFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $comm_cv_octave_hdf5_id_type" >&5 $as_echo "$comm_cv_octave_hdf5_id_type" >&6; } if test $comm_cv_octave_hdf5_id_type = yes; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_OCTAVE_HDF5_ID_TYPE=1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for octave_base_value::gripe_load and octave_base_value::gripe_save" >&5 $as_echo_n "checking for octave_base_value::gripe_load and octave_base_value::gripe_save... " >&6; } if ${comm_cv_octave_base_value_gripe_load_save+:} false; then : $as_echo_n "(cached) " >&6 else comm_save_CPPFLAGS=$CPPFLAGS comm_save_CXXFLAGS=$CXXFLAGS CPPFLAGS="$CPPFLAGS $HDF5_CPPFLAGS" CXXFLAGS="$CXXFLAGS $comm_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include class foo : public octave_base_value { public: foo () {} void func () { gripe_load ("func"); gripe_save ("func"); } }; int main () { foo x; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : comm_cv_octave_base_value_gripe_load_save=yes else comm_cv_octave_base_value_gripe_load_save=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CPPFLAGS=$comm_save_CPPFLAGS CXXFLAGS=$comm_save_CXXFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $comm_cv_octave_base_value_gripe_load_save" >&5 $as_echo "$comm_cv_octave_base_value_gripe_load_save" >&6; } if test $comm_cv_octave_base_value_gripe_load_save = yes; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE=1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether octave_base_value::print is const-qualified" >&5 $as_echo_n "checking whether octave_base_value::print is const-qualified... " >&6; } if ${comm_cv_octave_base_value_print_const_qualified+:} false; then : $as_echo_n "(cached) " >&6 else comm_save_CPPFLAGS=$CPPFLAGS comm_save_CXXFLAGS=$CXXFLAGS CPPFLAGS="$CPPFLAGS $HDF5_CPPFLAGS" CXXFLAGS="$CXXFLAGS $comm_CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { const octave_base_value x; x.print (std::cout); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : comm_cv_octave_base_value_print_const_qualified=yes else comm_cv_octave_base_value_print_const_qualified=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CPPFLAGS=$comm_save_CPPFLAGS CXXFLAGS=$comm_save_CXXFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $comm_cv_octave_base_value_print_const_qualified" >&5 $as_echo "$comm_cv_octave_base_value_print_const_qualified" >&6; } if test $comm_cv_octave_base_value_print_const_qualified = yes; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_OCTAVE_BASE_VALUE_PRINT_CONST=1" fi ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Octave-Forge communications package $as_me 0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Octave-Forge communications package config.status 0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi communications-1.2.1/src/PaxHeaders.3802/galois-def.h0000644000000000000000000000013212510010473017157 xustar0030 mtime=1428164923.942510204 30 atime=1428164923.942510204 30 ctime=1428164983.712815029 communications-1.2.1/src/galois-def.h0000644000000000000000000003076712510010473017521 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #if !defined (octave_galois_defs_h) #define octave_galois_defs_h 1 void gripe_nonconformant_galois (const char *op, int op1_m, int op1_primpoly, int op2_m, int op2_primpoly); void gripe_nonconformant_galois (const char *op, int m); void gripe_divzero_galois (const char *op); void gripe_invalid_galois (void); void gripe_range_galois (int m); void gripe_integer_galois (void); void gripe_copy_invalid_galois (void); void gripe_differ_galois (void); void gripe_invalid_table_galois (void); void gripe_square_galois (void); void gripe_integer_power_galois (void); void gripe_order_galois (int m); void gripe_degree_galois (int m); void gripe_irred_galois (int m); void gripe_init_galois (void); // Compute X % N, where N is 2^M - 1, without a slow divide #define MODN(X, M, N) \ { \ while (X >= N) \ { \ X -= N; \ X = (X >> M) + (X & N); \ } \ } #define CHECK_GALOIS(OP, RET, M1, M2, NN) \ { \ if (!M1.have_field () || !M2.have_field ()) \ { \ gripe_invalid_galois (); \ return RET (); \ } \ if ((M1.primpoly () != M2.primpoly ()) || (M1.m () != M2.m ())) \ { \ gripe_nonconformant_galois (OP, M1.m (), M1.primpoly (), M2.m (), M2.primpoly ()); \ return RET (); \ } \ } #define CHECK_MATRIX(OP, RET, M1, M2, NN) \ { \ int nr = M1.rows (); \ int nc = M1.cols (); \ \ if (!M1.have_field ()) \ { \ gripe_invalid_galois (); \ return RET (); \ } \ for (int i = 0; i < nr; i++) \ for (int j = 0; j < nc; j++) \ { \ if ((M1(i, j) < 0) || (M1(i, j) > NN)) \ { \ gripe_nonconformant_galois (OP, M1.m ()); \ return RET (); \ } \ if (((double)M1(i, j) - (double)((int)M1(i, j))) != 0.) \ { \ gripe_nonconformant_galois (OP, M1.m ()); \ return RET (); \ } \ } \ } #define CHECK_DIV_ZERO(OP, RET, M) \ { \ int nr = M.rows (); \ int nc = M.cols (); \ \ for (int i = 0; i < nr; i++) \ for (int j = 0; j < nc; j++) \ { \ if (M(i, j) == 0) \ { \ gripe_divzero_galois (OP); \ return RET (); \ } \ } \ } #define CHECK_NODIV_ZERO(OP, RET, M) #define MM_BIN_OP1(R, OP, M1, M2, GR1, GR2, CHECKTYPE) \ R \ OP (const M1& m1, const M2& m2) \ { \ R r (m ## GR1); \ \ int m1_nr = m1.rows (); \ int m1_nc = m1.cols (); \ \ int m2_nr = m2.rows (); \ int m2_nc = m2.cols (); \ \ CHECK_ ## CHECKTYPE (#OP, R, m ## GR1, m ## GR2, r.n ()); \ \ if (m1_nr != m2_nr || m1_nc != m2_nc) \ { \ if ((m1_nr == 1 && m1_nc == 1) && (m2_nr > 0 && m2_nc > 0)) \ { \ r.resize (dim_vector (m2_nr, m2_nc)); \ for (int i = 0; i < m2_nr; i++) \ for (int j = 0; j < m2_nc; j++) \ r(i, j) = (int)m1(0, 0) ^ (int)m2(i, j); \ } \ else if ((m2_nr == 1 && m2_nc == 1) && (m1_nr > 0 && m1_nc > 0)) \ { \ r.resize (dim_vector (m1_nr, m1_nc)); \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ r(i, j) = (int)m1(i, j) ^ (int)m2(0, 0); \ } \ else \ gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \ } \ else \ { \ if (m1_nr > 0 && m1_nc > 0) \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ r(i, j) ^= (int) m ## GR2 (i, j); \ } \ \ return r; \ } #define MM_BIN_OP2(R, F, OP, M1, M2, NN, GR1, GR2, CHECKTYPE, ZEROCHECK) \ R \ F (const M1& m1, const M2& m2) \ { \ R r (m ## GR1); \ \ int m1_nr = m1.rows (); \ int m1_nc = m1.cols (); \ \ int m2_nr = m2.rows (); \ int m2_nc = m2.cols (); \ \ CHECK_ ## CHECKTYPE (#F, R, m ## GR1, m ## GR2, r.n ()); \ \ CHECK_ ## ZEROCHECK ## DIV_ZERO (#F, R, m2); \ \ if (m1_nr != m2_nr || m1_nc != m2_nc) \ { \ if ((m1_nr == 1 && m1_nc == 1) && (m2_nr > 0 && m2_nc > 0)) \ { \ r.resize (dim_vector (m2_nr, m2_nc)); \ if (m1(0, 0) == 0) \ { \ for (int i = 0; i < m2_nr; i++) \ for (int j = 0; j < m2_nc; j++) \ r(i, j) = 0; \ } \ else \ { \ int indxm1 = r.index_of ((int)m1(0, 0)); \ for (int i = 0; i < m2_nr; i++) \ for (int j = 0; j < m2_nc; j++) \ { \ if (m2(i, j) == 0) \ r(i, j) = 0; \ else \ { \ r(i, j) = indxm1 OP r.index_of ((int)m2(i, j)) + NN; \ MODN (r(i, j), r.m (), r.n ()); \ r(i, j) = r.alpha_to (r(i, j)); \ } \ } \ } \ } \ else if ((m2_nr == 1 && m2_nc == 1) && (m1_nr > 0 && m1_nc > 0)) \ { \ r.resize (dim_vector (m1_nr, m1_nc)); \ if (m2(0, 0) == 0) \ { \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ r(i, j) = 0; \ } \ else \ { \ int indxm2 = r.index_of ((int)m2(0, 0)); \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ { \ if (m1(i, j) == 0) \ r(i, j) = 0; \ else \ { \ r(i, j) = r.index_of ((int)m1(i, j)) OP indxm2 + NN; \ MODN (r(i, j), r.m (), r.n ()); \ r(i, j) = r.alpha_to (r(i, j)); \ } \ } \ } \ } \ else \ gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ } \ else \ if (m1_nr > 0 && m1_nc > 0) \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ { \ if ((m1(i, j) == 0) || (m2(i, j) == 0)) \ r(i, j) = 0; \ else \ { \ r(i, j) = r.index_of ((int)m1(i, j)) OP r.index_of ((int)m2(i, j)) + NN; \ MODN (r(i, j), r.m (), r.n ()); \ r(i, j) = r.alpha_to (r(i, j)); \ } \ } \ \ return r; \ } #define MM_BIN_OPS1(R, M1, M2, GR1, GR2, CHECK) \ MM_BIN_OP1 (R, operator +, M1, M2, GR1, GR2, CHECK) \ MM_BIN_OP1 (R, operator -, M1, M2, GR1, GR2, CHECK) \ MM_BIN_OP2 (R, product, +, M1, M2, 0, GR1, GR2, CHECK, NO) \ MM_BIN_OP2 (R, quotient, -, M1, M2, r.n (), GR1, GR2, CHECK, ) #define MM_BIN_OPS2(R, M1, M2, GR1, GR2, CHECK) \ MM_BIN_OP1 (R, operator +, M1, M2, GR1, GR2, CHECK) #define MM_CMP_OP1(F, OP, M1, C1, M2, C2, GR1, GR2, CHECKTYPE) \ boolMatrix \ F (const M1& m1, const M2& m2) \ { \ boolMatrix r; \ \ int m1_nr = m1.rows (); \ int m1_nc = m1.cols (); \ \ int m2_nr = m2.rows (); \ int m2_nc = m2.cols (); \ \ CHECK_ ## CHECKTYPE (#F, boolMatrix, m ## GR1, m ## GR2, m ## GR1.n ()); \ \ if (m1_nr == m2_nr && m1_nc == m2_nc) \ { \ r.resize (m1_nr, m1_nc); \ \ for (int j = 0; j < m1_nc; j++) \ for (int i = 0; i < m1_nr; i++) \ r(i, j) = C1 (m1(i, j)) OP C2 (m2(i, j)); \ } \ else \ { \ if ((m1_nr == 1 && m1_nc == 1) && (m2_nr > 0 && m2_nc > 0)) \ { \ r.resize (m2_nr, m2_nc); \ for (int i = 0; i < m2_nr; i++) \ for (int j = 0; j < m2_nc; j++) \ r(i, j) = C1 (m1(0, 0)) OP C2 (m2(i, j)); \ } \ else if ((m2_nr == 1 && m2_nc == 1) && (m1_nr > 0 && m1_nc > 0)) \ { \ r.resize (m1_nr, m1_nc); \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ r(i, j) = C1 (m1(i, j)) OP C2 (m2(0, 0)); \ } \ else \ gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ } \ \ return r; \ } #define MM_CMP_OPS1(M1, C1, M2, C2, GR1, GR2, CHECK) \ MM_CMP_OP1 (mx_el_lt, <, M1, C1, M2, C2, GR1, GR2, CHECK) \ MM_CMP_OP1 (mx_el_le, <=, M1, C1, M2, C2, GR1, GR2, CHECK) \ MM_CMP_OP1 (mx_el_ge, >=, M1, C1, M2, C2, GR1, GR2, CHECK) \ MM_CMP_OP1 (mx_el_gt, >, M1, C1, M2, C2, GR1, GR2, CHECK) \ MM_CMP_OP1 (mx_el_eq, ==, M1, , M2, , GR1, GR2, CHECK) \ MM_CMP_OP1 (mx_el_ne, !=, M1, , M2, , GR1, GR2, CHECK) #define MM_BOOL_OP1(F, OP, M1, M2, ZERO, GR1, GR2, CHECKTYPE) \ boolMatrix \ F (const M1& m1, const M2& m2) \ { \ boolMatrix r; \ \ int m1_nr = m1.rows (); \ int m1_nc = m1.cols (); \ \ int m2_nr = m2.rows (); \ int m2_nc = m2.cols (); \ \ CHECK_ ## CHECKTYPE (#F, boolMatrix, m ## GR1, m ## GR2, m ## GR1.n ()); \ \ if (m1_nr == m2_nr && m1_nc == m2_nc) \ { \ if (m1_nr != 0 || m1_nc != 0) \ { \ r.resize (m1_nr, m1_nc); \ \ for (int j = 0; j < m1_nc; j++) \ for (int i = 0; i < m1_nr; i++) \ { \ r(i, j) = (m1(i, j) != ZERO) \ OP (m2(i, j) != ZERO); \ } \ } \ } \ else \ { \ if ((m1_nr == 1 && m1_nc == 1) && (m2_nr > 0 && m2_nc > 0)) \ { \ r.resize (m2_nr, m2_nc); \ for (int i = 0; i < m2_nr; i++) \ for (int j = 0; j < m2_nc; j++) \ r(i, j) = (m1(0, 0) != ZERO) \ OP (m2(i, j) != ZERO); \ } \ else if ((m2_nr == 1 && m2_nc == 1) && (m1_nr > 0 && m1_nc > 0)) \ { \ r.resize (m1_nr, m1_nc); \ for (int i = 0; i < m1_nr; i++) \ for (int j = 0; j < m1_nc; j++) \ r(i, j) = (m1(i, j) != ZERO) \ OP (m2(0, 0) != ZERO); \ } \ else if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \ gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ } \ \ return r; \ } #define MM_BOOL_OPS1(M1, M2, ZERO, GR1, GR2, CHECK) \ MM_BOOL_OP1 (mx_el_and, &&, M1, M2, ZERO, GR1, GR2, CHECK) \ MM_BOOL_OP1 (mx_el_or, ||, M1, M2, ZERO, GR1, GR2, CHECK) #define GALOIS_REDUCTION_OP(RET, ROW_EXPR, COL_EXPR, INIT_VAL, \ MT_RESULT) \ \ int nr = rows (); \ int nc = cols (); \ \ if (nr > 0 && nc > 0) \ { \ if ((nr == 1 && dim == -1) || dim == 1) \ { \ RET.resize (dim_vector (nr, 1)); \ for (int i = 0; i < nr; i++) \ { \ RET (i, 0) = INIT_VAL; \ for (int j = 0; j < nc; j++) \ { \ ROW_EXPR; \ } \ } \ } \ else \ { \ RET.resize (dim_vector (1, nc)); \ for (int j = 0; j < nc; j++) \ { \ RET (0, j) = INIT_VAL; \ for (int i = 0; i < nr; i++) \ { \ COL_EXPR; \ } \ } \ } \ } \ else if (nc == 0 && (nr == 0 || (nr == 1 && dim == -1))) \ RET.resize (dim_vector (1, 1), MT_RESULT); \ else if (nr == 0 && (dim == 0 || dim == -1)) \ RET.resize (dim_vector (1, nc), MT_RESULT); \ else if (nc == 0 && dim == 1) \ RET.resize (dim_vector (nr, 1), MT_RESULT); \ else \ RET.resize (dim_vector (nr > 0, nc > 0)); #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/ov-galois.h0000644000000000000000000000013012510010473017043 xustar0029 mtime=1428164923.96250975 29 atime=1428164923.96250975 30 ctime=1428164983.712815029 communications-1.2.1/src/ov-galois.h0000644000000000000000000001176312510010473017402 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #if !defined (octave_galois_h) #define octave_galois_h 1 #include #include #include "galois.h" // The keys of the values in the octave map #define __GALOIS_PRIMPOLY_STR "prim_poly" #define __GALOIS_ORDER_STR "m" #define __GALOIS_DATA_STR "x" #ifdef GALOIS_DISP_PRIVATES #define __GALOIS_LENGTH_STR "n" #define __GALOIS_ALPHA_TO_STR "alpha_to" #define __GALOIS_INDEX_OF_STR "index_of" #endif #if !defined (HAVE_OCTAVE_HDF5_ID_TYPE) #if defined (HAVE_HDF5) typedef hid_t octave_hdf5_id; #else typedef int octave_hdf5_id; #endif #endif class octave_value_list; class tree_walker; // Data structures. class octave_galois : public octave_base_value { public: octave_galois (const Matrix& data = Matrix (0, 0), const int _m = 1, const int _primpoly = 0) { gval = galois (data, _m, _primpoly); } octave_galois (const galois& gm) : octave_base_value (), gval (gm) { } octave_galois (const octave_galois& s) : octave_base_value (), gval (s.gval) { } ~octave_galois (void) { }; OV_REP_TYPE *clone (void) const { return new octave_galois (*this); } OV_REP_TYPE *empty_clone (void) const { return new octave_galois (); } octave_value subsref (const std::string &type, const std::list& idx); octave_value_list subsref (const std::string& type, const std::list& idx, int) { return subsref (type, idx); } octave_value do_index_op (const octave_value_list& idx, bool resize_ok); octave_value do_index_op (const octave_value_list& idx) { return do_index_op (idx, 0); } void assign (const octave_value_list& idx, const galois& rhs); dim_vector dims (void) const { return gval.dims (); } octave_value resize (const dim_vector& dv, bool) const; size_t byte_size (void) const { return gval.byte_size (); } octave_value all (int dim = 0) const { return gval.all (dim); } octave_value any (int dim = 0) const { return gval.any (dim); } bool is_matrix_type (void) const { return true; } bool is_defined (void) const { return true; } bool is_numeric_type (void) const { return true; } bool is_constant (void) const { return true; } bool is_true (void) const; bool is_galois_type (void) const { return true; } bool print_as_scalar (void) const; #if defined (HAVE_OCTAVE_BASE_VALUE_PRINT_CONST) void print (std::ostream& os, bool pr_as_read_syntax = false) const; #else void print (std::ostream& os, bool pr_as_read_syntax = false); #endif void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; bool print_name_tag (std::ostream& os, const std::string& name) const; void print_info (std::ostream& os, const std::string& prefix) const; bool is_real_matrix (void) const { return false; } bool is_real_type (void) const { return false; } // FIXME bool valid_as_scalar_index (void) const { return false; } double double_value (bool = false) const; double scalar_value (bool frc_str_conv = false) const { return double_value (frc_str_conv); } Matrix matrix_value (bool = false) const; NDArray array_value (bool = false) const; Complex complex_value (bool = false) const; ComplexMatrix complex_matrix_value (bool = false) const { return ComplexMatrix ( matrix_value ()); } galois galois_value (void) const { return gval; } octave_value_list dotref (const octave_value_list& idx); int m (void) const { return gval.m (); } int primpoly (void) const { return gval.primpoly (); } bool save_ascii (std::ostream& os); bool load_ascii (std::istream& is); bool save_binary (std::ostream& os, bool& save_as_floats); bool load_binary (std::istream& is, bool swap, oct_mach_info::float_format fmt); bool save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats); bool load_hdf5 (octave_hdf5_id loc_id, const char *name); private: // The array used to managed the Galios Field data galois gval; #if defined (DECLARE_OCTAVE_ALLOCATOR) DECLARE_OCTAVE_ALLOCATOR #endif DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA }; #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/galois.cc0000644000000000000000000000013212510010473016561 xustar0030 mtime=1428164923.946510113 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/galois.cc0000644000000000000000000010357412510010473017120 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include #include "galois.h" #include "galoisfield.h" #include "galois-def.h" #include galois_field_list stored_galois_fields; // galois class galois::galois (const Array& a, const int& _m, const int& _primpoly) : MArray (a.dims ()), field (NULL) { int _n = (1<<_m) - 1; // Check the validity of the data in the matrix for (int i = 0; i < rows (); i++) { for (int j = 0; j < columns (); j++) { if ((a(i, j) < 0) || (a(i, j) > _n)) { gripe_range_galois (_m); return; } xelem(i, j) = (int)a(i, j); } } field = stored_galois_fields.create_galois_field (_m, _primpoly); } galois::galois (const MArray& a, const int& _m, const int& _primpoly) : MArray (a.dims ()), field (NULL) { int _n = (1<<_m) - 1; // Check the validity of the data in the matrix for (int i = 0; i < rows (); i++) { for (int j = 0; j < columns (); j++) { if ((a(i, j) < 0) || (a(i, j) > _n)) { gripe_range_galois (_m); return; } xelem(i, j) = (int)a(i, j); } } field = stored_galois_fields.create_galois_field (_m, _primpoly); } galois::galois (const Matrix& a, const int& _m, const int& _primpoly) : MArray (a.dims ()), field (NULL) { int _n = (1<<_m) - 1; // Check the validity of the data in the matrix for (int i = 0; i < rows (); i++) { for (int j = 0; j < columns (); j++) { if ((a(i, j) < 0) || (a(i, j) > _n)) { gripe_range_galois (_m); return; } if ((a(i, j) - (double)((int)a(i, j))) != 0.) { gripe_integer_galois (); return; } xelem(i, j) = (int)a(i, j); } } field = stored_galois_fields.create_galois_field (_m, _primpoly); } galois::galois (int nr, int nc, const int& val, const int& _m, const int& _primpoly) : MArray (dim_vector (nr, nc), val), field (NULL) { int _n = (1<<_m) - 1; // Check the validity of the data in the matrix if ((val < 0) || (val > _n)) { gripe_range_galois (_m); return; } field = stored_galois_fields.create_galois_field (_m, _primpoly); } galois::galois (int nr, int nc, double val, const int& _m, const int& _primpoly) : MArray (dim_vector (nr, nc), (int)val), field (NULL) { int _n = (1<<_m) - 1; // Check the validity of the data in the matrix if ((val < 0) || (val > _n)) { gripe_range_galois (_m); return; } if ((val - (double)((int)val)) != 0.) { gripe_integer_galois (); return; } field = stored_galois_fields.create_galois_field (_m, _primpoly); } galois::galois (const galois& a) : MArray (a) { if (!a.have_field ()) { gripe_copy_invalid_galois (); field = NULL; return; } // This call to create_galois_field will just increment the usage counter field = stored_galois_fields.create_galois_field (a.m (), a.primpoly ()); } galois::~galois (void) { stored_galois_fields.delete_galois_field (field); field = NULL; } galois& galois::operator = (const galois& t) { if (!t.have_field ()) { gripe_copy_invalid_galois (); if (have_field ()) stored_galois_fields.delete_galois_field (field); field = NULL; return *this; } if (have_field ()) { if ((m () != t.m ()) || (primpoly () != t.primpoly ())) { stored_galois_fields.delete_galois_field (field); field = stored_galois_fields.create_galois_field (t.m (), t.primpoly ()); } } else field = stored_galois_fields.create_galois_field (t.m (), t.primpoly ()); // Copy the data MArray::operator = (t); return *this; } galois& galois::operator += (const galois& a) { int nr = rows (); int nc = cols (); int a_nr = a.rows (); int a_nc = a.cols (); if (have_field () && a.have_field ()) { if ((m () != a.m ()) || (primpoly () != a.primpoly ())) { gripe_differ_galois (); return *this; } } else { gripe_invalid_galois (); return *this; } if (nr != a_nr || nc != a_nc) { gripe_nonconformant ("operator +=", nr, nc, a_nr, a_nc); return *this; } for (int i = 0; i < rows (); i++) for (int j = 0; j < columns (); j++) xelem(i, j) ^= a (i, j); return *this; } galois& galois::operator -= (const galois& a) { int nr = rows (); int nc = cols (); int a_nr = a.rows (); int a_nc = a.cols (); if (have_field () && a.have_field ()) { if ((m () != a.m ()) || (primpoly () != a.primpoly ())) { gripe_differ_galois (); return *this; } } else { gripe_invalid_galois (); return *this; } if (nr != a_nr || nc != a_nc) { gripe_nonconformant ("operator -=", nr, nc, a_nr, a_nc); return *this; } for (int i = 0; i < rows (); i++) for (int j = 0; j < columns (); j++) xelem(i, j) ^= a (i, j); return *this; } galois galois::index (idx_vector& i, int resize_ok, const int& rfv) const { galois retval (MArray::index(i, resize_ok, rfv), m (), primpoly ()); return retval; } galois galois::index (idx_vector& i, idx_vector& j, int resize_ok, const int& rfv) const { galois retval (MArray::index(i, j, resize_ok, rfv), m (), primpoly ()); return retval; } galois galois::concat (const galois& rb, const Array& ra_idx) { if (rb.numel () > 0) insert (rb, ra_idx(0), ra_idx(1)); return *this; } galois galois::concat (const Matrix& rb, const Array& ra_idx) { if (numel () == 1) return *this; galois tmp (0, 0, 0, m (), primpoly ()); int _n = (1< _n)) { gripe_range_galois (m ()); return *this; } if ((rb(i, j) - (double)((int)rb(i, j))) != 0.) { gripe_integer_galois (); return *this; } tmp(i, j) = (int)rb(i, j); } } insert (tmp, ra_idx(0), ra_idx(1)); return *this; } galois concat (const Matrix& ra, const galois& rb, const Array& ra_idx) { galois retval (0, 0, 0, rb.m (), rb.primpoly ()); int _n = (1< _n)) { gripe_range_galois (rb.m ()); return retval; } if ((ra(i, j) - (double)((int)ra(i, j))) != 0.) { gripe_integer_galois (); return retval; } retval(i, j) = (int)ra(i, j); #else int tmp = (int)ra(i, j); if (tmp < 0) retval(i, j) = 0; else if (tmp > _n) retval(i, j) = _n; else retval(i, j) = tmp; #endif } } retval.insert (rb, ra_idx(0), ra_idx(1)); return retval; } galois& galois::insert (const galois& t, int r, int c) { if ((m () != t.m ()) || (primpoly () != t.primpoly ())) (*current_liboctave_error_handler) ("inserted galois variable must " "be in the same field"); else Array::insert (t, r, c); return *this; } galois galois::diag (void) const { return diag (0); } galois galois::diag (int k) const { int nnr = rows (); int nnc = cols (); galois retval (0, 0, 0, m (), primpoly ()); if (k > 0) nnc -= k; else if (k < 0) nnr += k; if (nnr > 0 && nnc > 0) { int ndiag = (nnr < nnc) ? nnr : nnc; retval.resize (dim_vector (ndiag, 1)); if (k > 0) { for (int i = 0; i < ndiag; i++) retval(i, 0) = xelem (i, i+k); } else if ( k < 0) { for (int i = 0; i < ndiag; i++) retval(i, 0) = xelem (i-k, i); } else { for (int i = 0; i < ndiag; i++) retval(i, 0) = xelem (i, i); } } else error ("diag: requested diagonal out of range"); return retval; } // unary operations boolMatrix galois::operator ! (void) const { int nr = rows (); int nc = cols (); boolMatrix b (nr, nc); for (int j = 0; j < nc; j++) for (int i = 0; i < nr; i++) b (i, j) = ! xelem (i, j); return b; } galois galois::transpose (void) const { galois a (Matrix (0, 0), m (), primpoly ()); int d1 = rows (); int d2 = cols (); a.resize (dim_vector (d2, d1)); for (int j = 0; j < d2; j++) for (int i = 0; i < d1; i++) a (j, i) = xelem (i, j); return a; } static inline int modn (int x, int m, int n) { while (x >= n) { x -= n; x = (x >> m) + (x & n); } return x; } galois elem_pow (const galois& a, const galois& b) { int a_nr = a.rows (); int a_nc = a.cols (); galois result (a_nr, a_nc, 0, a.m (), a.primpoly ()); int b_nr = b.rows (); int b_nc = b.cols (); if (a.have_field () && b.have_field ()) { if ((a.m () != b.m ()) || (a.primpoly () != b.primpoly ())) { gripe_differ_galois (); return galois (); } } else { gripe_invalid_galois (); return galois (); } if (a_nr == 1 && a_nc == 1) { result.resize (dim_vector (b_nr, b_nc), 0); int tmp = a.index_of (a(0, 0)); for (int j = 0; j < b_nc; j++) for (int i = 0; i < b_nr; i++) if (b(i, j) == 0) result(i, j) = 1; else if (a(0, 0) != 0) result(i, j) = a.alpha_to (modn (tmp * b(i, j), a.m (), a.n ())); } else if (b_nr == 1 && b_nc == 1) { for (int j = 0; j < a_nc; j++) for (int i = 0; i < a_nr; i++) if (b(0, 0) == 0) result(i, j) = 1; else if (a(i, j) != 0) result(i, j) = a.alpha_to (modn (a.index_of (a(i, j)) * b(0, 0), a.m (), a.n ())); } else { if (a_nr != b_nr || a_nc != b_nc) { gripe_nonconformant ("operator .^", a_nr, a_nc, a_nr, a_nc); return galois (); } for (int j = 0; j < a_nc; j++) for (int i = 0; i < a_nr; i++) if (b(i, j) == 0) result(i, j) = 1; else if (a(i, j) != 0) result(i, j) = a.alpha_to (modn (a.index_of (a(i, j)) * b(i, j), a.m (), a.n ())); } return result; } galois elem_pow (const galois& a, const Matrix& b) { int a_nr = a.rows (); int a_nc = a.cols (); galois result (a_nr, a_nc, 0, a.m (), a.primpoly ()); int b_nr = b.rows (); int b_nc = b.cols (); if (b_nr == 1 && b_nc == 1) return elem_pow (a, b(0, 0)); if (a_nr != b_nr || a_nc != b_nc) { gripe_nonconformant ("operator .^", a_nr, a_nc, b_nr, b_nc); return galois (); } for (int j = 0; j < a_nc; j++) for (int i = 0; i < a_nr; i++) { int tmp = (int)b(i, j); while (tmp < 0) tmp += a.n (); if (tmp == 0) result(i, j) = 1; else if (a(i, j) != 0) result(i, j) = a.alpha_to (modn (a.index_of (a(i, j)) * tmp, a.m (), a.n ())); } return result; } galois elem_pow (const galois& a, double b) { int a_nr = a.rows (); int a_nc = a.cols (); galois result (a_nr, a_nc, 0, a.m (), a.primpoly ()); int bi = (int) b; if ((double)bi != b) { gripe_integer_galois (); return galois (); } while (bi < 0) bi += a.n (); for (int j = 0; j < a_nc; j++) for (int i = 0; i < a_nr; i++) { if (bi == 0) result(i, j) = 1; else if (a(i, j) != 0) result(i, j) = a.alpha_to (modn (a.index_of (a(i, j)) * bi, a.m (), a.n ())); } return result; } galois elem_pow (const galois &a, int b) { int a_nr = a.rows (); int a_nc = a.cols (); galois result (a_nr, a_nc, 0, a.m (), a.primpoly ()); while (b < 0) b += a.n (); for (int j = 0; j < a_nc; j++) for (int i = 0; i < a_nr; i++) { if (b == 0) result(i, j) = 1; else if (a(i, j) != 0) result(i, j) = a.alpha_to (modn (a.index_of (a(i, j)) * b, a.m (), a.n ())); } return result; } galois pow (const galois& a, double b) { int bi = (int)b; if ((double)bi != b) { gripe_integer_power_galois (); return galois (); } return pow (a, bi); } galois pow (const galois& a, const galois& b) { int nr = b.rows (); int nc = b.cols (); if (a.have_field () && b.have_field ()) { if ((a.m () != b.m ()) || (a.primpoly () != b.primpoly ())) { gripe_differ_galois (); return galois (); } } else { gripe_invalid_galois (); return galois (); } if (nr != 1 || nc != 1) { gripe_square_galois (); return galois (); } else return pow (a, b(0, 0)); } galois pow (const galois& a, int b) { galois retval; int nr = a.rows (); int nc = a.cols (); if (!a.have_field ()) { gripe_invalid_galois (); return retval; } if (nr == 0 || nc == 0 || nr != nc) gripe_square_galois (); else if (b == 0) { retval = galois (nr, nc, 0, a.m (), a.primpoly ()); for (int i = 0; i < nr; i++) retval(i, i) = 1; } else { galois atmp; if (b < 0 ) { atmp = a.inverse (); b = abs (b); } else atmp = a; retval = atmp; b--; while (b > 0) { if (b & 1) retval = retval * atmp; b >>= 1; if (b > 0) atmp = atmp * atmp; } } return retval; } galois operator * (const Matrix& a, const galois& b) { galois tmp (a, b.m (), b.primpoly ()); OCTAVE_QUIT; return tmp * b; } galois operator * (const galois& a, const Matrix& b) { galois tmp (b, a.m (), a.primpoly ()); OCTAVE_QUIT; return a * tmp; } galois operator * (const galois& a, const galois& b) { if (a.have_field () && b.have_field ()) { if ((a.m () != b.m ()) || (a.primpoly () != b.primpoly ())) { gripe_differ_galois (); return galois (); } } else { gripe_invalid_galois (); return galois (); } int a_nr = a.rows (); int a_nc = a.cols (); int b_nr = b.rows (); int b_nc = b.cols (); if ((a_nr == 1 && a_nc == 1) || (b_nr == 1 && b_nc == 1)) return product (a, b); else if (a_nc != b_nr) { gripe_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc); return galois (); } else { galois retval (a_nr, b_nc, 0, a.m (), a.primpoly ()); if (a_nr != 0 && a_nc != 0 && b_nc != 0) { // This is not optimum for referencing b, but can use vector // to represent index(a(k,j)). Seems to be the fastest. galois c (a_nr, 1, 0, a.m (), a.primpoly ()); for (int j = 0; j < b_nr; j++) { for (int k = 0; k < a_nr; k++) c(k, 0) = a.index_of (a(k, j)); for (int i = 0; i < b_nc; i++) if (b(j, i) != 0) { int tmp = a.index_of (b(j, i)); for (int k = 0; k < a_nr; k++) { if (a(k, j) != 0) retval(k, i) = retval(k, i) ^ a.alpha_to (modn (tmp + c(k, 0), a.m (), a.n ())); } } } } return retval; } } // Other operators boolMatrix galois::all (int dim) const { return do_mx_red_op (*this, dim, mx_inline_all); } boolMatrix galois::any (int dim) const { return do_mx_red_op (*this, dim, mx_inline_any); } galois galois::prod (int dim) const { if (!have_field ()) { gripe_invalid_galois (); return galois (); } galois retval (0, 0, 0, m (), primpoly ()); #define ROW_EXPR \ if ((retval(i, 0) == 0) || (elem (i, j) == 0)) \ retval(i, 0) = 0; \ else \ retval(i, 0) = alpha_to (modn (index_of (retval(i, 0)) + \ index_of (elem (i, j)), m (), n ())); #define COL_EXPR \ if ((retval(0, j) == 0) || (elem (i, j) == 0)) \ retval(0, j) = 0; \ else \ retval(0, j) = alpha_to (modn (index_of (retval(0, j)) + \ index_of (elem (i, j)), m (), n ())); GALOIS_REDUCTION_OP (retval, ROW_EXPR, COL_EXPR, 1, 1); return retval; #undef ROW_EXPR #undef COL_EXPR } galois galois::sum (int dim) const { if (!have_field ()) { gripe_invalid_galois (); return galois (); } galois retval (0, 0, 0, m (), primpoly ()); #define ROW_EXPR \ retval(i, 0) ^= elem (i, j); #define COL_EXPR \ retval(0, j) ^= elem (i, j); GALOIS_REDUCTION_OP (retval, ROW_EXPR, COL_EXPR, 0, 0); return retval; #undef ROW_EXPR #undef COL_EXPR } galois galois::sumsq (int dim) const { if (!have_field ()) { gripe_invalid_galois (); return galois (); } galois retval (0, 0, 0, m (), primpoly ()); #define ROW_EXPR \ if (elem (i, j) != 0) \ retval(i, 0) ^= alpha_to (modn (2*index_of (elem (i, j)), m (), n ())); #define COL_EXPR \ if (elem (i, j) != 0) \ retval(0, j) ^= alpha_to (modn (2*index_of (elem (i, j)), m (), n ())); GALOIS_REDUCTION_OP (retval, ROW_EXPR, COL_EXPR, 0, 0); return retval; #undef ROW_EXPR #undef COL_EXPR } galois galois::sqrt (void) const { galois retval (*this); int nr = rows (); int nc = cols (); for (int j = 0; j < nc; j++) { for (int i = 0; i < nr; i++) if (retval.index_of (retval(i, j)) & 1) retval(i, j) = retval.alpha_to ((retval.index_of (retval(i, j)) + retval.n ()) / 2); else retval(i, j) = retval.alpha_to (retval.index_of (retval(i, j)) / 2); } return retval; } galois galois::log (void) const { bool warned = false; if (!have_field ()) { gripe_invalid_galois (); return galois (); } galois retval (*this); int nr = rows (); int nc = cols (); for (int j = 0; j < nc; j++) for (int i = 0; i < nr; i++) { if (retval(i, j) == 0) { if (!warned) { warning ("log of zero undefined in Galois field"); warned = true; } // How do I flag a NaN without either // 1) Having to check everytime that the data is valid // 2) Causing overflow in alpha_to or index_of!! retval(i, j) = retval.index_of (retval(i, j)); } else retval(i, j) = retval.index_of (retval(i, j)); } return retval; } galois galois::exp (void) const { bool warned = false; if (!have_field ()) { gripe_invalid_galois (); return galois (); } galois retval (*this); int nr = rows (); int nc = cols (); for (int j = 0; j < nc; j++) for (int i = 0; i < nr; i++) { if (retval(i, j) == n ()) { if (!warned) { warning ("warning: exp of 2^m-1 undefined in Galois field"); warned = true; } // How do I flag a NaN without either // 1) Having to check everytime that the data is valid // 2) Causing overflow in alpha_to or index_of!! retval(i, j) = retval.alpha_to (retval(i, j)); } else retval(i, j) = retval.alpha_to (retval(i, j)); } return retval; } template class base_lu ; void galoisLU::factor (const galois& a, const pivot_type& typ) { int a_nr = a.rows (); int a_nc = a.cols (); int mn = (a_nr > a_nc ? a_nc : a_nr); ptype = typ; info = 0; ipvt.resize (dim_vector (mn, 1)); a_fact = a; for (int j = 0; j < mn; j++) { int jp = j; // Find the pivot and test for singularity if (ptype == galoisLU::ROW) { for (int i = j+1; i < a_nr; i++) if (a_fact(i, j) > a_fact(jp, j)) jp = i; } else { for (int i = j+1; i < a_nc; i++) if (a_fact(j, i) > a_fact(j, jp)) jp = i; } ipvt(j) = jp; if (a_fact(jp, j) != 0) { if (ptype == galoisLU::ROW) { // Apply the interchange to columns 1:NC. if (jp != j) for (int i = 0; i < a_nc; i++) { int tmp = a_fact(j, i); a_fact(j, i) = a_fact(jp, i); a_fact(jp, i) = tmp; } } else { // Apply the interchange to rows 1:NR. if (jp != j) for (int i = 0; i < a_nr; i++) { int tmp = a_fact(i, j); a_fact(i, j) = a_fact(i, jp); a_fact(i, jp) = tmp; } } // Compute elements J+1:M of J-th column. if ( j < a_nr-1) { int idxj = a_fact.index_of (a_fact(j, j)); for (int i = j+1; i < a_nr; i++) { if (a_fact(i, j) == 0) a_fact(i, j) = 0; else a_fact(i, j) = a_fact.alpha_to (modn (a_fact.index_of (a_fact(i, j)) - idxj + a_fact.n (), a_fact.m (), a_fact.n ())); } } } else { info = 1; } if (j < mn-1) { // Update trailing submatrix. for (int i = j+1; i < a_nr; i++) { if (a_fact(i, j) != 0) { int idxi = a_fact.index_of (a_fact(i, j)); for (int k = j+1; k < a_nc; k++) { if (a_fact(j, k) != 0) a_fact(i, k) ^= a_fact.alpha_to (modn (a_fact.index_of (a_fact(j, k)) + idxi, a_fact.m (), a_fact.n ())); } } } } } } galois galoisLU::L (void) const { int a_nr = a_fact.rows (); int a_nc = a_fact.cols (); int mn = (a_nr < a_nc ? a_nr : a_nc); galois l (a_nr, mn, 0, a_fact.m (), a_fact.primpoly ()); for (int i = 0; i < mn; i++) l(i, i) = 1; for (int j = 0; j < mn; j++) for (int i = j+1; i < a_nr; i++) l(i, j) = a_fact (i, j); return l; } galois galoisLU::U (void) const { int a_nr = a_fact.rows (); int a_nc = a_fact.cols (); int mn = (a_nr < a_nc ? a_nr : a_nc); galois u (mn, a_nc, 0, a_fact.m (), a_fact.primpoly ()); for (int j = 0; j < a_nc; j++) for (int i = 0; i < (j+1 > mn ? mn : j+1); i++) u (i, j) = a_fact (i, j); return u; } galois galois::inverse (void) const { int info; return inverse (info); } galois galois::inverse (int& info, int force) const { int nr = rows (); int nc = cols (); info = 0; if (nr != nc || nr == 0 || nc == 0) { (*current_liboctave_error_handler) ("inverse requires square matrix"); return galois (); } else { int info = 0; // Solve with identity matrix to find the inverse. galois btmp (nr, nr, 0, m (), primpoly ()); for (int i = 0; i < nr; i++) btmp(i, i) = 1; galois retval = solve (btmp, info, 0); if (info == 0) return retval; else return galois (); } } galois galois::determinant (void) const { int info; return determinant (info); } galois galois::determinant (int& info) const { galois retval (1, 1, 0, m (), primpoly ()); int nr = rows (); int nc = cols (); info = -1; if (nr == 0 || nc == 0) { info = 0; retval(0, 0) = 1; } else { galoisLU fact (*this); if ( ! fact.singular ()) { galois A (fact.a_fact); info = 0; retval(0, 0) = A(0, 0); for (int i = 1; i < nr; i++) { if ((retval(0, 0) == 0) || (A(i, i) == 0)) { retval(0, 0) = 0; error ("What the hell are we doing here!!!"); } else retval(0, 0) = alpha_to (modn (index_of (retval(0, 0)) + index_of (A(i, i)), m (), n ())); } } } return retval; } galois galois::solve (const galois& b) const { int info; return solve (b, info); } galois galois::solve (const galois& b, int& info) const { return solve (b, info, 0); } galois galois::solve (const galois& b, int& info, solve_singularity_handler sing_handler) const { galois retval (b); if (!have_field () || !b.have_field ()) { gripe_invalid_galois (); return galois (); } else if ((m () != b.m ()) || (primpoly () != b.primpoly ())) { gripe_differ_galois (); return galois (); } int nr = rows (); int nc = cols (); int b_nr = b.rows (); int b_nc = b.cols (); galois c (nr, 1, 0, m (), primpoly ()); // if (nr == 0 || nc == 0 || nr != nc || nr != b_nr) if (nr == 0 || nc == 0 || nr != b_nr) { (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); return galois (); } else if (nc > nr) { // Under-determined system, use column interchanges. galoisLU fact ((*this), galoisLU::COL); if (fact.singular ()) { info = -1; if (sing_handler) sing_handler (0.0); else (*current_liboctave_error_handler)("galois matrix singular"); return galois (); } else { galois A (fact.a_fact); Array IP (fact.ipvt); // Resize the number of solution rows if needed if (nc > nr) retval.resize (dim_vector (b_nr+nc-nr, b_nc), 0); //Solve L*X = B, overwriting B with X. int mn = (nc < nr ? nc : nr); for (int k = 0; k < mn; k++) { for (int i = k+1; i < nr; i++) c(i, 0) = index_of (A(i, k)); for (int j = 0; j < b_nc; j++) if (retval(k, j) != 0) { int idx = index_of (retval(k, j)); for (int i = k+1; i < nr; i++) if (A(i, k) != 0) retval(i, j) ^= alpha_to (modn (c(i, 0) + idx, m (), n ())); } } // Solve U*X = B, overwriting B with X. for (int k = (nc < nr ? nc-1 : nr-1); k >= 0; k--) { int mn = k+1 < nr ? k+1 : nr; for (int i = 0; i < mn; i++) c(i, 0) = index_of (A(i, k)); mn = k < nr ? k : nr; for (int j = 0; j < b_nc; j++) if (retval(k, j) != 0) { retval(k, j) = alpha_to (modn (index_of (retval(k, j)) - c(k, 0) + n (), m (), n ())); int idx = index_of (retval(k, j)); for (int i = 0; i < mn; i++) if (A(i, k) != 0) retval(i, j) ^= alpha_to (modn (c(i, 0) + idx, m (), n ())); } } // Apply row interchanges to the right hand sides. //for (int j = 0; j < IP.length (); j++) for (int j = IP.length ()-1; j >= 0; j--) { int piv = IP(j); for (int i = 0; i < b_nc; i++) { int tmp = retval(j, i); retval(j, i) = retval(piv, i); retval(piv, i) = tmp; } } } } else { galoisLU fact (*this); if (fact.singular ()) { info = -1; if (sing_handler) sing_handler (0.0); else (*current_liboctave_error_handler)("galois matrix singular"); return galois (); } else { galois A (fact.a_fact); Array IP (fact.ipvt); // Apply row interchanges to the right hand sides. for (int j = 0; j < IP.length (); j++) { int piv = IP(j); for (int i = 0; i < b_nc; i++) { int tmp = retval(j, i); retval(j, i) = retval(piv, i); retval(piv, i) = tmp; } } //Solve L*X = B, overwriting B with X. int mn = (nc < nr ? nc : nr); for (int k = 0; k < mn; k++) { for (int i = k+1; i < nr; i++) c(i, 0) = index_of (A(i, k)); for (int j = 0; j < b_nc; j++) if (retval(k, j) != 0) { int idx = index_of (retval(k, j)); for (int i = k+1; i < nr; i++) if (A(i, k) != 0) retval(i, j) ^= alpha_to (modn (c(i, 0) + idx, m (), n ())); } } // Solve U*X = B, overwriting B with X. for (int k = (nc < nr ? nc-1 : nr-1); k >= 0; k--) { int mn = k+1 < nr ? k+1 : nr; for (int i = 0; i < mn; i++) c(i, 0) = index_of (A(i, k)); mn = k < nr ? k : nr; for (int j = 0; j < b_nc; j++) if (retval(k, j) != 0) { retval(k, j) = alpha_to (modn (index_of (retval(k, j)) - c(k, 0) + n (), m (), n ())); int idx = index_of (retval(k, j)); for (int i = 0; i < mn; i++) if (A(i, k) != 0) retval(i, j) ^= alpha_to (modn (c(i, 0) + idx, m (), n ())); } } // Resize the number of solution rows if needed if (nc < nr) retval.resize (dim_vector (b_nr+nc-nr, b_nc)); } } return retval; } galois xdiv (const galois& a, const Matrix& b) { galois btmp (b, a.m (), a.primpoly ()); return xdiv (a, btmp); } galois xdiv (const Matrix& a, const galois& b) { galois atmp (a, b.m (), b.primpoly ()); return xdiv (atmp, b); } galois xdiv (const galois& a, const galois& b) { int info = 0; int a_nc = a.cols (); int b_nc = b.cols (); // if ((a_nc != b_nc) || (b.rows () != b.cols ())) if (a_nc != b_nc) { int a_nr = a.rows (); int b_nr = b.rows (); gripe_nonconformant ("operator /", a_nr, a_nc, b_nr, b_nc); return galois (); } galois atmp = a.transpose (); galois btmp = b.transpose (); galois result = btmp.solve (atmp, info, 0); if (info == 0) return galois (result.transpose ()); else return galois (); } galois xleftdiv (const galois& a, const Matrix& b) { galois btmp (b, a.m (), a.primpoly ()); return xleftdiv (a, btmp); } galois xleftdiv (const Matrix& a, const galois& b) { galois atmp (a, b.m (), b.primpoly ()); return xleftdiv (atmp, b); } galois xleftdiv (const galois& a, const galois& b) { int info = 0; int a_nr = a.rows (); int b_nr = b.rows (); // if ((a_nr != b_nr) || (a.rows () != a.columns ())) if (a_nr != b_nr) { int a_nc = a.cols (); int b_nc = b.cols (); gripe_nonconformant ("operator \\", a_nr, a_nc, b_nr, b_nc); return galois (); } galois result = a.solve (b, info, 0); if (info == 0) return result; else return galois (); } MM_BIN_OPS1 (galois, galois, galois, 1, 2, GALOIS) MM_BIN_OPS1 (galois, galois, Matrix, 1, 2, MATRIX) MM_BIN_OPS1 (galois, Matrix, galois, 2, 1, MATRIX) MM_CMP_OPS1 (galois, , galois, , 1, 2, GALOIS) MM_CMP_OPS1 (galois, , Matrix, , 1, 2, MATRIX) MM_CMP_OPS1 (Matrix, , galois, , 2, 1, MATRIX) MM_BOOL_OPS1 (galois, galois, 0.0, 1, 2, GALOIS) MM_BOOL_OPS1 (galois, Matrix, 0.0, 1, 2, MATRIX) MM_BOOL_OPS1 (Matrix, galois, 0.0, 2, 1, MATRIX) /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/src/PaxHeaders.3802/op-gm-gm.cc0000644000000000000000000000013212510010473016723 xustar0030 mtime=1428164923.954509931 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/src/op-gm-gm.cc0000644000000000000000000001007212510010473017250 0ustar00rootroot00000000000000//Copyright (C) 2003 David Bateman // // This program 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. // // This program 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 this program; if not, see // . // // In addition to the terms of the GPL, you are permitted to link this // program with any Open Source program, as defined by the Open Source // Initiative (www.opensource.org) #include #include #include #include "galois.h" #include "ov-galois.h" #include "galois-ops.h" // galois unary ops. DEFUNOP_OP (not, galois, !) DEFUNOP (uminus, galois) { CAST_UNOP_ARG (const octave_galois&); // Unitary minus of Galois Field is itself!! return new octave_galois (v.galois_value ()); } DEFUNOP (uplus, galois) { CAST_UNOP_ARG (const octave_galois&); return new octave_galois (v.galois_value ()); } DEFUNOP (transpose, galois) { CAST_UNOP_ARG (const octave_galois&); return new octave_galois (v.galois_value ().transpose ()); } // galois by galois ops. DEFBINOP_OP_G (add, galois, galois, +) DEFBINOP_OP_G (sub, galois, galois, -) DEFBINOP_OP_G (mul, galois, galois, *) DEFBINOP_FN_G (div, galois, galois, xdiv) DEFBINOP_FN_G (pow, galois, galois, pow) DEFBINOP_FN_G (ldiv, galois, galois, xleftdiv) DEFBINOP_FN (lt, galois, galois, mx_el_lt) DEFBINOP_FN (le, galois, galois, mx_el_le) DEFBINOP_FN (eq, galois, galois, mx_el_eq) DEFBINOP_FN (ge, galois, galois, mx_el_ge) DEFBINOP_FN (gt, galois, galois, mx_el_gt) DEFBINOP_FN (ne, galois, galois, mx_el_ne) DEFBINOP_FN_G (el_mul, galois, galois, product) DEFBINOP_FN_G (el_div, galois, galois, quotient) DEFBINOP_FN_G (el_pow, galois, galois, elem_pow) DEFBINOP (el_ldiv, galois, galois) { CAST_BINOP_ARGS (const octave_galois&, const octave_galois&); return new octave_galois (quotient (v2.galois_value (), v1.galois_value ())); } DEFBINOP_FN (el_and, galois, galois, mx_el_and) DEFBINOP_FN (el_or, galois, galois, mx_el_or) DEFCATOP_G_METHOD (gm_gm, galois, galois, concat) DEFASSIGNOP_FN (assign, galois, galois, assign) void install_gm_gm_ops (void) { INSTALL_UNOP (op_not, octave_galois, not); INSTALL_UNOP (op_uminus, octave_galois, uminus); INSTALL_UNOP (op_uplus, octave_galois, uplus); INSTALL_UNOP (op_transpose, octave_galois, transpose); INSTALL_UNOP (op_hermitian, octave_galois, transpose); INSTALL_BINOP (op_add, octave_galois, octave_galois, add); INSTALL_BINOP (op_sub, octave_galois, octave_galois, sub); INSTALL_BINOP (op_mul, octave_galois, octave_galois, mul); INSTALL_BINOP (op_div, octave_galois, octave_galois, div); INSTALL_BINOP (op_pow, octave_galois, octave_galois, pow); INSTALL_BINOP (op_ldiv, octave_galois, octave_galois, ldiv); INSTALL_BINOP (op_lt, octave_galois, octave_galois, lt); INSTALL_BINOP (op_le, octave_galois, octave_galois, le); INSTALL_BINOP (op_eq, octave_galois, octave_galois, eq); INSTALL_BINOP (op_ge, octave_galois, octave_galois, ge); INSTALL_BINOP (op_gt, octave_galois, octave_galois, gt); INSTALL_BINOP (op_ne, octave_galois, octave_galois, ne); INSTALL_BINOP (op_el_mul, octave_galois, octave_galois, el_mul); INSTALL_BINOP (op_el_div, octave_galois, octave_galois, el_div); INSTALL_BINOP (op_el_pow, octave_galois, octave_galois, el_pow); INSTALL_BINOP (op_el_ldiv, octave_galois, octave_galois, el_ldiv); INSTALL_BINOP (op_el_and, octave_galois, octave_galois, el_and); INSTALL_BINOP (op_el_or, octave_galois, octave_galois, el_or); INSTALL_G_CATOP (octave_galois, octave_galois, gm_gm); INSTALL_ASSIGNOP (op_asn_eq, octave_galois, octave_galois, assign); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.1/PaxHeaders.3802/inst0000644000000000000000000000013212510010473015105 xustar0030 mtime=1428164923.938510295 30 atime=1428164983.712815029 30 ctime=1428164983.712815029 communications-1.2.1/inst/0000755000000000000000000000000012510010473015507 5ustar00rootroot00000000000000communications-1.2.1/inst/PaxHeaders.3802/quantiz.m0000644000000000000000000000013212510010473017033 xustar0030 mtime=1428164923.886511478 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/inst/quantiz.m0000644000000000000000000000465612510010473017373 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{qidx} =} quantiz (@var{x}, @var{table}) ## @deftypefnx {Function File} {[@var{qidx}, @var{q}] =} quantiz (@var{x}, @var{table}, @var{codes}) ## @deftypefnx {Function File} {[ @var{qidx}, @var{q}, @var{d}] =} quantiz (@dots{}) ## ## Quantization of an arbitrary signal relative to a partitioning. ## ## @table @code ## @item qidx = quantiz (x, table) ## Determine position of x in strictly monotonic table. The first ## interval, using index 0, corresponds to x <= table(1). ## Subsequent intervals are table(i-1) < x <= table(i). ## ## @item [qidx, q] = quantiz (x, table, codes) ## Associate each interval of the table with a code. Use codes(1) ## for x <= table(1) and codes(n+1) for table(n) < x <= table(n+1). ## ## @item [qidx, q, d] = quantiz (...) ## Compute distortion as mean squared distance of x from the ## corresponding quantization values. ## @end table ## @end deftypefn function [qidx, q, d] = quantiz (x, table, codes) if (nargin < 2 || nargin > 3) print_usage (); endif if (numel (table) == 1) qidx = double (table < x); else qidx = length (table) - lookup (flipud (table(:)), x); endif if (nargin > 2 && nargout > 1) q = codes(qidx + 1); endif if (nargout > 2) table = [table(1) ; table(:) ]; d = sumsq (x(:) - q(:)) / length (x); endif endfunction %!assert (quantiz (1:10, 0:9), 1:10); %!assert (quantiz ([1:10]', 0:9), [1:10]'); %!assert (quantiz (1:10, [3 6 9]), [0 0 0 1 1 1 2 2 2 3]); %!assert (quantiz (1:10, 5), [0 0 0 0 0 1 1 1 1 1]); %!assert (quantiz ([-Inf -1 0 1 Inf], [-1 0 1]), [0 0 1 2 3]); %!assert (quantiz ([-Inf -1 0 1 Inf], 0), [0 0 0 1 1]); %% Test input validation %!error quantiz () %!error quantiz (1) %!error quantiz (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/helscandeintrlv.m0000644000000000000000000000013212510010473020525 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/inst/helscandeintrlv.m0000644000000000000000000000205112510010473021050 0ustar00rootroot00000000000000## Copyright (C) 2010 Mark Borgerding ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{outdata} =} helscandeintrlv (@var{data}, @var{nrows}, @var{ncols}, @var{Nshift}) ## @var{nrows}-by-@var{ncols}. ## @seealso{helscandeintrlv} ## @end deftypefn function outdata = helscandeintrlv (data, Nrows, Ncols, Nshift) outdata = helscanintrlv (data, Nrows, Ncols, Nrows - Nshift); endfunction communications-1.2.1/inst/PaxHeaders.3802/pammod.m0000644000000000000000000000013212510010473016615 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/inst/pammod.m0000644000000000000000000000466612510010473017156 0ustar00rootroot00000000000000## Copyright (C) 2006 Charalampos C. Tsimenidis ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} pammod (@var{x}, @var{m}) ## @deftypefnx {Function File} {@var{y} =} pammod (@var{x}, @var{m}, @var{phi}) ## @deftypefnx {Function File} {@var{y} =} pammod (@var{x}, @var{m}, @var{phi}, @var{type}) ## ## Modulates an information sequence of integers @var{x} in the range ## @code{[0 @dots{} M-1]} onto a pulse amplitude modulated signal @var{y}. ## @var{phi} controls the initial phase and @var{type} controls the ## constellation mapping. If @var{type} is set to "Bin" will result in ## binary encoding, in contrast, if set to "Gray" will give Gray encoding. ## An example of Gray-encoded 8-PAM is ## ## @example ## @group ## d = randint (1, 1e4, 8); ## y = pammod (d, 8, 0, "gray"); ## z = awgn (y, 20); ## plot (z, "rx") ## @end group ## @end example ## @seealso{pamdemod} ## @end deftypefn function y = pammod (x, M, phi, type) if (nargin < 2) print_usage (); endif m = 0:M-1; if (!isempty (find (ismember (x, m) == 0))) error ("pammod: all elements of X must be integers in the range [0,M-1]"); endif if (nargin < 3) phi = 0; endif if (nargin < 4) type = "Bin"; endif constellation = [-M+1:2:M-1] .* exp (-1j*phi); if (strcmp (type, "Bin")||strcmp (type, "bin")) y = constellation(x+1); elseif (strcmp (type, "Gray")||strcmp (type, "gray")) [a, b] = sort (bitxor (m, bitshift (m, -1))); y = constellation(b(x+1)); else print_usage (); endif if (iscomplex (y) && all (imag (y(:)) == 0)) y = real (y); endif endfunction %!assert (round (pammod ([0:7], 8, 0, "Bin")), [-7:2:7]) %!assert (round (pammod ([0:7], 8, 0, "Gray")), [-7 -5 -1 -3 7 5 1 3]) %% Test input validation %!error pammod () %!error pammod (1) %!error pammod (1, 2, 3, "invalid") communications-1.2.1/inst/PaxHeaders.3802/fmdemod.m0000644000000000000000000000013212510010473016753 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/inst/fmdemod.m0000644000000000000000000000232412510010473017301 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} fmdemod (@var{x}, @var{fc}, @var{fs}) ## Create the FM demodulation of the signal x with carrier frequency fs. ## Where x is sample at frequency fs. ## @seealso{ammod, amdemod, fmmod} ## @end deftypefn function m = fmdemod (s, fc, fs) if (nargin != 3) print_usage (); endif ds = diff (s); m = amdemod (abs (ds), fc, fs); endfunction %% Test input validation %!error fmdemod () %!error fmdemod (1) %!error fmdemod (1, 2) %!error fmdemod (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/@galois0000644000000000000000000000013212510010473016463 xustar0030 mtime=1428164923.862512023 30 atime=1428164983.712815029 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/0000755000000000000000000000000012510010473017065 5ustar00rootroot00000000000000communications-1.2.1/inst/@galois/PaxHeaders.3802/reshape.m0000644000000000000000000000013212510010473020345 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/reshape.m0000644000000000000000000000346012510010473020675 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} reshape (@var{a}, @var{m}, @var{n}) ## Return a matrix with @var{m} rows and @var{n} columns whose elements are ## taken from the Galois array @var{a}. To decide how to order the elements, ## Octave pretends that the elements of a matrix are stored in column-major ## order (like Fortran arrays are stored). ## ## For example, ## ## @example ## reshape (gf ([1, 2, 3, 4], 3), 2, 2) ## ans = ## GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) ## ## Array elements = ## ## 1 3 ## 2 4 ## ## @end example ## ## The @code{reshape} function is equivalent to ## ## @example ## @group ## retval = gf (zeros (m, n), a.m, a.prim_poly); ## retval(:) = a; ## @end group ## @end example ## ## @noindent ## but it is somewhat less cryptic to use @code{reshape} instead of the ## colon operator. Note that the total number of elements in the original ## matrix must match the total number of elements in the new matrix. ## @seealso{:} ## @end deftypefn function varargout = reshape (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = greshape (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/inv.m0000644000000000000000000000013212510010473017512 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/inv.m0000644000000000000000000000217112510010473020040 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inv (@var{a}) ## Compute the inverse of the square matrix @var{a}. Return an estimate ## of the reciprocal condition number if requested, otherwise warn of an ## ill-conditioned matrix if the reciprocal condition number is small. ## @end deftypefn function varargout = inv (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = ginv (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/convmtx.m0000644000000000000000000000013212510010473020414 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/convmtx.m0000644000000000000000000000317612510010473020750 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} convmtx (@var{a}, @var{n}) ## ## Create matrix to perform repeated convolutions with the same vector ## in a Galois Field. If @var{a} is a column vector and @var{x} is a ## column vector of length @var{n}, in a Galois Field then ## ## @code{convmtx (@var{a}, @var{n}) * @var{x}} ## ## gives the convolution of of @var{a} and @var{x} and is the ## same as @code{conv (@var{a}, @var{x})}. The difference is if ## many vectors are to be convolved with the same vector, then ## this technique is possibly faster. ## ## Similarly, if @var{a} is a row vector and @var{x} is a row ## vector of length @var{n}, then ## ## @code{@var{x} * convmtx (@var{a}, @var{n})} ## ## is the same as @code{conv (@var{x}, @var{a})}. ## @seealso{conv} ## @end deftypefn function b = convmtx (a, n) if (!isgalois (a)) error ("convmtx: argument must be a galois variable"); endif b = gf (convmtx (a.x, n), a.m, a.prim_poly); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/diag.m0000644000000000000000000000013212510010473017622 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/diag.m0000644000000000000000000000275412510010473020157 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} diag (@var{v}, @var{k}) ## Return a diagonal matrix with Galois vector @var{v} on diagonal @var{k}. ## The second argument is optional. If it is positive, the vector is placed on ## the @var{k}-th super-diagonal. If it is negative, it is placed on the ## @var{-k}-th sub-diagonal. The default value of @var{k} is 0, and the ## vector is placed on the main diagonal. For example, ## ## @example ## diag (gf ([1, 2, 3], 2), 1) ## ans = ## GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7) ## ## Array elements = ## ## 0 1 0 0 ## 0 0 2 0 ## 0 0 0 3 ## 0 0 0 0 ## ## @end example ## @end deftypefn function varargout = diag (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gdiag (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/exp.m0000644000000000000000000000013212510010473017512 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/exp.m0000644000000000000000000000173112510010473020041 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} exp (@var{x}) ## Compute the anti-logarithm for each element of @var{x} for a Galois ## array. ## @end deftypefn function varargout = exp (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gexp (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/det.m0000644000000000000000000000013212510010473017472 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/det.m0000644000000000000000000000171112510010473020017 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {@var{d} =} det (@var{a}) ## Compute the determinant of the Galois array @var{a}. ## @end deftypefn function varargout = det (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gdet (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/sum.m0000644000000000000000000000013212510010473017522 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/sum.m0000644000000000000000000000202212510010473020043 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} sum (@var{x}, @var{dim}) ## Sum of elements along dimension @var{dim} of Galois array. If @var{dim} ## is omitted, it defaults to 1 (column-wise sum). ## @end deftypefn function varargout = sum (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gsum (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/inverse.m0000644000000000000000000000013212510010473020371 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/inverse.m0000644000000000000000000000167012510010473020722 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inverse (@var{a}) ## See inv. ## @end deftypefn function varargout = inverse (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = ginverse (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/filter.m0000644000000000000000000000013212510010473020203 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/filter.m0000644000000000000000000000511212510010473020527 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {y =} filter (@var{b}, @var{a}, @var{x}) ## @deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}) ## ## Digital filtering of vectors in a Galois Field. Returns the solution to ## the following linear, time-invariant difference equation over a Galois ## Field: ## @tex ## $$ ## \\sum_{k=0}^N a_{k+1} y_{n-k} = \\sum_{k=0}^M b_{k+1} x_{n-k}, \\qquad ## 1 \\le n \\le P ## $$ ## @end tex ## @ifnottex ## ## @smallexample ## @group ## N M ## SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k) for 1<=n<=length(x) ## k=0 k=0 ## @end group ## @end smallexample ## @end ifnottex ## ## @noindent ## where ## @tex ## $a \\in \\Re^{N-1}$, $b \\in \\Re^{M-1}$, and $x \\in \\Re^P$. ## @end tex ## @ifnottex ## N=length(a)-1 and M=length(b)-1. ## @end ifnottex ## An equivalent form of this equation is: ## @tex ## $$ ## y_n = -\\sum_{k=1}^N c_{k+1} y_{n-k} + \\sum_{k=0}^M d_{k+1} x_{n-k}, \\qquad ## 1 \\le n \\le P ## $$ ## @end tex ## @ifnottex ## ## @smallexample ## @group ## N M ## y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k) for 1<=n<=length(x) ## k=1 k=0 ## @end group ## @end smallexample ## @end ifnottex ## ## @noindent ## where ## @tex ## $c = a/a_1$ and $d = b/a_1$. ## @end tex ## @ifnottex ## c = a/a(1) and d = b/a(1). ## @end ifnottex ## ## If the fourth argument @var{si} is provided, it is taken as the ## initial state of the system and the final state is returned as ## @var{sf}. The state vector is a column vector whose length is ## equal to the length of the longest coefficient vector minus one. ## If @var{si} is not supplied, the initial state vector is set to all ## zeros. ## @end deftypefn function varargout = filter (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gfilter (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/log.m0000644000000000000000000000013212510010473017477 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/log.m0000644000000000000000000000173412510010473020031 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} log (@var{x}) ## Compute the natural logarithm for each element of @var{x} for a Galois ## array. ## @end deftypefn function varargout = log (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = glog (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/sumsq.m0000644000000000000000000000013212510010473020066 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/sumsq.m0000644000000000000000000000226112510010473020414 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} sumsq (@var{x}, @var{dim}) ## Sum of squares of elements along dimension @var{dim} of Galois array. ## If @var{dim} is omitted, it defaults to 1 (column-wise sum of squares). ## ## This function is equivalent to computing ## @example ## gsum (x .* conj (x), dim) ## @end example ## but it uses less memory. ## @end deftypefn function varargout = sumsq (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gsumsq (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/rank.m0000644000000000000000000000013212510010473017651 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/rank.m0000644000000000000000000000176512510010473020207 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {@var{d} =} rank (@var{a}) ## Compute the rank of the Galois array @var{a} by counting the independent ## rows and columns. ## @end deftypefn function varargout = rank (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = grank (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/ifft.m0000644000000000000000000000013212510010473017646 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/ifft.m0000644000000000000000000000316112510010473020174 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} ifft (@var{x}) ## ## If @var{x} is a column vector, finds the IFFT over the primitive element ## of the Galois Field of @var{x}. If @var{x} is in the Galois Field ## GF(2^@var{m}), then @var{x} must have @code{2^@var{m} - 1} elements. ## @seealso{ifft} ## @end deftypefn function y = ifft (x) if (nargin != 1) print_usage (); endif if (!isgalois (x)) error ("ifft: argument must be a galois variable"); endif n = 2^x.m - 1; if (n > 255) error (["ifft: argument must be in Galois Field GF(2^M)" ... ", where M is in the range [1,8]"]); endif alph = gf (2, x.m, x.prim_poly); [nr, nc] = size (x); if (nc == 1 && nr == n) y = dftmtx (1/alph) * x; elseif (nc == n && nr == 1) y = (dftmtx (1/alph) * x')'; else error ("ifft: argument must be a vector in GF(2^M) of length 2^M-1"); endif endfunction %%Test input validation %!error ifft (gf (1, 12)) communications-1.2.1/inst/@galois/PaxHeaders.3802/conv.m0000644000000000000000000000013212510010473017663 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/conv.m0000644000000000000000000000470712510010473020220 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} conv (@var{a}, @var{b}) ## Convolve two Galois vectors. ## ## @code{y = conv (a, b)} returns a vector of length equal to ## @code{length (a) + length (b) - 1}. ## If @var{a} and @var{b} are polynomial coefficient vectors, @code{conv} ## returns the coefficients of the product polynomial. ## @seealso{deconv} ## @end deftypefn function y = conv (a, b) if (nargin != 2) print_usage (); endif if (!isgalois (a) && !isgalois (b)) error ("conv: at least one argument must be a galois variable"); elseif (!isgalois (a)) a = gf (a, b.m, b.prim_poly); elseif (!isgalois (b)) b = gf (b, a.m, a.prim_poly); elseif (a.m != b.m && a.prim_poly != b.prim_poly) error ("conv: both vectors must be in the same galois field"); endif if (min (size (a)) > 1 || min (size (b)) > 1) error ("conv: both arguments must be vectors"); endif la = length (a); lb = length (b); ly = la + lb - 1; ## Ensure that both vectors are row vectors. if (rows (a) > 1) a = reshape (a, 1, la); endif if (rows (b) > 1) b = reshape (b, 1, lb); endif ## Use the shortest vector as the coefficent vector to filter. if (la < lb) if (ly > lb) ## Can't concatenate galois variables like this yet ## x = [b, (zeros (1, ly - lb))]; x = gf ([b, (zeros (1, ly - lb))], b.m, b.prim_poly); else x = b; endif y = filter (a, 1, x); else if (ly > la) ## Can't concatenate galois variables like this yet ## x = [a, (zeros (1, ly - la))]; x = gf ([a, (zeros (1, ly - la))], a.m, a.prim_poly); else x = a; endif y = filter (b, 1, x); endif endfunction %%Test input validation %!error conv (gf (1, 2), gf (1, 3)) %!error conv (gf (eye (3), 3), gf (eye (3), 3)) communications-1.2.1/inst/@galois/PaxHeaders.3802/lu.m0000644000000000000000000000013212510010473017336 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/lu.m0000644000000000000000000000356412510010473017673 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}] =} lu (@var{a}) ## @cindex LU decomposition of Galois matrix ## Compute the LU decomposition of @var{a} in a Galois Field. The result is ## returned in a permuted form, according to the optional return value ## @var{p}. For example, given the matrix ## @code{a = gf ([1, 2; 3, 4], 3)}, ## ## @example ## [l, u, p] = lu (a) ## @end example ## ## @noindent ## returns ## ## @example ## l = ## GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) ## ## Array elements = ## ## 1 0 ## 6 1 ## ## u = ## GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) ## ## Array elements = ## ## 3 4 ## 0 7 ## ## p = ## ## Permutation Matrix ## ## 0 1 ## 1 0 ## ## @end example ## ## Such that @code{@var{p} * @var{a} = @var{l} * @var{u}}. If the argument ## @var{p} is not included then the permutations are applied to @var{l} ## so that @code{@var{a} = @var{l} * @var{u}}. @var{l} is then a pseudo- ## lower triangular matrix. The matrix @var{a} can be rectangular. ## @end deftypefn function varargout = lu (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = glu (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/isequal.m0000644000000000000000000000013212510010473020361 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/isequal.m0000644000000000000000000000213112510010473020703 0ustar00rootroot00000000000000## Copyright (C) 2000 Paul Kienzle ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} isequal (@var{x1}, @var{x2}, @dots{}) ## Return true if all of @var{x1}, @var{x2}, @dots{} are equal. ## @seealso{isequalwithequalnans} ## @end deftypefn function t = isequal (x, varargin) if (nargin < 2) print_usage (); endif for arg = 1:length (varargin) y = varargin{arg}; t = all (x(:) == y(:)); if (!t) return endif endfor endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/dftmtx.m0000644000000000000000000000013212510010473020224 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/dftmtx.m0000644000000000000000000000422712510010473020556 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{d} =} dftmtx (@var{a}) ## ## Form a matrix, that can be used to perform Fourier transforms in ## a Galois Field. ## ## Given that @var{a} is an element of the Galois Field GF(2^m), and ## that the minimum value for @var{k} for which @code{@var{a} ^ @var{k}} ## is equal to one is @code{2^m - 1}, then this function produces a ## @var{k}-by-@var{k} matrix representing the discrete Fourier transform ## over a Galois Field with respect to @var{a}. The Fourier transform of ## a column vector is then given by @code{dftmtx (@var{a}) * @var{x}}. ## ## The inverse Fourier transform is given by @code{dftmtx (1 / @var{a})} ## @end deftypefn function d = dftmtx (a) if (nargin != 1) print_usage (); endif if (!isgalois (a)) error ("dftmtx: argument must be a galois variable"); endif m = a.m; prim = a.prim_poly; n = 2^a.m - 1; if (n > 255) error (["dftmtx: argument must be in Galois Field GF(2^M)" ... ", where M is in the range [1,8]"]); endif if (length (a) != 1) error ("dftmtx: argument must be a scalar"); endif mp = minpol (a); if (mp(1) != 1 || !isprimitive (mp)) error ("dftmtx: argument must be a primitive nth root of unity"); endif step = log (a); step = step.x; row = exp (gf ([0:n-1], m, prim)); d = zeros (n); for i = 1:n; d(i,:) = row .^ mod (step*(i-1), n); endfor endfunction %%Test input validation %!error dftmtx (gf (1, 12)) %!error dftmtx (gf (eye (3), 4)) communications-1.2.1/inst/@galois/PaxHeaders.3802/fft.m0000644000000000000000000000013212510010473017475 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/fft.m0000644000000000000000000000312412510010473020022 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} fft (@var{x}) ## ## If @var{x} is a column vector, finds the FFT over the primitive element ## of the Galois Field of @var{x}. If @var{x} is in the Galois Field ## GF(2^@var{m}), then @var{x} must have @code{2^@var{m} - 1} elements. ## @end deftypefn function y = fft (x) if (nargin != 1) print_usage (); endif if (!isgalois (x)) error ("fft: argument must be a galois variable"); endif n = 2^x.m - 1; if (n > 255) error (["fft: argument must be in Galois Field GF(2^M)" ... ", where M is in the range [1,8]"]); endif alph = gf (2, x.m, x.prim_poly); [nr, nc] = size (x); if (nc == 1 && nr == n) y = dftmtx (alph) * x; elseif (nc == n && nr == 1) y = (dftmtx (alph) * x')'; else error ("fft: argument must be a vector in GF(2^M) of length 2^M-1"); endif endfunction %%Test input validation %!error fft (gf (1, 12)) communications-1.2.1/inst/@galois/PaxHeaders.3802/roots.m0000644000000000000000000000013212510010473020064 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/roots.m0000644000000000000000000000352212510010473020413 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} roots (@var{v}) ## ## For a vector @var{v} with @math{N} components, return ## the roots of the polynomial over a Galois Field ## @tex ## $$ ## v_1 z^{N-1} + \cdots + v_{N-1} z + v_N. ## $$ ## @end tex ## @ifnottex ## ## @example ## v(1) * z^(N-1) + ... + v(N-1) * z + v(N). ## @end example ## @end ifnottex ## ## The number of roots returned and their value will be determined ## by the order and primitive polynomial of the Galois Field ## @end deftypefn function r = roots (v) if (nargin != 1) print_usage (); endif if (!isgalois (v)) error ("roots: argument must be a galois variable"); endif if (min (size (v)) > 1 || nargin != 1) print_usage (); endif v = reshape (v, 1, length (v)); m = v.m; prim_poly = v.prim_poly; n = 2^m - 1; poly = v; nr = 0; t = 0; r = []; while (t <= n && length (poly) > 1) [npoly, nrem] = deconv (poly, gf ([1, t], m, prim_poly)); if (any (nrem)) t = t + 1; else nr = nr + 1; r(nr) = t; poly = npoly; endif endwhile r = gf (r, m, prim_poly); endfunction %%Test input validation %!error roots (gf (eye (3), 3)) communications-1.2.1/inst/@galois/PaxHeaders.3802/deconv.m0000644000000000000000000000013212510010473020174 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/deconv.m0000644000000000000000000000463112510010473020525 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} deconv (@var{y}, @var{a}) ## Deconvolve two Galois vectors. ## ## @code{[b, r] = deconv (y, a)} solves for @var{b} and @var{r} such that ## @code{y = conv (a, b) + r}. ## ## If @var{y} and @var{a} are polynomial coefficient vectors, @var{b} will ## contain the coefficients of the polynomial quotient and @var{r} will be ## a remainder polynomial of lowest order. ## @seealso{conv} ## @end deftypefn function [b, r] = deconv (y, a) if (nargin != 2) print_usage (); endif if (!isgalois (y) && !isgalois (a)) error ("deconv: at least one argument must be a galois variable"); elseif (!isgalois (y)) y = gf (y, a.m, a.prim_poly); elseif (!isgalois (a)) a = gf (a, y.m, y.prim_poly); elseif (a.m != y.m && a.prim_poly != y.prim_poly) error ("deconv: both vectors must be in the same galois field"); endif if (min (size (a)) > 1 || min (size (y)) > 1) error ("deconv: both arguments must be vectors"); endif la = length (a); ly = length (y); lb = ly - la + 1; ## Ensure that both vectors are row vectors. if (rows (a) > 1) a = reshape (a, 1, la); endif if (rows (y) > 1) y = reshape (y, 1, ly); endif if (ly > la) b = filter (y, a, [1, (zeros (1, ly - la))]); elseif (ly == la) b = filter (y, a, 1); else b = gf (0, y.m, y.prim_poly); endif lc = la + length (b) - 1; if (ly == lc) r = y - conv (a, b); else ## Can't concatenate galois variables like this yet ## r = [(zeros (1, lc - ly)), y] - conv (a, b); r = gf ([(zeros (1, lc - ly)), y], y.m, y.prim_poly) - conv (a, b); endif endfunction %%Test input validation %!error deconv (gf (1, 2), gf (1, 3)) %!error deconv (gf (eye (3), 3), gf (eye (3), 3)) communications-1.2.1/inst/@galois/PaxHeaders.3802/sqrt.m0000644000000000000000000000013212510010473017707 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/sqrt.m0000644000000000000000000000175212510010473020241 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} sqrt (@var{x}) ## Compute the square root of @var{x}, element by element, in a Galois Field. ## @seealso{exp} ## @end deftypefn function varargout = sqrt (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gsqrt (varargin{:}); endfunction communications-1.2.1/inst/@galois/PaxHeaders.3802/prod.m0000644000000000000000000000013212510010473017662 xustar0030 mtime=1428164923.858512114 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/inst/@galois/prod.m0000644000000000000000000000203612510010473020210 0ustar00rootroot00000000000000## Copyright (C) 2011 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Loadable Function} {} prod (@var{x}, @var{dim}) ## Product of elements along dimension @var{dim} of Galois array. If ## @var{dim} is omitted, it defaults to 1 (column-wise products). ## @end deftypefn function varargout = prod (varargin) varargout = cell (1, max (1, nargout)); [varargout{:}] = gprod (varargin{:}); endfunction communications-1.2.1/inst/PaxHeaders.3802/lloyds.m0000644000000000000000000000013112510010473016645 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.038508013 30 ctime=1428164983.712815029 communications-1.2.1/inst/lloyds.m0000644000000000000000000001472312510010473017202 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @var{init_codes}) ## @deftypefnx {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @var{len}) ## @deftypefnx {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @dots{}, @var{tol}) ## @deftypefnx {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @dots{}, @var{tol}, @var{type}) ## @deftypefnx {Function File} {[@var{table}, @var{codes}, @var{dist}] =} lloyds (@dots{}) ## @deftypefnx {Function File} {[@var{table}, @var{codes}, @var{dist}, @var{reldist}] =} lloyds (@dots{}) ## ## Optimize the quantization table and codes to reduce distortion. This is ## based on the article by Lloyd ## ## S. Lloyd @emph{Least squared quantization in PCM}, IEEE Trans Inform ## Theory, Mar 1982, no 2, p129-137 ## ## which describes an iterative technique to reduce the quantization error ## by making the intervals of the table such that each interval has the same ## area under the PDF of the training signal @var{sig}. The initial codes to ## try can either be given in the vector @var{init_codes} or as scalar ## @var{len}. In the case of a scalar the initial codes will be an equi-spaced ## vector of length @var{len} between the minimum and maximum value of the ## training signal. ## ## The stopping criteria of the iterative algorithm is given by ## ## @example ## abs(@var{dist}(n) - @var{dist}(n-1)) < max(@var{tol}, abs(@var{eps}*max(@var{sig})) ## @end example ## ## By default @var{tol} is 1.e-7. The final input argument determines how the ## updated table is created. By default the centroid of the values of the ## training signal that fall within the interval described by @var{codes} ## are used to update @var{table}. If @var{type} is any other string than ## "centroid", this behavior is overridden and @var{table} is updated as ## follows. ## ## @example ## @var{table} = (@var{code}(2:length(@var{code})) + @var{code}(1:length(@var{code}-1))) / 2 ## @end example ## ## The optimized values are returned as @var{table} and @var{code}. In ## addition the distortion of the optimized codes representing the training ## signal is returned as @var{dist}. The relative distortion in the final ## iteration is also returned as @var{reldist}. ## ## @seealso{quantiz} ## @end deftypefn function [table, code, dist, reldist] = lloyds (sig, init, tol, type) if (nargin < 2 || nargin > 4) print_usage (); endif if (min (size (sig)) != 1) error ("lloyds: SIG must be a vector"); endif sig = sig(:); sigmin = min (sig); sigmax = max (sig); if (length (init) == 1) len = init; init = [0:len-1]' / (len - 1) * (sigmax - sigmin) + sigmin; elseif (min (size (init))) len = length (init); else error ("lloyds: invalid initial codebook"); endif lcode = length (init); if (any (init != sort (init))) ## Must be monotonically increasing error ("lloyds: INIT_CODES must be monotonically increasing"); endif if (nargin < 3) tol = 1e-7; elseif (isempty (tol)) tol = 1e-7; endif stop_criteria = max (eps * abs (sigmax), abs (tol)); if (nargin < 4) type = "centroid"; elseif (!ischar (type)) error ("lloyds: TYPE must be a string"); endif ## Setup initial codebook, table and distortion code = init(:); table = (code(2:lcode) + code(1:lcode-1))/2; [indx, ignore, dist] = quantiz (sig, table, code); reldist = abs (dist); while (reldist > stop_criteria) ## The formula of the code at the new iteration is ## ## code = Int_{table_{i-1}}^{table_i} x PSD(sig(x)) dx / .. ## Int_{table_{i-1}}^{table_i} PSD(sig(x)) dx ## ## As sig is a discrete signal, this comes down to counting the number ## of times "sig" has values in each interval of the table, and taking ## the mean of these values. If no value of the signals in interval, take ## the middle of the interval. That is calculate the centroid of the data ## of the training signal falling in the interval. We can reuse the index ## from the previous call to quantiz to define the values in the interval. for i = 1:lcode psd_in_interval = find (indx == i-1); if (!isempty (psd_in_interval)) code(i) = mean (sig(psd_in_interval)); elseif (i == 1) code(i) = (table(i) + sigmin) / 2; elseif (i == lcode) code(i) = (sigmax + table(i-1)) / 2; else code(i) = (table(i) + table(i-1)) / 2; endif endfor ## Now update the table. There is a problem here, in that I believe ## the elements of the new table should be given by b(i)=(c(i+1)+c(i))/2, ## but Matlab doesn't seem to do this. Matlab seems to also take the ## centroid of the code for the table (this was a real pain to find ## why my results and Matlab's disagreed). For this reason, I have a ## default behavior the same as Matlab, and allow a flag to overide ## it to be the behavior I expect. If any one wants to tell me what ## the CORRECT behavior is, then I'll get rid of of the irrelevant ## case below. if (strcmp (type, "centroid")) for i = 1:lcode-1; sig_in_code = sig(find (sig >= code(i))); sig_in_code = sig_in_code(find (sig_in_code < code(i+1))); if (!isempty (sig_in_code)) table(i) = mean (sig_in_code); else table(i) = (code(i+1) + code(i)) / 2; endif endfor else table = (code(2:lcode) + code(1:lcode-1))/2; endif ## Update the distortion levels reldist = dist; [indx, ignore, dist] = quantiz (sig, table, code); reldist = abs (reldist - dist); endwhile if (size (init, 1) == 1) code = code'; table = table'; endif endfunction %% Test input validation %!error lloyds () %!error lloyds (1) %!error lloyds (1, 2, 3, 4, 5) %!error lloyds (1, [3 2 1]) %!error lloyds (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/randsrc.m0000644000000000000000000000013112510010473016773 xustar0029 mtime=1428164923.91851075 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/randsrc.m0000644000000000000000000000751612510010473017332 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} =} randsrc (@var{n}) ## @deftypefnx {Function File} {@var{b} =} randsrc (@var{n}, @var{m}) ## @deftypefnx {Function File} {@var{b} =} randsrc (@var{n}, @var{m}, @var{alphabet}) ## @deftypefnx {Function File} {@var{b} =} randsrc (@var{n}, @var{m}, @var{alphabet}, @var{seed}) ## ## Generate a matrix of random symbols. The size of the matrix is ## @var{n} rows by @var{m} columns. By default @var{m} is equal to @var{n}. ## ## The variable @var{alphabet} can be either a row vector or a matrix with ## two rows. When @var{alphabet} is a row vector the symbols returned in ## @var{b} are chosen with equal probability from @var{alphabet}. When ## @var{alphabet} has two rows, the second row determines the probability ## with which each of the symbols is chosen. The sum of the probabilities ## must equal 1. By default @var{alphabet} is [-1 1]. ## ## The variable @var{seed} allows the random number generator to be seeded ## with a fixed value. The initial seed will be restored when returning. ## @end deftypefn function b = randsrc (n, m, alphabet, seed) switch (nargin) case 0 m = 1; n = 1; alphabet = [-1, 1]; seed = Inf; case 1 m = n; alphabet = [-1, 1]; seed = Inf; case 2 alphabet = [-1, 1]; seed = Inf; case 3 seed = Inf; case 4 otherwise print_usage (); endswitch ## Check alphabet [ar, ac] = size (alphabet); if (ac == 1) b = alphabet (1, 1) * ones (n, m); return; endif if (ar == 1) prob = [1:ac] / ac; elseif (ar == 2) prob = alphabet(2,:); alphabet = alphabet(1,:); if (abs (1 - sum (prob)) > eps) error ("randsrc: the probabilities of ALPHABET must add up to 1"); endif prob = cumsum (prob); else error ("randsrc: ALPHABET must be a vector or a matrix with 2 rows"); endif ## Check seed; if (!isinf (seed)) old_seed = rand ("seed"); rand ("seed", seed); endif ## Create indexes with the right probabilities tmp = rand (n, m); b = ones (n, m); for i = 1:ac-1 b = b + (tmp > prob(i)); endfor ## Map the indexes to the symbols b = alphabet(b); ## BUG: the above gives a row vector for some reason. Force what we want b = reshape (b, n, m); ## Get back to the old if (!isinf (seed)) rand ("seed", old_seed); endif endfunction %!shared n, alph1, alph2, seed, a1, a2, a3, a4, a5, a6 %! n = 10; alph1 = [0, 1; 0.3, 0.7]; alph2 = ["a", "b"]; seed = 1; %! a1 = randsrc (n); a2 = randsrc (n, n); %! a3 = randsrc (n, n, alph1); a4 = randsrc (n, n, alph2); %! a5 = randsrc (n, n, alph1, seed); a6 = randsrc (n, n, alph1, seed); %!error randsrc (n, n, n, n, n); %!assert (size (a1) == [n, n] && size (a2) == [n, n]); %!assert (max ([a1(:); a2(:)]) <= 1 && min ([a1(:); a2(:)]) >= -1); %!assert (size (a3) == [n, n] && size (a4) == [n, n]); %!assert (max (a3(:)) <= 1 && min (a3(:)) >= 0); %!assert (max (toascii (a4(:))) <= toascii ("b")) %!assert (max (toascii (a4(:))) >= toascii ("a")) %!assert (a5(:) == a6(:)); %% Test input validation %!error randsrc (1, 2, 3, 4, 5) %!error randsrc (1, 1, ones (3)) %!error randsrc (1, 1, [0 1 2; 0.5 0.5 0.5]) communications-1.2.1/inst/PaxHeaders.3802/symerr.m0000644000000000000000000000013212510010473016661 xustar0030 mtime=1428164923.934510386 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/symerr.m0000644000000000000000000001177712510010473017223 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{num}, @var{rate}] =} symerr (@var{a}, @var{b}) ## @deftypefnx {Function File} {[@var{num}, @var{rate}] =} symerr (@dots{}, @var{flag}) ## @deftypefnx {Function File} {[@var{num}, @var{rate} @var{ind}] =} symerr (@dots{}) ## ## Compares two matrices and returns the number of symbol errors and the ## symbol error rate. The variables @var{a} and @var{b} can be either: ## ## @table @asis ## @item Both matrices ## In this case both matrices must be the same size and then by default the ## return values @var{num} and @var{rate} are the overall number of symbol ## errors and the overall symbol error rate. ## @item One column vector ## In this case the column vector is used for symbol error comparison ## column-wise with the matrix. The returned values @var{num} and @var{rate} ## are then row vectors containing the number of symbol errors and the symbol ## error rate for each of the column-wise comparisons. The number of rows in ## the matrix must be the same as the length of the column vector ## @item One row vector ## In this case the row vector is used for symbol error comparison row-wise ## with the matrix. The returned values @var{num} and @var{rate} are then ## column vectors containing the number of symbol errors and the symbol error ## rate for each of the row-wise comparisons. The number of columns in the ## matrix must be the same as the length of the row vector ## @end table ## ## This behavior can be overridden with the variable @var{flag}. @var{flag} ## can take the value "column-wise", "row-wise" or "overall". A column-wise ## comparison is not possible with a row vector and visa-versa. ## @end deftypefn function [num, rate, ind] = symerr (a, b, _flag) if (nargin < 2 || nargin > 4) print_usage (); endif if (! (!any (isinf (a(:))) && !any (isnan (a(:))) && all (isreal (a(:))) && all (a(:) == fix (a(:))) && all (a(:) >= 0))) error ("symerr: all elements of A must be non-negative integers"); endif if (! (!any (isinf (b(:))) && !any (isnan (b(:))) && all (isreal (b(:))) && all (b(:) == fix (b(:))) && all (b(:) >= 0))) error ("symerr: all elements of B must be non-negative integers"); endif [ar, ac] = size (a); [br, bc] = size (b); if (ar == br && ac == bc) type = "matrix"; flag = "overall"; c = 1; elseif (any ([ar, br] == 1)) type = "row"; flag = "row"; if (ac != bc) error ("symerr: A and B must have the same number of columns for row-wise comparison"); endif if (ar == 1) a = ones (br, 1) * a; else b = ones (ar, 1) * b; endif elseif (any ([ac, bc] == 1)) type = "column"; flag = "column"; if (ar != br) error ("symerr: A and B must have the same number of rows for column-wise comparison"); endif if (ac == 1) a = a * ones (1, bc); else b = b * ones (1, ac); endif else error ("symerr: A and B must have the same size"); endif if (nargin > 2) if (ischar (_flag)) if (strcmp (_flag, "row-wise")) if (strcmp (type, "column")) error ("symerr: row-wise comparison not possible with column inputs"); endif flag = "row"; elseif (strcmp (_flag, "column-wise")) if (strcmp (type, "row")) error ("symerr: column-wise comparison not possible with row inputs"); endif flag = "column"; elseif (strcmp (_flag, "overall")) flag = "overall"; else error ("symerr: invalid option '%s'", _flag); endif else error ("symerr: FLAG must be a string"); endif endif ## Call the core error function to count the bit errors ind = (__errcore__ (a, b) != 0); switch (flag) case "row" if (strcmp (type, "matrix") && ac == 1) num = ind; else num = sum (ind')'; endif rate = num / max (ac, bc); case "column" if (strcmp (type, "matrix") && ar == 1) num = ind; else num = sum (ind); endif rate = num / max (ar, br); case "overall" num = sum (sum (ind)); rate = num / max (ar, br) / max (ac, bc); otherwise error ("symerr: invalid comparison type '%s'", flag); endswitch endfunction %% Test input validation %!error symerr () %!error symerr (1) %!error symerr (1, 2, 3, 4, 5) %!error symerr (1, 1, 1) %!error symerr (1, 1, "invalid") communications-1.2.1/inst/PaxHeaders.3802/modmap.m0000644000000000000000000000013212510010473016615 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/modmap.m0000644000000000000000000002473312510010473017153 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} modmap (@var{method}, @dots{}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "ask", @var{m}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "fsk", @var{m}, @var{tone}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "msk") ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "psk", @var{m}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask", @var{m}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask/cir", @var{nsig}, @var{amp}, @var{phs}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask/arb", @var{inphase}, @var{quadr}) ## @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask/arb", @var{map}) ## ## Mapping of a digital signal to an analog signal. With no output arguments ## @code{modmap} plots the constellation of the mapping. In this case the ## first argument must be the string @var{method} defining one of "ask", ## "fsk", "msk", "qask", "qask/cir" or "qask/arb". The arguments following ## the string @var{method} are generally the same as those after the ## corresponding string in the function call without output arguments. ## The exception is @code{modmap ("msk", @var{Fd})}. ## ## With an output argument, @var{y} is the complex mapped analog signal. In ## this case the arguments @var{x}, @var{fd} and @var{fs} are required. The ## variable @var{x} is the digital signal to be mapped, @var{fd} is the ## sampling rate of the of digital signal and the @var{fs} is the sampling ## rate of the analog signal. It is required that @code{@var{fs}/@var{fd}} ## is an integer. ## ## The available mapping of the digital signal are ## ## @table @asis ## @item "ask" ## Amplitude shift keying ## @item "fsk" ## Frequency shift keying ## @item "msk" ## Minimum shift keying ## @item "psk" ## Phase shift keying ## @item "qask" ## @itemx "qsk" ## @itemx "qam" ## Quadrature amplitude shift keying ## @end table ## ## In addition the "qask", "qsk" and "qam" method can be modified with the ## flags "/cir" or "/arb". That is "qask/cir" and "qask/arb", etc are valid ## methods and give circular- and arbitrary-qask mappings respectively. ## ## The additional argument @var{m} is the order of the modulation to use. ## @var{m} must be larger than the largest element of @var{x}. The variable ## @var{tone} is the FSK tone to use in the modulation. ## ## For "qask/cir", the additional arguments are the same as for ## @code{apkconst}, and you are referred to @code{apkconst} for the definitions ## of the additional variables. ## ## For "qask/arb", the additional arguments @var{inphase} and @var{quadr} give ## the in-phase and quadrature components of the mapping, in a similar mapping ## to the outputs of @code{qaskenco} with one argument. Similar @var{map} ## represents the in-phase and quadrature components of the mapping as ## the real and imaginary parts of the variable @var{map}. ## @seealso{demodmap, dmodce, amodce, apkconst, qaskenco} ## @end deftypefn function y = modmap (varargin) method = "sample"; if (nargout == 0) if (nargin < 1) error ("modmap: too few arguments"); endif method = varargin{1}; optarg = 1; M = 2; fd = 1; fs = 1; elseif (nargout == 1) if (nargin < 3) error ("modmap: too few arguments"); endif x = varargin{1}; fd = varargin{2}; fs = varargin{3}; if (nargin > 3) method = varargin{4}; endif M = max (2, 2^ceil (log2 (max (x(:)) + 1))); optarg = 4; if (!isscalar (fs) || !isscalar (fd) || !isreal (fs) || !isreal (fd) || ... (fs <= 0) || (fd <= 0)) error ("modmap: FD and FS must be positive real values"); endif if (abs (fs/fd - fix (fs/fd)) > eps) error ("modmap: FS must be an integer multiple of FD"); endif nn = round (fs/fd); if (min (size (x)) == 1) n = length (x); yy = zeros (n, 1); if (size (x, 1) == 1) yy = yy'; endif for i = 1:nn yy(i:nn:nn*n) = x; endfor else n = size (x, 1); yy = zeros (n*nn, size (x, 2)); for i = 1:nn yy(i:nn:nn*n,:) = x; endfor endif x = yy; else error ("modmap: too many output arguments"); endif if (!ischar (method)) error ("modmap: METHOD must be a string"); endif if (isempty (findstr (method, "/arb")) && isempty (findstr (method, "/cir"))) if (nargin > optarg) M = varargin{optarg+1}; if (! (isscalar (M) && isreal (M) && M == fix (M) && M >= 0)) error ("modmap: M must be a positive integer"); endif endif if (nargout != 0 && M < max (x(:)) + 1) error ("modmap: M must be greater than all elements of X"); endif endif if (strcmp (method, "ask")) if (nargin > optarg + 1) error ("modmap: too many arguments"); endif if (nargout == 0) if (M/2 == floor (M/2)) apkconst (2*ones (1, M/2), 2*([1:M/2]-0.5)/(M-1)); else apkconst ([1, 2*ones(1, floor (M/2))], 2*([0:floor(M/2)])/(M-1)); endif else if (M/2 == floor (M/2)) c = [-2*([M/2:-1:1]-0.5)/(M-1), 2*([1:M/2]-0.5)/(M-1)]; else c = [-2*([floor(M/2):-1:1])/(M-1), 0, 2*([1:floor(M/2)])/(M-1)]; endif y = c(x+1); if (size (x, 2) == 1) y = y'; endif endif elseif (strcmp (method, "psk")) if (nargin > optarg + 1) error ("modmap: too many arguments"); endif if (nargout == 0) apkconst (M, "n"); else c = apkconst (M); y = c(x+1); if (size (x, 2) == 1) y = y'; endif endif elseif (strcmp (method, "msk")) if (nargout == 0) if (nargin > optarg) fd = varargin{optarg+1}; if (!isscalar (fd)) error ("modmap: FD must be a scalar"); endif endif if (nargin > optarg + 1) error ("modmap: too many arguments"); endif ## This is an ugly plot, with little info. But hey!!! try stem ([0, fd], [2, 1]); catch error ("modmap: cannot find stem-plot function"); end_try_catch title ("MSK constellation"); xlabel ("Frequency (Hz)"); ylabel (""); axis ([-fd, 2*fd, 0, 2]); else if (nargin > optarg) error ("modmap: too many arguments"); endif tone = fd/2; y = tone * x; endif elseif (strcmp (method, "fsk")) if (nargin > optarg + 1) tone = varargin{optarg+2}; if (!isscalar (tone)) error ("modmap: TONE must be a scalar"); endif else tone = fd; endif if (nargin > optarg + 2) error ("modmap: too many arguments"); endif if (nargout == 0) ## This is an ugly plot, with little info. But hey!!! try stem ([0:tone:(M-1)*tone], [2, ones(1, M-1)]); catch error ("modmap: can not find stem-plot function"); end_try_catch title ("FSK constellation"); xlabel ("Frequency (Hz)"); ylabel (""); axis ([-tone, M*tone, 0, 2]); else y = tone * x; endif elseif ((strcmp (method, "qask")) || (strcmp (method, "qsk")) || ... (strcmp (method, "qam"))) if (nargin > optarg + 1) error ("modmap: too many arguments"); endif if (nargout == 0) qaskenco (M); else y = qaskenco (x, M); endif elseif ((strcmp (method, "qask/cir")) || (strcmp (method, "qsk/cir")) || ... (strcmp (method, "qam/cir"))) nsig = M; amp = []; phs = []; if (nargin > optarg) nsig = varargin{optarg+1}; if (!isvector (nsig) || sum (nsig) < M) error ("modmap: NSIG must be a vector of M constellation points for METHOD qask/cir"); endif endif if (nargin > optarg + 1) amp = varargin{optarg+2}; endif if (nargin > optarg + 2) phs = varargin{optarg+3}; endif if (nargout == 0) apkconst (nsig, amp, phs, "n"); else c = apkconst (nsig, amp, phs); y = c(x+1); if (size (x, 2) == 1) y = y'; endif endif elseif ((strcmp (method, "qask/arb")) || (strcmp (method, "qsk/arb")) || ... (strcmp (method, "qam/arb"))) if (nargin == optarg) [inphase, quadr] = qaskenco (M); elseif (nargin == optarg+1) c = varargin{optarg+1}; inphase = real (c); quadr = imag (c); elseif (nargin == optarg+2) inphase = varargin{optarg+1}; quadr = varargin{optarg+2}; else error ("modmap: too many arguments"); endif if (!isreal (inphase) || !isreal (quadr) || !isvector (inphase) || ... !isvector (quadr) || !all (isfinite (inphase)) || ... !all (isfinite (quadr)) || (length (inphase) < M)) error ("modmap: invalid mapping for METHOD qask/arb"); endif if (nargout == 0) inphase = inphase(:); quadr = quadr(:); plot (inphase, quadr, "+r"); title ("QASK Constellation"); xlabel ("In-phase"); ylabel ("Quadrature"); axis ([min(inphase) - 1, max(inphase) + 1, min(quadr) - 1, max(quadr) + 1]); xd = 0.02 * max (inphase); if (nargin == 2) msg = msg(:); for i = 1:length (inphase) text (inphase(i)+xd, quadr(i), num2str (msg(i))); endfor else for i = 1:length (inphase) text (inphase(i)+xd, quadr(i), num2str (i-1)); endfor endif refresh; else y = inphase(x+1) + 1i * quadr(x+1); if (size (x, 2) == 1) y = y'; endif endif elseif (strcmp (method, "sample")) if (nargout == 0) error ("modmap: no constellation for resampling"); endif ## Just for resampling !!! So don't need anything else here y = x; else error ("modmap: invalid mapping METHOD '%s'", method); endif endfunction %% Test input validation %!error modmap () %!error modmap (1, 0, 0) communications-1.2.1/inst/PaxHeaders.3802/cosets.m0000644000000000000000000000013212510010473016640 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/cosets.m0000644000000000000000000000321112510010473017162 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} cosets (@var{m}, @var{prim}) ## ## Finds the elements of GF(2^@var{m}) with primitive polynomial @var{prim}, ## that share the same minimum polynomial. Returns a cell array of the ## partitioning of GF(2^@var{m}). ## @end deftypefn function c = cosets (m, prim) if (nargin == 1) prim = 0; ## This flags to use default primitive elseif (nargin != 2) print_usage (); endif n = 2^m-1; found = zeros (1, n); c{1} = gf (1, m, prim); found(1) = 1; nc = 2; f = log (gf (1:n, m, prim)); while (!all (found)) t = find (!found); idx = f(t(find (f(t) == min (f(t).x)))).x; set = idx; r = rem (idx*2, n); while (r > idx) set = [set, r]; r = rem (r*2, n); endwhile c{nc} = gf (sort (exp (gf (set, m, prim)).x), m, prim); found(c{nc}.x) = ones (1, length (c{nc})); nc = nc + 1; endwhile endfunction %% Test input validation %!error cosets () %!error cosets (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/matdeintrlv.m0000644000000000000000000000013112510010473017670 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/matdeintrlv.m0000644000000000000000000000236112510010473020220 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{intrlvd} =} matdeintrlv (@var{data}, @var{nrows}, @var{ncols}) ## Restore elements of @var{data} with a temporary matrix of size ## @var{nrows}-by-@var{ncols}. ## @seealso{matintrlv} ## @end deftypefn function intrlvd = matdeintrlv (data, Nrows, Ncols) if (nargin != 3) print_usage (); endif intrlvd = matintrlv (data, Ncols, Nrows); endfunction %% Test input validation %!error matdeintrlv () %!error matdeintrlv (1) %!error matdeintrlv (1, 2) %!error matdeintrlv (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/shannonfanoenco.m0000644000000000000000000000013212510010473020515 xustar0030 mtime=1428164923.934510386 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/shannonfanoenco.m0000644000000000000000000000372712510010473021053 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} shannonfanoenco (@var{hcode}, @var{dict}) ## ## Returns the Shannon-Fano encoded signal using @var{dict}. ## This function uses a @var{dict} built from the @code{shannonfanodict} ## and uses it to encode a signal list into a Shannon-Fano code. ## Restrictions include a signal set that strictly belongs in the ## @code{range [1,N]} with @code{N = length (dict)}. Also dict can only be ## from the @code{shannonfanodict} routine. ## An example use of @code{shannonfanoenco} is ## ## @example ## @group ## hd = shannonfanodict (1:4, [0.5 0.25 0.15 0.10]); ## shannonfanoenco (1:4, hd) ## @result{} [0 1 0 1 1 0 1 1 1 0] ## @end group ## @end example ## @seealso{shannonfanodeco, shannonfanodict} ## @end deftypefn function sf_code = shannonfanoenco (sig, dict) if (nargin != 2) print_usage (); endif if (max (sig) > length (dict) || min (sig) < 1) error ("shannonfanoenco: all elements of SIG must be in the range [1,N]"); endif sf_code = [dict{sig}]; endfunction %!assert (shannonfanoenco (1:4, shannonfanodict (1:4, [0.5 0.25 0.15 0.10])), [0 1 0 1 1 0 1 1 1 0], 0) %% Test input validation %!error shannonfanoenco () %!error shannonfanoenco (1) %!error shannonfanoenco (1, 2, 3) %!error shannonfanoenco (1, {}) communications-1.2.1/inst/PaxHeaders.3802/demodmap.m0000644000000000000000000000013212510010473017126 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/demodmap.m0000644000000000000000000002063512510010473017461 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "ask", @var{m}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "fsk", @var{m}, @var{tone}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "msk") ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "psk", @var{m}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask", @var{m}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask/cir", @var{nsig}, @var{amp}, @var{phs}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask/arb", @var{inphase}, @var{quadr}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask/arb", @var{map}) ## @deftypefnx {Function File} {z =} demodmap (@var{y}, [@var{fd}, @var{off}], @dots{}) ## ## Demapping of an analog signal to a digital signal. The function ## @code{demodmap} must have at least three input arguments and one output ## argument. Argument @var{y} is a complex variable representing the analog ## signal to be demapped. The variables @var{fd} and @var{fs} are the ## sampling rate of the of digital signal and the sampling rate of the ## analog signal respectively. It is required that @code{@var{fs}/@var{fd}} ## is an integer. ## ## The available mapping of the digital signal are ## ## @table @asis ## @item "ask" ## Amplitude shift keying ## @item "fsk" ## Frequency shift keying ## @item "msk" ## Minimum shift keying ## @item "psk" ## Phase shift keying ## @item "qask" ## @itemx "qsk" ## @itemx "qam" ## Quadrature amplitude shift keying ## @end table ## ## In addition the "qask", "qsk" and "qam" method can be modified with the ## flags "/cir" or "/arb". That is "qask/cir" and "qask/arb", etc are valid ## methods and give circular- and arbitrary-qask mappings respectively. Also ## the method "fsk" and "msk" can be modified with the flag "/max", in which ## case @var{y} is assumed to be a matrix with @var{m} columns, representing ## the symbol correlations. ## ## The variable @var{m} is the order of the modulation to use. By default ## this is 2, and in general should be specified. ## ## For "qask/cir", the additional arguments are the same as for ## @code{apkconst}, and you are referred to @code{apkconst} for the definitions ## of the additional variables. ## ## For "qask/arb", the additional arguments @var{inphase} and @var{quadr} give ## the in-phase and quadrature components of the mapping, in a similar mapping ## to the outputs of @code{qaskenco} with one argument. Similar @var{map} ## represents the in-phase and quadrature components of the mapping as ## the real and imaginary parts of the variable @var{map}. ## @seealso{modmap, ddemodce, ademodce, apkconst, qaskenco} ## @end deftypefn function z = demodmap (y, fd, fs, varargin) if (nargin < 3) print_usage (); endif if (!isscalar (fs) || !isreal (fs) || !isreal (fd) || fs <= 0 || fd <= 0) error ("demodmap: FD and FS must be positive real values"); endif if (abs (fs/fd - fix (fs/fd)) > eps) error ("demodmap: FS must be an integer multiple of FD"); endif if (!isscalar (fd)) if (isequal (size (fd), [1, 2])) off = fd(2); fd = fd(1); else error ("demodmap: FD must be a scalar or a 2-element vector"); endif else off = 0; endif if (nargin > 3) method = varargin{1}; if (!ischar (method) || (!strcmp (method, "ask") && ... isempty (findstr (method, "msk")) && isempty (findstr (method, "fsk")) && ... isempty (findstr (method, "samp")) && !strcmp (method, "psk") && ... !strcmp (method, "qask") && !strcmp (method, "qam") && ... !strcmp (method, "qsk") && !strcmp (method, "qask/cir") && ... !strcmp (method, "qam/cir") && !strcmp (method, "qsk/cir") && ... !strcmp (method, "qask/arb") && !strcmp (method, "qam/arb") && ... !strcmp (method, "qsk/arb"))) error ("demodmap: invalid mapping METHOD '%s'", method); endif else method = "sample"; endif if (! (isreal (off) && off == fix (off) && off >= 0 && off < fs/fd)) error ("demodmap: OFF must be an integer in the range [0,FS/FD)"); endif if (off == 0) off = round (fs/fd); endif if (min (size (y)) == 1) y = y(off:round (fs/fd):length (y)); else y = y(off:round (fs/fd):size (y, 1),:); endif if (strcmp (method, "ask") || !isempty (findstr (method, "fsk")) || ... strcmp (method, "psk") || strcmp (method, "qask") || ... strcmp (method, "qam") || strcmp (method, "qsk")) if (nargin > 4) M = varargin{2}; else M = 2; endif if (!isempty (findstr (method, "fsk")) && (nargin > 5)) error ("demodmap: too many arguments"); endif endif z = []; if (!isempty (findstr (method, "fsk")) || !isempty (findstr (method, "msk"))) if (findstr (method, "msk")) if (nargin > 4) error ("demodmap: too many arguments"); endif M = 2; tone = fd/2; else if (nargin > 5) tone = varargin{3}; else tone = fd; endif if (nargin > 6) error ("demodmap: too many arguments"); endif endif if (findstr (method, "/max")) if (size (y, 2) != M) error ("demodmap: Y must be a matrix with M columns for METHOD */max"); endif ## We have an M-column maximum from which with pick index of the maximum ## value in each row as the decoded value [a, b] = max (y'); z = (b - 1)'; else c = [0:M-1]*tone; endif elseif (strcmp (method, "ask")) if (M/2 == floor (M/2)) c = [ -2*([M/2:-1:1]-0.5)/(M-1), 2*([1:M/2]-0.5)/(M-1)]; else c = [ -2*([floor(M/2):-1:1])/(M-1), 0, 2*([1:floor(M/2)])/(M-1)]; endif elseif (strcmp (method, "psk")) c = apkconst (M, [], []); elseif (!isempty (findstr (method, "qask")) || ... !isempty (findstr (method, "qsk")) || ... !isempty (findstr (method, "qam"))) if (findstr (method, "/cir")) nsig = 2; amp = []; phs = []; if (nargin > 4) nsig = varargin{2}; if (!isvector (nsig)) error ("demodmap: NSIG must be a vector of constellation points for METHOD qask/cir"); endif endif if (nargin > 5) amp = varargin{3}; endif if (nargin > 6) phs = varargin{4}; endif c = apkconst (nsig, amp, phs); M = length (c); elseif (findstr (method, "/arb")) if (nargin == 4) c = qaskenco (2); elseif (nargin == 5) c = varargin{2}; elseif (nargin == 6) inphase = varargin{2}; quadr = varargin{3}; c = inphase + 1i*quadr; elseif (nargin > 6) error ("demodmap: too many arguments"); endif M = length (c); else ## Could do "c = qaskenco (M)", but qaskdeco's speed is not dependent ## on M, while speed of code below is O(M). z = qaskdeco (y, M); endif endif ## Have we decoded yet? If not have a mapping that we can use. if (isempty (z)) c = c(:); z = zeros (size (y)); if (size (y, 1) == 1) [a, b] = min (abs (repmat (y(:).', M, 1) - repmat (c, 1, size (y, 2)))); z = b - 1; elseif (size (y, 1) == 1) [a, b] = min (abs (repmat (y(:), M, 1) - repmat (c, 1, size (y, 1)))); z = (b - 1).'; else for i = 1:size (y, 1) [a, b] = min (abs (repmat (y(i,:), M, 1) - repmat (c, 1, size (y, 2)))); z(i,:) = b - 1; endfor endif endif endfunction %% Test input validation %!error demodmap () %!error demodmap (1) %!error demodmap (1, 2) %!error demodmap (1, 2, 3, "invalid") communications-1.2.1/inst/PaxHeaders.3802/amdemod.m0000644000000000000000000000013212510010473016746 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/amdemod.m0000644000000000000000000000246312510010473017300 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{m} =} amdemod (@var{s}, @var{fc}, @var{fs}) ## Compute the amplitude demodulation of the signal @var{s} with a carrier ## frequency of @var{fc} and a sample frequency of @var{fs}. ## @seealso{ammod} ## @end deftypefn function m = amdemod (s, fc, fs) if (nargin != 3) print_usage (); endif t = 0:1./fs:(length (s) - 1)./fs; e = s .* cos (2.*pi.*fc.*t); [b a] = butter (5, fc.*2./fs); m = filtfilt (b, a, e).*2; endfunction %% Test input validation %!error amdemod () %!error amdemod (1) %!error amdemod (1, 2) %!error amdemod (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/deintrlv.m0000644000000000000000000000013212510010473017167 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/deintrlv.m0000644000000000000000000000333312510010473017516 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{deintrlvd} =} deintrlv (@var{data}, @var{elements}) ## Restore elements of @var{data} according to @var{elements}. ## @seealso{intrlv} ## @end deftypefn function deintrlvd = deintrlv (data, elements) if (nargin != 2) print_usage (); endif if (!isvector (elements)) error ("deintrlv: ELEMENTS must be a vector"); endif ind = 1:length (elements); invperm(elements) = ind; if (isvector (data)) if (length (elements) != length (data) || any (sort (elements) != 1:length (data))) error ("deintrlv: ELEMENTS must be a permutation of DATA indices"); endif deintrlvd = data(invperm); else if (length (elements) != size (data, 1) || any (sort (elements) != 1:size (data, 1))) error ("deintrlv: ELEMENTS must be a permutation of DATA indices"); endif deintrlvd = data(invperm,:); endif endfunction %% Test input validation %!error deintrlv () %!error deintrlv (1) %!error deintrlv (1, 2, 3) %!error deintrlv ([0 0], [2 3]) communications-1.2.1/inst/PaxHeaders.3802/huffmanenco.m0000644000000000000000000000013112510010473017630 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/huffmanenco.m0000644000000000000000000000370112510010473020157 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} huffmanenco (@var{sig}, @var{dict}) ## ## Returns the Huffman encoded signal using @var{dict}. This function uses ## a @var{dict} built from the @code{huffmandict} and uses it to encode a ## signal list into a Huffman list. A restrictions is that a signal set must ## strictly belong in the range @code{[1,N]} with @code{N = length (dict)}. ## Also @var{dict} can only be from the @code{huffmandict} routine. ## An example of the use of @code{huffmanenco} is ## ## @example ## @group ## hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]); ## huffmanenco (1:4, hd) ## @result{} [1 0 1 0 0 0 0 0 1] ## @end group ## @end example ## @seealso{huffmandict, huffmandeco} ## @end deftypefn function hcode = huffmanenco (sig, dict) if (nargin != 2 || ! iscell (dict)) print_usage (); elseif (max (sig) > length (dict) || min (sig) < 1) error ("huffmanenco: all elements of SIG must be integers in the range [1,N]"); endif hcode = [dict{sig}]; endfunction %!assert (huffmanenco (1:4, huffmandict (1:4, [0.5 0.25 0.15 0.10])), [1 0 1 0 0 0 0 0 1], 0) %% Test input validation %!error huffmanenco () %!error huffmanenco (1) %!error huffmanenco (1, 2) %!error huffmanenco (1, 2, 3) %!error huffmanenco (1, {}) communications-1.2.1/inst/PaxHeaders.3802/egolaygen.m0000644000000000000000000000013212510010473017312 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/egolaygen.m0000644000000000000000000000335612510010473017646 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{G}, @var{P}] =} egolaygen () ## Extended Golay code generator matrix. ## ## Returns @var{G}, the Extended Golay code (24,12) generator matrix, ## which can correct up to 3 errors. @var{P} is the parity ## check matrix, for this code. ## ## @seealso{egolaydec, egolayenc} ## @end deftypefn function [G, P] = egolaygen () if (nargin != 0) print_usage (); endif I = eye (12); P = [1 0 0 0 1 1 1 0 1 1 0 1; 0 0 0 1 1 1 0 1 1 0 1 1; 0 0 1 1 1 0 1 1 0 1 0 1; 0 1 1 1 0 1 1 0 1 0 0 1; 1 1 1 0 1 1 0 1 0 0 0 1; 1 1 0 1 1 0 1 0 0 0 1 1; 1 0 1 1 0 1 0 0 0 1 1 1; 0 1 1 0 1 0 0 0 1 1 1 1; 1 1 0 1 0 0 0 1 1 1 0 1; 1 0 1 0 0 0 1 1 1 0 1 1; 0 1 0 0 0 1 1 1 0 1 1 1; 1 1 1 1 1 1 1 1 1 1 1 0;]; G = [P I]; # generator. endfunction %!test %! g = egolaygen (); %! assert (size (g), [12, 24]) %! assert (g(:,13:end), eye (12)) %! assert (sum (g(:,1:12)), [7*ones(1, 11), 11]) %% Test input validation %!error egolaygen (1) communications-1.2.1/inst/PaxHeaders.3802/awgn.m0000644000000000000000000000013212510010473016274 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/awgn.m0000644000000000000000000001031412510010473016620 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} awgn (@var{x}, @var{snr}) ## @deftypefnx {Function File} {@var{y} =} awgn (@var{x}, @var{snr}, @var{pwr}) ## @deftypefnx {Function File} {@var{y} =} awgn (@var{x}, @var{snr}, @var{pwr}, @var{seed}) ## @deftypefnx {Function File} {@var{y} =} awgn (@dots{}, @var{type}) ## ## Add white Gaussian noise to a voltage signal. ## ## The input @var{x} is assumed to be a real or complex voltage signal. The ## returned value @var{y} will be the same form and size as @var{x} but with ## Gaussian noise added. Unless the power is specified in @var{pwr}, the ## signal power is assumed to be 0dBW, and the noise of @var{snr} dB will be ## added with respect to this. If @var{pwr} is a numeric value then the signal ## @var{x} is assumed to be @var{pwr} dBW, otherwise if @var{pwr} is ## "measured", then the power in the signal will be measured and the noise ## added relative to this measured power. ## ## If @var{seed} is specified, then the random number generator seed is ## initialized with this value ## ## By default the @var{snr} and @var{pwr} are assumed to be in dB and dBW ## respectively. This default behavior can be chosen with @var{type} ## set to "dB". In the case where @var{type} is set to "linear", @var{pwr} ## is assumed to be in Watts and @var{snr} is a ratio. ## @seealso{randn, wgn} ## @end deftypefn function y = awgn (x, snr, varargin) if (nargin < 2 || nargin > 5) print_usage (); endif [m, n] = size (x); if (isreal (x)) out = "real"; else out = "complex"; endif p = 0; seed = []; type = "dB"; meas = 0; narg = 0; for i = 1:length (varargin) arg = varargin{i}; if (ischar (arg)) if (strcmp (arg, "measured")) meas = 1; elseif (strcmp (arg, "dB")) type = "dB"; elseif (strcmp (arg, "linear")) type = "linear"; else error ("awgn: invalid argument '%s'", arg); endif else narg++; switch (narg) case 1 p = arg; case 2 seed = arg; otherwise error ("awgn: too many arguments"); endswitch endif endfor if (isempty (p)) p = 0; endif if (!isempty (seed)) if (! (isscalar (seed) && isreal (seed) && seed >= 0 && seed == fix (seed))) error ("awgn: random SEED must be an integer"); endif endif if (!isscalar (p) || !isreal (p)) error ("awgn: PWR must be a scalar"); endif if (strcmp (type, "linear") && p < 0) error ("awgn: PWR must be a non-negative scalar for TYPE \"linear\""); endif if (!isscalar (snr) || !isreal (snr)) error ("awgn: SNR must be a scalar"); endif if (strcmp (type, "linear") && snr < 0) error ("awgn: SNR must be a non-negative scalar for TYPE \"linear\""); endif if (!isempty (seed)) randn ("state", seed); endif if (meas == 1) p = sum (abs (x(:)) .^ 2) / length (x(:)); if (strcmp (type, "dB")) p = 10 * log10 (p); endif endif if (strcmp (type, "linear")) np = p / snr; else np = p - snr; endif y = x + wgn (m, n, np, 1, seed, type, out); endfunction %!shared x, y, noisy %! x = [0:0.01:2*pi]; y = sin (x); %! noisy = awgn (y, 20, "dB", "measured"); ## Test of noisy is pretty arbitrary, but should pickup most errors %!assert (isreal (noisy)); %!assert (iscomplex (awgn (y + 1i, 20, "dB", "measured"))); %!assert (size (y) == size (noisy)) %!assert (abs (10*log10 (mean (y.^2)/mean ((y-noisy).^ 2)) - 20) < 1); %% Test input validation %!error awgn (); %!error awgn (1); %!error awgn (1, 1, 1, 1, 1); communications-1.2.1/inst/PaxHeaders.3802/randint.m0000644000000000000000000000013112510010473016776 xustar0029 mtime=1428164923.91851075 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/randint.m0000644000000000000000000000635612510010473017336 0ustar00rootroot00000000000000## Copyright (C) 2001 Laurent Mazet ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} =} randint (@var{n}) ## @deftypefnx {Function File} {@var{b} =} randint (@var{n}, @var{m}) ## @deftypefnx {Function File} {@var{b} =} randint (@var{n}, @var{m}, @var{range}) ## @deftypefnx {Function File} {@var{b} =} randint (@var{n}, @var{m}, @var{range}, @var{seed}) ## ## Generate a matrix of random binary numbers. The size of the matrix is ## @var{n} rows by @var{m} columns. By default @var{m} is equal to @var{n}. ## ## The range in which the integers are generated will is determined by ## the variable @var{range}. If @var{range} is an integer, the value will ## lie in the range [0,@var{range}-1], or [@var{range}+1,0] if @var{range} ## is negative. If @var{range} contains two elements the integers will lie ## within these two elements, inclusive. By default @var{range} is ## assumed to be [0:1]. ## ## The variable @var{seed} allows the random number generator to be seeded ## with a fixed value. The initial seed will be restored when returning. ## @end deftypefn function b = randint (n, m, range, seed) switch (nargin) case 1 m = n; range = [0, 1]; seed = Inf; case 2 range = [0, 1]; seed = Inf; case 3 seed = Inf; case 4 otherwise print_usage (); endswitch ## Check range if (length (range) == 1) if (range < 0) range = [range+1, 0]; else range = [0, range-1]; endif elseif ( prod (size (range)) != 2) error ("randint: RANGE must be a scalar or a 2-element vector"); endif range = sort (range); ## Check seed; if (!isinf (seed)) old_seed = rand ("seed"); rand ("seed", seed); endif b = range (1) - 1 + ceil (rand (n, m) * (range (2) - range (1) + 1)); ## Get back to the old if (!isinf (seed)) rand ("seed", old_seed); endif endfunction %!shared n, m, seed, a1, a2, a3, a4, a5, a6 %! n = 10; m = 32; seed = 1; a1 = randint (n); a2 = randint (n, n); %! a3 = randint (n, n, m); a4 = randint (n, n, [-m, m]); %! a5 = randint (n, n, m, seed); a6 = randint (n, n, m, seed); %!error randint (); %!error randint (n, n, n, n, n); %!assert (size (a1) == [n, n] && size (a2) == [n, n]); %!assert (max ([a1(:); a2(:)]) <= 1 && min ([a1(:); a2(:)]) >= 0); %!assert (size (a3) == [n, n] && size (a4) == [n, n]); %!assert (max (a3(:)) < m && min (a3(:)) >= 0); %!assert (max (a4(:)) <= m && min (a4(:)) >= -m); %!assert (a5(:) == a6(:)); %!test %! a = randint (10, 10, -32); %! assert (max (a(:)) <= 0 && min (a(:)) > -32); %% Test input validation %!error randint (1, 2, 3, 4, 5) %!error randint (1, 1, [1 2 3]) communications-1.2.1/inst/PaxHeaders.3802/matintrlv.m0000644000000000000000000000013112510010473017357 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/matintrlv.m0000644000000000000000000000363012510010473017707 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{intrlvd} =} matintrlv (@var{data}, @var{nrows}, @var{ncols}) ## Interleaved elements of @var{data} with a temporary matrix of size ## @var{nrows}-by-@var{ncols}. ## @seealso{matdeintrlv} ## @end deftypefn function intrlvd = matintrlv (data, Nrows, Ncols) if (nargin != 3) print_usage (); endif if (! (isscalar (Nrows) && Nrows == fix (Nrows))) error ("matintrlv: NROWS must be an integer"); endif if (! (isscalar (Ncols) && Ncols == fix (Ncols))) error ("matintrlv: NCOLS must be an integer"); endif s = size (data); if (isvector (data)) if (length (data) != Nrows*Ncols) error ("matintrlv: DATA must be a vector of length NCOLS*NROWS"); endif data = reshape (data, Ncols, Nrows)'; intrlvd = reshape (data, s); else for k = 1:s(2); if (length (data) != Nrows*Ncols) error ("matintrlv: DATA must have NCOLS*NROWS rows"); endif tmp(:,:,k) = reshape (data(:,k), Ncols, Nrows)'; intrlvd(:,k) = reshape (tmp(:,:,k), s(1), 1); endfor endif endfunction %% Test input validation %!error matintrlv () %!error matintrlv (1) %!error matintrlv (1, 2) %!error matintrlv (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/qaskdeco.m0000644000000000000000000000013212510010473017132 xustar0030 mtime=1428164923.886511478 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/qaskdeco.m0000644000000000000000000001705712510010473017471 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{msg} =} qaskdeco (@var{c}, @var{m}) ## @deftypefnx {Function File} {@var{msg} =} qaskdeco (@var{inphase}, @var{quadr}, @var{m}) ## @deftypefnx {Function File} {@var{msg} =} qaskdeco (@dots{}, @var{mnmx}) ## ## Demaps an analog signal using a square QASK constellation. The input signal ## maybe either a complex variable @var{c}, or as two real variables ## @var{inphase} and @var{quadr} representing the in-phase and quadrature ## components of the signal. ## ## The argument @var{m} must be a positive integer power of 2. By default the ## same constellation as created in @code{qaskenco} is used by @code{qaskdeco}. ## If is possible to change the values of the minimum and maximum of the ## in-phase and quadrature components of the constellation to account for ## linear changes in the signal values in the received signal. The variable ## @var{mnmx} is a 2-by-2 matrix of the following form ## ## @multitable @columnfractions 0.125 0.05 0.25 0.05 0.25 0.05 ## @item @tab | @tab min in-phase @tab , @tab max in-phase @tab | ## @item @tab | @tab min quadrature @tab , @tab max quadrature @tab | ## @end multitable ## ## If @code{sqrt (@var{m})} is an integer, then @code{qaskenco} uses a Gray ## mapping. Otherwise, an attempt is made to create a nearly square mapping ## with a minimum Hamming distance between adjacent constellation points. ## @seealso{qaskenco} ## @end deftypefn function a = qaskdeco (varargin) have_mnmx = 0; if (nargin == 2) c = varargin{1}; inphase = real (c); quadr = imag (c); M = varargin{2}; elseif (nargin == 3) if (all (size (varargin{3}) == [2 2])) c = varargin{1}; inphase = real (c); quadr = imag (c); M = varargin{2}; mnmx = varargin{3}; have_mnmx = 1; else inphase = varargin{1}; quadr = varargin{2}; M = varargin{3}; endif elseif (nargin == 4) inphase = varargin{1}; quadr = varargin{2}; M = varargin{3}; mnmx = varargin{4}; have_mnmx = 1; else print_usage (); endif if (iscomplex (inphase) || iscomplex (quadr)) error ("qaskdeco: INPHASE and QUADR must be real"); endif if (!isscalar (M) || M != ceil (M) || M < 2) error ("qaskdeco: M must be a positive integer greater than 2"); endif if (log2 (M) != ceil (log2 (M))) error ("qaskdeco: M must be a power of 2"); endif if (have_mnmx) if (any (size (mnmx) != [2 2])) error ("qaskdeco: MNMX must be a 2-by-2 matrix of min and max values"); endif else if ((M == 2) || (M == 4)) mnmx = [-1, 1; -1, 1]; elseif (M == 8) mnmx = [-3, 3; -1, 1]; elseif (sqrt (M) == fix (sqrt (M))) NC = 2^floor (log2 (sqrt (M))); mnmx = [-NC+1, NC-1; -NC+1, NC-1]; else NC = 2^floor (log2 (sqrt (M))) + 2*sqrt (M/32); mnmx = [-NC+1, NC-1; -NC+1, NC-1]; endif endif if (M == 2) layout = [0, 1]'; elseif (M == 4) layout = [0, 1; 2, 3]; elseif (M == 8) layout = [4, 5; 0, 1; 2, 3; 6, 7]; else NC = 2^floor (log2 (sqrt (M))); MM = NC * NC; Gray = [0 1]; for i = 2:ceil (log2 (NC)) Gray = [Gray 2^(i-1) + fliplr(Gray)]; endfor Gray = fliplr (de2bi (shift (Gray, length (Gray)/2 - 1))); Gray2 = zeros (MM, log2 (MM)); Gray2(:,1:2:log2 (MM)) = repmat (Gray, NC, 1); for i = 1:NC Gray2(i:NC:MM,2:2:log2 (MM)) = Gray; endfor layout = reshape (bi2de (fliplr (Gray2)), NC, NC); if (MM != M) ## Not sure this is the best that can be done for these mappings. If ## anyone wants to improve this, go ahead, but do it in qaskenco too. OFF = sqrt (M/32); NR = NC + 2*OFF; layout2 = NaN * ones (NR); layout2(1+OFF:OFF+NC,1+OFF:OFF+NC) = layout; layout2(1:OFF,1+OFF:OFF+NC) = MM + layout(OFF:-1:1,:); layout2(NR-OFF+1:NR,1+OFF:OFF+NC) = MM + layout(NC:-1:NC-OFF+1,:); layout2(1+2*OFF:NC,1:OFF) = MM + layout(OFF+1:NC-OFF,OFF:-1:1); layout2(1+2*OFF:NC,NR-OFF+1:NR) = MM + ... layout(OFF+1:NC-OFF,NC:-1:NC-OFF+1); layout2(1+OFF:2*OFF,1:OFF) = MM + ... layout(NC/2:-1:NC/2-OFF+1,NC/2:-1:OFF+1); layout2(NC+1:OFF+NC,1:OFF) = MM + ... layout(NC-OFF:-1:NC/2+1,NC/2:-1:OFF+1); layout2(1+OFF:2*OFF,NR-OFF+1:NR) = MM + ... layout(NC/2:-1:NC/2-OFF+1,NC-OFF:-1:NC/2+1); layout2(NC+1:OFF+NC,NR-OFF+1:NR) = MM + ... layout(NC-OFF:-1:NC/2+1,NC-OFF:-1:NC/2+1); layout = layout2; endif endif ix = 1 + (inphase - mnmx(1,1)) / (mnmx(1,2)-mnmx(1,1)) * (size (layout, 1) - 1); qx = 1 + (quadr - mnmx(2,1)) / (mnmx(2,2)-mnmx(2,1)) * (size (layout, 2) - 1); try wfi = warning ("off", "Octave:fortran-indexing"); catch wfi = 0; end_try_catch unwind_protect a = layout(size (layout, 1) * (max (min (round (qx), size (layout, 2)), 1) - 1) + ... max (min (round (ix), size (layout, 1)), 1)); ## FIXME: Why is this necessary?? if ((M == 2) && (size (inphase, 1) == 1)) a = a'; endif if (any (isnan (a(:)))) ## We have a non-square constellation, with some invalid points. ## Map to nearest valid constellation points... indx = find (isnan (a(:))); ix = ix(indx); qx = qx(indx); ang = atan2 (quadr(indx), inphase(indx)); qx(find (ang > 3*pi/4)) = NR-OFF; ix(find ((ang <= 3*pi/4) & (ang > pi/2))) = OFF+1; ix(find ((ang <= pi/2) & (ang > pi/4))) = NR - OFF; qx(find ((ang <= pi/4) & (ang > 0))) = NR - OFF; qx(find ((ang <= 0) & (ang > -pi/4))) = OFF+1; ix(find ((ang <= -pi/4) & (ang > -pi/2))) = NR - OFF; ix(find ((ang <= -pi/2) & (ang > -3*pi/4))) = OFF+1; qx(find (ang <= -3*pi/4)) = OFF+1; a(indx) = layout(size (layout, 1) * (max (min (round (qx), ... size (layout, 2)), 1)-1) + max (min (round (ix), size (layout, 1)), 1)); endif unwind_protect_cleanup warning (wfi); end_unwind_protect endfunction %!function dec = __fntestqask1__ (msg, m) %! [inp, qudr] = qaskenco (msg, m); %! dec = qaskdeco (inp, qudr, m); %!function __fntestqask2__ (m, dims) %! msg = floor (rand (dims) * m); %! assert (__fntestqask1__ (msg, m), msg); %!test __fntestqask2__ (2, [100, 100]) %!test __fntestqask2__ (4, [100, 100]) %!test __fntestqask2__ (8, [100, 100]) %!test __fntestqask2__ (16, [100, 100]) %!test __fntestqask2__ (32, [100, 100]) %!test __fntestqask2__ (64, [100, 100]) %!test __fntestqask2__ (2, [100, 100, 3]) %!test __fntestqask2__ (4, [100, 100, 3]) %!test __fntestqask2__ (8, [100, 100, 3]) %!test __fntestqask2__ (16, [100, 100, 3]) %!test __fntestqask2__ (32, [100, 100, 3]) %!test __fntestqask2__ (64, [100, 100, 3]) %% Test input validation %!error qaskdeco () %!error qaskdeco (1) %!error qaskdeco (1, 2, 3, 4, 5) %!error qaskdeco (1, 1) %!error qaskdeco (1, 5) communications-1.2.1/inst/PaxHeaders.3802/reedmullerdec.m0000644000000000000000000000013112510010473020153 xustar0029 mtime=1428164923.91851075 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/reedmullerdec.m0000644000000000000000000001607412510010473020511 0ustar00rootroot00000000000000## Copyright (C) 2007, 2011 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} reedmullerdec (@var{VV}, @var{G}, @var{R}, @var{M}) ## ## Decode the received code word @var{VV} using the RM-generator matrix @var{G}, ## of order @var{R}, @var{M}, returning the code-word C. We use the standard ## majority logic vote method due to Irving S. Reed. The received word has to be ## a matrix of column size equal to to code-word size (i.e @math{2^m}). Each row ## is treated as a separate received word. ## ## The second return value is the message @var{M} got from @var{C}. ## ## G is obtained from definition type construction of Reed-Muller code, ## of order @var{R}, length @math{2^M}. Use the function reedmullergen, ## for the generator matrix for the (@var{R},@var{M}) order RM code. ## ## Faster code constructions (also easier) exist, but since ## finding permutation order of the basis vectors, is important, we ## stick with the standard definitions. To use decoder ## function reedmullerdec, you need to use this specific ## generator function. ## ## see: Lin & Costello, Ch.4, "Error Control Coding", 2nd Ed, Pearson. ## ## @example ## @group ## g = reedmullergen (2, 4); ## msg = rand (1, 11) > 0.5; ## c = mod (msg * g, 2); ## [dec_c, dec_m] = reedmullerdec (c, g, 2, 4) ## @end group ## @end example ## @seealso{reedmullergen, reedmullerenc} ## @end deftypefn ## FIXME: make possible to use different generators, if permutation ## matrix (i.e polynomial vector elements of rows of G are given function [C, CMM] = reedmullerdec (VV, G, R, M) if (nargin != 4) print_usage (); endif ## we do a R+1 level majority logic decoding. ## at each order of polynomial modifying the code-word. U = 0:M-1; # allowed basis vectors in V2^M. C = -1 * ones (size (VV)); # preset the output word. [Rows, Cols] = size (G); # rows shadows rows() ## first get the row index of G & its corresponding permutation ## elements. P{1} = [0]; for idx = 1:M P{idx+1} = idx; endfor idx = idx + 1; Ufull = 1:M; r = 2; while (r <= R) TMP = nchoosek (Ufull, r); for idy = 1:nchoosek (M, r) P{idx+idy} = TMP(idy,:); endfor idx = idx+idy; r = r + 1; endwhile ## enter majority logic decoding loop, R+1 order polynomial, ## but we do it here for n-k times, both are equivalent. NCODES = size (VV); NCODES = NCODES(1); v_adjust = []; for row_v = 1:1:NCODES V = VV(row_v,:); CM = -1*ones (1, Rows); ## Now start at bottom row, and get the index set, ## for each until the 2nd most row. ## special case, r=0, parity check, so just sum-up. if (R == 0) wt = __majority_logic_vote (V); CMM(row_v,:) = wt; C(row_v,:) = mod (wt*G, 2); continue; endif order = R; Gadj = G; prev_len = length (P{Rows}); for idx = Rows:-1:1 ## adjust the V received vector, at change of each order. if (prev_len != length (P{idx}) || idx == 1) # force for_ idx=1 v_adjust = mod (CM(idx+1:end)*Gadj(idx+1:end,:), 2); Gadj(idx+1:end,:) = 0; V = mod (V+ v_adjust, 2); # + = - in GF(2). order = order - 1; if (order == 0) # special handling of the all-1s basis vector. CM(idx) = __majority_logic_vote (V); break endif endif prev_len = length (P{idx}); Si = P{idx}; # index identifier Si = sort (Si, "descend"); ## generate index elements B = __binvec (0:(2.^length (Si) - 1)); WTS = 2.^[Si-1]; ## actual index set elements. S = sum (B.*repmat (WTS, [2^length(Si), 1]), 2); ## doing the operation set difference U \ S to get SCi SCi = U; Si_diff = Si-1; rmidx = []; for idy = 1:M if (any (Si_diff == SCi(idy))) rmidx = [rmidx, idy]; endif endfor SCi(rmidx) = []; SCi = sort (SCi, "descend"); ## corner case RM(r=m,m) case if (length (SCi) > 0) ## generate the set SC, B = __binvec (0:(2.^length (SCi) - 1)); WTS = 2.^[SCi]; ## actual index set elements. SC = sum (B.*repmat (WTS, [2^length(SCi), 1]), 2); else SC = [0]; # default, has to be empty set mathematically; endif ## next compute the checksums & form the weights. wts = []; # clear prev history for id_el = 1:length (SC) sc_el = SC(id_el); elems = sc_el + S; elems = elems + 1; # adjust indexing wt = mod (sum (V(elems)), 2); # add elements of V, rx vector. wts(id_el) = wt; # this is checksum endfor ## do the majority logic vote. CM(idx) = __majority_logic_vote (wts); endfor CMM(row_v,:) = CM; C(row_v,:) = mod (CM*G, 2); endfor endfunction ## ## utility functions ## function bvec = __binvec (dec_vec) maxlen = ceil (log2 (max (dec_vec) + 1)); x = []; bvec = zeros (length (dec_vec), maxlen); for idx = maxlen:-1:1 tmp = mod (dec_vec, 2); bvec(:,idx) = tmp.'; dec_vec = (dec_vec - tmp) ./ 2; endfor endfunction ## ## crude majority logic decoding; force the = case to 0 by default. ## function wt = __majority_logic_vote (wts) wt = sum (wts) - sum (1 - wts); # count no of 1s - no of 0s. if (wt != 0) wt = (wt > 0); #else #wt = rand () > 0.5; # break the tie. #endif endif endfunction ## ## majority logic decoding, tie-break using random. ## function wt = __majority_logic_vote_random (wts) wt = (1 + sign (sum (wts) - sum (1 - wts)))/2; if (wt == 0.5) wt = (rand () > 0.5); endif endfunction % test cases %G=[1 1 1 1,1 1 1 1; % 0 1 0 1,0 1 0 1; % 0 0 1 1,0 0 1 1; % 0 0 0 0 1 1 1 1]; %m=[1 0 0 1]; %c=mod(m*G,2); %c(1)=1-c(1); # corrects errors! %[dc,dm]=reedmullerdec(c,G,1,3) %pause % %G=reedmullergen(1,4); %m=[1 0 0 0 1]; %c=mod(m*G,2); %[dc,dm]=reedmullerdec(c,G,1,4) %pause % %G=reedmullergen(3,4); %m=[ones(1,15)]; %c=mod(m*G,2); %[dc,dm]=reedmullerdec(c,G,3,4) %pause % %G=reedmullergen(2,3); %m=[0 0 0 1 1 1 1] %c=mod(m*G,2) %[dc,dm]=reedmullerdec(c,G,2,3) %pause % %G=reedmullergen(3,3); %c1=mod([ones(1,8)]*G,2); %c2=mod([ones(1,4),zeros(1,4)]*G,2); %[dC,dM]=reedmullerdec([c2;c2;c1;c2],G,3,3) % % ## special case of repetition code. % G=reedmullergen(0,3); % G % c1=1*G; % c2=0*G; C=[c1; c2] % [dC,dM]=reedmullerdec(C,G,0,3) %% Test input validation %!error reedmullerdec () %!error reedmullerdec (1) %!error reedmullerdec (1, 2) %!error reedmullerdec (1, 2, 3) %!error reedmullerdec (1, 2, 3, 4, 5) communications-1.2.1/inst/PaxHeaders.3802/biterr.m0000644000000000000000000000013212510010473016627 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/biterr.m0000644000000000000000000001330312510010473017154 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{num}, @var{rate}] =} biterr (@var{a}, @var{b}) ## @deftypefnx {Function File} {[@var{num}, @var{rate}] =} biterr (@dots{}, @var{k}) ## @deftypefnx {Function File} {[@var{num}, @var{rate}] =} biterr (@dots{}, @var{flag}) ## @deftypefnx {Function File} {[@var{num}, @var{rate} @var{ind}] =} biterr (@dots{}) ## ## Compares two matrices and returns the number of bit errors and the bit ## error rate. The binary representations of the variables @var{a} and ## @var{b} are treated and @var{a} and @var{b} can be either: ## ## @table @asis ## @item Both matrices ## In this case both matrices must be the same size and then by default the ## return values @var{num} and @var{rate} are the overall number of bit ## errors and the overall bit error rate. ## @item One column vector ## In this case the column vector is used for bit error comparison column-wise ## with the matrix. The returned values @var{num} and @var{rate} are then ## row vectors containing the number of bit errors and the bit error rate for ## each of the column-wise comparisons. The number of rows in the matrix ## must be the same as the length of the column vector ## @item One row vector ## In this case the row vector is used for bit error comparison row-wise ## with the matrix. The returned values @var{num} and @var{rate} are then ## column vectors containing the number of bit errors and the bit error rate ## for each of the row-wise comparisons. The number of columns in the matrix ## must be the same as the length of the row vector ## @end table ## ## This behavior can be overridden with the variable @var{flag}. @var{flag} ## can take the value "column-wise", "row-wise" or "overall". A column-wise ## comparison is not possible with a row vector and visa-versa. ## ## By default the number of bits in each symbol is assumed to be give by the ## number required to represent the maximum value of @var{a} and @var{b}. ## The number of bits to represent a symbol can be overridden by the variable ## @var{k}. ## @end deftypefn function [num, rate, ind] = biterr (a, b, varargin) if (nargin < 2 || nargin > 4) print_usage (); endif if (ndims (a) > 2 || ndims (b) > 2) error ("biterr: A and B must not have more than 2 dimensions"); endif if (! (!any (isinf (a(:))) && !any (isnan (a(:))) && all (isreal (a(:))) && all (a(:) == fix (a(:))) && all (a(:) >= 0))) error ("biterr: all elements of A must be non-negative integers"); endif if (! (!any (isinf (b(:))) && !any (isnan (b(:))) && all (isreal (b(:))) && all (b(:) == fix (b(:))) && all (b(:) >= 0))) error ("biterr: all elements of B must be non-negative integers"); endif [ar, ac] = size (a); [br, bc] = size (b); k = max ([max(a(:)), max(b(:))]); m = 1; while (k > (2^m-1)) m = m + 1; endwhile if (ar == br && ac == bc) type = "matrix"; flag = "overall"; c = 1; elseif (any ([ar, br] == 1)) type = "row"; flag = "row"; if (ac != bc) error ("biterr: A and B must have the same number of columns for row-wise comparison"); endif if (ar == 1) a = ones (br, 1) * a; else b = ones (ar, 1) * b; endif elseif (any ([ac, bc] == 1)) type = "column"; flag = "column"; if (ar != br) error ("biterr: A and B must have the same number of rows for column-wise comparison"); endif if (ac == 1) a = a * ones (1, bc); else b = b * ones (1, ac); endif else error ("biterr: A and B must have the same size"); endif k = 0; for i = 1:length (varargin) arg = varargin{i}; if (ischar (arg)) if (strcmp (arg, "row-wise")) if (strcmp (type, "column")) error ("biterr: row-wise comparison not possible with column inputs"); endif flag = "row"; elseif (strcmp (arg, "column-wise")) if (strcmp (type, "row")) error ("biterr: column-wise comparison not possible with row inputs"); endif flag = "column"; elseif (strcmp (arg, "overall")) flag = "overall"; else error ("biterr: invalid option '%s'", arg); endif else k = arg; if (k < m) error ("biterr: K must be >= the number of bits in the elements of A and B"); endif endif endfor if (k == 0) k = m; endif ## Call the core error function to count the bit errors ind = __errcore__ (a, b); switch (flag) case "row" if (strcmp (type, "matrix") && ac == 1) num = ind; else num = sum (ind')'; endif rate = num / k / max (ac, bc); case "column" if (strcmp (type, "matrix") && ar == 1) num = ind; else num = sum (ind); endif rate = num / k / max (ar, br); case "overall" num = sum (sum (ind)); rate = num / k / max (ar, br) / max (ac, bc); otherwise error ("biterr: invalid comparison type '%s'", flag); endswitch endfunction %% Test input validation %!error biterr () %!error biterr (1) %!error biterr (1, 2, 3, 4, 5) %!error biterr (10, 10, 2) communications-1.2.1/inst/PaxHeaders.3802/compand.m0000644000000000000000000000013212510010473016761 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/compand.m0000644000000000000000000000722012510010473017307 0ustar00rootroot00000000000000## Copyright (C) 2001 Paul Kienzle ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "mu/compressor") ## @deftypefnx {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "mu/expander") ## @deftypefnx {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "A/compressor") ## @deftypefnx {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "A/expander") ## ## Compresses and expanding the dynamic range of a signal using a mu-law or ## or A-law algorithm. ## ## The mu-law compressor/expander for reducing the dynamic range, is used ## if the fourth argument of @code{compand} starts with "mu/". Whereas the ## A-law compressor/expander is used if @code{compand} starts with "A/". ## The mu-law algorithm uses the formulation ## ## @tex ## $$ ## y = {V log (1 + \\mu / V \\|x\\|) \\over log (1 + \\mu)} sgn(x) ## $$ ## @end tex ## @ifnottex ## @example ## @group ## ## V log (1 + \mu/V |x|) ## y = -------------------- sgn(x) ## log (1 + \mu) ## ## @end group ## @end example ## @end ifnottex ## ## while the A-law algorithm used the formulation ## ## @tex ## $$ ## y = { \\left\{ \\matrix{ {A / (1 + log A) x}, & 0 <= \\|x\\| <= V/A \\cr ## & \\cr ## {V log (1 + log(A/V \\|x\\|) ) \\over 1 + logA}, & ## V/A < \\|x\\| <= V} \\right. } ## $$ ## @end tex ## @ifnottex ## @example ## @group ## ## / A / (1 + log A) x, 0 <= |x| <= V/A ## | ## y = < V ( 1 + log (A/V |x|) ) ## | ----------------------- sgn(x), V/A < |x| <= V ## \ 1 + log A ## @end group ## @end example ## @end ifnottex ## ## Neither converts from or to audio file ulaw format. Use mu2lin or lin2mu ## instead. ## ## @seealso{m2ulin, lin2mu} ## @end deftypefn function y = compand (x, mu, V, stype) if (nargin != 3 && nargin != 4) print_usage (); endif if (nargin < 4) stype = "mu/compressor"; else stype = tolower (stype); endif if (strcmp (stype, "mu/compressor")) y = (V/log (1 + mu)) * log (1 + (mu/V)*abs (x)) .* sign (x); elseif (strcmp (stype, "mu/expander")) y = (V/mu) * (exp (abs (x) * (log (1 + mu)/V)) - 1) .* sign (x); elseif (strcmp (stype, "a/compressor")) y = zeros (size (x)); idx = find (abs (x) <= V/mu); if (idx) y(idx) = (mu / (1 + log (mu))) * abs (x(idx)); endif idx = find (abs (x) > V/mu); if (idx) y(idx) = (V / (1 + log (mu))) * (1 + log ((mu/V) * abs (x(idx)))); endif y = y .* sign (x); elseif (strcmp (stype, "a/expander")) y = zeros (size (x)); idx = find (abs (x) <= V / (1 + log (mu))); if (idx) y(idx) = ((1 + log (mu))/mu) * abs (x(idx)); endif idx = find (abs (x) > V / (1 + log (mu))); if (idx) y(idx) = exp (((1 + log (mu))/V) * abs (x(idx)) - 1) * (V/mu); endif y = y .* sign (x); endif endfunction %% Test input validation %!error compand () %!error compand (1) %!error compand (1, 2) %!error compand (1, 2, 3, 4, 5) communications-1.2.1/inst/PaxHeaders.3802/qfuncinv.m0000644000000000000000000000013212510010473017171 xustar0030 mtime=1428164923.886511478 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/qfuncinv.m0000644000000000000000000000211312510010473017513 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} qfuncinv (@var{x}) ## Compute the inverse Q function. ## @seealso{erfc, erf} ## @end deftypefn function y = qfuncinv (x) if (nargin != 1) print_usage (); endif y = -norminv (x); endfunction %!assert (qfuncinv ([0 0.5 1]), [Inf 0 -Inf]) %% Test input validation %!error qfuncinv () %!error qfuncinv (1, 2) communications-1.2.1/inst/PaxHeaders.3802/decode.m0000644000000000000000000000013212510010473016563 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.042507921 30 ctime=1428164983.712815029 communications-1.2.1/inst/decode.m0000644000000000000000000002541512510010473017117 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}) ## @deftypefnx {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}, @var{typ}) ## @deftypefnx {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}, @var{typ}, @var{opt1}) ## @deftypefnx {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}, @var{typ}, @var{opt1}, @var{opt2}) ## @deftypefnx {Function File} {[@var{msg}, @var{err}] =} decode (@dots{}) ## @deftypefnx {Function File} {[@var{msg}, @var{err}, @var{ccode}] =} decode (@dots{}) ## @deftypefnx {Function File} {[@var{msg}, @var{err}, @var{ccode}, @var{cerr}] =} decode (@dots{}) ## ## Top level block decoder. This function makes use of the lower level ## functions such as @code{cyclpoly}, @code{cyclgen}, @code{hammgen}, and ## @code{bchenco}. The coded message to decode is pass in @var{code}, the ## codeword length is @var{n} and the message length is @var{k}. This ## function is used to decode messages using either: ## ## @table @asis ## @item A [n,k] linear block code defined by a generator matrix ## @item A [n,k] cyclic code defined by a generator polynomial ## @item A [n,k] Hamming code defined by a primitive polynomial ## @item A [n,k] BCH code code defined by a generator polynomial ## @end table ## ## The type of coding to use is defined by the variable @var{typ}. This ## variable is a string taking one of the values ## ## @table @code ## @item "linear" ## @itemx "linear/binary" ## A linear block code is assumed with the message @var{msg} being in a ## binary format. In this case the argument @var{opt1} is the generator ## matrix, and is required. Additionally, @var{opt2} containing the ## syndrome lookup table (see @code{syndtable}) can also be passed. ## @item "cyclic" ## @itemx "cyclic/binary" ## A cyclic code is assumed with the message @var{msg} being in a binary ## format. The generator polynomial to use can be defined in @var{opt1}. ## The default generator polynomial to use will be ## @code{cyclpoly (@var{n}, @var{k})}. Additionally, @var{opt2} containing the ## syndrome lookup table (see @code{syndtable}) can also be passed. ## @item "hamming" ## @itemx "hamming/binary" ## A Hamming code is assumed with the message @var{msg} being in a binary ## format. In this case @var{n} must be of an integer of the form ## @code{2^@var{m}-1}, where @var{m} is an integer. In addition @var{k} ## must be @code{@var{n}-@var{m}}. The primitive polynomial to use can ## be defined in @var{opt1}. The default primitive polynomial to use is ## the same as defined by @code{hammgen}. The variable @var{opt2} should ## not be defined. ## @item "bch" ## @itemx "bch/binary" ## A BCH code is assumed with the message @var{msg} being in a binary ## format. The primitive polynomial to use can be defined in @var{opt2}. ## The error correction capability of the code can also be defined in ## @var{opt1}. Use the empty matrix [] to let the error correction ## capability take the default value. ## @end table ## ## In addition the argument "binary" above can be replaced with "decimal", ## in which case the message is assumed to be a decimal vector, with each ## value representing a symbol to be coded. The binary format can be in two ## forms ## ## @table @code ## @item An @var{x}-by-@var{n} matrix ## Each row of this matrix represents a symbol to be decoded ## @item A vector with length divisible by @var{n} ## The coded symbols are created from groups of @var{n} elements of this vector ## @end table ## ## The decoded message is return in @var{msg}. The number of errors encountered ## is returned in @var{err}. If the coded message format is "decimal" or a ## "binary" matrix, then @var{err} is a column vector having a length equal ## to the number of decoded symbols. If @var{code} is a "binary" vector, then ## @var{err} is the same length as @var{msg} and indicated the number of ## errors in each symbol. If the value @var{err} is positive it indicates the ## number of errors corrected in the corresponding symbol. A negative value ## indicates an uncorrectable error. The corrected code is returned in ## @var{ccode} in a similar format to the coded message @var{msg}. The ## variable @var{cerr} contains similar data to @var{err} for @var{ccode}. ## ## It should be noted that all internal calculations are performed in the ## binary format. Therefore for large values of @var{n}, it is preferable ## to use the binary format to pass the messages to avoid possible rounding ## errors. Additionally, if repeated calls to @code{decode} will be performed, ## it is often faster to create a generator matrix externally with the ## functions @code{hammgen} or @code{cyclgen}, rather than let @code{decode} ## recalculate this matrix at each iteration. In this case @var{typ} should ## be "linear". The exception to this case is BCH codes, where the required ## syndrome table is too large. The BCH decoder, decodes directly from the ## polynomial never explicitly forming the syndrome table. ## ## @seealso{encode, cyclgen, cyclpoly, hammgen, bchdeco, bchpoly, syndtable} ## @end deftypefn function [msg, err, ccode, cerr] = decode (code, n, k, typ, opt1, opt2) if (nargin < 3 || nargin > 6) print_usage (); endif if (! (isscalar (n) && n == fix (n) && n >= 3)) error ("decode: N must be an integer greater than 3"); endif if (! (isscalar (k) && k == fix (k) && k <= n)) error ("decode: K must be an integer less than N"); endif if (nargin > 3) if (!ischar (typ)) error ("decode: TYP must be a string"); else ## Why the hell did matlab decide on such an ugly way of passing 2 args! if (strcmp (typ, "linear") || strcmp (typ, "linear/binary")) coding = "linear"; msgtyp = "binary"; elseif (strcmp (typ, "linear/decimal")) coding = "linear"; msgtyp = "decimal"; elseif (strcmp (typ, "cyclic") || strcmp (typ, "cyclic/binary")) coding = "cyclic"; msgtyp = "binary"; elseif (strcmp (typ, "cyclic/decimal")) coding = "cyclic"; msgtyp = "decimal"; elseif (strcmp (typ, "bch") || strcmp (typ, "bch/binary")) coding = "bch"; msgtyp = "binary"; elseif (strcmp (typ, "bch/decimal")) coding = "bch"; msgtyp = "decimal"; elseif (strcmp (typ, "hamming") || strcmp (typ, "hamming/binary")) coding = "hamming"; msgtyp = "binary"; elseif (strcmp (typ, "hamming/decimal")) coding = "hamming"; msgtyp = "decimal"; else error ("decode: invalid coding and/or message TYP '%s'", typ); endif endif else coding = "hamming"; msgtyp = "binary"; endif if (strcmp (msgtyp, "binary")) vecttyp = 0; if ((max (code(:)) > 1) || (min (code(:)) < 0)) error ("decode: CODE must be a binary matrix"); endif [ncodewords, n2] = size (code); len = n2*ncodewords; if (len/n != fix (len/n)) error ("decode: size of CODE must be a multiple of N"); endif if (min (n2, ncodewords) == 1) vecttyp = 1; ncodewords = len / n; code = reshape (code, n, ncodewords); code = code'; elseif (n2 != n) error ("decode: CODE must be a matrix with N columns"); endif else if (!isvector (code)) error ("decode: decimal CODE type must be a vector"); endif if (max (code) > 2^n-1 || min (code) < 0) error ("decode: all elements of CODE must be in the range [0,2^N-1]"); endif ncodewords = length (code); code = de2bi (code(:), n); endif if (strcmp (coding, "bch")) if (nargin < 5 || isempty (opt1)) tmp = bchpoly (n, k, "probe"); t = tmp(3); else t = opt1; endif if (nargin > 5) [msg err ccode] = bchdeco (code, k, t, opt2); else [msg err ccode] = bchdeco (code, k, t); endif cerr = err; else if (strcmp (coding, "linear")) if (nargin > 4) gen = opt1; if ((size (gen, 1) != k) || (size (gen, 2) != n)) error ("decode: generator matrix must be of size KxN"); endif par = gen2par (gen); if (nargin > 5) st = opt2; else st = syndtable (par); endif else error ("decode: linear coding requires a generator matrix"); endif elseif (strcmp (coding, "cyclic")) if (nargin > 4) [par, gen] = cyclgen (n, opt1); else [par, gen] = cyclgen (n, cyclpoly (n, k)); endif if (nargin > 5) ## FIXME: Should we check that the generator polynomial is ## consistent with the syndrome table. Where is the acceleration in ## this case??? st = opt2; else st = syndtable (par); endif else m = log2 (n + 1); if (! (m == fix (m) && m >= 3 && m <= 16)) error ("decode: N must be equal to 2^M-1 for integer M in the range [3,16]"); endif if (k != (n-m)) error ("decode: K must be equal to N-M for Hamming decoder"); endif if (nargin > 4) [par, gen] = hammgen (m, opt1); else [par, gen] = hammgen (m); endif if (nargin > 5) error ("decode: too many arguments for Hamming decoder"); else st = syndtable (par); endif endif errvec = st(bi2de ((mod (par * code', 2))', "left-msb") + 1,:); ccode = mod (code+errvec, 2); err = sum (errvec'); cerr = err; if (isequal (gen(:,1:k), eye (k))) msg = ccode(:,1:k); elseif (isequal (gen(:,n-k+1:n), eye (k))) msg = ccode(:,n-k+1:n); else error ("decode: generator matrix must be in standard form"); endif endif if (strcmp (msgtyp, "binary") && vecttyp == 1) msg = msg'; msg = msg(:); ccode = ccode'; ccode = ccode(:); err = ones (k, 1) * err; err = err(:); cerr = ones (n, 1) * cerr; cerr = cerr(:); else err = err(:); cerr = cerr(:); if (strcmp (msgtyp, "decimal")) msg = bi2de (msg); ccode = bi2de (ccode); endif endif endfunction %% Test input validation %!error decode () %!error decode (1) %!error decode (1, 2) %!error decode (1, 2, 3, 4, 5, 6, 7) %!error decode (1, 2, 3) %!error decode (1, 5, 6) %!error decode (1, 5, 3, "invalid") communications-1.2.1/inst/PaxHeaders.3802/ricedeco.m0000644000000000000000000000013112510010473017114 xustar0030 mtime=1428164923.922510659 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/ricedeco.m0000644000000000000000000000464412510010473017452 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} ricedeco (@var{code}, @var{K}) ## ## Returns the Rice decoded signal vector using @var{code} and @var{K}. ## Compulsory K is need to be specified. ## A restrictions is that a signal set must strictly be non-negative. ## The value of code is a cell array of row-vectors which have the ## encoded rice value for a single sample. The Rice algorithm is ## used to encode the "code" and only that can be meaningfully ## decoded. @var{code} is assumed to have been of format generated ## by the function @code{riceenco}. ## ## Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info Theory ## ## An example of the use of @code{ricedeco} is ## @example ## @group ## ricedeco (riceenco (1:4, 2), 2) ## @result{} [1 2 3 4] ## @end group ## @end example ## @seealso{riceenco} ## @end deftypefn ## ## ##! /usr/bin/octave -q ##A stress test routine ##for i=1:100 ## sig=abs(randint(1,10,[0,255])); ## [code,k]=riceenco(sig) ## sig_d=ricedeco(code,k) ## if(isequal(sig_d,sig)!=1) ## error("Some mistake in ricedeco/enco pair"); ## endif ##endfor ## function sig_op = ricedeco (code, K) if (nargin != 2 || ! iscell (code)) print_usage (); endif L = length (code); K_pow_2 = 2**K; if (K != 0) power_seq = [2.^((K-1):-1:0)]; for j = 1:L word = code{j}; idx = find (word == 0)(1); val = sum (word(1:idx)); sig_op(j) = val * K_pow_2 + sum (word(idx+1:end) .* power_seq); endfor else for j = 1:L sig_op(j) = sum (code{j}); endfor endif endfunction %!assert (ricedeco (riceenco (1:4, 2), 2), [1:4]) %% Test input validation %!error ricedeco () %!error ricedeco (1) %!error ricedeco (1, 2) %!error ricedeco (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/pskmod.m0000644000000000000000000000013112510010473016634 xustar0030 mtime=1428164923.882511568 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/pskmod.m0000644000000000000000000000467512510010473017176 0ustar00rootroot00000000000000## Copyright (C) 2006 Charalampos C. Tsimenidis ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} pskmod (@var{x}, @var{m}) ## @deftypefnx {Function File} {@var{y} =} pskmod (@var{x}, @var{m}, @var{phi}) ## @deftypefnx {Function File} {@var{y} =} pskmod (@var{x}, @var{m}, @var{phi}, @var{type}) ## ## Modulates an information sequence of integers @var{x} in the range ## @code{[0 @dots{} M-1]} onto a complex baseband phase shift keying ## modulated signal @var{y}. @var{phi} controls the initial phase and ## @var{type} controls the constellation mapping. If @var{type} is set ## to "Bin" will result in binary encoding, in contrast, if set to "Gray" ## will give Gray encoding. An example of Gray-encoded QPSK is ## ## @example ## @group ## d = randint (1, 5e3, 4); ## y = pskmod (d, 4, 0, "gray"); ## z = awgn (y, 30); ## plot (z, "rx") ## @end group ## @end example ## @seealso{pskdemod} ## @end deftypefn function y = pskmod (x, M, phi, type) if (nargin < 2 || nargin > 4) print_usage (); endif m = 0:M-1; if (!isempty (find (ismember (x, m) == 0))) error ("pskmod: all elements of X must be integers in the range [0,M-1]"); endif if (nargin < 3) phi = 0; endif if (nargin < 4) type = "Bin"; endif constellation = exp (1j*2*pi*m/M+1j*phi); if (strcmp (type, "Bin") || strcmp (type, "bin")) y = constellation(x+1); elseif (strcmp (type, "Gray") || strcmp (type, "gray")) [a, b] = sort (bitxor (m, bitshift (m, -1))); y = constellation(b(x+1)); else print_usage (); endif endfunction %!assert (round (pskmod ([0:3], 4, 0, "Bin")), [1 j -1 -j]) %!assert (round (pskmod ([0:3], 4, 0, "Gray")), [1 j -j -1]) %% Test input validation %!error pskmod () %!error pskmod (1) %!error pskmod (1, 2, 3, 4, 5) %!error pskmod (1, 2, 3, "invalid") %!error pskmod (0:7, 4) communications-1.2.1/inst/PaxHeaders.3802/bsc.m0000644000000000000000000000013112510010473016106 xustar0030 mtime=1428164923.866511933 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/bsc.m0000644000000000000000000000331512510010473016436 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} bsc (@var{data}, @var{p}) ## Send @var{data} into a binary symmetric channel with probability ## @var{p} of error one each symbol. ## @end deftypefn function ndata = bsc (data, p) if (nargin != 2) print_usage (); endif if (! (isscalar (p) && p >= 0 && p <= 1)) error ("bsc: P must be a positive scalar in the range [0,1]"); endif if (! (all (data(:) == fix (data(:))) && all (data(:) >= 0) && all (data(:) <= 1))) error ("bsc: DATA must be a binary sequence"); endif ndata = data; ndata(find (data == 0)) = randsrc (size (ndata(find (data == 0)), 1), size (ndata(find (data == 0)), 2), [-1 -2; 1-p p]); ndata(find (data == 1)) = randsrc (size (ndata(find (data == 1)), 1), size (ndata(find (data == 1)), 2), [1 0; 1-p p]); ndata(find (ndata == -1)) = 0; ndata(find (ndata == -2)) = 1; endfunction %% Test input validation %!error bsc () %!error bsc (1) %!error bsc (1, 2, 3) %!error bsc (1, 2) %!error bsc (2, 1) communications-1.2.1/inst/PaxHeaders.3802/lz77deco.m0000644000000000000000000000013012510010473016774 xustar0029 mtime=1428164923.87851166 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/lz77deco.m0000644000000000000000000000416412510010473017330 0ustar00rootroot00000000000000## Copyright (C) 2007 Gorka Lertxundi ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{m} =} lz77deco (@var{c}, @var{alph}, @var{la}, @var{n}) ## Lempel-Ziv 77 source algorithm decoding implementation. Where ## ## @table @asis ## @item @var{m} ## message decoded (1xN). ## @item @var{c} ## encoded message (Mx3). ## @item @var{alph} ## size of alphabet. ## @item @var{la} ## lookahead buffer size. ## @item @var{n} ## sliding window buffer size. ## @end table ## @seealso{lz77enco} ## @end deftypefn function m = lz77deco (c, alph, la, n) if (la <= 0 || n <= 0) error ("lz77deco: LA and N must be positive integers"); endif if (n - la < la) error ("lz77deco: N must be >= 2*LA"); endif if (alph < 2) error ("lz77deco: ALPH must be >= 2"); endif if (columns (c) != 3) error ("lz77deco: C must be a matrix with 3 columns"); endif window = zeros (1, n); x = length (c); len = length (c); for x = 1:len ## update window temp = n - la + c(x,2) - c(x,1); for y = 1:temp window(n-la+y) = window(c(x,1)+y); endfor window(n-la+c(x,2)+1) = c(x,3); ## decoded message m_deco = window(n-la+1:n-la+c(x,2)+1); if (x == 1) m = m_deco; else m = [m m_deco]; endif ## CCW shift temp = c(x,2) + 1; window(1:n-la) = window(temp+1:n-la+temp); endfor endfunction %!demo %! lz77deco ([8 2 1 ; 7 3 2 ; 6 7 2 ; 2 8 0], 3, 9, 18) %% Test input validation %!error lz77deco (1, 2, 3, 4) %!error lz77deco (1, 1, 1, 1) communications-1.2.1/inst/PaxHeaders.3802/apkconst.m0000644000000000000000000000013112510010473017161 xustar0030 mtime=1428164923.862512023 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/apkconst.m0000644000000000000000000001100012510010473017477 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} apkconst (@var{nsig}) ## @deftypefnx {Function File} {} apkconst (@var{nsig}, @var{amp}) ## @deftypefnx {Function File} {} apkconst (@var{nsig}, @var{amp}, @var{phs}) ## @deftypefnx {Function File} {} apkconst (@dots{}, "n") ## @deftypefnx {Function File} {} apkconst (@dots{}, @var{str}) ## @deftypefnx {Function File} {@var{y} =} apkconst (@dots{}) ## ## Plots a ASK/PSK signal constellation. Argument @var{nsig} is a real vector ## whose length determines the number of ASK radii in the constellation. ## The values of vector @var{nsig} determine the number of points in each ## ASK radii. ## ## By default the radii of each ASK modulated level is given by the index of ## @var{nsig}. The amplitudes can be defined explicitly in the variable ## @var{amp}, which is a vector of the same length as @var{nsig}. ## ## By default the first point in each ASK radii has zero phase, and following ## points are coding in an anti-clockwise manner. If @var{phs} is defined then ## it is a vector of the same length as @var{nsig} defining the initial phase ## in each ASK radii. ## ## In addition @code{apkconst} takes two string arguments "n" and @var{str}. ## If the string "n" is included in the arguments, then a number is printed ## next to each constellation point giving the symbol value that would be ## mapped to this point by the @code{modmap} function. The argument @var{str} ## is a plot style string (example "r+") and determines the default gnuplot ## point style to use for plot points in the constellation. ## ## If @code{apkconst} is called with a return argument, then no plot is ## created. However the return value is a vector giving the in-phase and ## quadrature values of the symbols in the constellation. ## @seealso{dmod, ddemod, modmap, demodmap} ## @end deftypefn function yout = apkconst (varargin) if (nargin < 1 || nargin > 5) print_usage (); endif numargs = 0; printnums = 0; fmt = "+r"; amp = []; phs = []; for i = 1:length (varargin) arg = varargin{i}; if (ischar (arg)) if (strcmp (arg, "n")) try text (); printnums = 1; catch printnums = 0; end_try_catch else fmt = arg; endif else numargs++; switch (numargs) case 1 nsig = arg; case 2 amp = arg; case 3 phs = arg; otherwise error ("apkconst: too many numerical arguments"); endswitch endif endfor if (numargs < 1) error ("apkconst: must have at least one vector argument"); endif if (isempty (amp)) amp = 1:length (nsig); endif if (isempty (phs)) phs = zeros (size (amp)); endif if (!isvector (nsig) || !isvector (amp) || !isvector (phs) || ... (length (nsig) != length (amp)) || (length (nsig) != length (phs))) error ("apkconst: NSIG, AMP, and PHS must be vectors of common size"); endif if (length (nsig) == 0) error ("apkconst: NSIG must have non-zero length"); endif y = []; for i = 1:length (nsig) if (nsig(i) < 1) error ("apkconst: NSIG must have at least one point in ASK radii"); endif y = [y; amp(i) * [cos(2*pi*[0:nsig(i)-1]'/nsig(i) + phs(i)) + ... 1i*sin(2*pi*[0:nsig(i)-1]'/nsig(i) + phs(i))]]; endfor if (nargout == 0) r = [0:0.02:2]'*pi; x0 = cos (r) * amp; y0 = sin (r) * amp; plot (x0, y0, "b"); yy = [real(y), imag(y)]; hold on; if (printnums) xd = 0.05 * max (real (y)); for i = 1:length (y) text (real (y(i)) + xd, imag (y(i)), num2str (i-1)); endfor endif plot (real (y), imag (y), fmt); title ("ASK/PSK Constellation"); xlabel ("In-phase"); ylabel ("Quadrature"); else yout = y; endif endfunction %% Test input validation %!error apkconst () %!error apkconst (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/systematize.m0000644000000000000000000000013112510010473017720 xustar0030 mtime=1428164923.934510386 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/systematize.m0000644000000000000000000000630012510010473020245 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} systematize (@var{G}) ## ## Given @var{G}, extract P parity check matrix. Assume row-operations in GF(2). ## @var{G} is of size KxN, when decomposed through row-operations into a @var{I} of size KxK ## identity matrix, and a parity check matrix @var{P} of size Kx(N-K). ## ## Most arbitrary code with a given generator matrix @var{G}, can be converted into its ## systematic form using this function. ## ## This function returns 2 values, first is default being @var{Gx} the systematic version of ## the @var{G} matrix, and then the parity check matrix @var{P}. ## ## @example ## @group ## g = [1 1 1 1; 1 1 0 1; 1 0 0 1]; ## [gx, p] = systematize (g); ## @result{} gx = [1 0 0 1; 0 1 0 0; 0 0 1 0]; ## @result{} p = [1 0 0]; ## @end group ## @end example ## @seealso{bchpoly, biterr} ## @end deftypefn function [G, P] = systematize (G) if (nargin != 1) print_usage (); endif [K, N] = size (G); if (K >= N) error ("systematize: G must be a KxN matrix, with K < N"); endif ## ## gauss-jordan echelon formation, ## and then back-operations to get I of size KxK ## remaining is the P matrix. ## for row = 1:K ## ## pick a pivot for this row, by finding the ## first of remaining rows that have non-zero element ## in the pivot. ## found_pivot = 0; if (G(row,row) > 0) found_pivot = 1; else ## ## next step of Gauss-Jordan, you need to ## re-sort the remaining rows, such that their ## pivot element is non-zero. ## for idx = row+1:K if (G(idx,row) > 0) tmp = G(row,:); G(row,:) = G(idx,:); G(idx,:) = tmp; found_pivot = 1; break; endif endfor endif ## ## some linearly dependent problems: ## if (!found_pivot) error ("systematize: could not systematize matrix G"); return endif ## ## Gauss-Jordan method: ## pick pivot element, then remove it ## from the rest of the rows. ## for idx = row+1:K if (G(idx,row) > 0) G(idx,:) = mod (G(idx,:) + G(row,:), 2); endif endfor endfor ## ## Now work-backward. ## for row = K:-1:2 for idx = row-1:-1:1 if (G(idx,row) > 0) G(idx,:) = mod (G(idx,:) + G(row,:), 2); endif endfor endfor #I = G(:,1:K); P = G(:,K+1:end); endfunction %% Test input validation %!error systematize () %!error systematize (1, 2) %!error systematize (eye (3)) communications-1.2.1/inst/PaxHeaders.3802/dpcmenco.m0000644000000000000000000000013112510010473017127 xustar0030 mtime=1428164923.870511841 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/dpcmenco.m0000644000000000000000000000551212510010473017460 0ustar00rootroot00000000000000## Copyright (C) 2012 Leonardo Araujo ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{qidx} =} dpcmenco (@var{sig}, @var{codebook}, @var{partition}, @var{predictor}) ## @deftypefnx {Function File} {[@var{qidx}, @var{q}] =} dpcmenco (@var{sig}, @var{codebook}, @var{partition}, @var{predictor}) ## @deftypefnx {Function File} {[@var{qidx}, @var{q}, @var{d}] =} dpcmenco (@dots{}) ## Encode using differential pulse code modulation (DPCM). ## ## @table @code ## @item qidx = dpcmenco (sig, codebook, partition, predictor) ## Determine position of the prediction error in a strictly monotonic table (partition). ## The predictor vector describes a m-th order prediction for the ## output according to the following equation ## y(k) = p(1)sig(k-1) + p(2)sig(k-2) + ... + p(m-1)sig(k-m+1) + p(m)sig(k-m) , ## where the predictor vector is given by ## predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)]. ## ## @item [qidx, q] = dpcmenco (sig, codebook, partition, predictor) ## Also return the quantized values. ## ## @item [qidx, q, d] = dpcmenco (...) ## Also compute distortion: mean squared distance of original sig from the ## corresponding quantized values. ## ## @end table ## @seealso{dpcmdeco, dpcmopt, quantiz} ## @end deftypefn function [indx, quants, distor] = dpcmenco (sig, codebook, partition, predictor) if (nargin != 4) print_usage (); endif y = zeros (size (sig)); indx = []; quants = []; for i = 1:length (y) ## use last predicted value to find the error y(i) = y(max (i - length (predictor) + 1, 1):i) * predictor(end:-1:max (end-i+1, 1))'; # convolution e(i) = sig(i) - y(i); # error [indx(i), quants(i)] = quantiz (e(i), partition, codebook); # quantize the error ## predictor yp = y(max (i - length (predictor) + 1, 1):i) * predictor(end:-1:max (end-i+1, 1))'; # convolution y(i) = yp + quants(i); # update prediction value endfor ## compute distortion if (nargout > 2) sigq = dpcmdeco (indx, codebook, predictor); distor = sumsq (sig(:) - sigq(:)) / length (sig); endif endfunction %% Test input validation %!error dpcmenco () %!error dpcmenco (1) %!error dpcmenco (1, 2) %!error dpcmenco (1, 2, 3) %!error dpcmenco (1, 2, 3, 4, 5) communications-1.2.1/inst/PaxHeaders.3802/huffmandict.m0000644000000000000000000000013012510010473017626 xustar0029 mtime=1428164923.87851166 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/huffmandict.m0000644000000000000000000001502412510010473020157 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} huffmandict (@var{symb}, @var{prob}) ## @deftypefnx {Function File} {} huffmandict (@var{symb}, @var{prob}, @var{toggle}) ## @deftypefnx {Function File} {} huffmandict (@var{symb}, @var{prob}, @var{toggle}, @var{minvar}) ## ## Builds a Huffman code, given a probability list. The Huffman codes ## per symbol are output as a list of strings-per-source symbol. A zero ## probability symbol is NOT assigned any codeword as this symbol doesn't ## occur in practice anyway. ## ## @var{toggle} is an optional argument with values 1 or 0, that starts ## building a code based on 1s or 0s, defaulting to 0. Also @var{minvar} ## is a boolean value that is useful in choosing if you want to optimize ## buffer for transmission in the applications of Huffman coding, however ## it doesn't affect the type or average codeword length of the generated ## code. An example of the use of @code{huffmandict} is ## ## @example ## @group ## huffmandict (symbols, [0.5 0.25 0.15 0.1], 1) ## @result{} @{[0], [1 0], [1 1 1], [1 1 0]@} ## huffmandict (symbols, 0.25 * ones (1,4), 1) ## @result{} @{[1 1], [1 0], [0 1], [0 0]@} ## ## prob = [0.5 0 0.25 0.15 0.1]; ## dict = huffmandict (1:5, prob, 1); ## entropy (prob) ## @result{} 2.3219 ## laverage (dict, prob) ## @result{} 1.8500 ## ## x = [0.2 0.4 0.2 0.1 0.1]; ## huffmandict (1, x, 0, true) ## @result{} @{[1 0], [0 0], [1 1], [0 1 0], [0 1 1]@} ## huffmandict (1, x) ## @result{} @{[0 1], [1], [0 0 1], [0 0 0 0], [0 0 0 1]@} ## @end group ## @end example ## ## Reference: Dr.Rao's course EE5351 Digital Video Coding, at UT-Arlington. ## @seealso{huffmandeco, huffmanenco} ## @end deftypefn ## Huffman code algorithm. ## while (uncombined_symbols_remain) ## combine least probable symbols into one with, ## their probability being the sum of the two. ## save this result as a stage at lowest order rung. ## (Moving to lowest position possible makes it non-minimum variance ## entropy coding) ## end ## ## for each (stage) ## Walk the tree we built, and assign each row either 1, ## or 0 of ## end ## ## reverse each symbol, and dump it out. ## function cw_list = huffmandict (sym, source_prob, togglecode = 0, minvar = 0) if (nargin < 2) print_usage (); ## need to compare to 1 elseif ((sum (source_prob) - 1.0) > 1e-7) error ("huffmandict: the elements of PROB must add up to 1"); endif ## need to find & eliminate the zero-probability code words. ## in practice we donot need to assign anything to them. Reasoning ## being that if_ it doesnt occur why bother saving its value anyway? ## --(Oct 9) Actually some experts in the area dont agree to this, ## and being a generic implementation we should stick to generating ## CWs for_ zero symbols. Why impose a bad implementation? --Muthu origsource_prob = source_prob; ## sort the list and know the index transpositions. kills the speed O(n^2). L = length (source_prob); index = [1:L]; for itr1 = 1:L for itr2 = itr1:L if (source_prob(itr1) < source_prob(itr2)) t = source_prob(itr1); source_prob(itr1) = source_prob(itr2); source_prob(itr2) = t; t = index(itr1); index(itr1) = index(itr2); index(itr2) = t; endif endfor endfor stage_list = {}; cw_list = cell (1, L); stage_curr = {}; stage_curr.prob_list = source_prob; stage_curr.sym_list = {}; S = length (source_prob); for i = 1:S; stage_curr.sym_list{i} = [i]; #cw_list{i} = ""; endfor ## another O(n^2) part. I = 1; while (I < S) L = length (stage_curr.prob_list); nprob = stage_curr.prob_list(L-1) + stage_curr.prob_list(L); nsym = [stage_curr.sym_list{L-1}(1:end), stage_curr.sym_list{L}(1:end)]; ## stage_curr; ## archive old stage list. stage_list{I} = stage_curr; ## insert the new probability into the list, at the ## first-position (greedy?) possible. for i = 1:(L-2) if ((minvar && stage_curr.prob_list(i) <= nprob) || ... stage_curr.prob_list(i) < nprob) break; endif endfor stage_curr.prob_list = [stage_curr.prob_list(1:i-1) nprob stage_curr.prob_list(i:L-2)]; stage_curr.sym_list = {stage_curr.sym_list{1:i-1}, nsym, stage_curr.sym_list{i:L-2}}; ## Loopie I = I + 1; endwhile if (togglecode == 0) one_cw = 1; zero_cw = 0; else one_cw = 0; zero_cw = 1; endif ## another O(n^2) part. I = I - 1; while (I > 0) stage_curr = stage_list{I}; L = length (stage_curr.sym_list); clist = stage_curr.sym_list{L}; for k = 1:length (clist) cw_list{1,clist(k)} = [cw_list{1,clist(k)} one_cw]; endfor clist = stage_curr.sym_list{L-1}; for k = 1:length (clist) cw_list{1,clist(k)} = [cw_list{1,clist(k)}, zero_cw]; endfor ## Loopie I = I - 1; endwhile ## zero all the code-words of zero-probability length, 'cos they ## never occur. S = length (source_prob); for itr = (S+1):length (origsource_prob) cw_list{1,itr} = -1; endfor #disp("Before resorting") #cw_list nw_list = cell (1, L); ## ## Re-sort the indices according to the probability list. ## L = length (source_prob); for itr = 1:(L) t = cw_list{index(itr)}; nw_list{index(itr)} = cw_list{itr}; endfor cw_list = nw_list; ## zero all the code-words of zero-probability length, 'cos they ## never occur. #for itr = 1:L # if (origsource_prob(itr) == 0) # cw_list{itr} = ""; # endif #endfor endfunction %!assert (huffmandict (1:4, [0.5 0.25 0.15 0.1], 1), {[0], [1 0], [1 1 1], [1 1 0]}, 0) %!assert (huffmandict (1:4, 0.25*ones (1, 4), 1), {[1 1], [1 0], [0 1], [0 0]}, 0) %!assert (huffmandict (1:4, [1 0 0 0 ]), {[1], [0 1], [0 0 0], [0 0 1]}, 0) %% Test input validation %!error huffmandict () %!error huffmandict (1) %!error huffmandict (1, [0.5 0.5 0.5]) communications-1.2.1/inst/PaxHeaders.3802/bi2de.m0000644000000000000000000000013112510010473016324 xustar0030 mtime=1428164923.862512023 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/bi2de.m0000644000000000000000000000544612510010473016663 0ustar00rootroot00000000000000## Copyright (C) 2001 Laurent Mazet ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{d} =} bi2de (@var{b}) ## @deftypefnx {Function File} {@var{d} =} bi2de (@var{b}, @var{f}) ## @deftypefnx {Function File} {@var{d} =} bi2de (@var{b}, @var{p}) ## @deftypefnx {Function File} {@var{d} =} bi2de (@var{b}, @var{p}, @var{f}) ## ## Convert bit matrix to a vector of integers ## ## Each row of the matrix @var{b} is treated as a single integer represented ## in binary form. The elements of @var{b}, must therefore be '0' or '1' ## ## If @var{p} is defined then it is treated as the base of the decomposition ## and the elements of @var{b} must then lie between '0' and 'p-1'. ## ## The variable @var{f} defines whether the first or last element of @var{b} ## is considered to be the most-significant. Valid values of @var{f} are ## "right-msb" or "left-msb". By default @var{f} is "right-msb". ## ## @seealso{de2bi} ## @end deftypefn function d = bi2de (b, p, f) switch (nargin) case 1 p = 2; f = "right-msb"; case 2 if (ischar (p)) f = p; p = 2; else f = "right-msb"; endif case 3 if (ischar (p)) tmp = f; f = p; p = tmp; endif otherwise print_usage (); endswitch if (! (all (b(:) == fix (b(:))) && all (b(:) >= 0) && all (b(:) < p))) error ("bi2de: all elements of B must be integers in the range [0,P-1]"); endif if (strcmp (f, "left-msb")) b = b(:,size (b, 2):-1:1); elseif (!strcmp (f, "right-msb")) error ("bi2de: invalid option '%s'", f); endif if (length (b) == 0) d = []; else d = b * (p .^ [0:(columns (b) - 1)]'); endif endfunction %!shared x %! x = randi ([0 1], 100, 16); %!assert (bi2de (0), 0) %!assert (bi2de (1), 1) %!assert (bi2de (ones (1, 8)), 255) %!assert (bi2de ([7 7 7 7], 8), 4095) %!assert (size (bi2de (x)), [100 1]) %!assert (bi2de (x, "right-msb"), bi2de (x)) %!assert (bi2de (x, "left-msb"), bi2de (fliplr (x))) %% Test input validation %!error bi2de () %!error bi2de (1, 2, 3, 4) %!error bi2de (1, 2, 3) %!error bi2de (1, 2, "invalid") %!error bi2de (0.1) %!error bi2de (-1) %!error bi2de (2) %!error bi2de (7, 6) communications-1.2.1/inst/PaxHeaders.3802/fibosplitstream.m0000644000000000000000000000013112510010473020546 xustar0030 mtime=1428164923.870511841 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/fibosplitstream.m0000644000000000000000000000460712510010473021103 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} fibosplitstream (@var{code}) ## ## Returns the split data stream at the word boundaries. ## Assuming the stream was originally encoded using @code{fiboenco} ## and this routine splits the stream at the points where "11" ## occur together & gives us the code-words which ## can later be decoded from the @code{fibodeco} This however doesn't ## mean that we intend to verify if all the codewords are correct, ## and in fact the last symbol in the return list can or can not be ## a valid codeword. ## ## A example use of @code{fibosplitstream} would be ## @example ## @group ## fibodeco (fibosplitstream ([fiboenco(randint (1, 100, [0, 255]))@{:@}])) ## fibodeco (fibosplitstream ([fiboenco(1:10)@{:@}])) ## @end group ## @end example ## @seealso{fiboenco, fibodeco} ## @end deftypefn function symbols = fibosplitstream (stream) if (nargin != 1) print_usage (); endif symbols = {}; itr = 1; L = length (stream); ## ## Plain & Simple Algorithm. O(N) ## Walk till marker "11" or find it. ## Then split & save. A little tricky to ## handle the edge case_ without tripping over. ## idx = []; mark = 1; prev_bit = stream(1); just_decoded = 0; for i = 2:L if (!just_decoded && (stream(i)+prev_bit) == 2) symbols{itr} = [stream(mark:i)]; mark = i + 1; prev_bit = 0; just_decoded = 1; itr = itr+1; else prev_bit = stream(i); just_decoded = 0; endif endfor if (mark < L) symbols{itr} = stream(mark:end); endif endfunction %!assert (fibodeco (fibosplitstream ([fiboenco(1:10){:}])), [1:10]) %% Test input validation %!error fibosplitstream () %!error fibosplitstream (1, 2) communications-1.2.1/inst/PaxHeaders.3802/qaskenco.m0000644000000000000000000000013112510010473017143 xustar0030 mtime=1428164923.886511478 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/qaskenco.m0000644000000000000000000001405412510010473017475 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} qaskenco (@var{m}) ## @deftypefnx {Function File} {} qaskenco (@var{msg}, @var{m}) ## @deftypefnx {Function File} {@var{y} =} qaskenco (@dots{}) ## @deftypefnx {Function File} {[@var{inphase}, @var{quadr}] =} qaskenco (@dots{}) ## ## Map a digital signal using a square QASK constellation. The argument ## @var{m} must be a positive integer power of 2. With two input arguments ## the variable @var{msg} represents the message to be encoded. The values ## of @var{msg} must be between 0 and @code{@var{m}-1}. In all cases ## @code{qaskenco (@var{M})} is equivalent to @code{qaskenco (1:@var{m}, @var{m})} ## ## Three types of outputs can be created depending on the number of output ## arguments. That is ## ## @table @asis ## @item No output arguments ## In this case @code{qaskenco} plots the constellation. Only the ## points in @var{msg} are plotted, which in the case of a single input ## argument is all constellation points. ## @item A single output argument ## The returned variable is a complex variable representing the in-phase ## and quadrature components of the mapped message @var{msg}. With, a ## single input argument this effectively gives the mapping from symbols ## to constellation points ## @item Two output arguments ## This is the same as one output argument, expect that the in-phase ## and quadrature components are returned explicitly. That is ## ## @example ## c = qaskenco (msg, m); ## [a, b] = qaskenco (msg, m); ## all (c == a + 1i*b) ## @result{} 1 ## @end example ## @end table ## ## If @code{sqrt (@var{m})} is an integer, then @code{qaskenco} uses a Gray ## mapping. Otherwise, an attempt is made to create a nearly square mapping ## with a minimum Hamming distance between adjacent constellation points. ## @seealso{qaskdeco} ## @end deftypefn function [a, b] = qaskenco (msg, M) if (nargin == 1) M = msg; elseif (nargin == 2) if (min (msg(:)) < 0 || max (msg(:)) > M-1) error ("qaskenco: all elements of MSG must be in the range [0:M-1]"); endif else print_usage (); endif if (!isscalar (M) || M != ceil (M) || M < 2) error ("qaskenco: M must be a positive integer greater than 2"); endif if (log2 (M) != ceil (log2 (M))) error ("qaskenco: M must be a power of 2"); endif if (M == 2) inphase = [-1, 1]; quadr = [ 0, 0]; elseif (M == 4) inphase = [-1, -1, 1, 1]; quadr = [-1, 1, -1, 1]; elseif (M == 8) inphase = [-1, -1, 1, 1, -3, -3, 3, 3]; quadr = [-1, 1, -1, 1, -1, 1, -1, 1]; else NC = 2^floor (log2 (sqrt (M))); MM = NC * NC; Gray = [0, 1]; for i = 2:ceil (log2 (NC)) Gray = [Gray 2^(i-1) + fliplr(Gray)]; endfor Gray = fliplr (de2bi (shift (Gray, length (Gray)/2 - 1))); Gray2 = zeros (MM, log2 (MM)); Gray2(:,1:2:log2 (MM)) = repmat (Gray, NC, 1); for i = 1:NC Gray2(i:NC:MM,2:2:log2 (MM)) = Gray; endfor layout = reshape (bi2de (fliplr (Gray2)), NC, NC); if (MM != M) ## Not sure this is the best that can be done for these mappings. If ## anyone wants to improve this, go ahead, but do it in qaskdeco too. OFF = sqrt (M/32); NR = NC + 2*OFF; layout2 = NaN * ones (NR); layout2(1+OFF:OFF+NC,1+OFF:OFF+NC) = layout; layout2(1:OFF,1+OFF:OFF+NC) = MM + layout(OFF:-1:1,:); layout2(NR-OFF+1:NR,1+OFF:OFF+NC) = MM + layout(NC:-1:NC-OFF+1,:); layout2(1+2*OFF:NC,1:OFF) = MM + layout(OFF+1:NC-OFF,OFF:-1:1); layout2(1+2*OFF:NC,NR-OFF+1:NR) = MM + ... layout(OFF+1:NC-OFF,NC:-1:NC-OFF+1); layout2(1+OFF:2*OFF,1:OFF) = MM + ... layout(NC/2:-1:NC/2-OFF+1,NC/2:-1:OFF+1); layout2(NC+1:OFF+NC,1:OFF) = MM + ... layout(NC-OFF:-1:NC/2+1,NC/2:-1:OFF+1); layout2(1+OFF:2*OFF,NR-OFF+1:NR) = MM + ... layout(NC/2:-1:NC/2-OFF+1,NC-OFF:-1:NC/2+1); layout2(NC+1:OFF+NC,NR-OFF+1:NR) = MM + ... layout(NC-OFF:-1:NC/2+1,NC-OFF:-1:NC/2+1); NC = NR; layout = layout2; endif inphase = repmat ([0:NC-1]*2 - NC + 1, 1, NC); for i = 1:NC quadr(i:NC:NC*NC) = [0:NC-1]*2 - NC + 1; endfor [dummy, indx] = sort (layout(:)); indx = indx(1:M); ## Get rid of remaining NaN's inphase = inphase(indx); quadr = quadr(indx); endif if (nargin == 2) inphase = inphase(msg+1); quadr = quadr(msg+1); ## Fix up indexing if using column vector if (size (msg, 2) == 1) inphase = inphase'; quadr = quadr'; endif endif if (nargout == 0) inphase = inphase(:); quadr = quadr(:); plot (inphase, quadr, "r+"); title ("QASK Constellation"); xlabel ("In-phase"); ylabel ("Quadrature"); axis ([min(inphase) - 1, max(inphase) + 1, min(quadr) - 1, max(quadr) + 1]); xd = 0.02 * max (inphase); if (nargin == 2) msg = msg(:); for i = 1:length (inphase) text (inphase(i) + xd, quadr(i), num2str (msg(i))); endfor else for i = 1:length (inphase) text (inphase(i) + xd, quadr(i), num2str (i-1)); endfor endif elseif (nargout == 1) a = inphase + 1i * quadr; else a = inphase; b = quadr; endif endfunction %% Test input validation %!error qaskenco () %!error qaskenco (1, 2, 3) %!error qaskenco (0:7, 3) communications-1.2.1/inst/PaxHeaders.3802/randintrlv.m0000644000000000000000000000013012510010473017521 xustar0029 mtime=1428164923.91851075 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/randintrlv.m0000644000000000000000000000241512510010473020052 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{intrlvd} =} randintrlv (@var{data}, @var{state}) ## Interleaves elements of @var{data} with a random permutation. ## @seealso{intrlv, deintrlv} ## @end deftypefn function intrlvd = randintrlv (data, state) if (nargin != 2) print_usage (); endif if (isvector (data)) l = length (data); else l = size (data, 1); endif rand ("state", state); intrlvd = intrlv (data, randperm (l)); endfunction %% Test input validation %!error randintrlv () %!error randintrlv (1) %!error randintrlv (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/vec2mat.m0000644000000000000000000000013112510010473016700 xustar0030 mtime=1428164923.934510386 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/vec2mat.m0000644000000000000000000000345012510010473017230 0ustar00rootroot00000000000000## Copyright (C) 2001 Laurent Mazet ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{m} =} vec2mat (@var{v}, @var{c}) ## @deftypefnx {Function File} {@var{m} =} vec2mat (@var{v}, @var{c}, @var{d}) ## @deftypefnx {Function File} {[@var{m}, @var{add}] =} vec2mat (@dots{}) ## ## Converts the vector @var{v} into a @var{c} column matrix with row priority ## arrangement and with the final column padded with the value @var{d} to the ## correct length. By default @var{d} is 0. The amount of padding added to ## the matrix is returned in @var{add}. ## @end deftypefn function [M, d] = vec2mat (V, c, val) switch (nargin) case 1 M = V; return; case 2 val = 0; case 3 val = val; otherwise print_usage (); endswitch V = V.'; V = V(:); r = ceil (length (V) / c); d = r * c - length (V); if (d != 0) V = [V; val*ones(d, 1)]; endif M = reshape (V, c, r).'; endfunction %!assert (vec2mat ([]), []) %!assert (vec2mat (1), 1) %!assert (vec2mat (1, 5), [1 0 0 0 0]) %!assert (vec2mat (0:8), 0:8) %!assert (vec2mat (0:8, 3), [0:2; 3:5; 6:8]) %% Test input validation %!error vec2mat () %!error vec2mat (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/poly2trellis.m0000644000000000000000000000013112510010473020003 xustar0030 mtime=1428164923.882511568 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/poly2trellis.m0000644000000000000000000001564312510010473020342 0ustar00rootroot00000000000000## Copyright (C) 2012 Mike Miller ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{t} =} poly2trellis (@var{m}, @var{g}) ## ## Convert convolutional code generator polynomials into trellis form. ## ## The arguments @var{m} and @var{g} together describe a rate k/n feedforward ## convolutional encoder. The output @var{t} is a trellis structure describing ## the same encoder with the fields listed below. ## ## The vector @var{m} is a k-by-1 array containing the lengths of each of the ## shift registers for the k input bits to the encoder. ## ## The matrix @var{g} is a k-by-n octal-value matrix describing the generation ## of each of the n outputs from each of the k inputs. For a particular entry ## of @var{g}, the least-significant bit corresponds to the most-delayed input ## bit in the kth shift-register. ## ## The returned trellis structure contains the following fields: ## ## @table @samp ## @item numInputSymbols ## The number of k-bit input symbols possible, i.e. 2^k. ## ## @item numOutputSymbols ## The number of n-bit output symbols possible, i.e. 2^n. ## ## @item numStates ## The number of states in the trellis. ## ## @item nextStates ## The state transition table for the trellis. The ith row contains the indices ## of the states reachable from the (i-1)th state for each possible input ## symbol. ## ## @item outputs ## A table of octal-encoded output values for the trellis. The ith row contains ## values representing the output symbols produced in the (i-1)th state for each ## possible input symbol. ## @end table ## ## Input symbols, output symbols, and encoder states are all interpreted with ## the lowest indices being the most significant bits. ## ## References: ## ## [1] S. Lin and D. J. Costello, "Convolutional codes," in @cite{Error ## Control Coding}, 2nd ed. Upper Saddle River, NJ: Pearson, 2004, ## ch. 11, pp. 453-513. ## ## @seealso{istrellis} ## @end deftypefn function t = poly2trellis (m, g) if (nargin != 2) print_usage (); endif ## Notation agrees with Lin & Costello for the most part: ## m = length of each modulo-2 adder ## = 1 + nu(:) = one more than length of each shift register ## g = generator sequences, k-by-n ## k = bits per input symbol = number of shift registers ## n = bits per output symbol = number of modulo-2 adders [nr, k] = size (m); if (nr != 1) error ("poly2trellis: M must be a 1-by-k positive integer row vector"); endif if (! (all (m == fix (m)) && all (m > 0))) error ("poly2trellis: M must be a 1-by-k positive integer row vector"); endif [nr, n] = size (g); if (nr != k) error ("poly2trellis: G must be a k-by-n octal matrix"); endif ## Convert g to decimal, let oct2dec validate the octal values g = oct2dec (g); ## Check the ranges of the generators ## nu = total number of linear shift registers for all k nu = sum (m) - k; ## Number of states and input symbols needed to capture the state machine nstates = 2^nu; ninputs = 2^k; noutputs = 2^n; t = struct ("numInputSymbols", ninputs, "numOutputSymbols", noutputs, "numStates", nstates, "nextStates", zeros (nstates, ninputs), "outputs", zeros (nstates, ninputs)); ## Split state indices into values for each distinct shift register. ## Also precalculate new bit position for each shift register and the left ## shifts required to reassemble the states into one state value. ## ## Conventions: ## - Each shift register shifts to the right, MSB-to-LSB ## - The MSB of each shift register is the newest input ## - The MSBs of the state represent the k=1 shift register statebits = de2bi (0:nstates - 1); states = zeros (nstates, k); newbit = zeros (1, k); shifts = zeros (1, k); offset = 1; for i = 1:k nu_i = m(i) - 1; if (nu_i > 0) states(:,i) = bi2de (statebits(:, offset:offset + nu_i - 1)); endif newbit(i) = bitshift (1, nu_i); shifts(i) = offset - 1; offset += nu_i; if (any (g(i,:) >= 2^m(i))) error ("poly2trellis: code size is greater than constraint length"); endif if (all (g(i,:) < 2^nu_i) || !any (mod (g(i,:), 2))) error ("poly2trellis: code size is less than constraint length"); endif endfor ## Generate conversion list of all possible output octal values outputs = str2num (dec2base (0:noutputs - 1, 8)); ## Walk the trellis, each row index is state, each column index is input for s = 1:nstates for i = 1:k ## For each next input bit [0,1] calculate inputs to modulo-2 adder ## and the next state for the ith linear shift register, left-shifted ## to be combined into the total state. state = states(s,i) + [0; newbit(i)]; next = bitshift (bitshift (state, -1), shifts(i)); ## Calculate the modulo-2 sum of the state plus input for each n for ## this particular shift register. ## The MSB of the output represents the n=1 generator(s) out = [0; 0]; for adder = 1:n val = mod (sum (de2bi (bitand (g(i, adder), state)), 2), 2); out += bitshift (val, n - adder); endfor ## Accumulate contributions to the trellis for this shift register. ## The contribution to each input symbol depends on whether the ## (k-i)th bit is 0 or 1. bitpos = k - i; for symbol = 1:ninputs idx = bitget (symbol - 1, bitpos + 1) + 1; t.nextStates(s, symbol) += next(idx); t.outputs(s, symbol) = bitxor (t.outputs(s, symbol), out(idx)); endfor endfor ## Convert output values to octal representation t.outputs(s,:) = outputs(t.outputs(s,:) + 1); endfor endfunction %% Test the simple (2,1,3) encoder from Lin & Costello example 11.1 %!test %! T = struct ("numInputSymbols", 2, %! "numOutputSymbols", 4, %! "numStates", 8, %! "nextStates", [0 4; 0 4; 1 5; 1 5; 2 6; 2 6; 3 7; 3 7], %! "outputs", [0 3; 3 0; 3 0; 0 3; 1 2; 2 1; 2 1; 1 2]); %! t = poly2trellis (4, [13 17]); %! assert (t, T) %! assert (istrellis (t), true) %% Test input validation %!error poly2trellis () %!error poly2trellis (1, 2, 3) %!error poly2trellis (1) %!error poly2trellis (2, 8) %!error poly2trellis (0, 0) %!error poly2trellis (2, 0) %!error poly2trellis (2, 2) %!error poly2trellis (2, 7) communications-1.2.1/inst/PaxHeaders.3802/convenc.m0000644000000000000000000000013112510010473016772 xustar0030 mtime=1428164923.866511933 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/convenc.m0000644000000000000000000000723512510010473017327 0ustar00rootroot00000000000000## Copyright (C) 2013 Mike Miller ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} convenc (@var{msg}, @var{t}) ## @deftypefnx {Function File} {@var{y} =} convenc (@var{msg}, @var{t}, @var{punct}) ## @deftypefnx {Function File} {@var{y} =} convenc (@var{msg}, @var{t}, @var{punct}, @var{s0}) ## @deftypefnx {Function File} {[@var{y}, @var{state_end}] =} convenc (@dots{}) ## Encode the binary vector @var{msg} with the convolutional encoder ## described by the trellis structure @var{t}. ## ## The rate @math{k/n} convolutional encoder encodes @math{k} bits at a ## time from the input vector and produces @math{n} bits at a time into the ## output vector. The input @var{msg} must have a length that is a multiple ## of @math{k}. ## ## If the initial state @var{s0} is specified, it indicates the internal ## state of the encoder when the first @math{k} input bits are fed in. The ## default value of @var{s0} is 0. ## ## The optional output argument @var{state_end} indicates the internal state ## of the encoder after the last bits are encoded. This allows the state of ## the encoder to be saved and applied to the next call to @code{convenc} to ## process data in blocks. ## ## @seealso{poly2trellis} ## @end deftypefn function [y, state_end] = convenc (msg, t, punct, s0 = 0) if (nargin < 2 || nargin > 4) print_usage (); endif if (! (isvector (msg) && all (msg == 0 | msg == 1))) error ("convenc: MSG must be a binary vector"); endif if (! istrellis (t)) error ("convenc: T must be a valid trellis structure"); endif if (nargin < 3) punct = []; endif if (! isempty (punct)) warning ("convenc: ignoring PUNCT, puncturing is not yet implemented"); endif ## FIXME: Add error check for valid punct binary vector if (nargin == 4 && ! (isscalar (s0) && s0 == fix (s0) && s0 >= 0 && s0 < t.numStates)) error ("convenc: S must be an integer in the range [0,T.numStates-1]"); endif k = log2 (t.numInputSymbols); n = log2 (t.numOutputSymbols); in_symbols = numel (msg) / k; if (in_symbols != fix (in_symbols)) error ("convenc: length of MSG must be a multiple of k"); endif transpose = (columns (msg) == 1); msg = msg(:).'; state = s0; y = []; ## FIXME: Implement output puncturing for idx = 1:k:numel (msg) in_sym = bi2de (msg(idx:idx+k-1), "left-msb"); out_sym = oct2dec (t.outputs(state+1,in_sym+1)); state = t.nextStates(state+1,in_sym+1); out_bits = de2bi (out_sym, n, "left-msb"); y = [y out_bits]; endfor if (transpose) y = y(:); endif if (nargout > 1) state_end = state; endif endfunction %!test %! t = poly2trellis (1, 1); %! m = randi ([0 1], 128, 1); %! [y, s] = convenc (m, t); %! assert (y, m) %! assert (s, 0) %!test %! t = poly2trellis (3, [7 5]); %! m = [1 1 0 1 1 1 0 0 1 0 0 0]; %! y = [1 1 0 1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 1 0 1 1 0 0]; %! assert (convenc (m, t), y) %% Test input validation %!error convenc () %!error convenc (1) %!error convenc (1, 2) %!error convenc (1, 2, 3, 4, 5) communications-1.2.1/inst/PaxHeaders.3802/fibodeco.m0000644000000000000000000000013112510010473017111 xustar0030 mtime=1428164923.870511841 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/fibodeco.m0000644000000000000000000000530412510010473017441 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} fibodeco (@var{code}) ## ## Returns the decoded Fibonacci value from the binary vectors @var{code}. ## Universal codes like Fibonacci codes have a useful synchronization property, ## only for 255 maximum value we have designed these routines. We assume ## user has partitioned the code into several unique segments based on ## the suffix property of unique strings "11" and we just decode the ## parts. Partitioning the stream is as simple as identifying the ## "11" pairs that occur, at the terminating ends. This system implements ## the standard binary Fibonacci codes, which means that row vectors ## can only contain 0 or 1. Ref: @url{http://en.wikipedia.org/wiki/Fibonacci_coding} ## ## @example ## @group ## fibodeco (@{[0 1 0 0 1 1]@}) ## @result{} 10 ## fibodeco (@{[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]@}) ## @result{} [1, 2, 3, 4] ## @end group ## @end example ## @seealso{fiboenco} ## @end deftypefn function num = fibodeco (code) ## ## generate fibonacci series table. ## ## f(1)=1; ## f(2)=1; ## ## while ((f(end-1)+f(end)) < 256) ## val=(f(end-1)+f(end)); ## f=[f val]; ## endwhile ## f=f(2:end); ## ## all numbers terminate with 1 except 0 itself. ## ## ## f= [75025 46368 28657 17711 10946 6765 4181 2584 \ ## 1597 987 610 377 233 144 89 55 \ ## 34 21 13 8 5 3 2 1]; ## ## f= [ 233 144 89 55 34 21 13 8 5 3 2 1]; f = [1 2 3 5 8 13 21 34 55 89 144 233]; L_C = length (code); if (nargin != 1) print_usage (); endif for j = 1:L_C word = code{j}; ## discard the terminating 1. word = word(1:end-1); L = length (word); num(j) = sum (word.*f(1:L)); endfor endfunction %!assert (fibodeco ({[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]}), [1:4]) %!assert (fibodeco ({[0 1 0 0 1 1]}), 10) %% Test input validation %!error fibodeco () %!error fibodeco (1, 2) communications-1.2.1/inst/PaxHeaders.3802/shannonfanodeco.m0000644000000000000000000000013112510010473020502 xustar0030 mtime=1428164923.930510477 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/shannonfanodeco.m0000644000000000000000000001063012510010473021030 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} shannonfanodeco (@var{hcode}, @var{dict}) ## ## Returns the original signal that was Shannon-Fano encoded. The signal ## was encoded using @code{shannonfanoenco}. This function uses ## a dict built from the @code{shannonfanodict} and uses it to decode a signal ## list into a Shannon-Fano list. Restrictions include hcode is expected to be a binary code; ## returned signal set that strictly belongs in the @code{range [1,N]}, ## with @code{N = length (dict)}. Also dict can only be from the ## @code{shannonfanodict (...)} routine. Whenever decoding fails, ## those signal values are indicated by -1, and we successively ## try to restart decoding from the next bit that hasn't failed in ## decoding, ad-infinitum. ## ## An example use of @code{shannonfanodeco} is ## @example ## @group ## hd = shannonfanodict (1:4, [0.5 0.25 0.15 0.10]); ## hcode = shannonfanoenco (1:4, hd) ## @result{} hcode = [0 1 0 1 1 0 1 1 1 0] ## shannonfanodeco (hcode, hd) ## @result{} [1 2 3 4] ## @end group ## @end example ## @seealso{shannonfanoenco, shannonfanodict} ## @end deftypefn function sig = shannonfanodeco (hcode, dict) if (nargin != 2 || ! iscell (dict)) print_usage (); endif if (max (hcode) > 1 || min (hcode) < 0) error ("shannonfanodeco: all elements of HCODE must be in the range [0,1]"); endif ## FIXME: ## O(log(N)) algorithms exist, but we need some effort to implement those ## Maybe sometime later, it would be a nice 1-day project ## Ref: A memory efficient Shannonfano Decoding Algorithm, AINA 2005, IEEE ## ## FIXME: Somebody can implement a "faster" algorithm than O(N^3) at present ## Decoding Algorithm O(N+k*log(N)) which is approximately O(N+Nlog(N)) ## ## 1. Separate the dictionary by the lengths ## and knows symbol correspondence. ## ## 2. Find the symbol in the dict of lengths l,h where ## l = smallest cw length ignoring 0 length CW, and ## h = largest cw length , with k=h-l+1; ## ## 3. Match the k codewords to the dict using binary ## search, and then you can declare decision. ## ## 4. In case of non-decodable words skip the start-bit ## used in the previous case, and then restart the same ## procedure from the next bit. ## L = length (dict); lenL = length (dict{1}); lenH = 0; ## ## Know the ranges of operation ## for itr = 1:L t = length (dict{itr}); if (t < lenL) lenL = t; endif if (t > lenH) lenH = t; endif endfor ## ## Now do a O(N^4) algorithm ## itr = 0; # offset into the hcode sig = []; # output CL = length (hcode); ## whole decoding loop. while (itr < CL) ## decode one element (or just try to). for itr_y = lenL:lenH ## look for word in dictionary. ## with flag to indicate found ## or not found. Detect end of buffer. if ((itr+itr_y) > CL) break; endif word = hcode(itr+1:itr+itr_y); flag = 0; ## word ## search loop. for itr_z = 1:L if (isequal (dict{itr_z}, word)) itr = itr + itr_y; sig = [sig itr_z]; flag = 1; break; endif endfor if (flag == 1) break; # also need to break_ above then. endif endfor ## could not decode if (flag == 0) itr = itr + 1; sig = [sig -1]; endif endwhile endfunction %!assert (shannonfanodeco (shannonfanoenco (1:4, shannonfanodict (1:4, [0.5 0.25 0.15 0.10])), shannonfanodict (1:4, [0.5 0.25 0.15 0.10])), [1:4], 0) %% Test input validation %!error shannonfanodeco () %!error shannonfanodeco (1) %!error shannonfanodeco (1, 2, 3) %!error shannonfanodeco (1, 2) %!error shannonfanodeco (2, {}) communications-1.2.1/inst/PaxHeaders.3802/prbs_iterator.m0000644000000000000000000000013112510010473020216 xustar0030 mtime=1428164923.882511568 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/prbs_iterator.m0000644000000000000000000001122312510010473020543 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{outputseq}, @var{prbs}] =} prbs_iterator (@var{prbs}, @var{iterations}) ## This function generates the output bits from the PRBS ## state, for the number of iterations specified. ## ## First argument is the PRBS structure obtained from prbs_generator. ## PRBS iterations is specified in the second argument. ## PRBS start state is taken from the prbs.sregs. ## ## Second argument of the output is PRBS structure with a new ## state. This allows usage like: ## ## @example ## [seq, prbs] = prbs_iterator (prbs, niterations); ## @end example ## ## while the state of the PRBS is updated. ## ## Example: If you had a PRBS shift register like the diagram ## below with 4 registers we use representation by polynomial ## of [ 1 2 3 4], and feedback connections between [ 1 3 4 ]. ## The output PRBS sequence is taken from the position 4. ## ## @example ## @group ## +---+ +----+ +---+ +---+ ## | D |----| D |---| D |---| D | ## +---+ +----+ +---+ +---+ ## | | | ## \ / / ## [+]---------------+------+ ## 1 + 0.D + 1.D^2 + 1.D^3 ## @end group ## @end example ## ## The code to implement this PRBS will be ## ## @example ## @group ## prbs = prbs_generator ([1 3 4], @{[1 3 4]@}, [1 0 1 1]); ## x = prbs_iterator (prbs, 15) ## @result{} x = [1 1 0 1 0 1 1 1 1 0 0 0 1 0 0] ## @end group ## @end example ## @seealso{prbs_generator, prbs_sequence} ## @end deftypefn function [outputseq, prbs] = prbs_iterator (prbs, iterations = 2^(prbs.reglen)-1) if (nargin < 1 || nargin > 2) print_usage (); endif outputseq = zeros (1, iterations); nstate = zeros (1, prbs.reglen); ## For each iteration, shift the output bit. Then compute the xor pattern of connections. ## Finally apply feedback the stuff. Insert the computed pattern. for itr = 1:iterations ## save output. outputseq(itr) = prbs.sregs(prbs.reglen); ## compute the feedback. for itr2 = 1:prbs.conlen val = 0; L = length (prbs.connections{itr2}); for itr3 = 2:L val = bitxor (val, prbs.sregs(prbs.connections{itr2}(itr3))); endfor nstate(prbs.connections{itr2}(1)) = val; endfor ## rotate the output discarding the last output. prbs.sregs = [0 prbs.sregs(1:prbs.reglen-1)]; ## insert the feedback. for itr2 = 1:prbs.conlen prbs.sregs(itr2) = nstate(itr2); nstate(itr2) = 0; # reset. endfor endfor endfunction ## ## TEST CASES FOR PRBS. ## ## ## 2^31 -1 : D31 + D28 + 1 =0 inverted ## 2^23 -1 : D23 + D18 + 1 = 0 , ## 2^15 -1 : D15 + D14 + 1 = 0, ## 2^10 -1 : D10 + D7 + 1 = 0, ## 2^7 -1 : D7 + D6 + 1 = 0, ## 2^4 -1 : D3 + D2 + 1 = 0, ## ## +---+ +----+ +---+ +---+ ## | D |----| D |---| D |---| D | ## +---+ +----+ +---+ +---+ ## | | | ## \ / / ## [+]---------------+------+ ## 1 + 0.D + 1.D^2 + 1.D^3 ## ## ## prbs=prbs_generator([1 3 4],{[1 3 4]},[1 0 1 1]); ## x = prbs_iterator(prbs,15) ## y = prbs_iterator(prbs,30)(16:end) ## z = prbs_sequence(prbs) ## exit ## break ## ## Multiple Tap, Simple Sequence Generator. ## ## n=10; ## k=8; ## inits=round(abs(rand(1,n)*1.0)) ## prbs=prbs_generator([n 1],{[1 2 k n-1 n]},inits); ## prbs_iterator(prbs,1023) ## prbs_seqlength(prbs,inits) ##prbs=prbs_generator([1 2 3],{[1 2 3]},[1 1 1]); ##prbs_iterator(prbs,7) ## ## 2^4 -1 : D4 + D1 + 1 = 0, ## ## +---+ +----+ +---+ +---+ ## | D |----| D |---| D |---| D | ## +---+ +----+ +---+ +---+ ## | | | ## \ / / ## [+]---------------+------+ ## 1 + 0.D + 1.D^2 + 1.D^3 ## ##prbs=prbs_generator([1 3 4],{[1 2 4]},[1 0 1 1]); ##prbs_iterator(prbs,16) ##prbs_iterator(prbs,32) ##prbs=prbs_generator([7],{[1 7 6]},[1 0 0 1 0 0 0]); ##y=prbs_iterator(prbs,128); ##x=prbs_iterator(prbs,256); %% Test input validation %!error prbs_iterator () %!error prbs_iterator (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/reedmullerenc.m0000644000000000000000000000013012510010473020164 xustar0029 mtime=1428164923.91851075 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/reedmullerenc.m0000644000000000000000000000361212510010473020515 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} reedmullerenc (@var{MSG}, @var{R}, @var{M}) ## ## Definition type construction of Reed-Muller code, ## of order @var{R}, length @math{2^M}. This function ## returns the generator matrix for the said order RM code. ## ## Encodes the given message word/block, of column size k, ## corresponding to the RM(@var{R},@var{M}), and outputs a ## code matrix @var{C}, on each row with corresponding codeword. ## The second return value is the @var{G}, which is generator matrix ## used for this code. ## ## @example ## @group ## msg = rand (10, 11) > 0.5; ## [c, g] = reedmullerenc (msg, 2, 4); ## @end group ## @end example ## @seealso{reedmullerdec, reedmullergen} ## @end deftypefn function [C, G] = reedmullerenc (MSG, R, M) if (nargin != 3) print_usage (); endif G = reedmullergen (R, M); if (columns (MSG) != rows (G)) error ("reedmullerenc: MSG must be a matrix with K columns"); endif C = zeros (rows (MSG), 2.^M); for idx = 1:rows (MSG) C(idx,:) = mod (MSG(idx,:)*G, 2); endfor endfunction %% Test input validation %!error reedmullerenc () %!error reedmullerenc (1) %!error reedmullerenc (1, 2) %!error reedmullerenc (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/shannonfanodict.m0000644000000000000000000000013112510010473020513 xustar0030 mtime=1428164923.930510477 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/shannonfanodict.m0000644000000000000000000000631212510010473021043 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} shannonfanodict (@var{symbols}, @var{symbol_probabilites}) ## ## Returns the code dictionary for source using Shannon-Fano algorithm. ## Dictionary is built from @var{symbol_probabilities} using the ## Shannon-Fano scheme. Output is a dictionary cell-array, which ## are codewords, and correspond to the order of input probability. ## ## @example ## @group ## cw = shannonfanodict (1:4, [0.5 0.25 0.15 0.1]); ## assert (redundancy (cw, [0.5 0.25 0.15 0.1]), 0.25841, 0.001) ## shannonfanodict (1:5, [0.35 0.17 0.17 0.16 0.15]) ## shannonfanodict (1:8, [8 7 6 5 5 4 3 2] / 40) ## @end group ## @end example ## @seealso{shannonfanoenc, shannonfanodec} ## @end deftypefn function cw_list = shannonfanodict (symbol, P) if (nargin != 2) print_usage (); endif DMAX = length (P); S = 1:DMAX; if (sum (P) - 1.000 > 1e-7) error ("shannonfanodict: the elements of P must add up to 1"); endif ## ## FIXME: Is there any other way of doing the ## topological sort? Insertion sort is bad. ## ## Sort the probability list in ## descending/non-increasing order. ## Using plain vanilla insertion sort. ## for i = 1:DMAX for j = i:DMAX if (P(i) < P(j)) ## Swap prob t = P(i); P(i) = P(j); P(j) = t; ## Swap symb t = S(i); S(i) = S(j); S(j) = t; endif endfor endfor ## Now for each symbol you need to ## create code as first [-log p(i)] bits of ## cumulative function sum(p(1:i)) ## ## printf("Shannon Codes\n"); ## data_table=zeros(1,DMAX); cw_list = {}; for itr = 1:DMAX if (P(itr) != 0) digits = ceil (-log2 (P(itr))); # somany digits needed. else digits = 0; # dont assign digits for zero probability symbols. endif Psum = sum ([0 P](1:itr)); # Cumulative probability s = []; for i = 1:digits; Psum = 2 * Psum; if (Psum >= 1.00) s = [s 1]; Psum = Psum - 1.00; else s = [s 0]; endif endfor cw_list{itr} = s; endfor ## re-arrange the list accroding to input prob list. cw_list2 = {}; for i = 1:length (cw_list) cw_list2{i} = cw_list{S(i)}; endfor cw_list = cw_list2; endfunction %!shared CW, P %!test %! P = [0.5 0.25 0.15 0.1]; %! assert (shannonfanodict (1:4, P), {[0], [1 0], [1 1 0], [1 1 1 0]}) %% Test input validation %!error shannonfanodict () %!error shannonfanodict (1) %!error shannonfanodict (1, 2, 3) %!error shannonfanodict (1, [0.5 0.5 0.5]) communications-1.2.1/inst/PaxHeaders.3802/randerr.m0000644000000000000000000000013112510010473016774 xustar0030 mtime=1428164923.886511478 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/randerr.m0000644000000000000000000000755312510010473017334 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} =} randerr (@var{n}) ## @deftypefnx {Function File} {@var{b} =} randerr (@var{n}, @var{m}) ## @deftypefnx {Function File} {@var{b} =} randerr (@var{n}, @var{m}, @var{err}) ## @deftypefnx {Function File} {@var{b} =} randerr (@var{n}, @var{m}, @var{err}, @var{seed}) ## ## Generate a matrix of random bit errors. The size of the matrix is ## @var{n} rows by @var{m} columns. By default @var{m} is equal to @var{n}. ## Bit errors in the matrix are indicated by a 1. ## ## The variable @var{err} determines the number of errors per row. By ## default the return matrix @var{b} has exactly one bit error per row. ## If @var{err} is a scalar, there each row of @var{b} has exactly this ## number of errors per row. If @var{err} is a vector then each row has ## a number of errors that is in this vector. Each number of errors has ## an equal probability. If @var{err} is a matrix with two rows, then ## the first row determines the number of errors and the second their ## probabilities. ## ## The variable @var{seed} allows the random number generator to be seeded ## with a fixed value. The initial seed will be restored when returning. ## @end deftypefn function b = randerr (n, m, err, seed) switch (nargin) case 0 m = 1; n = 1; err = 1; seed = Inf; case 1 m = n; err = 1; seed = Inf; case 2 err = 1; seed = Inf; case 3 seed = Inf; case 4 otherwise print_usage (); endswitch ## Check error vector [ar, ac] = size (err); if (ac == 1) if (ar > 1) err = err'; endif elseif ((ac > 1) && (ar != 1) && (ar != 2)) error ("randerr: ERR must be a scalar, a vector, or a matrix with 2 rows"); endif for i = 1:ac if (err(1,i) > m) error ("randerr: number of errors in ERR must be no greater than M"); endif endfor # Use randsrc to calculate the number of errors per row nerrs = randsrc (n, 1, err, seed); # Now put to errors into place in the return matrix b = zeros (n, m); for i = 1:n if (nerrs(i) > 0) if (nerrs(i) == 1) indx = sort (randint (1, nerrs(i), m, seed)); else do indx = sort (randint (1, nerrs(i), m, seed)); until (! any (indx(1:nerrs(i)-1) == indx(2:nerrs(i)))) endif b(i,indx+1) = ones (1, nerrs(i)); endif endfor endfunction %!shared n, err1, err2, seed, a1, a2, a3, a4, a5, a6 %! n = 10; err1 = 2; err2 = [1, 2; 0.7, 0.3] ; seed = 1; %! a1 = randerr (n); a2 = randerr (n, n); %! a3 = randerr (n, n, err1); a4 = randerr (n, n, err2); %! a5 = randerr (n, n, err1, seed); a6 = randerr (n, n, err1, seed); %!error randerr (n, n, n, n, n); %!assert (size (a1) == [n, n] && size (a2) == [n, n]); %!assert (all (sum (a1.') == 1) && all (sum (a2.') == 1)) %!assert (all ((a1(:) == 1 | a1(:) == 0)) && all ((a2(:) == 1 | a2(:) == 0))) %!assert (size (a3) == [n, n] && size (a4) == [n, n]); %!assert (all (sum (a3.') == err1)) %!assert (all ((a3(:) == 1 | a3(:) == 0))) %!assert (all ((sum (a4.') == err2(1,1)) | (sum (a4.') == err2(1,2)))) %!assert (all ((a4(:) == 1 | a4(:) == 0))) %!assert (a5(:) == a6(:)); %% Test input validation %!error randerr (1, 2, 3, 4, 5) communications-1.2.1/inst/PaxHeaders.3802/minpol.m0000644000000000000000000000013012510010473016634 xustar0029 mtime=1428164923.87851166 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/minpol.m0000644000000000000000000000452012510010473017164 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} minpol (@var{v}) ## ## Finds the minimum polynomial for elements of a Galois Field. For a ## vector @var{v} with @math{N} components, representing @math{N} values ## in a Galois Field GF(2^@var{m}), return the minimum polynomial in GF(2) ## representing those values. ## @end deftypefn function r = minpol (v) if (nargin != 1) print_usage (); endif if (!isgalois (v)) error ("minpol: V must be a Galois field scalar or vector"); endif if (min (size (v)) > 1 || nargin != 1) print_usage (); endif n = length (v); m = v.m; prim_poly = v.prim_poly; r = zeros (n, m + 1); ## Find cosets of GF(2^m) and convert from cell array to matrix cyclocoset = cosets (m, prim_poly); cyclomat = zeros (max (size (cyclocoset)), m); for j = 1:max (size (cyclocoset)) cyclomat(j,1:length (cyclocoset{j})) = cyclocoset{j}; endfor for j = 1:n if (v(j) == 0) ## Special case r(j,m-1) = 1; else ## Find the coset within which the current element falls [rc, ignored] = find (cyclomat == v(j)); rv = cyclomat(rc,:); ## Create the minimum polynomial from its roots ptmp = gf ([1, rv(1)], m, prim_poly); for i = 2:length (rv) ptmp = conv (ptmp, [1, rv(i)]); endfor ## Need to left-shift polynomial to divide by x while can i = 0; while (!ptmp(m+1-i)) i = i + 1; endwhile ptmp = [zeros(1, i), ptmp(1:m+1-i)]; r(j,:) = ptmp; endif endfor ## Ok, now put the return value into GF(2) r = gf (r, 1); endfunction %% Test input validation %!error minpol () %!error minpol (1) %!error minpol (1, 2) communications-1.2.1/inst/PaxHeaders.3802/helintrlv.m0000644000000000000000000000013112510010473017346 xustar0030 mtime=1428164923.874511751 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/helintrlv.m0000644000000000000000000000437612510010473017706 0ustar00rootroot00000000000000## Copyright (C) 2010 Mark Borgerding ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{outdata} =} helintrlv (@var{data}, @var{col}, @var{ngrp}, @var{stp}) ## @var{col}-by-@var{ngrp}. ## @seealso{heldeintrlv} ## @end deftypefn function [outdata, outstate] = helintrlv (data, col, ngrp, stp, init_state) if (nargin < 4 || nargin > 5) print_usage (); endif if (! (isscalar (col) && col == fix (col))) error ("helintrlv: COL must be an integer"); endif if (! (isscalar (ngrp) && ngrp == fix (ngrp))) error ("helintrlv: NGRP must be an integer"); endif didTranspose = 0; if (isvector (data) && columns (data) > rows (data)) data = data.'; didTranspose = 1; endif s = size (data); if (s(1) != col*ngrp) error ("helintrlv: DATA must have length equal to COL*NGRP"); endif if (nargin == 4) init_state = zeros (stp*col*(col-1)/2, s(2)); endif outstate = []; # for each column for k = 1:s(2) tmp = reshape (data(:,k), ngrp, col); instate = init_state(:,k); outstateCol = []; for k1 = 2:col curStepSize = (k1-1)*stp; tmpCol = [instate(1:curStepSize); tmp(:,k1)]; tmp(:,k1) = tmpCol(1:ngrp); outstateCol = [outstateCol; tmpCol(end+1-curStepSize:end)]; instate = instate(curStepSize+1:end); endfor outdata(:,k) = reshape (tmp.', s(1), 1); outstate = [outstate outstateCol]; endfor if (didTranspose) outdata = outdata.'; endif endfunction %% Test input validation %!error helintrlv () %!error helintrlv (1) %!error helintrlv (1, 2) %!error helintrlv (1, 2, 3) %!error helintrlv (1, 2, 3, 4, 5, 6) communications-1.2.1/inst/PaxHeaders.3802/ademodce.m0000644000000000000000000000013112510010473017100 xustar0030 mtime=1428164923.862512023 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/ademodce.m0000644000000000000000000001457412510010473017441 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-tc", offset) ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-tc/costas", offset) ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-sc") ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-sc/costas") ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amssb") ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "qam") ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "qam/cmplx") ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "fm", @var{dev}) ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "pm", @var{dev}) ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, [@var{Fs}, @var{iphs}], @dots{}) ## @deftypefnx {Function File} {@var{y} =} ademodce (@dots{}, @var{num}, @var{den}) ## ## Baseband demodulator for analog signals. The input signal is specified by ## @var{x}, its sampling frequency by @var{Fs} and the type of modulation ## by the third argument, @var{typ}. The default values of @var{Fs} is 1 and ## @var{typ} is "amdsb-tc". ## ## If the argument @var{Fs} is a two element vector, the first element ## represents the sampling rate and the second the initial phase. ## ## The different types of demodulations that are available are ## ## @table @asis ## @item "am" ## @itemx "amdsb-tc" ## Double-sideband with carrier ## @item "amdsb-tc/costas" ## Double-sideband with carrier and Costas phase locked loop ## @item "amdsb-sc" ## Double-sideband with suppressed carrier ## @item "amssb" ## Single-sideband with frequency domain Hilbert filtering ## @item "qam" ## Quadrature amplitude demodulation. In-phase in odd-columns and quadrature ## in even-columns ## @item "qam/cmplx" ## Quadrature amplitude demodulation with complex return value. ## @item "fm" ## Frequency demodulation ## @item "pm" ## Phase demodulation ## @end table ## ## Additional arguments are available for the demodulations "amdsb-tc", "fm", ## "pm". These arguments are ## ## @table @code ## @item offset ## The offset in the input signal for the transmitted carrier. ## @item dev ## The deviation of the phase and frequency modulation ## @end table ## ## It is possible to specify a low-pass filter, by the numerator @var{num} ## and denominator @var{den} that will be applied to the returned vector. ## ## @seealso{ademodce, dmodce} ## @end deftypefn function y = ademodce (x, Fs, typ, varargin) if (nargin < 1) print_usage (); elseif (nargin < 2) Fs = 1; typ = "am"; elseif (nargin < 3) typ = "am"; endif if (isempty (Fs)) Fs = 1; iphs = 0; elseif (isscalar (Fs)) iphs = 0; else if ((max (size (Fs)) != 2) || (min (size (Fs)) != 1)) error ("ademodce: FS must be a scalar or a 2-element vector"); endif Fs = Fs(1); iphs = Fs(2); endif ## Pass the optional arguments dev = 1; num = []; den = []; narg = 1; if (!ischar (typ)) error ("ademodce: demodulation type must be a string"); elseif (strcmp (typ, "am") || strcmp (typ, "amdsb-tc")) if (length (varargin) > 0) offset = varargin{1}; narg = narg + 1; endif elseif (strcmp (typ, "fm") || strcmp (typ, "pm")) if (length (varargin) > 0) dev = varargin{1}; narg = narg + 1; endif endif if (length (varargin) == narg) error ("ademodce: must specify numerator and denominator of transfer function"); elseif (length (varargin) == narg+1) num = varargin{narg}; den = varargin{narg+1}; elseif (length (varargin) != narg - 1) error ("ademodce: too many arguments"); endif if (strcmp (typ, "am") || findstr (typ, "amdsb-tc")) if (findstr (typ, "/costas")) error ("ademodce: Costas phase locked loop not yet implemented"); endif y = real (x * exp (-1i * iphs)); if (exist ("offset", "var")) y = y - offset; else if (min (size (y)) == 1) y = y - mean (y); else for i = 1:size (y, 2) y(:,i) = y(:,i) - mean (y(:,i)); endfor endif endif elseif (strcmp (typ, "amdsb-sc")) y = real (x * exp (-1i * iphs)); elseif (findstr (typ, "amssb")) if (findstr (typ, "/costas")) error ("ademodce: Costas phase locked loop not yet implemented"); endif y = real (x * exp (-1i * iphs)); elseif (strcmp (typ, "qam")) y1 = x * exp (-1i * iphs); y = zeros (size (y1, 1), 2*size (y1, 2)); y(:,1:2:size (y, 2)) = real (y1); y(:,2:2:size (y, 2)) = imag (y1); elseif (strcmp (typ, "qam/cmplx")) y = x * exp (-1i * iphs); elseif (strcmp (typ, "pm")) y = ( -1i * log (x) + iphs) / dev; elseif (strcmp (typ, "fm")) ## This can't work as it doesn't take into account the ## phase wrapping in the modulation process. Therefore ## we'll get some of the demodulated values in error, with ## most of the values being correct.. ## ## Not sure the best approach to fixing this. Perhaps implement ## a PLL with the ouput of the phase detector being the demodulated ## signal... warning ("ademodce: FM demodulation broken!!") pm = Fs / dev / pi * ( - 1i * log (x) + iphs) y = [pm(:,1), (pm(:,2:size (pm, 2)) - pm(:,1:size (pm, 2)-1))]; else error ("ademodce: unknown demodulation type '%s'", typ); endif if (!isempty (num) && !isempty (dem)) ## Low-pass filter the output if (min (size (y)) == 1) y = filter (num, den, y); else for i = 1:size (y, 2) y(:,i) = filter (num, den, y(:,i)); endfor endif endif endfunction %% Test input validation %!error ademodce () %!error ademodce (1, 2, "invalid") %!error ademodce (1, 2, "am", 3, 4, 5, 6) communications-1.2.1/inst/PaxHeaders.3802/rsencof.m0000644000000000000000000000013112510010473016776 xustar0030 mtime=1428164923.926510568 29 atime=1428164924.04650783 30 ctime=1428164983.712815029 communications-1.2.1/inst/rsencof.m0000644000000000000000000000671612510010473017336 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} rsencof (@var{in}, @var{out}) ## @deftypefnx {Function File} {} rsencof (@var{in}, @var{out}, @var{t}) ## @deftypefnx {Function File} {} rsencof (@dots{}, @var{pad}) ## ## Encodes an ASCII file using a Reed-Solomon coder. The input file is ## defined by @var{in} and the result is written to the output file @var{out}. ## The type of coding to use is determined by whether the input file is 7- ## or 8-bit. If the input file is 7-bit, the default coding is [127,117]. ## while the default coding for an 8-bit file is a [255, 235]. This allows ## for 5 or 10 error characters in 127 or 255 symbols to be corrected ## respectively. The number of errors that can be corrected can be overridden ## by the variable @var{t}. ## ## If the file is not an integer multiple of the message size (127 or 255) ## in length, then the file is padded with the EOT (ASCII character 4) ## characters before coding. Whether these characters are written to the ## output is defined by the @var{pad} variable. Valid values for @var{pad} ## are "pad" (the default) and "nopad", which write or not the padding ## respectively. ## ## @seealso{rsdecof} ## @end deftypefn function rsencof (in, out, varargin) if (nargin < 2 || nargin > 4) print_usage (); endif if (!ischar (in) || !ischar (out)) error ("rsencof: IN and OUT must be strings"); endif t = 0; pad = 1; for i = 1:length (varargin) arg = varargin{i}; if (ischar (arg)) if (strcmp (arg, "pad")) pad = 1; elseif (strcmp (arg, "nopad")) pad = 0; else error ("rsencof: unrecognized string argument"); endif else if (! (isscalar (t) && t == fix (d) && t > 0)) error ("rsencof: T must be a positive integer"); endif endif endfor try fid = fopen (in, "r"); catch error ("rsencof: could not open '%s' for reading", in); end_try_catch [msg, count] = fread (fid, Inf, "char"); fclose (fid); is8bit = (max (msg) > 127); if (is8bit) m = 8; n = 255; if (t == 0) t = 10; endif else m = 7; n = 127; if (t == 0) t = 5; endif endif k = n - 2 * t; ncodewords = ceil (count / k); npad = k * ncodewords - count; msg = reshape ([msg ; 4 * ones(npad, 1)], k, ncodewords)'; code = rsenc (gf (msg, m), n, k, "beginning")'; code = code(:); try fid = fopen (out, "w"); catch error ("rsencof: could not open '%s' for writing", out); end_try_catch if (pad) fwrite (fid, code, "char"); else fwrite (fid, code(1:(ncodewords*n-npad)), "char"); endif fclose (fid); endfunction %% Test input validation %!error rsencof () %!error rsencof (1) %!error rsencof (1, 2, 3, 4, 5) %!error rsencof (1, 2) %!error rsencof ("in", "out", 0) %!error rsencof ("in", "out", "invalid") communications-1.2.1/inst/PaxHeaders.3802/dpcmdeco.m0000644000000000000000000000013212510010473017116 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/dpcmdeco.m0000644000000000000000000000327012510010473017445 0ustar00rootroot00000000000000## Copyright (C) 2012 Leonardo Araujo ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{sig} =} dpcmdeco (@var{indx}, @var{codebook}, @var{predictor}) ## Decode using differential pulse code modulation (DPCM). ## ## @table @code ## @item sig = dpcmdeco (indx, codebook, predictor) ## Decode the signal coded by DPCM. ## Use the prediction model and the coded prediction error given by a codebook and ## the index of each sample in this codebook. ## ## @end table ## @seealso{dpcmenco, dpcmopt} ## @end deftypefn function sig = dpcmdeco (indx, codebook, predictor) if (nargin != 3) print_usage (); endif quants = codebook(indx+1); sig = zeros (size (quants)); for i = 1 : length (sig) ## signal prediction (convolution of signal and predictor coefficients) + quantization error sig(i) = sig(max (i - length (predictor) + 1, 1):i) * predictor(end:-1:max (end-i+1, 1))' + quants(i); endfor endfunction %% Test input validation %!error dpcmdeco () %!error dpcmdeco (1) %!error dpcmdeco (1, 2) %!error dpcmdeco (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/encode.m0000644000000000000000000000013212510010473016575 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/encode.m0000644000000000000000000002003312510010473017120 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{code} =} encode (@var{msg}, @var{n}, @var{k}) ## @deftypefnx {Function File} {@var{code} =} encode (@var{msg}, @var{n}, @var{k}, @var{typ}) ## @deftypefnx {Function File} {@var{code} =} encode (@var{msg}, @var{n}, @var{k}, @var{typ}, @var{opt}) ## @deftypefnx {Function File} {[@var{code}, @var{added}] =} encode (@dots{}) ## ## Top level block encoder. This function makes use of the lower level ## functions such as @code{cyclpoly}, @code{cyclgen}, @code{hammgen}, and ## @code{bchenco}. The message to code is pass in @var{msg}, the ## codeword length is @var{n} and the message length is @var{k}. This ## function is used to encode messages using either: ## ## @table @asis ## @item A [n,k] linear block code defined by a generator matrix ## @item A [n,k] cyclic code defined by a generator polynomial ## @item A [n,k] Hamming code defined by a primitive polynomial ## @item A [n,k] BCH code code defined by a generator polynomial ## @end table ## ## The type of coding to use is defined by the variable @var{typ}. This ## variable is a string taking one of the values ## ## @table @code ## @item "linear" ## @itemx "linear/binary" ## A linear block code is assumed with the coded message @var{code} being in ## a binary format. In this case the argument @var{opt} is the generator ## matrix, and is required. ## @item "cyclic" ## @itemx "cyclic/binary" ## A cyclic code is assumed with the coded message @var{code} being in a ## binary format. The generator polynomial to use can be defined in @var{opt}. ## The default generator polynomial to use will be ## @code{cyclpoly (@var{n}, @var{k})} ## @item "hamming" ## @itemx "hamming/binary" ## A Hamming code is assumed with the coded message @var{code} being in a ## binary format. In this case @var{n} must be of an integer of the form ## @code{2^@var{m}-1}, where @var{m} is an integer. In addition @var{k} ## must be @code{@var{n}-@var{m}}. The primitive polynomial to use can ## be defined in @var{opt}. The default primitive polynomial to use is ## the same as defined by @code{hammgen}. ## @item "bch" ## @itemx "bch/binary" ## A BCH code is assumed with the coded message @var{code} being in a binary ## format. The generator polynomial to use can be defined in @var{opt}. ## The default generator polynomial to use will be ## @code{bchpoly (@var{n}, @var{k})} ## @end table ## ## In addition the argument "binary" above can be replaced with "decimal", ## in which case the message is assumed to be a decimal vector, with each ## value representing a symbol to be coded. The binary format can be in two ## forms ## ## @table @code ## @item An @var{x}-by-@var{k} matrix ## Each row of this matrix represents a symbol to be coded ## @item A vector ## The symbols are created from groups of @var{k} elements of this vector. ## If the vector length is not divisible by @var{k}, then zeros are added ## and the number of zeros added is returned in @var{added}. ## @end table ## ## It should be noted that all internal calculations are performed in the ## binary format. Therefore for large values of @var{n}, it is preferable ## to use the binary format to pass the messages to avoid possible rounding ## errors. Additionally, if repeated calls to @code{encode} will be performed, ## it is often faster to create a generator matrix externally with the ## functions @code{hammgen} or @code{cyclgen}, rather than let @code{encode} ## recalculate this matrix at each iteration. In this case @var{typ} should ## be "linear". The exception to this case is BCH codes, whose encoder ## is implemented directly from the polynomial and is significantly faster. ## ## @seealso{decode, cyclgen, cyclpoly, hammgen, bchenco, bchpoly} ## @end deftypefn function [code, added] = encode (msg, n, k, typ, opt) if (nargin < 3 || nargin > 5) print_usage (); endif if (! (isscalar (n) && n == fix (n) && n >= 3)) error ("encode: N must be an integer greater than 3"); endif if (! (isscalar (k) && k == fix (k) && k <= n)) error ("encode: K must be an integer less than N"); endif if (nargin > 3) if (!ischar (typ)) error ("encode: TYP must be a string"); else ## Why the hell did matlab decide on such an ugly way of passing 2 args! if (strcmp (typ, "linear") || strcmp (typ, "linear/binary")) coding = "linear"; msgtyp = "binary"; elseif (strcmp (typ, "linear/decimal")) coding = "linear"; msgtyp = "decimal"; elseif (strcmp (typ, "cyclic") || strcmp (typ, "cyclic/binary")) coding = "cyclic"; msgtyp = "binary"; elseif (strcmp (typ, "cyclic/decimal")) coding = "cyclic"; msgtyp = "decimal"; elseif (strcmp (typ, "bch") || strcmp (typ, "bch/binary")) coding = "bch"; msgtyp = "binary"; elseif (strcmp (typ, "bch/decimal")) coding = "bch"; msgtyp = "decimal"; elseif (strcmp (typ, "hamming") || strcmp (typ, "hamming/binary")) coding = "hamming"; msgtyp = "binary"; elseif (strcmp (typ, "hamming/decimal")) coding = "hamming"; msgtyp = "decimal"; else error ("encode: invalid coding and/or message TYP '%s'", typ); endif endif else coding = "hamming"; msgtyp = "binary"; endif added = 0; if (strcmp (msgtyp, "binary")) vecttyp = 0; if (max (msg(:)) > 1 || min (msg(:)) < 0) error ("encode: MSG must be a binary matrix"); endif [ncodewords, k2] = size (msg); len = k2*ncodewords; if (min (k2, ncodewords) == 1) vecttyp = 1; msg = vec2mat (msg, k); ncodewords = size (msg, 1); elseif (k2 != k) error ("encode: MSG must be a matrix with K columns"); endif else if (!isvector (msg)) error ("encode: decimal MSG type must be a vector"); endif if (max (msg) > 2^k-1 || min (msg) < 0) error ("encode: all elements of MSG must be in the range [0,2^K-1]"); endif ncodewords = length (msg); msg = de2bi (msg(:), k); endif if (strcmp (coding, "bch")) if (nargin > 4) code = bchenco (msg, n, k, opt); else code = bchenco (msg, n, k); endif else if (strcmp (coding, "linear")) if (nargin > 4) gen = opt; if ((size (gen, 1) != k) || (size (gen, 2) != n)) error ("encode: generator matrix must be of size KxN"); endif else error ("encode: linear coding requires a generator matrix"); endif elseif (strcmp (coding, "cyclic")) if (nargin > 4) [par, gen] = cyclgen (n, opt); else [par, gen] = cyclgen (n, cyclpoly (n, k)); endif else m = log2 (n + 1); if (! (m == fix (m) && m >= 3 && m <= 16)) error ("encode: N must be equal to 2^M-1 for integer M in the range [3,16]"); endif if (k != (n-m)) error ("encode: K must be equal to N-M for Hamming coder"); endif if (nargin > 4) [par, gen] = hammgen (m, opt); else [par, gen] = hammgen (m); endif endif code = mod (msg * gen, 2); endif if (strcmp (msgtyp, "binary") && vecttyp == 1) code = code'; code = code(:); elseif (strcmp (msgtyp, "decimal")) code = bi2de (code); endif endfunction %% Test input validation %!error encode () %!error encode (1) %!error encode (1, 2) %!error encode (1, 2, 3, 4, 5, 6) %!error decode (1, 2, 3) %!error decode (1, 5, 6) %!error decode (1, 5, 3, "invalid") communications-1.2.1/inst/PaxHeaders.3802/wgn.m0000644000000000000000000000013212510010473016133 xustar0030 mtime=1428164923.938510295 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/wgn.m0000644000000000000000000001047112510010473016463 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} wgn (@var{m}, @var{n}, @var{p}) ## @deftypefnx {Function File} {@var{y} =} wgn (@var{m}, @var{n}, @var{p}, @var{imp}) ## @deftypefnx {Function File} {@var{y} =} wgn (@var{m}, @var{n}, @var{p}, @var{imp}, @var{seed}) ## @deftypefnx {Function File} {@var{y} =} wgn (@dots{}, @var{type}) ## @deftypefnx {Function File} {@var{y} =} wgn (@dots{}, @var{output}) ## ## Returns a M-by-N matrix @var{y} of white Gaussian noise. @var{p} specifies ## the power of the output noise, which is assumed to be referenced to an ## impedance of 1 Ohm, unless @var{imp} explicitly defines the impedance. ## ## If @var{seed} is defined then the randn function is seeded with this ## value. ## ## The arguments @var{type} and @var{output} must follow the above numerical ## arguments, but can be specified in any order. @var{type} specifies the ## units of @var{p}, and can be "dB", "dBW", "dBm" or "linear". "dB" is ## in fact the same as "dBW" and is keep as a misnomer of Matlab. The ## units of "linear" are in Watts. ## ## The @var{output} variable should be either "real" or "complex". If the ## output is complex then the power @var{p} is divided equally between the ## real and imaginary parts. ## ## @seealso{randn, awgn} ## @end deftypefn function y = wgn (m, n, p, varargin) if (nargin < 3 || nargin > 7) print_usage (); endif if (!isscalar (m) || !isreal (m) || m < 0 || !isscalar (n) || ... !isreal (n) || n < 0) error ("wgn: M and N must be positive integers"); endif type = "dBW"; out = "real"; imp = 1; seed = []; narg = 0; for i = 1:length (varargin) arg = varargin{i}; if (ischar (arg)) if (strcmp (arg, "real")) out = "real"; elseif (strcmp (arg, "complex")) out = "complex"; elseif (strcmp (arg, "dB")) type = "dBW"; elseif (strcmp (arg, "dBW")) type = "dBW"; elseif (strcmp (arg, "dBm")) type = "dBm"; elseif (strcmp (arg, "linear")) type = "linear"; else error ("wgn: invalid argument '%s'", arg); endif else narg++; switch (narg) case 1 imp = arg; case 2 seed = arg; otherwise error ("wgn: too many arguments"); endswitch endif endfor if (isempty (imp)) imp = 1; elseif (!isscalar (imp) || !isreal (imp) || imp < 0) error ("wgn: IMP must be a non-negative scalar"); endif if (!isempty (seed)) if (! (isscalar (seed) && isreal (seed) && seed == fix (seed) && seed >= 0)) error ("wgn: random SEED must be integer"); endif endif if (!isscalar (p) || !isreal (p)) error ("wgn: P must be a scalar"); endif if (strcmp (type, "linear") && p < 0) error ("wgn: P must be a non-negative scalar for TYPE \"linear\""); endif if (strcmp (type, "dBW")) np = 10^(p/10); elseif (strcmp (type, "dBm")) np = 10^((p - 30)/10); elseif (strcmp (type, "linear")) np = p; endif if (!isempty (seed)) randn ("state", seed); endif if (strcmp (out, "complex")) y = (sqrt (imp*np/2)) * (randn (m, n) + 1i*randn (m, n)); else y = (sqrt (imp*np)) * randn (m, n); endif endfunction ## Allow 30% error in standard deviation, due to randomness %!assert (isreal (wgn (10, 10, 30, 1, "dBm", "real"))); %!assert (iscomplex (wgn (10, 10, 30, 1, "dBm", "complex"))); %!assert (abs (std (wgn (10000, 1, 30, 1, "dBm")) - 1) < 0.3); %!assert (abs (std (wgn (10000, 1, 0, 1, "dBW")) - 1) < 0.3); %!assert (abs (std (wgn (10000, 1, 1, 1, "linear")) - 1) < 0.3); %% Test input validation %!error wgn (); %!error wgn (1); %!error wgn (1, 1); %!error wgn (1, 1, 1, 1, 1, 1); communications-1.2.1/inst/PaxHeaders.3802/scatterplot.m0000644000000000000000000000013212510010473017704 xustar0030 mtime=1428164923.930510477 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/scatterplot.m0000644000000000000000000001157212510010473020237 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} scatterplot (@var{x}) ## @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}) ## @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}, @var{off}) ## @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}, @var{off}, @var{str}) ## @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}, @var{off}, @var{str}, @var{h}) ## @deftypefnx {Function File} {@var{h} =} scatterplot (@dots{}) ## ## Display the scatter plot of a signal. The signal @var{x} can be either in ## one of three forms ## ## @table @asis ## @item A real vector ## In this case the signal is assumed to be real and represented by the vector ## @var{x}. The scatterplot is plotted along the x axis only. ## @item A complex vector ## In this case the in-phase and quadrature components of the signal are ## plotted separately on the x and y axes respectively. ## @item A matrix with two columns ## In this case the first column represents the in-phase and the second the ## quadrature components of a complex signal and are plotted on the x and ## y axes respectively. ## @end table ## ## Each point of the scatter plot is assumed to be separated by @var{n} ## elements in the signal. The first element of the signal to plot is ## determined by @var{off}. By default @var{n} is 1 and @var{off} is 0. ## ## The string @var{str} is a plot style string (example "r+"), ## and by default is the default gnuplot point style. ## ## The figure handle to use can be defined by @var{h}. If @var{h} is not ## given, then the next available figure handle is used. The figure handle ## used in returned on @var{hout}. ## @seealso{eyediagram} ## @end deftypefn function varargout = scatterplot (x, n, _off, str, h) if (nargin < 1 || nargin > 5) print_usage (); endif if (isreal (x)) if (min (size (x)) == 1) signal = "real"; xr = x(:); xi = zeros (size (xr)); elseif (size (x, 2) == 2) signal = "complex"; xr = x(:,1); xi = x(:,2); else error ("scatterplot: real X must be a vector or a 2-column matrix"); endif else signal = "complex"; if (min (size (x)) != 1) error ("scatterplot: complex X must be a vector"); endif xr = real (x(:)); xi = imag (x(:)); endif if (!length (xr)) error ("scatterplot: X must not be empty"); endif if (nargin > 1) if (! (isscalar (n) && isreal (n) && n == fix (n) && n > 0)) error ("scatterplot: N must be a positive integer"); endif else n = 1; endif if (nargin > 2) if (! (isscalar (_off) && isreal (_off) && _off == fix (_off) && _off >= 0 && _off < length (x))) error ("scatterplot: OFF must be an integer in the range [0,N-1]"); endif off = _off; else off = 0; endif if (nargin > 3) if (isempty (str)) fmt = "."; elseif (ischar (str)) fmt = str; else error ("scatterplot: STR must be a string"); endif else fmt = "."; endif if (nargin > 4) if (isempty (h)) hout = figure (); elseif (isfigure (h) && strcmp (get (h, "tag"), "scatterplot")) hout = h; else error ("scatterplot: H must be a scatterplot figure handle"); endif else hout = figure (); endif set (hout, "tag", "scatterplot"); set (hout, "name", "Scatter Plot"); set (0, "currentfigure", hout); xr = xr(off+1:n:rows (xr)); xi = xi(off+1:n:rows (xi)); plot (xr, xi, fmt); if (!strcmp (signal, "complex")) ## FIXME: What is the appropriate xrange xmax = max (xr); xmin = min (xr); xran = xmax - xmin xmax = ceil (2 * xmax / xran) / 2 * xran; xmin = floor (2 * xmin / xran) / 2 * xran; axis ([xmin, xmax, -1, 1]); endif title ("Scatter plot"); xlabel ("In-phase"); ylabel ("Quadrature"); legend ("off"); if (nargout > 0) varargout{1} = hout; endif endfunction %!demo %! n = 200; %! ovsp = 5; %! x = 1:n; %! xi = [1:1/ovsp:n-0.1]; %! y = randsrc (1, n, [1 + i, 1 - i, -1 - i, -1 + i]); %! yi = interp1 (x, y, xi); %! noisy = awgn (yi, 15, "measured"); %! h = scatterplot (noisy); %! hold on; %! scatterplot (noisy, ovsp, 0, "r+", h); %% Test input validation %!error scatterplot () %!error scatterplot (1, 2, 3, 4, 5, 6) %!error scatterplot (1, -1) communications-1.2.1/inst/PaxHeaders.3802/genqammod.m0000644000000000000000000000013212510010473017310 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/genqammod.m0000644000000000000000000000353412510010473017642 0ustar00rootroot00000000000000## Copyright (C) 2006 Charalampos C. Tsimenidis ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} genqammod (@var{x}, @var{c}) ## ## Modulates an information sequence of integers @var{x} in the range ## @code{[0 @dots{} M-1]} onto a quadrature amplitude modulated signal ## @var{y}, where @code{M = length (c) - 1} and @var{c} is a 1D vector ## specifying the signal constellation mapping to be used. An example of ## combined 4PAM-4PSK is ## ## @example ## @group ## d = randint (1, 1e4, 8); ## c = [1+j -1+j -1-j 1-j 1+sqrt(3) j*(1+sqrt(3)) -1-sqrt(3) -j*(1+sqrt(3))]; ## y = genqammod (d, c); ## z = awgn (y, 20); ## plot (z, "rx") ## @end group ## @end example ## @seealso{genqamdemod} ## @end deftypefn function y = genqammod (x, c) if (nargin != 2) print_usage (); endif m = 0:length (c)-1; if (!isempty (find (ismember (x, m) == 0))) error ("genqammod: all elements of X must be integers in the range [0,M]"); endif y = c(x+1); endfunction %!assert (genqammod ([0:7], [-7:2:7]), [-7:2:7]) %!assert (genqammod ([0:7], [-7 -5 -1 -3 7 5 1 3]), [-7 -5 -1 -3 7 5 1 3]) %% Test input validation %!error genqammod () %!error genqammod (1) %!error genqammod (1, 2, 3) %!error genqammod (10, -7:2:7) communications-1.2.1/inst/PaxHeaders.3802/fiboenco.m0000644000000000000000000000013212510010473017124 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/fiboenco.m0000644000000000000000000000575512510010473017465 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} fiboenco (@var{num}) ## ## Returns the cell-array of encoded Fibonacci value from the column vectors @var{num}. ## Universal codes like Fibonacci codes have a useful synchronization ## property, only for 255 maximum value we have designed these routines. We assume ## user has partitioned the code into several unique segments based on ## the suffix property of unique elements [1 1] and we just decode the ## parts. Partitioning the stream is as simple as identifying the [1 1] ## pairs that occur, at the terminating ends. This system implements ## the standard binary Fibonacci codes, which means that row vectors ## can only contain 0 or 1. Ref: http://en.wikipedia.org/wiki/Fibonacci_coding ## Ugly O(k.N^2) encoder.Ref: Wikipedia article accessed March, 2006. ## @url{http://en.wikipedia.org/wiki/Fibonacci_coding}, UCI Data Compression ## Book, @url{http://www.ics.uci.edu/~dan/pubs/DC-Sec3.html}, (accessed ## October 2006) ## ## @example ## @group ## fiboenco (10) ## @result{} @{[ 0 1 0 0 1 1]@} ## fiboenco (1:4) ## @result{} @{[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]@} ## @end group ## @end example ## @seealso{fibodeco} ## @end deftypefn function op_num = fiboenco (num) ## ## generate fibonacci series table. ## ## f(1)=1; ## f(2)=1; ## ## while ((f(end-1)+f(end)) < 256) ## val=(f(end-1)+f(end)); ## f=[f val]; ## endwhile ## f=sort(f(2:end),"descend"); ## ## f= [75025 46368 28657 17711 10946 6765 4181 2584 \ ## 1597 987 610 377 233 144 89 55 \ ## 34 21 13 8 5 3 2 1]; if (nargin != 1 || min (num) <= 0 || max (num) > 608) print_usage (); endif f = [233 144 89 55 34 21 13 8 5 3 2 1]; onum = num; LEN_F = length (f); LEN_N = length (num); for j = 1:LEN_N N = num(j); rval = []; ## create Fibonacci encoding of a number for i = find (f <= N):LEN_F if (N >= f(i)) N = N-f(i); rval = [1 rval]; else rval = [0 rval]; endif endfor op_num{j} = [rval 1]; endfor endfunction %!assert (fibodeco (fiboenco (1:600)), [1:600]) %% Test input validation %!error fiboenco () %!error fiboenco (1, 2) %!error fiboenco (0) %!error fiboenco (1000) communications-1.2.1/inst/PaxHeaders.3802/qfunc.m0000644000000000000000000000013212510010473016454 xustar0030 mtime=1428164923.886511478 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/qfunc.m0000644000000000000000000000207712510010473017007 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} qfunc (@var{x}) ## Compute the Q function. ## @seealso{erfc, erf} ## @end deftypefn function y = qfunc (x) if (nargin != 1) print_usage (); endif y = erfc (x / sqrt(2)) / 2; endfunction %!assert (qfunc ([-Inf 0 Inf]), [1 0.5 0]) %% Test input validation %!error qfunc () %!error qfunc (1, 2) communications-1.2.1/inst/PaxHeaders.3802/rleenco.m0000644000000000000000000000013212510010473016767 xustar0030 mtime=1428164923.922510659 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/rleenco.m0000644000000000000000000000326712510010473017324 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} rleenco (@var{message}) ## ## Returns run-length encoded @var{message}. The RLE form is built from ## @var{message}. The original @var{message} has to be in the form of a ## row-vector. The encoded @var{message} format (encoded RLE) is like ## [repetition factor]+, values. ## ## An example use of @code{rleenco} is ## @example ## @group ## message = [5 4 4 1 1 1] ## rleenco (message) ## @result{} [1 5 2 4 3 1]; ## @end group ## @end example ## @seealso{rleenco} ## @end deftypefn function rmsg = rleenco (message) if (nargin != 1) print_usage (); endif rmsg = []; L = length (message); itr = 1; while (itr <= L) times = 0; val = message(itr); while (itr <= L && message(itr) == val) itr = itr + 1; times = times + 1; endwhile rmsg = [rmsg times val]; endwhile endfunction %!assert (rleenco ([5 4 4 1 1 1]), [1 5 2 4 3 1]) %% Test input validation %!error rleenco () %!error rleenco (1, 2) communications-1.2.1/inst/PaxHeaders.3802/hammgen.m0000644000000000000000000000013212510010473016754 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/hammgen.m0000644000000000000000000000546512510010473017313 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{h} =} hammgen (@var{m}) ## @deftypefnx {Function File} {@var{h} =} hammgen (@var{m}, @var{p}) ## @deftypefnx {Function File} {[@var{h}, @var{g}] =} hammgen (@dots{}) ## @deftypefnx {Function File} {[@var{h}, @var{g}, @var{n}, @var{k}] =} hammgen (@dots{}) ## ## Produce the parity check and generator matrices of a Hamming code. The ## variable @var{m} defines the [@var{n},@var{k}] Hamming code where ## @code{@var{n} = 2 ^ @var{m} - 1} and @code{@var{k} = @var{n} - @var{m}}. ## @var{m} must be between 3 and 16. ## ## The parity check matrix is generated relative to the primitive polynomial ## of GF(2^@var{m}). If @var{p} is specified the default primitive polynomial ## of GF(2^@var{m}) is overridden. @var{p} must be a valid primitive ## polynomial of the correct order for GF(2^@var{m}). ## ## The parity check matrix is returned in the @var{m} by @var{n} matrix ## @var{h}, and if requested the generator matrix is returned in the @var{k} ## by @var{n} matrix @var{g}. ## ## @seealso{gen2par} ## @end deftypefn function [h, g, n, k] = hammgen (m, p) if (nargin < 1 || nargin > 2) print_usage (); endif if (! (isscalar (m) && m == fix (m) && m >= 3 && m <= 16)) error ("hammgen: M must be an integer in the range [3,16]"); endif if (nargin > 1) if (!isscalar (p)) p = bi2de (p); endif if (! (p == fix (p) && p >= 2^m && p <= 2^(m+1) && isprimitive (p))) error ("hammgen: P must be a primitive polynomial of GF(2^M)"); endif else ## Get the primitive polynomial of GF(2^M). Note that the default ## primitive polynomial is not necessarily primpoly(m,"min"), so ## have to create a Galois variable to extract the default primitive. ## The problem is, this limits m to be less than or equal to 16, ## as the Galois type itself is limited to this value p = gf (0, m).prim_poly; endif n = 2^m -1; k = n - m; if (nargout > 1) [h, g] = cyclgen (n, p); else h = cyclgen (n, p); endif endfunction %% Test input validation %!error hammgen () %!error hammgen (1, 2, 3) %!error hammgen (1) %!error hammgen (20) %!error hammgen (3, 4) communications-1.2.1/inst/PaxHeaders.3802/qamdemod.m0000644000000000000000000000013212510010473017127 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/qamdemod.m0000644000000000000000000000271412510010473017460 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## Copyright (C) 2009 Christian Neumair ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} qamdemod (@var{x}, @var{m}) ## Create the QAM demodulation of x with a size of alphabet m. ## @seealso{qammod, pskmod, pskdemod} ## @end deftypefn function z = qamdemod (y, m) if (nargin != 2) print_usage (); endif c = sqrt (m); if (! (c == fix (c) && log2 (c) == fix (log2 (c)))) error ("qamdemod: M must be a square of a power of 2"); endif x = qammod (0:(m-1), m); x = reshape (x, 1, m); z = zeros (size (y)); for k = 1:numel (y) [n z(k)] = min (abs (y(k) - x)); endfor z = z - 1; endfunction %% Test input validation %!error qamdemod () %!error qamdemod (1) %!error qamdemod (1, 2) %!error qamdemod (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/qammod.m0000644000000000000000000000013212510010473016616 xustar0030 mtime=1428164923.886511478 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/qammod.m0000644000000000000000000000277412510010473017155 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} qammod (@var{x}, @var{m}) ## Create the QAM modulation of x with a size of alphabet m. ## @seealso{qamdemod, pskmod, pskdemod} ## @end deftypefn function y = qammod (x, m) if (nargin != 2) print_usage (); endif if (any (x >= m)) error ("qammod: all elements of X must be in the range [0,M-1]"); endif if (!all (x == fix (x))) error ("qammod: all elements of X must be integers"); endif c = sqrt (m); if (! (c == fix (c) && log2 (c) == fix (log2 (c)))) error ("qammod: M must be a square of a power of 2"); endif b = -2 .* mod (x, (c)) + c - 1; a = 2 .* floor (x ./ (c)) - c + 1; y = a + i.*b; endfunction %% Test input validation %!error qammod () %!error qammod (1) %!error qammod (1, 2) %!error qammod (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/prbs_generator.m0000644000000000000000000000013212510010473020354 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/prbs_generator.m0000644000000000000000000000526312510010473020707 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{prbs} =} prbs_generator (@var{polynomial}, @var{connections}, @var{initstate}) ## Implement book keeping for a Pseudo-Random Binary Sequence ( PRBS ) ## also called as a Linear Feedback Shift Register. ## ## Given a polynomial create a PRBS structure for that polynomial. ## Now all we need is to just create this polynomial and make it work. ## polynomial must be a vector containing the powers of x and an optional ## value 1. eg: x^3 + x^2 + x + 1 must be written as [3 2 1 0] ## all the coefficients are either 1 or 0. It generates only a Binary \ ## sequence, and the generator polynomial need to be only a binary ## polynomial in GF(2). ## ## connections, contains a struct of vectors where each vector is the ## connection list mapping its vec(2:end) elements to the vec(1) output. ## ## Example: If you had a PRBS shift register like the diagram ## below with 4 registers we use representation by polynomial ## of [ 1 2 3 4], and feedback connections between [ 1 3 4 ]. ## The output PRBS sequence is taken from the position 4. ## ## @example ## @group ## +---+ +----+ +---+ +---+ ## | D |----| D |---| D |---| D | ## +---+ +----+ +---+ +---+ ## | | | ## \ / / ## [+]---------------+------+ ## 1 + 0.D + 1.D^2 + 1.D^3 ## @end group ## @end example ## ## The code to implement this PRBS with a start state of [1 0 1 1] ## will be: ## ## @example ## @group ## prbs = prbs_generator ([1 3 4], @{[1 3 4]@}, [1 0 1 1]); ## x = prbs_sequence (prbs) ## @result{} x = 15 ## prbs_iterator (prbs, 15) ## @result{} [1 1 0 1 0 1 1 1 1 0 0 0 1 0 0] ## @end group ## @end example ## @seealso{prbs_iterator, prbs_sequence} ## @end deftypefn function prbs = prbs_generator (polynomial, connections, initstate) prbs.reglen = max (polynomial); prbs.polynomial = polynomial; prbs.sregs = initstate; prbs.connections = connections; prbs.conlen = length (connections); endfunction communications-1.2.1/inst/PaxHeaders.3802/pamdemod.m0000644000000000000000000000013212510010473017126 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/pamdemod.m0000644000000000000000000000441212510010473017454 0ustar00rootroot00000000000000## Copyright (C) 2006 Charalampos C. Tsimenidis ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}) ## @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}) ## @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}, @var{type}) ## ## Demodulates a pulse amplitude modulated signal @var{x} into an ## information sequence of integers in the range @code{[0 @dots{} M-1]}. ## @var{phi} controls the initial phase and @var{type} controls the ## constellation mapping. If @var{type} is set to "Bin" will result in ## binary encoding, in contrast, if set to "Gray" will give Gray encoding. ## An example of Gray-encoded 8-PAM is ## ## @example ## @group ## d = randint (1, 1e4, 8); ## y = pammod (d, 8, 0, "gray"); ## z = awgn (y, 20); ## d_est = pamdemod (z, 8, 0, "gray"); ## plot (z, "rx") ## biterr (d, d_est) ## @end group ## @end example ## @seealso{pammod} ## @end deftypefn function y = pamdemod (x, M, phi, type) if (nargin < 2) print_usage (); endif if (nargin < 3) phi = 0; endif if (nargin < 4) type = "Bin"; endif index = genqamdemod (x, [-M+1:2:M-1] .* exp (-1j*phi)); if (strcmp (type, "Bin") || strcmp (type, "bin")) y = index; elseif (strcmp (type, "Gray") || strcmp (type, "gray")) m = 0:M-1; map = bitxor (m, bitshift (m, -1)); y = map(index+1); else print_usage (); endif endfunction %!assert (pamdemod ([-7:2:7], 8, 0, "Bin"), [0:7]) %!assert (pamdemod ([-7:2:7], 8, 0, "Gray"), [0 1 3 2 6 7 5 4]) %% Test input validation %!error pamdemod () %!error pamdemod (1) %!error pamdemod (1, 2, 3, "invalid") communications-1.2.1/inst/PaxHeaders.3802/lz77enco.m0000644000000000000000000000013112510010473017007 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/lz77enco.m0000644000000000000000000000474212510010473017344 0ustar00rootroot00000000000000## Copyright (C) 2007 Gorka Lertxundi ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{c} =} lz77enco (@var{m}, @var{alph}, @var{la}, @var{n}) ## Lempel-Ziv 77 source algorithm implementation. Where ## ## @table @asis ## @item @var{c} ## encoded message (Mx3). ## @item @var{alph} ## size of alphabet. ## @item @var{la} ## lookahead buffer size. ## @item @var{n} ## sliding window buffer size. ## @end table ## @seealso{lz77deco} ## @end deftypefn function c = lz77enco (m, alph, la, n) if (la <= 0 || n <= 0) error ("lz77enco: LA and N must be positive integers"); endif if (n - la < la) error ("lz77deco: N must be >= 2*LA"); endif if (alph < 2) error ("lz77enco: ALPH must be >= 2"); endif if (max (m) + 1 > alph) error ("lz77enco: ALPH must be greater than the largest element of M"); endif if (rows (m) != 1) error ("lz77enco: M must be a row vector"); endif c = zeros (1, 3); enco = zeros (1, 3); window = zeros (1, n); x = length (m); len = length (m); while (x != 0) ## update window window(1:n-la) = window(enco(2)+2:n-la+enco(2)+1); if (x < la) window(n-la+1:n) = [m(len-x+1:len) zeros(1, la-x)]; else window(n-la+1:n) = m(len-x+1:len-x+la); endif ## get a reference (position,length) to longest match, and next symbol enco = [0 0 0]; for y = (n-la):-1:1 z = 0; while (z != la && window(y+z) == window(n-la+z+1)) z += 1; endwhile if (enco(2) < z) enco(1) = y-1; enco(2) = z; enco(3) = window(n-la+z+1); endif endfor ## encoded message if (x == len) c = enco; else c = [c ; enco]; endif x -= enco(2)+1; endwhile endfunction %!demo %! lz77enco ([0 0 1 0 1 0 2 1 0 2 1 0 2 1 2 0 2 1 0 2 1 2 0 0], 3, 9, 18) %% Test input validation %!error lz77enco (1, 1, 1, 1) communications-1.2.1/inst/PaxHeaders.3802/eyediagram.m0000644000000000000000000000013212510010473017447 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/eyediagram.m0000644000000000000000000001404312510010473017776 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} eyediagram (@var{x}, @var{n}) ## @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}) ## @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}, @var{off}) ## @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}, @var{off}, @var{str}) ## @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}, @var{off}, @var{str}, @var{h}) ## @deftypefnx {Function File} {@var{h} =} eyediagram (@dots{}) ## ## Plot the eye-diagram of a signal. The signal @var{x} can be either in one ## of three forms ## ## @table @asis ## @item A real vector ## In this case the signal is assumed to be real and represented by the vector ## @var{x}. A single eye-diagram representing this signal is plotted. ## @item A complex vector ## In this case the in-phase and quadrature components of the signal are ## plotted separately. ## @item A matrix with two columns ## In this case the first column represents the in-phase and the second the ## quadrature components of a complex signal. ## @end table ## ## Each line of the eye-diagram has @var{n} elements and the period is assumed ## to be given by @var{per}. The time axis is then [-@var{per}/2 @var{per}/2]. ## By default @var{per} is 1. ## ## By default the signal is assumed to start at -@var{per}/2. This can be ## overridden by the @var{off} variable, which gives the number of samples ## to delay the signal. ## ## The string @var{str} is a plot style string (example "r+"), ## and by default is the default gnuplot line style. ## ## The figure handle to use can be defined by @var{h}. If @var{h} is not ## given, then the next available figure handle is used. The figure handle ## used in returned on @var{hout}. ## @seealso{scatterplot} ## @end deftypefn function varargout = eyediagram (x, n, _per, _off, str, h) if (nargin < 2 || nargin > 6) print_usage (); endif if (isreal (x)) if (min (size (x)) == 1) signal = "real"; xr = x(:); elseif (size (x, 2) == 2) signal = "complex"; xr = x(:,1); xi = x(:,2); else error ("eyediagram: real X must be a vector or a 2-column matrix"); endif else signal = "complex"; if (min (size (x)) != 1) error ("eyediagram: complex X must be a vector"); endif xr = real (x(:)); xi = imag (x(:)); endif if (!length (xr)) error ("eyediagram: X must not be empty"); endif if (! (isscalar (n) && isreal (n) && n == fix (n) && n > 0)) error ("eyediagram: N must be a positive integer"); endif if (nargin > 2) if (isempty (_per)) per = 1; elseif (isscalar (_per) && isreal (_per)) per = _per; else error ("eyediagram: PER must be a real scalar"); endif else per = 1; endif if (nargin > 3) if (isempty (_off)) off = 0; elseif (! (isscalar (_off) && isreal (_off) && _off == fix (_off) && _off >= 0 && _off < n)) error ("eyediagram: OFF must be an integer in the range [0,N-1]"); else off = _off; endif else off = 0; endif if (nargin > 4) if (isempty (str)) fmt = "-"; elseif (ischar (str)) fmt = str; else error ("eyediagram: STR must be a string"); endif else fmt = "-"; endif if (nargin > 5) if (isempty (h)) hout = figure (); elseif (isfigure (h) && strcmp (get (h, "tag"), "eyediagram")) hout = h; else error ("eyediagram: H must be an eyediagram figure handle"); endif else hout = figure (); endif set (hout, "tag", "eyediagram"); set (hout, "name", "Eye Diagram"); set (0, "currentfigure", hout); horiz = (per*[0:n]/n - per/2)'; if (n/2 != fix (n/2)) horiz = horiz - per / n / 2; endif lx = length (xr); off = mod (off + ceil (n/2), n); Nn = ceil ((off + lx) / n); post = Nn*n - off - lx; xr = reshape ([NaN * ones(off, 1); xr; NaN * ones(post, 1)], n, Nn); xr = [xr ; [xr(1,2:end), NaN]]; xr = [xr; NaN * ones(1, Nn)]; if (all (isnan (xr(2:end,end)))) xr(:,end) = []; horiz = [repmat(horiz(1:n+1), 1, Nn-1); NaN * ones(1, Nn - 1)](:); else horiz = [repmat(horiz(1:n+1), 1, Nn); NaN * ones(1, Nn)](:); endif if (strcmp(signal,"complex")) xi = reshape([NaN * ones(off,1); xi; NaN * ones(post, 1)], n, Nn); xi = [xi ; [xi(1,2:end), NaN]]; xi = [xi; NaN * ones(1, Nn)]; if (all (isnan (xi(2:end,end)))) xi(:,end) = []; endif endif if (strcmp (signal, "complex")) subplot (2, 1, 1); plot (horiz, xr(:), fmt); xlim ([horiz(1), horiz(end-1)]); title ("Eye-diagram for in-phase signal"); xlabel ("Time"); ylabel ("Amplitude"); subplot (2, 1, 2); plot (horiz, xi(:), fmt); xlim ([horiz(1), horiz(end-1)]); title ("Eye-diagram for quadrature signal"); xlabel ("Time"); ylabel ("Amplitude"); else plot (horiz, xr(:), fmt); xlim ([horiz(1), horiz(end-1)]); title ("Eye-diagram for signal"); xlabel ("Time"); ylabel ("Amplitude"); endif if (nargout > 0) varargout{1} = hout; endif endfunction %!demo %! n = 50; %! ovsp = 50; %! x = 1:n; %! xi = [1:1/ovsp:n-0.1]; %! y = randsrc (1, n, [1 + i, 1 - i, -1 - i, -1 + i]); %! yi = interp1 (x, y, xi); %! noisy = awgn (yi, 15, "measured"); %! eyediagram (noisy, ovsp); %% Test input validation %!error eyediagram () %!error eyediagram (1) %!error eyediagram (1, 2, 3, 4, 5, 6) %!error eyediagram (1, -1) communications-1.2.1/inst/PaxHeaders.3802/rsgenpoly.m0000644000000000000000000000013212510010473017362 xustar0030 mtime=1428164923.926510568 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/rsgenpoly.m0000644000000000000000000001133712510010473017714 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}) ## @deftypefnx {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}, @var{p}) ## @deftypefnx {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}, @var{p}, @var{b}, @var{s}) ## @deftypefnx {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}, @var{p}, @var{b}) ## @deftypefnx {Function File} {[@var{g}, @var{t}] =} rsgenpoly (@dots{}) ## ## Creates a generator polynomial for a Reed-Solomon coding with message ## length of @var{k} and codelength of @var{n}. @var{n} must be greater ## than @var{k} and their difference must be even. The generator polynomial ## is returned on @var{g} as a polynomial over the Galois Field GF(2^@var{m}) ## where @var{n} is equal to @code{2^@var{m}-1}. If @var{m} is not integer ## the next highest integer value is used and a generator for a shorten ## Reed-Solomon code is returned. ## ## The elements of @var{g} represent the coefficients of the polynomial in ## descending order. If the length of @var{g} is lg, then the generator ## polynomial is given by ## @tex ## $$ ## g_0 x^{lg-1} + g_1 x^{lg-2} + \cdots + g_{lg-1} x + g_lg. ## $$ ## @end tex ## @ifnottex ## ## @example ## @var{g}(0) * x^(lg-1) + @var{g}(1) * x^(lg-2) + ... + @var{g}(lg-1) * x + @var{g}(lg). ## @end example ## @end ifnottex ## ## If @var{p} is defined then it is used as the primitive polynomial of the ## Galois Field GF(2^@var{m}). The default primitive polynomial will be used ## if @var{p} is equal to []. ## ## The variables @var{b} and @var{s} determine the form of the generator ## polynomial in the following manner. ## @tex ## $$ ## g = (x - A^{bs}) (x - A^{(b+1)s}) \cdots (x - A ^{(b+2t-1)s}). ## $$ ## @end tex ## @ifnottex ## ## @example ## @var{g} = (@var{x} - A^(@var{b}*@var{s})) * (@var{x} - A^((@var{b}+1)*@var{s})) * ... * (@var{x} - A^((@var{b}+2*@var{t}-1)*@var{s})). ## @end example ## @end ifnottex ## ## where @var{t} is @code{(@var{n}-@var{k})/2}, and A is the primitive element ## of the Galois Field. Therefore @var{b} is the first consecutive root of the ## generator polynomial and @var{s} is the primitive element to generate the ## polynomial roots. ## ## If requested the variable @var{t}, which gives the error correction ## capability of the Reed-Solomon code. ## @seealso{gf, rsenc, rsdec} ## @end deftypefn function [g, t] = rsgenpoly (n, k, _prim, _b, _s) if (nargin < 2 || nargin > 5) print_usage (); endif if (! (isscalar (n) && n == fix (n) && n > 2)) error ("rsgenpoly: N must be an integer greater than 2"); endif if (! (isscalar (k) && k == fix (k) && k > 0)) error ("rsgenpoly: K must be a non-negative integer"); endif if ((n-k)/2 != fix ((n-k)/2)) error ("rsgenpoly: N-K must be an even integer"); endif m = ceil (log2 (n+1)); ## Adjust n and k if n not equal to 2^m-1 dif = 2^m - 1 - n; n = n + dif; k = k + dif; prim = 0; if (nargin > 2) if (isempty (_prim)) prim = 0; else prim = _prim; endif endif if (! (isscalar (prim) && prim == fix (prim) && prim >= 0)) error ("rsgenpoly: P must be an integer representing a primitive polynomial"); endif if (prim != 0) if (!isprimitive (prim)) error ("rsgenpoly: P must be an integer representing a primitive polynomial"); endif if (prim < 2^m || prim > 2^(m+1)) error ("rsgenpoly: P must be a primitive polynomial with order 2^M"); endif endif b = 1; if (nargin > 3) b = _b; endif if (! (isscalar (b) && b == fix (b) && b >= 0)) error ("rsgenpoly: B must be a non-negative integer"); endif s = 1; if (nargin > 4) s = _s; endif if (! (isscalar (s) && s == fix (s) && s >= 0)) error ("rsgenpoly: S must be a non-negative integer"); endif alph = gf (2, m, prim); t = (n - k) / 2; g = gf (1, m, prim); for i = 1:2*t g = conv (g, gf ([1, alph^((b+i-1)*s)], m, prim)); endfor endfunction %% Test input validation %!error rsgenpoly () %!error rsgenpoly (1) %!error rsgenpoly (1, 2, 3, 4, 5, 6) %!error rsgenpoly (1, 2) %!error rsgenpoly (2, 0) %!error rsgenpoly (4, 3) communications-1.2.1/inst/PaxHeaders.3802/istrellis.m0000644000000000000000000000013112510010473017351 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/istrellis.m0000644000000000000000000000774412510010473017713 0ustar00rootroot00000000000000## Copyright (C) 2012 Mike Miller ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} istrellis (@var{t}) ## @deftypefnx {Function File} {[@var{status}, @var{text}] =} istrellis (@var{t}) ## ## Return true if @var{t} is a valid trellis structure. ## ## If called with two output arguments, @var{text} contains a string indicating ## a reason if @var{status} is false or an empty string if @var{status} is true. ## ## @seealso{poly2trellis, struct} ## @end deftypefn function [status, text] = istrellis (t) if (nargin != 1) print_usage (); endif status = false; text = ""; if (! (isstruct (t) && isfield (t, "numInputSymbols") && isfield (t, "numOutputSymbols") && isfield (t, "numStates") && isfield (t, "nextStates") && isfield (t, "outputs"))) text = "t is not a valid trellis structure"; else try outputs = oct2dec (t.outputs); outputs_is_octal = true; catch outputs_is_octal = false; end_try_catch k = log2 (t.numInputSymbols); n = log2 (t.numOutputSymbols); nu = log2 (t.numStates); if (! (isscalar (k) && k == fix (k) && k >= 0)) text = "numInputSymbols is not a power of 2"; elseif (! (isscalar (n) && n == fix (n) && n >= 0)) text = "numOutputSymbols is not a power of 2"; elseif (! (isscalar (nu) && nu == fix (nu) && nu >= 0)) text = "numStates is not a power of 2"; elseif (any (size (t.nextStates) != [t.numStates t.numInputSymbols])) text = "nextStates is not a numStates-by-numInputSymbols matrix"; elseif (any (size (t.outputs) != [t.numStates t.numInputSymbols])) text = "outputs is not a numStates-by-numInputSymbols matrix"; elseif (! (all (t.nextStates(:) == fix (t.nextStates(:))) && all (t.nextStates(:) >= 0) && all (t.nextStates(:) < t.numStates))) text = "nextStates must contain integers from 0 to numStates-1"; elseif (! (outputs_is_octal && all (t.outputs(:) == fix (t.outputs(:))) && all (t.outputs(:) >= 0) && all (outputs(:) < t.numOutputSymbols))) text = "outputs must contain octal integers from 0 to numOutputSymbols-1"; else status = true; endif endif endfunction %% Test the simple (2,1,3) encoder from Lin & Costello example 11.1 %!test %! T = struct ("numInputSymbols", 2, %! "numOutputSymbols", 4, %! "numStates", 8, %! "nextStates", [0 4; 0 4; 1 5; 1 5; 2 6; 2 6; 3 7; 3 7], %! "outputs", [0 3; 3 0; 3 0; 0 3; 1 2; 2 1; 2 1; 1 2]); %! assert (istrellis (T), true) %% Tests of invalid arguments or invalid structures %!test %! [status, text] = istrellis ([]); %! assert (status, false); %! assert (isempty (strfind (text, "not a valid trellis")), false) %!test %! [status, text] = istrellis (struct ()); %! assert (status, false); %! assert (isempty (strfind (text, "not a valid trellis")), false) %!test %! T = struct ("numInputSymbols", 3, %! "numOutputSymbols", 4, %! "numStates", 0, %! "nextStates", zeros (0, 4), %! "outputs", zeros (0, 4)); %! [status, text] = istrellis (T); %! assert (status, false); %! assert (isempty (strfind (text, "numInputSymbols")), false) %% Test input validation %!error istrellis () %!error istrellis (1, 2) communications-1.2.1/inst/PaxHeaders.3802/riceenco.m0000644000000000000000000000013212510010473017127 xustar0030 mtime=1428164923.922510659 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/riceenco.m0000644000000000000000000000671512510010473017465 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} riceenco (@var{sig}, @var{K}) ## ## Returns the Rice encoded signal using @var{K} or optimal K . ## Default optimal K is chosen between 0-7. Currently no other way ## to increase the range except to specify explicitly. Also returns ## @var{K} parameter used (in case it were to be chosen optimally) ## and @var{Ltot} the total length of output code in bits. ## This function uses a @var{K} if supplied or by default chooses ## the optimal K for encoding signal vector into a rice coded vector. ## A restrictions is that a signal set must strictly be non-negative. ## The Rice algorithm is used to encode the data into unary coded ## quotient part which is represented as a set of 1's separated from ## the K-part (binary) using a zero. This scheme doesn't need any ## kind of dictionaries and its close to O(N), but this implementation ## *may be* sluggish, though correct. ## ## Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans ## Info' Theory ## ## An example of the use of @code{riceenco} is ## @example ## @group ## riceenco (1:4) ## @result{} @{[0 1], [1 0 0], [1 0 1], [1 1 0 0]@} ## riceenco (1:10, 2) ## @result{} @{[0 0 1], [0 1 0], [0 1 1], [1 0 0 0], ## [1 0 0 1], [1 0 1 0], [1 0 1 1], [1 1 0 0 0], ## [1 1 0 0 1], [1 1 0 1 0]@} ## @end group ## @end example ## @seealso{ricedeco} ## @end deftypefn function [rcode, K, Ltot] = riceenco (sig, K) if (nargin < 1 || nargin > 2) print_usage (); elseif (nargin < 2) use_optimal_k = 1; else use_optimal_k = 0; endif if (min (sig) < 0) error ("riceenco: all elements of SIG must be non-negative numbers"); endif L = length (sig); ## compute the optimal rice parameter. if (use_optimal_k) k_opt = 0; len_past = sum (sig) + L + k_opt*L; quot = sig; for k = 1:7 k_pow_2 = 2**k; quot_k = floor (sig./k_pow_2); len = sum (quot_k)+L+k*L; if (len < len_past) len_past = len; k_opt = k; rem = mod (sig, k_pow_2); quot = quot_k; endif endfor Ltot = len_past; K = k_opt; K_pow_2 = 2**K; else K_pow_2 = 2**K; quot = floor (sig./K_pow_2); rem = mod (sig, K_pow_2); endif for j = 1:L rice_part = zeros (1, K); ## ## How can we eliminate this loop? ## I essentially need to get the binary ## representation of rem(j) in the rice_part(i) ## for i = K:-1:1 rice_part(i) = mod (rem(j), 2); rem(j) = floor (rem(j)/2); endfor rcode{j} = [ones(1, quot(j)) 0 rice_part]; endfor Ltot = sum (quot) + L + K*L; endfunction %!assert (riceenco (1:4, 2), {[0 0 1], [0 1 0], [0 1 1], [1 0 0 0]}) %% Test input validation %!error riceenco () %!error riceenco (1, 2, 3) %!error riceenco (-1) communications-1.2.1/inst/PaxHeaders.3802/dpcmopt.m0000644000000000000000000000013212510010473017006 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/dpcmopt.m0000644000000000000000000000616712510010473017345 0ustar00rootroot00000000000000## Copyright (C) 2012 Leonardo Araujo ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{predictor} =} dpcmopt (@var{training_set}, @var{ord}) ## @deftypefnx {Function File} {[@var{predictor}, @var{partition}, @var{codebook}] =} dpcmopt (@var{training_set}, @var{ord}, @var{cb}) ## Optimize the DPCM parameters and codebook. ## ## It uses the Levinson-Durbin algorithm to find the all-pole IIR filter ## using the autocorrelation sequence. After the best predictor is found, ## it uses the Lloyds algorithm to find the best codebook and partition ## for the interval. ## ## @table @code ## @item predictor = dpcmopt (training_set, ord) ## Optimize the DPCM parameters using the Levinson-Durbin algorithm. ## The predictor vector describes a m-th order prediction for the ## output according to the following equation ## y(k) = p(1)sig(k-1) + p(2)sig(k-2) + ... + p(m-1)sig(k-m+1) + p(m)sig(k-m) ## where the predictor vector is given by ## predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)]. ## ## training_set is the training data used to find the best predictor. ## ## ord is the order of the desired prediction model. ## ## @item [predictor, partition, codebook] = dpcmopt (training_set,ord,cb) ## Optimize the DPCM parameters and also uses the Lloyds algorithm to find ## the best codebook and partition for the given training signal. ## ## cb might be the initial codebook used by Lloyds algorithm or ## the length of the desired codebook. ## ## @end table ## @seealso{dpcmenco, dpcmdeco, levinson, lloyds} ## @end deftypefn function [predictor, partition, codebook] = dpcmopt (training_set, ord, cb) if (nargin < 2 || nargin > 3) print_usage (); endif training_set = training_set(:); L = length (training_set); corr_tr = xcorr (training_set'); # autocorrelation ncorr_tr = corr_tr(L:L+ord+1) ./ (L - [1:ord+2]); # normalize ## use Levinson-Durbin recursion to solve the Yule-Walker equations a = levinson (ncorr_tr, ord); predictor = [0 - a(2:end)]; if (nargin > 2 && nargout > 1) ## predictive error e = []; for i = ord+1 : L e(i-ord) = training_set(i) - fliplr (predictor) * training_set(i-ord:i); endfor ## find the best codebook and partition table if (length (cb) == 1) len = cb; [partition, codebook] = lloyds (e, len); else initcodebook = cb; [partition, codebook] = lloyds (e, initcodebook); endif endif endfunction %% Test input validation %!error dpcmopt () %!error dpcmopt (1) %!error dpcmopt (1, 2, 3, 4) communications-1.2.1/inst/PaxHeaders.3802/reedmullergen.m0000644000000000000000000000013112510010473020171 xustar0029 mtime=1428164923.91851075 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/reedmullergen.m0000644000000000000000000000451612510010473020525 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} reedmullergen (@var{R}, @var{M}) ## ## Definition type construction of Reed-Muller code, ## of order @var{R}, length @math{2^M}. This function ## returns the generator matrix for the said order RM code. ## ## RM(r,m) codes are characterized by codewords, ## @code{sum ( (m,0) + (m,1) + @dots{} + (m,r)}. ## Each of the codeword is got through spanning the ## space, using the finite set of m-basis codewords. ## Each codeword is @math{2^M} elements long. ## see: Lin & Costello, "Error Control Coding", 2nd Ed. ## ## Faster code constructions (also easier) exist, but since ## finding permutation order of the basis vectors, is important, we ## stick with the standard definitions. To use decoder ## function reedmullerdec, you need to use this specific ## generator function. ## ## @example ## @group ## g = reedmullergen (2, 4); ## @end group ## @end example ## @seealso{reedmullerdec, reedmullerenc} ## @end deftypefn function G = reedmullergen (R, M) if (nargin != 2) print_usage (); endif G = ones (1, 2^M); if (R == 0) return; endif a = [0]; b = [1]; V = []; for idx = 1:M; row = repmat ([a, b], [1, 2^(M-idx)]); V(idx,:) = row; a = [a, a]; b = [b, b]; endfor G = [G; V]; if (R == 1) return else r = 2; while (r <= R) p = nchoosek (1:M, r); prod = V(p(:,1),:) .* V(p(:,2),:); for idx = 3:r prod = prod .* V(p(:,idx),:); endfor G = [G; prod]; r = r + 1; endwhile endif endfunction %% Test input validation %!error reedmullergen () %!error reedmullergen (1) %!error reedmullergen (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/prbs_sequence.m0000644000000000000000000000013212510010473020176 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/prbs_sequence.m0000644000000000000000000000567612510010473020541 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{itrs}, @var{seq}] =} prbs_sequence (@var{prbs}) ## Implement book keeping for a Pseudo-Random Binary Sequence ( PRBS ) ## also called as a Linear Feedback Shift Register. ## ## For the given PRBS in a intial state, compute the PRBS sequence length. ## Length is period of output when the PRBS state is same as ## the start state of PRBS. ## ## Example: If you had a PRBS shift register like the diagram ## below with 4 registers we use representation by polynomial ## of [ 1 2 3 4], and feedback connections between [ 1 3 4 ]. ## The output PRBS sequence is taken from the position 4. ## ## @example ## @group ## +---+ +----+ +---+ +---+ ## | D |----| D |---| D |---| D | ## +---+ +----+ +---+ +---+ ## | | | ## \ / / ## [+]---------------+------+ ## 1 + 0.D + 1.D^2 + 1.D^3 ## @end group ## @end example ## ## The code to implement this PRBS will be ## ## @example ## @group ## prbs = prbs_generator ([1 3 4], @{[1 3 4]@}, [1 0 1 1]); ## x = prbs_sequence (prbs) ## @result{} x = 15 ## @end group ## @end example ## @seealso{prbs_generator} ## @end deftypefn function [itrs, seq] = prbs_sequence (prbs) if (nargin != 1) print_usage (); endif nstate = zeros (1, prbs.reglen); itrs = 0; seq = []; inits = prbs.sregs; ## For each iteration, shift the output bit. Then compute the xor pattern of connections. ## Finally apply feedback the stuff. Insert the computed pattern. while (true) itrs = itrs + 1; ## compute the feedback. for itr2 = 1:prbs.conlen val = 0; L = length (prbs.connections{itr2}); for itr3 = 2:L val = bitxor (val, prbs.sregs(prbs.connections{itr2}(itr3))); endfor nstate(prbs.connections{itr2}(1)) = val; endfor ## rotate the output discarding the last output. seq = [seq, prbs.sregs(end)]; prbs.sregs = [0 prbs.sregs(1:prbs.reglen-1)]; ## insert the feedback. for itr2 = 1:prbs.conlen prbs.sregs(itr2) = nstate(itr2); nstate(itr2) = 0; # reset. endfor if (isequal (prbs.sregs, inits)) break endif endwhile endfunction %% Test input validation %!error prbs_sequence () %!error prbs_sequence (1, 2) communications-1.2.1/inst/PaxHeaders.3802/gfweight.m0000644000000000000000000000013212510010473017144 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/gfweight.m0000644000000000000000000000554012510010473017475 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{w} =} gfweight (@var{gen}) ## @deftypefnx {Function File} {@var{w} =} gfweight (@var{gen}, "gen") ## @deftypefnx {Function File} {@var{w} =} gfweight (@var{par}, "par") ## @deftypefnx {Function File} {@var{w} =} gfweight (@var{p}, n) ## ## Calculate the minimum weight or distance of a linear block code. The ## code can be either defined by its generator or parity check matrix, or ## its generator polynomial. By default if the first argument is a matrix, ## it is assumed to be the generator matrix of the code. The type of the ## matrix can be defined by a flag "gen" for the generator matrix or ## "par" for the parity check matrix. ## ## If the first argument is a vector, it is assumed that it defines the ## generator polynomial of the code. In this case a second argument is ## required that defines the codeword length. ## ## @seealso{hammgen, cyclpoly, bchpoly} ## @end deftypefn function w = gfweight (arg1, arg2) if (nargin < 1 || nargin > 2) print_usage (); endif if (isvector (arg1)) if (nargin != 2) error ("gfweight: codeword length required if first argument is a generator polynomial"); endif [ign, gen] = cyclgen (arg2, arg1); elseif (ismatrix (arg1)) if (nargin == 2) if (ischar (arg2)) if (strcmp (arg2, "gen")) gen = arg1; elseif (strcmp (arg2, "par")) gen = gen2par (arg1); else error ("gfweight: invalid option '%s'", arg2); endif else error ("gfweight: second argument must be a string if first argument is a matrix"); endif else gen = arg1; endif else error ("gfweight: first argument must be a matrix or a vector"); endif [k, n] = size (gen); if (n < k) error ("gfweight: GEN must be a generator matrix in standard form"); endif ## We only need to test codewords 1:2^k-1 against the zero code word ## We do the equivalent of ## w = min (sum ((mod (de2bi ([1:2^k-1]') * gen, 2))')); ## But in a more memory efficient manner in an oct-file w = __gfweight__ (gen); endfunction %% Test input validation %!error gfweight () %!error gfweight (1, 2, 3) %!error gfweight ([1 2 3]) communications-1.2.1/inst/PaxHeaders.3802/rsdecof.m0000644000000000000000000000013212510010473016765 xustar0030 mtime=1428164923.926510568 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/rsdecof.m0000644000000000000000000000551412510010473017317 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} rsdecof (@var{in}, @var{out}) ## @deftypefnx {Function File} {} rsdecof (@var{in}, @var{out}, @var{t}) ## ## Decodes an ASCII file using a Reed-Solomon coder. The input file is ## defined by @var{in} and the result is written to the output file @var{out}. ## The type of coding to use is determined by whether the input file is 7- ## or 8-bit. If the input file is 7-bit, the default coding is [127,117]. ## while the default coding for an 8-bit file is a [255, 235]. This allows ## for 5 or 10 error characters in 127 or 255 symbols to be corrected ## respectively. The number of errors that can be corrected can be overridden ## by the variable @var{t}. ## ## If the file is not an integer multiple of the message size (127 or 255) ## in length, then the file is padded with the EOT (ASCII character 4) ## character before decoding. ## ## @seealso{rsencof} ## @end deftypefn function rsdecof (in, out, t) if (nargin < 2 || nargin > 3) print_usage (); endif if (!ischar (in) || !ischar (out)) error ("rsdecof: IN and OUT must be strings"); endif if (nargin != 3) t = 0; else if (! (isscalar (t) && t == fix (t) && t > 0)) error ("rsdecof: T must be a positive integer"); endif endif try fid = fopen (in, "rt"); catch error ("rsdecof: could not open '%s' for reading", in); end_try_catch [code, count] = fread (fid, Inf, "char"); fclose (fid); is8bit = (max (code) > 127); if (is8bit) m = 8; n = 255; if (t == 0) t = 10; endif else m = 7; n = 127; if (t == 0) t = 5; endif endif k = n - 2 * t; ncodewords = ceil (count / n); npad = n * ncodewords - count; code = reshape ([code ; 4 * ones(npad, 1)], n, ncodewords)'; msg = rsdec (gf (code, m), n, k, "beginning")'; msg = msg(:); try fid = fopen (out, "w+t"); catch error ("rsdecof: could not open '%s' for writing", out); end_try_catch fwrite (fid, msg(1:(ncodewords*k-npad)), "char"); fclose (fid); endfunction %% Test input validation %!error rsdecof () %!error rsdecof (1) %!error rsdecof (1, 2, 3, 4) %!error rsdecof (1, 2) %!error rsdecof ("in", "out", 0) communications-1.2.1/inst/PaxHeaders.3802/egolaydec.m0000644000000000000000000000013212510010473017274 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.050507738 30 ctime=1428164983.712815029 communications-1.2.1/inst/egolaydec.m0000644000000000000000000000655512510010473017634 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{C}, @var{err}] =} egolaydec (@var{R}) ## Decode Extended Golay code. ## ## Given @var{R}, the received Extended Golay code, this function tries to ## decode it using the Extended Golay code parity check matrix. ## Extended Golay code (24,12) which can correct up to 3 errors. ## ## The received code @var{R}, needs to be of length Nx24, for encoding. We can ## decode several codes at once, if they are stacked as a matrix of 24 columns, ## each code in a separate row. ## ## The generator used in here is same as obtained from the function ## @code{egolaygen}. ## ## The function returns @var{C}, the error-corrected code word from the received ## word. If decoding failed, @var{err} value is 1, otherwise it is 0. ## ## Extended Golay code (24,12) which can correct up to 3 ## errors. Decoding algorithm follows from Lin & Costello. ## ## Ref: Lin & Costello, pg 128, Ch4, "Error Control Coding", 2nd ed, Pearson. ## ## @example ## @group ## msg = rand (10, 12) > 0.5; ## c1 = egolayenc (msg); ## c1(:,1) = mod (c1(:,1) + 1, 2) ## c2 = egolaydec (c1) ## @end group ## @end example ## ## @seealso{egolaygen, egolayenc} ## @end deftypefn function [C, dec_error] = egolaydec (R) if (nargin != 1) print_usage (); elseif (columns (R) != 24) error ("egolaydec: R must be a matrix with 24 columns"); endif dec_error = []; [~, P] = egolaygen (); H = [eye(12); P]; # parity check matrix transpose C = zeros (size (R)); for rspn = 1:rows (R) RR = R(rspn,:); S = mod (RR*H, 2); wt = sum (S); done = 0; E = [S, zeros(1, 12)]; if (wt <= 3) E = [S, zeros(1, 12)]; done = 1; else SP = mod (repmat (S, [12, 1]) + P, 2); idx = find (sum (SP, 2) <= 2); if (idx) idx = idx(1); # pick first of matches. Ui = zeros (1, 12); Ui(idx) = 1; E = [SP(idx, :), Ui]; done = 1; endif endif if (!done) X = mod (S*P, 2); wt = sum (X); if (wt == 2 || wt == 3) E = [zeros(1, 12), X]; done = 1; else SP = mod (repmat (X, [12, 1]) + P, 2); idx = find (sum (SP, 2) == 2); if (idx) idx = idx(1); Ui = zeros (1, 12); Ui(idx) = 1; E = [Ui, SP(idx, :)]; done = 1; endif endif endif dec_error = [dec_error; 1-done]; C(rspn, :) = mod (E+RR, 2); endfor endfunction %!assert (egolaydec ([1 1 1 zeros(1, 21)]), zeros (1, 24)) %!assert (egolaydec ([1 0 1 zeros(1, 20) 1]), zeros (1, 24)) %% Test input validation %!error egolaydec () %!error egolaydec (1) %!error egolaydec (1, 2) communications-1.2.1/inst/PaxHeaders.3802/gftable.m0000644000000000000000000000013212510010473016744 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/gftable.m0000644000000000000000000000217012510010473017271 0ustar00rootroot00000000000000## Copyright (C) 2002 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} gftable (@var{m}, @var{primpoly}) ## ## This function exists for compatibility with matlab. As the Octave Galois ## fields store a copy of the lookup tables for every field in use internally, ## there is no need to use this function. ## ## @seealso{gf} ## @end deftypefn function r = gftable (m, prim) endfunction %% Mark file as being tested. No test needed for function that does nothing. %!assert (1) communications-1.2.1/inst/PaxHeaders.3802/huffmandeco.m0000644000000000000000000000013112510010473017616 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/huffmandeco.m0000644000000000000000000000767612510010473020164 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## Copyright (C) 2011 Ferran Mesas Garcia ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{sig} =} huffmandeco (@var{hcode}, @var{dict}) ## Decode signal encoded by @code{huffmanenco}. ## ## This function uses a dict built from the ## @code{huffmandict} and uses it to decode a signal list into a Huffman ## list. A restriction is that @var{hcode} is expected to be a binary code ## ## The returned @var{sig} set that strictly belongs in the range @code{[1,N]} ## with @code{N = length (@var{dict})}. Also @var{dict} can only be from the ## @code{huffmandict} routine. Whenever decoding fails, those signal values a ## re indicated by @code{-1}, and we successively try to restart decoding ## from the next bit that hasn't failed in decoding, ad-infinitum. An example ## of the use of @code{huffmandeco} is: ## ## @example ## @group ## hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]); ## hcode = huffmanenco (1:4, hd); ## back = huffmandeco (hcode, hd) ## @result{} [1 2 3 4] ## @end group ## @end example ## @seealso{huffmandict, huffmanenco} ## @end deftypefn function symbols = huffmandeco (hcode, dict) if (nargin != 2) print_usage (); elseif (!all ((hcode == 1) + (hcode == 0)) || !isvector (hcode)) error ("huffmandeco: HCODE must be a binary vector"); elseif (! iscell (dict)) error ("huffmandeco: DICT must be a dictionary from huffmandict"); endif ## Convert the Huffman Dictionary to a Huffman Tree represented by ## an array. tree = dict2tree (dict); ## Traverse the tree and store the symbols. symbols = []; pointer = 1; # a pointer to a node of the tree. for i = 1:length (hcode); if (tree(pointer) != -1) symbols = [symbols, tree(pointer)]; pointer = 1; endif pointer = 2 * pointer + hcode(i); endfor ## Check if decodification was successful if (tree(pointer) == -1) warning ("huffmandeco: could not decode last symbol") endif symbols = [symbols, tree(pointer)]; endfunction function tree = dict2tree (dict) L = length (dict); lengths = zeros (1, L); ## the depth of the tree is limited by the maximum word length. for i = 1:L lengths(i) = length (dict{i}); endfor m = max (lengths); tree = zeros (1, 2^(m+1)-1)-1; for i = 1:L pointer = 1; word = dict{i}; for bit = word pointer = 2 * pointer + bit; endfor tree(pointer) = i; endfor endfunction %!assert (huffmandeco (huffmanenco (1:4, huffmandict (1:4, [0.5 0.25 0.15 0.10])), huffmandict (1:4, [0.5 0.25 0.15 0.10])), [1:4], 0) %!assert (huffmandeco (huffmanenco ([1:100 100:-1:1], huffmandict (1:100, ones (1, 100)/100)), huffmandict (1:100, ones (1, 100)/100)), [1:100 100:-1:1], 0) %!assert (huffmandeco ([huffmanenco(1:4, huffmandict (1:4, [0.5 0.25 0.15 0.10])) 0], huffmandict (1:4, [0.5 0.25 0.15 0.10])), [1:4 -1], 0) %!fail ("huffmandeco ([huffmanenco(1:4, huffmandict (1:4, [0.5 0.25 0.15 0.10])) 0], huffmandict (1:4, [0.5 0.25 0.15 0.10]))", "warning") %!fail ("huffmandeco ('this is not a code', huffmandict (1:4, [0.5 0.25 0.15 0.10]))") %!fail ("huffmandeco ([1 0 1 0], 'this is not a dictionary')") %% Test input validation %!error huffmandeco () %!error huffmandeco (1) %!error huffmandeco (1, 2, 3) %!error huffmandeco (1, 2) %!error huffmandeco (2, {}) communications-1.2.1/inst/PaxHeaders.3802/amodce.m0000644000000000000000000000013212510010473016570 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/amodce.m0000644000000000000000000001341112510010473017115 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amdsb-tc", offset) ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amdsb-sc") ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amssb") ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amssb/time", @var{num}, @var{den}) ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "qam") ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "fm", @var{dev}) ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "pm", @var{dev}) ## @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, [@var{Fs}, @var{iphs}], @dots{}) ## ## Baseband modulator for analog signals. The input signal is specified by ## @var{x}, its sampling frequency by @var{Fs} and the type of modulation ## by the third argument, @var{typ}. The default values of @var{Fs} is 1 and ## @var{typ} is "amdsb-tc". ## ## If the argument @var{Fs} is a two element vector, the first element ## represents the sampling rate and the second the initial phase. ## ## The different types of modulations that are available are ## ## @table @asis ## @item "am" ## @itemx "amdsb-tc" ## Double-sideband with carrier ## @item "amdsb-sc" ## Double-sideband with suppressed carrier ## @item "amssb" ## Single-sideband with frequency domain Hilbert filtering ## @item "amssb/time" ## Single-sideband with time domain filtering. Hilbert filter is used by ## default, but the filter can be specified ## @item "qam" ## Quadrature amplitude modulation ## @item "fm" ## Frequency modulation ## @item "pm" ## Phase modulation ## @end table ## ## Additional arguments are available for the modulations "amdsb-tc", "fm", ## "pm" and "amssb/time". These arguments are ## ## @table @code ## @item offset ## The offset in the input signal for the transmitted carrier. ## @item dev ## The deviation of the phase and frequency modulation ## @item num ## @itemx den ## The numerator and denominator of the filter transfer function for the ## time domain filtering of the SSB modulation ## @end table ## ## @seealso{ademodce, dmodce} ## @end deftypefn function y = amodce (x, Fs, typ, varargin) if (nargin < 1) print_usage (); elseif (nargin < 2) Fs = 1; typ = "am"; elseif (nargin < 3) typ = "am"; endif if (isempty (Fs)) Fs = 1; iphs = 0; elseif (isscalar (Fs)) iphs = 0; else if (max (size (Fs)) != 2 || min (size (Fs)) != 1) error ("amodce: FS must be a scalar or a 2-element vector"); endif Fs = Fs(1); iphs = Fs(2); endif ## Pass the optional arguments offset = min (x(:)); dev = 1; num = []; den = []; narg = 1; if (!ischar (typ)) error ("amodce: modulation type must be a string"); elseif (strcmp (typ, "am") || strcmp (typ, "amdsb-tc")) if (length (varargin) > 0) offset = varargin{1}; narg = narg + 1; endif elseif (strcmp (typ, "fm") || strcmp (typ, "pm")) if (length (varargin) > 0) dev = varargin{1}; narg = narg + 1; endif endif if (length (varargin) == narg) error ("amodce: must specify numerator and denominator of transfer function"); elseif (length (varargin) == narg + 1) num = varargin{narg}; den = varargin{narg+1}; elseif (length (varargin) != narg - 1) error ("amodce: too many arguments"); endif if (strcmp (typ, "am") || strcmp (typ, "amdsb-tc")) y = (x + offset) * exp (1i * iphs); elseif (strcmp (typ, "amdsb-sc")) y = x * exp (1i * iphs); elseif (strcmp (typ, "amssb")) if (!isreal (x)) error ("amodce: SSB modulated signal must be real"); endif ## Damn, must treat Hilbert transform row-by-row!!! y = zeros (size (x)); for i = 1:size (x, 2) y(:,i) = hilbert (x(:,i)) * exp (1i * iphs); endfor elseif (strcmp (typ, "amssb/time")) if (isempty (num) || isempty (dem)) error ("amodce: Hilbert transform in time domain not yet implemented"); endif y = zeros (size (x)); for i = 1:size (x, 2) y(:,i) = filter (num, den, x(:,i)); y(:,i) = (x(:,i) + 1i*y(:,i)) * exp (1i * iphs); endfor elseif (strcmp (typ, "qam")) if (isreal (x)) xc = columns (x); if (xc/2 != fix (xc/2)) error ("amodce: QAM modulation must have an even number of columns for real signals"); endif y = (x(:,1:2:xc) + 1i * x(:,2:2:xc)); else y = x; endif y = y * exp (1i * iphs); elseif (strcmp (typ, "pm")) y = exp (1i * (dev*x + iphs)); elseif (strcmp (typ, "fm")) ## To convert to PM signal, need to evaluate ## p(t) = \int_0^t dev * x(T) dT ## As x(t) is discrete and not a function, the only way to perform the ## above integration is with Simpson's rule. Note \Delta T = 2 * pi / Fs. pm = pi / Fs * dev * (cumsum ([zeros(1, size (x, 2)); x(1:size (x, 1) - 1,:)]) ... + cumsum (x)); y = exp (1i * (pm + iphs)); else error ("amodce: unknown modulation specified '%s'", typ); endif endfunction %% Test input validation %!error amodce () %!error amodce (1, 2, "invalid") %!error amodce (1, 2, "am", 3, 4, 5, 6) communications-1.2.1/inst/PaxHeaders.3802/golombenco.m0000644000000000000000000000013212510010473017464 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/golombenco.m0000644000000000000000000000756512510010473020026 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} golombenco (@var{sig}, @var{m}) ## ## Returns the Golomb coded signal as cell array. ## Also total length of output code in bits can be obtained. ## This function uses a @var{m} need to be supplied for encoding signal vector ## into a Golomb coded vector. A restrictions is that ## a signal set must strictly be non-negative. Also the parameter @var{m} need to ## be a non-zero number, unless which it makes divide-by-zero errors. ## The Golomb algorithm [1], is used to encode the data into unary coded ## quotient part which is represented as a set of 1's separated from ## the K-part (binary) using a zero. This scheme doesn't need any ## kind of dictionaries, it is a parameterized prefix codes. ## Implementation is close to O(N^2), but this implementation ## *may be* sluggish, though correct. Details of the scheme are, to ## encode the remainder(r of number N) using the floor(log2(m)) bits ## when rem is in range 0:(2^ceil(log2(m)) - N), and encode it as ## r+(2^ceil(log2(m)) - N), using total of 2^ceil(log2(m)) bits ## in other instance it doesn't belong to case 1. Quotient is coded ## simply just using the unary code. Also according to [2] Golomb codes ## are optimal for sequences using the Bernoulli probability model: ## P(n)=p^n-1.q & p+q=1, and when M=[1/log2(p)], or P=2^(1/M). ## ## Reference: 1. Solomon Golomb, Run length Encodings, 1966 IEEE Trans ## Info' Theory. 2. Khalid Sayood, Data Compression, 3rd Edition ## ## An example of the use of @code{golombenco} is ## @example ## @group ## golombenco (1:4, 2) ## @result{} @{[0 1], [1 0 0], [1 0 1], [1 1 0 0]@} ## golombenco (1:10, 2) ## @result{} @{[0 1], [1 0 0], [1 0 1], [1 1 0 0], ## [1 1 0 1], [1 1 1 0 0], [1 1 1 0 1], [1 1 1 1 0 0], ## [1 1 1 1 0 1], [1 1 1 1 1 0 0]@} ## @end group ## @end example ## @seealso{golombdeco} ## @end deftypefn function [gcode, Ltot] = golombenco (sig, m) if (nargin != 2 || m <= 0) print_usage (); endif if (min (sig) < 0) error ("golombenco: all elements of SIG must be non-negative numbers"); endif L = length (sig); quot = floor (sig./m); rem = sig-quot.*m; C = ceil (log2 (m)); partition_limit = 2**C-m; Ltot = 0; for j = 1:L if ( rem(j) < partition_limit ) BITS = C-1; else rem(j) = rem(j)+partition_limit; BITS = C; endif Ltot = Ltot+BITS+1; golomb_part = zeros (1, BITS); ## ## How can we eliminate this loop? ## I essentially need to get the binary ## representation of rem(j) in the golomb_part(i); ## -maybe when JWE or someone imports dec2binvec. ## This does MSB -> LSB for i = BITS:-1:1 golomb_part(i) = mod (rem(j), 2); rem(j) = floor (rem(j)/2); endfor ## ## actual golomb code: sandwich the unary coded quotient, ## and the remainder. ## gcode{j} = [ones(1, quot(j)) 0 golomb_part]; endfor Ltot = sum (quot)+Ltot; endfunction %!assert (golombenco (3:5, 5), {[0 1 1 0], [0 1 1 1], [1 0 0 0 ]}) %!assert (golombenco (3:5, 3), {[1 0 0] , [1 0 1 0], [1 0 1 1]}) %% Test input validation %!error golombenco () %!error golombenco (1) %!error golombenco (1, 2, 3) %!error golombenco (1, 0) communications-1.2.1/inst/PaxHeaders.3802/bchpoly.m0000644000000000000000000000013212510010473017000 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/bchpoly.m0000644000000000000000000002002312510010473017322 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{p} =} bchpoly () ## @deftypefnx {Function File} {@var{p} =} bchpoly (@var{n}) ## @deftypefnx {Function File} {@var{p} =} bchpoly (@var{n}, @var{k}) ## @deftypefnx {Function File} {@var{p} =} bchpoly (@var{prim}, @var{k}) ## @deftypefnx {Function File} {@var{p} =} bchpoly (@var{n}, @var{k}, @var{prim}) ## @deftypefnx {Function File} {@var{p} =} bchpoly (@dots{}, @var{probe}) ## @deftypefnx {Function File} {[@var{p}, @var{f}] =} bchpoly (@dots{}) ## @deftypefnx {Function File} {[@var{p}, @var{f}, @var{c}] =} bchpoly (@dots{}) ## @deftypefnx {Function File} {[@var{p}, @var{f}, @var{c}, @var{par}] =} bchpoly (@dots{}) ## @deftypefnx {Function File} {[@var{p}, @var{f}, @var{c}, @var{par}, @var{t}] =} bchpoly (@dots{}) ## ## Calculates the generator polynomials for a BCH coder. Called with no input ## arguments @code{bchpoly} returns a list of all of the valid BCH codes for ## the codeword length 7, 15, 31, 63, 127, 255 and 511. A three column matrix ## is returned with each row representing a separate valid BCH code. The first ## column is the codeword length, the second the message length and the third ## the error correction capability of the code. ## ## Called with a single input argument, @code{bchpoly} returns the valid BCH ## codes for the specified codeword length @var{n}. The output format is the ## same as above. ## ## When called with two or more arguments, @code{bchpoly} calculates the ## generator polynomial of a particular BCH code. The generator polynomial ## is returned in @var{p} as a vector representation of a polynomial in ## GF(2). The terms of the polynomial are listed least-significant term ## first. ## ## The desired BCH code can be specified by its codeword length @var{n} ## and its message length @var{k}. Alternatively, the primitive polynomial ## over which to calculate the polynomial can be specified as @var{prim}. ## If a vector representation of the primitive polynomial is given, then ## @var{prim} can be specified as the first argument of two arguments, ## or as the third argument. However, if an integer representation of the ## primitive polynomial is used, then the primitive polynomial must be ## specified as the third argument. ## ## When called with two or more arguments, @code{bchpoly} can also return the ## factors @var{f} of the generator polynomial @var{p}, the cyclotomic coset ## for the Galois field over which the BCH code is calculated, the parity ## check matrix @var{par} and the error correction capability @var{t}. It ## should be noted that the parity check matrix is calculated with ## @code{cyclgen} and limitations in this function means that the parity ## check matrix is only available for codeword length up to 63. For ## codeword length longer than this @var{par} returns an empty matrix. ## ## With a string argument @var{probe} defined, the action of @code{bchpoly} ## is to calculate the error correcting capability of the BCH code defined ## by @var{n}, @var{k} and @var{prim} and return it in @var{p}. This is ## similar to a call to @code{bchpoly} with zero or one argument, except that ## only a single code is checked. Any string value for @var{probe} will ## force this action. ## ## In general the codeword length @var{n} can be expressed as ## @code{2^@var{m}-1}, where @var{m} is an integer. However, if ## [@var{n},@var{k}] is a valid BCH code, then a shortened BCH code of ## the form [@var{n}-@var{x},@var{k}-@var{x}] can be created with the ## same generator polynomial ## ## @seealso{cyclpoly, encode, decode, cosets} ## @end deftypefn function [p, f, c, par, t] = bchpoly (nn, k, varargin) if (nargin < 0 || nargin > 4) print_usage (); endif probe = 0; prim = 0; ## Set to zero to use default primitive polynomial if (nargin == 0) m = [3:9]; n = 2.^m - 1; nn = n; elseif (isscalar (nn)) m = ceil (log2 (nn+1)); n = 2.^m - 1; if (! (n == fix (n) && n >= 7 && m == fix (m))) error ("bchpoly: N must be a integer greater than 3"); endif else prim = bi2de (n); if (!isprimitive (prim)) error ("bchpoly: PRIM must be a primitive polynomial of GF(2^M)"); endif m = length (n) - 1; n = 2^m - 1; endif if (nargin > 1 && ! (isscalar (k) && k == fix (k) && k <= n)) error ("bchpoly: K must be an integer less than N"); endif for i = 1:length (varargin) arg = varargin{i}; if (ischar (arg)) probe = 1; if (nargout > 1) error ("bchpoly: only one output argument allowed when probing valid codes"); endif else if (prim != 0) error ("bchpoly: primitive polynomial already defined"); endif prim = arg; if (!isscalar (prim)) prim = bi2de (prim); endif if (! (prim == fix (prim) && prim >= 2^m && prim <= 2^(m+1) && isprimitive (prim))) error ("bchpoly: PRIM must be a primitive polynomial of GF(2^M)"); endif endif endfor ## Am I using the right algo to calculate the correction capability? if (nargin < 2) if (nargout > 1) error ("bchpoly: only one output argument allowed when probing valid codes"); endif p = []; for ni = 1:length (n) c = cosets (m(ni), prim); nc = length (c); fc = zeros (1, nc); f = []; for t = 1:floor (n(ni)/2) for i = 1:nc if (fc(i) != 1) cl = log (c{i}); for j = 2*(t-1)+1:2*t if (find (cl == j)) f = [f, c{i}.x]; fc(i) = 1; break; endif endfor endif endfor k = nn(ni) - length (f); if (k < 2) break; endif if (!isempty (p) && (k == p(size (p, 1),2))) p(size (p, 1),:) = [nn(ni), k, t]; else p = [p; [nn(ni), k, t]]; endif endfor endfor else c = cosets (m, prim); nc = length (c); fc = zeros (1, nc); f = []; fl = 0; f0 = []; f1 = []; t = 0; do t++; f0 = f1; for i = 1:nc if (fc(i) != 1) cl = log (c{i}); for j = 2*(t-1)+1:2*t if (find (cl == j)) f1 = [f1, c{i}.x]; fc(i) = 1; ptmp = gf ([c{i}(1), 1], m, prim); for l = 2:length (c{i}) ptmp = conv (ptmp, [c{i}(l), 1]); endfor f = [f; [ptmp.x, zeros(1, m - length (ptmp) + 1)]]; fl = fl + length (ptmp); break; endif endfor endif endfor until (length (f1) > nn - k) t--; if (nn - length (f0) != k) error ("bchpoly: could not find valid generator polynomial for parameters"); endif if (probe) p = [nn, k, t]; else ## Have to delete a line from the list of minimum polynomials ## since we've gone one past in calculating f1 above to be ## sure or the error correcting capability f = f(1:size (f, 1) - 1,:); p = gf ([f0(1), 1], m, prim); for i = 2:length (f0) p = conv (p, [f0(i), 1]); endfor p = p.x; if (nargout > 3) if (n > 64) warning ("bchpoly: could not create parity matrix"); par = []; else par = cyclgen (n, p); endif endif endif endif endfunction %% Test input validation %!error bchpoly (1) %!error bchpoly (1, 2, 3, 4, 5) %!error bchpoly (5, 10) communications-1.2.1/inst/PaxHeaders.3802/gen2par.m0000644000000000000000000000013212510010473016676 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/gen2par.m0000644000000000000000000000343512510010473017230 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{par} =} gen2par (@var{gen}) ## @deftypefnx {Function File} {@var{gen} =} gen2par (@var{par}) ## ## Converts binary generator matrix @var{gen} to the parity check matrix ## @var{par} and visa-versa. The input matrix must be in standard form. ## That is a generator matrix must be k-by-n and in the form [eye(k) P] ## or [P eye(k)], and the parity matrix must be (n-k)-by-n and of the ## form [eye(n-k) P'] or [P' eye(n-k)]. ## ## @seealso{cyclgen, hammgen} ## @end deftypefn function par = gen2par (gen) if (nargin != 1) print_usage (); endif [gr, gc] = size (gen); if (gr > gc) error ("gen2par: GEN must be a generator matrix in standard form"); endif ## Identify where is the identity matrix if (isequal (gen(:,1:gr), eye (gr))) par = [gen(:,gr+1:gc)', eye(gc-gr)]; elseif (isequal (gen(:,gc-gr+1:gc), eye (gr))) par = [eye(gc-gr), gen(:,1:gc-gr)']; else error ("gen2par: GEN must be a generator matrix in standard form"); endif endfunction %% Test input validation %!error gen2par () %!error gen2par (1, 2) %!error gen2par ([1; 2]) communications-1.2.1/inst/PaxHeaders.3802/egolayenc.m0000644000000000000000000000013212510010473017306 xustar0030 mtime=1428164923.870511841 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/egolayenc.m0000644000000000000000000000323412510010473017635 0ustar00rootroot00000000000000## Copyright (C) 2007 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{C} =} egolayenc (@var{M}) ## Encode with Extended Golay code. ## ## The message @var{M}, needs to be of size Nx12, for encoding. ## We can encode several messages, into codes at once, if they ## are stacked in the order suggested. ## ## The generator used in here is same as obtained from the ## function @code{egolaygen}. Extended Golay code (24,12) which can correct ## up to 3 errors. ## ## @example ## @group ## msg = rand (10, 12) > 0.5; ## c = egolayenc (msg) ## @end group ## @end example ## ## @seealso{egolaygen, egolaydec} ## @end deftypefn function C = egolayenc (M) if (nargin != 1) print_usage (); elseif (columns (M) != 12) error ("egolayenc: M must be a matrix with 12 columns"); endif G = egolaygen (); # generator C = mod (M * repmat (G, [1, rows(M)]), 2); C = C(:, 1:24); endfunction %% Test input validation %!error egolayenc () %!error egolayenc (1) %!error egolayenc (1, 2) communications-1.2.1/inst/PaxHeaders.3802/intrlv.m0000644000000000000000000000013112510010473016655 xustar0029 mtime=1428164923.87851166 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/intrlv.m0000644000000000000000000000316212510010473017205 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{intrlvd} =} intrlv (@var{data}, @var{elements}) ## Interleaved elements of @var{data} according to @var{elements}. ## @seealso{deintrlv} ## @end deftypefn function intrlvd = intrlv (data, elements) if (nargin != 2) print_usage (); endif if (!isvector (elements)) error ("intrlv: ELEMENTS must be a vector"); endif if (isvector (data)) if (length (elements) != length (data) || any (sort (elements) != 1:length (data))) error ("intrlv: ELEMENTS must be a permutation of DATA indices"); endif intrlvd = data(elements); else if (length (elements) != size (data, 1) || any (sort (elements) != 1:size (data, 1))) error ("intrlv: ELEMENTS must be a permutation of DATA indices"); endif intrlvd = data(elements,:); endif endfunction %% Test input validation %!error intrlv () %!error intrlv (1) %!error intrlv (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/pskdemod.m0000644000000000000000000000013212510010473017146 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/pskdemod.m0000644000000000000000000000441612510010473017500 0ustar00rootroot00000000000000## Copyright (C) 2006 Charalampos C. Tsimenidis ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}) ## @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}) ## @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}, @var{type}) ## ## Demodulates a complex-baseband phase shift keying modulated signal ## into an information sequence of integers in the range ## @code{[0 @dots{} M-1]}. @var{phi} controls the initial phase and ## @var{type} controls the constellation mapping. If @var{type} is set ## to "Bin" will result in binary encoding, in contrast, if set to ## "Gray" will give Gray encoding. An example of Gray-encoded 8-PSK is ## ## @example ## @group ## d = randint (1, 1e3, 8); ## y = pskmod (d, 8, 0, "gray"); ## z = awgn (y, 20); ## d_est = pskdemod (z, 8, 0, "gray"); ## plot (z, "rx") ## biterr (d, d_est) ## @end group ## @end example ## @seealso{pskmod} ## @end deftypefn function y = pskdemod (x, M, phi, type) if (nargin < 2) print_usage (); endif if (nargin < 3) phi = 0; endif if (nargin < 4) type = "Bin"; endif m = 0:M-1; index = mod (round ((arg (x) - phi) * M/2/pi), M) + 1; if (strcmp (type, "Bin") || strcmp (type, "bin")) y = index-1; elseif (strcmp (type, "Gray") || strcmp (type, "gray")) map = bitxor (m, bitshift (m, -1)); y = map(index); else print_usage (); endif endfunction %!assert (pskdemod ([1 j -1 -j], 4, 0, "Bin"), [0:3]) %!assert (pskdemod ([1 j -j -1], 4, 0, "Gray"), [0:3]) %% Test input validation %!error pskdemod () %!error pskdemod (1) %!error pskdemod (1, 2, 3, "invalid") communications-1.2.1/inst/PaxHeaders.3802/de2bi.m0000644000000000000000000000013212510010473016325 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/de2bi.m0000644000000000000000000000662012510010473016656 0ustar00rootroot00000000000000## Copyright (C) 2001 Laurent Mazet ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{b} =} de2bi (@var{d}) ## @deftypefnx {Function File} {@var{b} =} de2bi (@var{d}, @var{n}) ## @deftypefnx {Function File} {@var{b} =} de2bi (@var{d}, @var{n}, @var{p}) ## @deftypefnx {Function File} {@var{b} =} de2bi (@var{d}, @var{n}, @var{p}, @var{f}) ## ## Convert a non-negative integer to bit vector. ## ## The variable @var{d} must be a vector of non-negative integers. @code{de2bi} ## then returns a matrix where each row represents the binary representation ## of elements of @var{d}. If @var{n} is defined then the returned matrix ## will have @var{n} columns. This number of columns can be either larger ## than the minimum needed and zeros will be added to the msb of the ## binary representation or smaller than the minimum in which case the ## least-significant part of the element is returned. ## ## If @var{p} is defined then it is used as the base for the decomposition ## of the returned values. That is the elements of the returned value are ## between '0' and 'p-1'. ## ## The variable @var{f} defines whether the first or last element of @var{b} ## is considered to be the most-significant. Valid values of @var{f} are ## "right-msb" or "left-msb". By default @var{f} is "right-msb". ## ## @seealso{bi2de} ## @end deftypefn function b = de2bi (d, n, p, f) if (nargin == 1) p = 2; n = floor ( log (max (max (d), 1)) ./ log (p) ) + 1; f = "right-msb"; elseif (nargin == 2) p = 2; f = "right-msb"; elseif (nargin == 3) if (ischar (p)) f = p; p = 2; else f = "right-msb"; endif elseif (nargin == 4) if (ischar (p)) tmp = f; f = p; p = tmp; endif else print_usage (); endif d = d(:); if (! (all (d == fix (d)) && all (d >= 0))) error ("de2bi: all elements of D must be non-negative integers"); endif if (isempty (n)) n = floor ( log (max (max (d), 1)) ./ log (p) ) + 1; endif power = ones (length (d), 1) * (p .^ [0 : n-1] ); d = d * ones (1, n); b = floor (rem (d, p*power) ./ power); if (strcmp (f, "left-msb")) b = b(:,columns (b):-1:1); elseif (!strcmp (f, "right-msb")) error ("de2bi: invalid option '%s'", f); endif endfunction %!shared x %! x = randi ([0 2^16-1], 100, 1); %!assert (de2bi (0), 0) %!assert (de2bi (1), 1) %!assert (de2bi (255), ones (1, 8)) %!assert (de2bi (255, [], 256), 255) %!assert (de2bi (1023, 8, 8), [7 7 7 1 0 0 0 0]) %!assert (size (de2bi (x, 16)), [100 16]) %!assert (de2bi (x, 16, "right-msb"), de2bi (x, 16)) %!assert (de2bi (x, 16, "left-msb"), fliplr (de2bi (x, 16))) %% Test input validation %!error de2bi () %!error de2bi (1, 2, 3, 4, 5) %!error de2bi (1, 2, 3, 4) %!error de2bi (1, 2, 3, "invalid") %!error de2bi (0.1) %!error de2bi (-1) communications-1.2.1/inst/PaxHeaders.3802/fmmod.m0000644000000000000000000000013212510010473016442 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/fmmod.m0000644000000000000000000000236712510010473016777 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} fmmod (@var{x}, @var{fc}, @var{fs}) ## Create the FM modulation of the signal x with carrier frequency fs. Where ## x is sample at frequency fs. ## @seealso{ammod, fmdemod, amdemod} ## @end deftypefn function s = fmmod (m, fc, fs, freqdev) if (nargin < 3) print_usage (); endif l = length (m); t = 0:1./fs:(l-1)./fs; int_m = cumsum (m)./fs; s = cos (2*pi.*fc.*t + 2*pi.*freqdev.*int_m); endfunction %% Test input validation %!error fmmod () %!error fmmod (1) %!error fmmod (1, 2) communications-1.2.1/inst/PaxHeaders.3802/randdeintrlv.m0000644000000000000000000000013212510010473020034 xustar0030 mtime=1428164923.886511478 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/randdeintrlv.m0000644000000000000000000000244512510010473020366 0ustar00rootroot00000000000000## Copyright (C) 2008 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{intrlvd} =} randdeintrlv (@var{data}, @var{state}) ## Restore elements of @var{data} with a random permutation. ## @seealso{randintrlv, intrlv, deintrlv} ## @end deftypefn function deintrlvd = randdeintrlv (data, state) if (nargin != 2) print_usage (); endif if (isvector (data)) l = length (data); else l = size (data, 1); endif rand ("state", state); deintrlvd = deintrlv (data, randperm (l)); endfunction %% Test input validation %!error randdeintrlv () %!error randdeintrlv (1) %!error randdeintrlv (1, 2, 3) communications-1.2.1/inst/PaxHeaders.3802/helscanintrlv.m0000644000000000000000000000013212510010473020214 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/helscanintrlv.m0000644000000000000000000000377412510010473020554 0ustar00rootroot00000000000000## Copyright (C) 2010 Mark Borgerding ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{outdata} =} helscanintrlv (@var{data}, @var{nrows}, @var{ncols}, @var{Nshift}) ## @var{nrows}-by-@var{ncols}. ## @seealso{helscandeintrlv} ## @end deftypefn function outdata = helscanintrlv (data, Nrows, Ncols, Nshift) if (nargin != 4) print_usage (); endif if (! (isscalar (Nrows) && Nrows == fix (Nrows))) error ("helscanintrlv: NROWS must be an integer"); endif if (! (isscalar (Ncols) && Ncols == fix (Ncols))) error ("helscanintrlv: NCOLS must be an integer"); endif didTranspose = 0; if (isvector (data) && columns (data) > rows (data)) data = data.'; didTranspose = 1; endif s = size (data); if (size (data, 1) != Nrows*Ncols) error ("helscanintrlv: DATA must have length equal to NCOLS*NROWS"); endif # create the interleaving indices idx0 = 0:Nrows*Ncols-1; idxMod = rem (idx0, Ncols); idxFlr = idx0 - idxMod; inds = 1 + rem (idxFlr + idxMod * Ncols * Nshift + idxMod, Nrows*Ncols); # for each column for k = 1:s(2) outdata(:,k) = data(inds,k); endfor if (didTranspose) outdata = outdata.'; endif endfunction %% Test input validation %!error helscanintrlv () %!error helscanintrlv (1) %!error helscanintrlv (1, 2) %!error helscanintrlv (1, 2, 3) %!error helscanintrlv (1, 2, 3, 4, 5) communications-1.2.1/inst/PaxHeaders.3802/oct2dec.m0000644000000000000000000000013212510010473016663 xustar0030 mtime=1428164923.882511568 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/oct2dec.m0000644000000000000000000000341212510010473017210 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {@var{d} =} oct2dec (@var{c}) ## ## Convert octal to decimal values. ## ## Each element of the octal matrix @var{c} is converted to a decimal value. ## ## @seealso{base2dec, bin2dec, dec2bin} ## @end deftypefn function d = oct2dec (c) if (nargin != 1) print_usage (); endif # Check for negative or non-integer values if (! (all (c(:) == fix (c(:))) && all (c(:) >= 0))) error ("oct2dec: C must be an octal matrix"); endif d = zeros (size (c)); l = size (c, 2); for k = 1:l str = num2str (c(:,k), "%ld"); d(:,k) = base2dec (str, 8); if (any (isnan (d(:,k)))) error ("oct2dec: C must be an octal matrix"); endif endfor endfunction %!shared x, y %! x = reshape ([0:79], 10, 8)(1:8,:); %! y = reshape ([0:63], 8, 8); %!assert (oct2dec (0), 0) %!assert (oct2dec (77777777), 2^24 - 1) %!assert (oct2dec (x), y) %% Test input validation %!error oct2dec () %!error oct2dec (0, 0) %!error oct2dec (0.1) %!error oct2dec (-1) %!error oct2dec (8) communications-1.2.1/inst/PaxHeaders.3802/rledeco.m0000644000000000000000000000013212510010473016755 xustar0030 mtime=1428164923.922510659 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/rledeco.m0000644000000000000000000000310412510010473017300 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} rledeco (@var{message}) ## ## Returns decoded run-length @var{message}. The RLE encoded @var{message} ## has to be in the form of a row-vector. The message format (encoded RLE) ## is like repetition [factor, value]+. ## ## An example use of @code{rledeco} is ## @example ## @group ## message = [1 5 2 4 3 1]; ## rledeco (message) ## @result{} [5 4 4 1 1 1] ## @end group ## @end example ## @seealso{rledeco} ## @end deftypefn function rmsg = rledeco (message) if (nargin != 1) print_usage (); endif rmsg = []; L = length (message); itr = 1; while (itr < L) times = message(itr); val = message(itr+1); rmsg = [rmsg val * (ones (1, times))]; itr = itr + 2; endwhile endfunction %!assert (rledeco ([1 5 2 4 3 1]), [5 4 4 1 1 1]) %% Test input validation %!error rledeco () %!error rledeco (1, 2) communications-1.2.1/inst/PaxHeaders.3802/comms.m0000644000000000000000000000013212510010473016456 xustar0030 mtime=1428164923.866511933 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/comms.m0000644000000000000000000005335212510010473017013 0ustar00rootroot00000000000000## Copyright (C) 2003 David Bateman ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} comms ("help") ## @deftypefnx {Function File} {} comms ("info") ## @deftypefnx {Function File} {} comms ("info", @var{mod}) ## @deftypefnx {Function File} {} comms ("test") ## @deftypefnx {Function File} {} comms ("test", @var{mod}) ## ## Manual and test code for the Octave Communications toolbox. There are ## 5 possible ways to call this function. ## ## @table @code ## @item comms ("help") ## Display this help message. Called with no arguments, this function also ## displays this help message ## @item comms ("info") ## Open the Communications toolbox manual ## @item comms ("info", @var{mod}) ## Open the Communications toolbox manual at the section specified by ## @var{mod} ## @item comms ("test") ## Run all of the test code for the Communications toolbox. ## @item comms ("test", @var{mod}) ## Run only the test code for the Communications toolbox in the module ## @var{mod}. ## @end table ## ## Valid values for the variable @var{mod} are ## ## @table @asis ## @item "all" ## All of the toolbox ## @item "random" ## The random signal generation and analysis package ## @item "source" ## The source coding functions of the package ## @item "block" ## The block coding functions ## @item "convol" ## The convolution coding package ## @item "modulation" ## The modulation package ## @item "special" ## The special filter functions ## @item "galois" ## The Galois fields package ## @end table ## ## Please note that this function file should be used as an example of the ## use of this toolbox. ## @end deftypefn function retval = comms (typ, tests) if (nargin < 1) help ("comms"); elseif (nargin < 2) tests = "all"; endif if (strcmp (tests, "all")) nodename = "Top"; elseif (strcmp (tests, "random")) nodename = "Random Signals"; elseif (strcmp (tests, "source")) nodename = "Source Coding"; elseif (strcmp (tests, "block")) nodename = "Block Coding"; elseif (strcmp (tests, "convol")) nodename = "Convolutional Coding"; elseif (strcmp (tests, "modulation")) nodename = "Modulations"; elseif (strcmp (tests, "special")) nodename = "Special Fields"; elseif (strcmp (tests, "galois")) nodename = "Galois Fields"; else error ("comms: unrecognized package"); endif if (strcmp (typ, "help")) help ("comms"); elseif (strcmp (typ, "info")) infopaths = ["."]; if (!isempty (char (strsplit (path, ":")))) infopaths = [infopaths; char(strsplit (path, ":"))]; endif if (!isempty (char (strsplit (DEFAULT_LOADPATH, ":")))) infopaths = [infopaths; char(strsplit (DEFAULT_LOADPATH, ":"))]; endif for i = 1:size (infopaths, 1) infopath = deblank (infopaths(i,:)); len = length (infopath); if (len) if (len > 1 && strcmp (infopath([len-1, len]), "//")) [status, showfile] = system (["find '", infopath(1:len-1), ... "' -name ", infofile]); else [status, showfile] = system (["find '", infopath, "' -name ", ... infofile, " -maxdepth 1"]); endif if (length (showfile)) break; endif endif endfor if (!exist ("showfile") || !length (showfile)) error ("comms: info file not found"); endif if (showfile(length (showfile)) == "\n") showfile = showfile(1:length (showfile)-1); endif if (exist ("INFO_PROGAM")) [testret, testout] = system (["'", INFO_PROGRAM, "' --version"]); if (testret) error ("comms: info command not found"); else system (["'", INFO_PROGRAM, "' --file '", showfile, "' --node '", ... nodename, "'"]); endif else [testret, testout] = system ("info --version"); if (testret) error ("comms: info command not found"); else system (["info --file '", showfile, "' --node '", nodename, "'"]); endif endif elseif (strcmp (typ, "test")) pso = page_screen_output (); unwind_protect page_screen_output (0); if (strcmp (tests, "random") || strcmp (tests, "all")) fprintf ("\n<< Random Signals Package >>\n"); fprintf (" Signal Creation: "); n = 10; m = 32; x = randint (n, n, m); if (any (size (x) != [10, 10]) || (max (x(:)) >= m) || (min (x(:) < 0))) error ("FAILED"); endif x = randsrc (n, n, [1, 1i, -1, -1i,]); if (any (size (x) != [10, 10]) || ... !all (all ((x == 1) | (x == 1i) | (x == -1) | (x == -1i)))) error ("FAILED"); endif x = randerr (n, n); if (any (size (x) != [10, 10]) || any (sum (x') != ones (1, n))) error ("FAILED"); endif nse_30dBm_1Ohm = wgn (10000, 1, 30, 1, "dBm"); nse_0dBW_1Ohm = wgn (10000, 1, 0, 1, "dBW"); nse_1W_1Ohm = wgn (10000, 1, 1, 1, "linear"); ## Standard deviations should be about 1... If it is greater than ## some value flag an error dev = [std(nse_30dBm_1Ohm), std(nse_0dBW_1Ohm), std(nse_1W_1Ohm)]; if (any (dev > 1.5)) error ("FAILED"); endif x = [0:0.1:2*pi]; y = sin (x); noisy = awgn (y, 10, "dB", "measured"); if (any (size (y) != size (noisy))) error ("FAILED"); endif ## This is a pretty arbitrary test, but should pick up gross errors if (any (abs (y - noisy) > 1)) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Signal Analysis: "); ## Protect!! Since bitxor might not be installed try n = 10; m = 8; msg = randint (n, n, 2^m); noisy = bitxor (msg, diag (3*ones (1, n))); [berr, brate] = biterr (msg, noisy, m); if ((berr != 2*n) || (brate != 2/(n*m))) error ("FAILED"); endif [serr, srate] = symerr (msg, noisy); if ((serr != n) || (srate != 1/n)) error ("FAILED"); endif catch end_try_catch ## Can not easily test eyediagram, scatterplot!! fprintf ("PASSED\n"); endif if (strcmp (tests, "source") || strcmp (tests, "all")) fprintf ("\n<< Source Coding Package >>\n"); fprintf (" PCM Functions: "); fprintf ("Not tested\n"); fprintf (" Quantization Functions: "); x = [0:0.1:2*pi]; y = sin (x); [tab, cod] = lloyds (y, 16); [i, q, d] = quantiz (y, tab, cod); if (abs (d) > 0.1) error ("FAILED"); endif mu = 0.1; V = 1; x = sin ([0:0.1:2*pi]); y = compand (x, mu, V, "mu/compressor"); z = compand (x, mu, V, "mu/expander"); ## Again this is a pretty arbitrary test if (max (abs (x-z)) > 0.1) error ("FAILED"); endif fprintf ("PASSED\n"); endif if (strcmp (tests, "block") || strcmp (tests, "all")) fprintf ("\n<< Block Coding Package >>\n"); fprintf (" Cyclic Coding: "); nsym = 100; m = 4; n = 2^m-1; # [15,11] Hamming code k = n - m; p = cyclpoly (n, k); if (bi2de (p) != primpoly (m, "nodisplay")) error ("FAILED"); endif [par, gen] = cyclgen (n, p); if (any (any (gen2par (par) != gen))) error ("FAILED"); endif if (gfweight (gen) != 3) error ("FAILED"); endif msg = randint (nsym, k); code = encode (msg, n, k, "cyclic"); noisy = mod (code + randerr (nsym, n), 2); dec = decode (noisy, n, k, "cyclic"); if (any (any (dec != msg))) error ("FAILED"); endif try # Protect! If bitshift isn't install!! msg = randint (nsym, 1, n); code = encode (msg, n, k, "cyclic/decimal"); noisy = mod (code + bitshift (1, randint (nsym, 1, n)), n+1); dec = decode (noisy, n, k, "cyclic/decimal"); if (any (dec != msg)) error ("FAILED"); endif catch end_try_catch fprintf ("PASSED\n"); fprintf (" Hamming Coding: "); nsym = 100; m = 4; [par, gen, n, k] = hammgen (m); if (any (any (gen2par (par) != gen))) error ("FAILED"); endif if (gfweight (gen) != 3) error ("FAILED"); endif msg = randint (nsym, k); code = encode (msg, n, k, "hamming"); noisy = mod (code + randerr (nsym, n), 2); dec = decode (noisy, n, k, "hamming"); if (any (any (dec != msg))) error ("FAILED"); endif try # Protect! If bitshift isn't install!! msg = randint (nsym, 1, n); code = encode (msg, n, k, "hamming/decimal"); noisy = mod (code + bitshift (1, randint (nsym, 1, n)), n+1); dec = decode (noisy, n, k, "hamming/decimal"); if (any (dec != msg)) error ("FAILED"); endif catch end_try_catch fprintf ("PASSED\n"); fprintf (" BCH Coding: "); ## Setup m = 5; nsym = 100; p = bchpoly (2^m - 1); ## Pick a BCH code from the list at random l = ceil (size (p, 1) * rand (1, 1)); n = p(l,1); k = p(l,2); t = p(l,3); ## Symbols represented by rows of binary matrix msg = randint (nsym, k); code = encode (msg, n, k, "bch"); noisy = mod (code + randerr (nsym, n), 2); dec = decode (noisy, n, k, "bch"); if (any (any (dec != msg))) error ("FAILED"); endif try # Protect! If bitshift isn't install!! msg = randint (nsym, 1, n); code = encode (msg, n, k, "bch/decimal"); noisy = mod (code + bitshift (1, randint (nsym, 1, n)), n+1); dec = decode (noisy, n, k, "bch/decimal"); if (any (dec != msg)) error ("FAILED"); endif catch end_try_catch fprintf ("PASSED\n"); fprintf (" Reed-Solomon Coding: "); ## Test for a CCSDS like coder, but without dual-basis translation mrs = 8; nrs = 2^mrs -1; krs = nrs - 32; prs = 391; fcr = 112; step = 11; ## CCSDS generator polynomial ggrs = rsgenpoly (nrs, krs, prs, fcr, step); ## Code two blocks msg = gf (floor (2^mrs*rand (2, krs)), mrs, prs); cde = rsenc (msg, nrs, krs, ggrs); ## Introduce errors noisy = cde + [255, 0, 255, 0, 255, zeros(1, 250); ... 0, 255, 0, 255, zeros(1, 251)]; ## Decode (better to pass fcr and step rather than gg for speed) dec = rsdec (noisy, nrs, krs, fcr, step); if (any (dec != msg)) error ("FAILED"); endif fprintf ("PASSED\n"); endif if (strcmp (tests, "convol") || strcmp (tests, "all")) fprintf ("\n<< Convolutional Coding Package >>\n"); fprintf (" Utility functions: "); ## create a trellis, use poly2trellis and test with istrellis fprintf ("Not tested\n"); fprintf (" Coding: "); ## use convenc, puncturing?? fprintf ("Not tested\n"); fprintf (" Viterbi: "); ## use vitdec fprintf ("Not tested\n"); endif if (strcmp (tests, "modulation") || strcmp (tests, "all")) fprintf ("\n<< Modulation Package >>\n"); fprintf (" Analog Modulation: "); Fs = 100; t = [0:1/Fs:2]; x = sin (2*pi*t); xq = x + 1i * cos (2*pi*t); ## Can not test FM as it doesn't work !!! if ((max (abs (x - ademodce (amodce (x, Fs, "pm"), Fs, "pm"))) > 0.001) || ... (max (abs (x - ademodce (amodce (x, Fs, "am"), Fs, "am"))) > 0.001) || ... (max (abs (xq - ademodce (amodce (xq, Fs, "qam"), Fs, "qam/cmplx"))) > 0.001)) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Digital Mapping: "); m = 32; n = 100; x = randint (n, n, 32); if ((x != demodmap (modmap (x, 1, 1, "ask", m), 1, 1, "ask", m)) || ... (x != demodmap (modmap (x, 1, 1, "fsk", m), 1, 1, "fsk", m)) || ... (x != demodmap (modmap (x, 1, 1, "msk"), 1, 1, "msk")) || ... (x != demodmap (modmap (x, 1, 1, "psk", m), 1, 1, "psk", m)) || ... (x != demodmap (modmap (x, 1, 1, "qask", m), 1, 1, "qask", m)) || ... (x != demodmap (modmap (x, 1, 1, "qask/cir", ... [floor(m/2), m - floor(m/2)]), 1, 1, "qask/cir", ... [floor(m/2), m - floor(m/2)]))) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Digital Modulation: "); fprintf ("Not tested\n"); endif if (strcmp (tests, "special") || strcmp (tests, "all")) fprintf ("\n<< Special Filters Package >>\n"); fprintf (" Hankel/Hilbert: "); ## use hank2sys, hilbiir fprintf ("Not tested\n"); fprintf (" Raised Cosine: "); ## use rcosflt, rcosiir rcosine, rcosfir fprintf ("Not tested\n"); endif if (strcmp (tests, "galois") || strcmp (tests, "all")) fprintf ("\n<< Galois Fields Package >>\n"); ## Testing of the Galois Fields package m = 3; ## must be greater than 2 fprintf (" Find primitive polynomials: "); prims = primpoly (m, "all", "nodisplay"); for i = 2^m:2^(m+1) - 1 if (find (prims == i)) if (!isprimitive (i)) error ("Error in primitive polynomials"); endif else if (isprimitive (i)) error ("Error in primitive polynomials"); endif endif endfor fprintf ("PASSED\n"); fprintf (" Create Galois variables: "); n = 2^m-1; gempty = gf ([], m); gzero = gf (0, m); gone = gf (1, m); gmax = gf (n, m); grow = gf (0:n, m); gcol = gf ([0:n]', m); matlen = ceil (sqrt (2^m)); gmat = gf (reshape (mod ([0:matlen*matlen-1], 2^m), matlen, matlen), m); fprintf ("PASSED\n"); fprintf (" Access Galois structures: "); if (gcol.m != m || gcol.prim_poly != primpoly (m, "min", ... "nodisplay")) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Miscellaneous functions: "); if (size (gmat) != [matlen, matlen]) error ("FAILED"); endif if (length (grow) != 2^m) error ("FAILED"); endif if (!any (grow) || all (grow) || any (gzero) || !all (gone)) error ("FAILED"); endif if (isempty (gone) || !isempty (gempty)) error ("FAILED"); endif tmp = diag (grow); if (size (tmp, 1) != 2^m || size (tmp, 2) != 2^m) error ("FAILED"); endif for i = 1:2^m for j = 1:2^m if ((i == j) && (tmp(i,j) != grow(i))) error ("FAILED"); elseif ((i != j) && (tmp(i,j) != 0)) error ("FAILED"); endif endfor endfor tmp = diag (gmat); if (length (tmp) != matlen) error ("FAILED"); endif for i = 1:matlen if (gmat(i,i) != tmp(i)) error ("FAILED"); endif endfor tmp = reshape (gmat, prod (size (gmat)), 1); if (length (tmp) != prod (size (gmat))) error ("FAILED"); endif if (exp (log (gf ([1:n], m))) != [1:n]) error ("FAILED"); endif tmp = sqrt (gmat); if (tmp .* tmp != gmat) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Unary operators: "); tmp = - grow; if (tmp != grow) error ("FAILED"); endif tmp = !grow; if (tmp(1) != 1) error ("FAILED"); endif if (any (tmp(2:length (tmp)))) error ("FAILED"); endif tmp = gmat'; for i = 1:size (gmat, 1) for j = 1:size (gmat, 2) if (gmat(i,j) != tmp(j,i)) error ("FAILED"); endif endfor endfor fprintf ("PASSED\n"); fprintf (" Arithmetic operators: "); if (any (gmat + gmat)) error ("FAILED"); endif multbl = gcol * grow; elsqr = gcol .* gcol; elsqr2 = gcol .^ gf (2, m); for i = 1:length (elsqr) if (elsqr(i) != multbl(i,i)) error ("FAILED"); endif endfor for i = 1:length (elsqr) if (elsqr(i) != elsqr2(i)) error ("FAILED"); endif endfor tmp = grow(2:length (grow)) ./ gcol(2:length (gcol))'; if (length (tmp) != n || any (tmp != ones (1, length (grow) - 1))) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Logical operators: "); if (grow(1) != gzero || grow(2) != gone || grow(2^m) != n) error ("FAILED"); endif if (!(grow(1) == gzero) || any (grow != gcol')) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Polynomial manipulation: "); poly1 = gf ([2, 4, 5, 1], 3); poly2 = gf ([1, 2], 3); sumpoly = poly1 + [0, 0, poly2]; ## Already test "+" mulpoly = conv (poly1, poly2); ## multiplication poly3 = [poly, remd] = deconv (mulpoly, poly2); if (!isequal (poly1, poly3)) error ("FAILED"); endif if (any (remd)) error ("FAILED"); endif x0 = gf ([0, 1, 2, 3], 3); y0 = polyval (poly1, x0); alph = gf (2, 3); y1 = alph * x0.^3 + alph.^2 * x0.^2 + (alph.^2+1) *x0 + 1; if (!isequal (y0, y1)) error ("FAILED"); endif roots1 = roots (poly1); ck1 = polyval (poly1, roots1); if (any (ck1)) error ("FAILED"); endif b = minpol (alph); bpoly = bi2de (b.x, "left-msb"); if (bpoly != alph.prim_poly) error ("FAILED"); endif c = cosets (3); c2 = c{2}; mpol = minpol (c2(1)); for i = 2:length (c2) if (mpol != minpol (c2(i))) error ("FAILED"); endif endfor fprintf ("PASSED\n"); fprintf (" Linear Algebra: "); [l, u, p] = lu (gmat); if (any (l*u - p*gmat)) error ("FAILED"); endif g1 = inv (gmat); g2 = gmat ^ -1; if (any (g1*gmat != eye (matlen))) error ("FAILED"); endif if (any (g1 != g2)) error ("FAILED"); endif matdet = 0; while (!matdet) granmat = gf (floor (2^m*rand (matlen)), m); matdet = det (granmat); endwhile matrank = rank (granmat); smallcol = gf ([0:matlen-1], m)'; sol1 = granmat \ smallcol; sol2 = smallcol' / granmat; if (any (granmat * sol1 != smallcol)) error ("FAILED"); endif if (any (sol2 * granmat != smallcol')) error ("FAILED"); endif fprintf ("PASSED\n"); fprintf (" Signal Processing functions: "); b = gf ([1, 0, 0, 1, 0, 1, 0, 1], m); a = gf ([1, 0, 1, 1], m); x = gf ([1, zeros(1, 99)], m); y0 = filter (b, a, x); y1 = conv (grow+1, grow); y2 = grow * convmtx (grow+1, length (grow)); if (any (y1 != y2)) error ("FAILED"); endif [y3, remd] = deconv (y2, grow+1); if (any (y3 != grow)) error ("FAILED"); endif if (any (remd)) error ("FAILED"); endif alph = gf (2, m); x = gf (floor (2^m*rand (n, 1)), m); fm = dftmtx (alph); ifm = dftmtx (1/alph); y0 = fft (x); y1 = fm * x; if (any (y0 != y1)) error ("FAILED"); endif z0 = ifft (y0); z1 = ifm * y1; if (any (z0 != x)) error ("FAILED"); endif if (any (z1 != x)) error ("FAILED"); endif fprintf ("PASSED\n"); endif fprintf ("\n"); unwind_protect_cleanup page_screen_output (pso); end_unwind_protect else print_usage (); endif endfunction %!test %! try comms ("test"); %! catch disp (lasterr ()); end_try_catch communications-1.2.1/inst/PaxHeaders.3802/golombdeco.m0000644000000000000000000000013212510010473017452 xustar0030 mtime=1428164923.874511751 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/golombdeco.m0000644000000000000000000000555712510010473020013 0ustar00rootroot00000000000000## Copyright (C) 2006 Muthiah Annamalai ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} golombdeco (@var{code}, @var{m}) ## ## Returns the Golomb decoded signal vector using @var{code} and @var{m}. ## Compulsory m is need to be specified. A restrictions is that a ## signal set must strictly be non-negative. The value of code ## is a cell array of row-vectors which have the encoded Golomb value ## for a single sample. The Golomb algorithm is ## used to encode the "code" and only that can be meaningfully ## decoded. @var{code} is assumed to have been of format generated ## by the function @code{golombenco}. Also the parameter @var{m} need to ## be a non-zero number, unless which it makes divide-by-zero errors. ## This function works backward the Golomb algorithm see ## @code{golombenco} for more details on that. ## Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info Theory ## ## An example of the use of @code{golombdeco} is ## @example ## @group ## golombdeco (golombenco (1:4, 2), 2) ## @result{} [1 2 3 4] ## @end group ## @end example ## @seealso{golombenco} ## @end deftypefn ##! /usr/bin/octave -q #A stress test routine #for i=1:100 # sig=abs(randint(1,10,[0,255])); # k=mod(i,10)+1; # code=golombenco(sig,k); # assert(golombdeco(code,k),sig) #endfor # #for k=1:10; # assert(golombdeco(golombenco(4:10,k),k),[4:10]); #endfor # function sig_op = golombdeco (code, m) if (nargin != 2 || ! iscell (code) || m <= 0) print_usage (); endif L = length (code); C = ceil (log2 (m)); partition_limit = 2**C - m; power_seq = [2.^(ceil (log2 (m)) - 1:-1:0)]; power_seq_mod = power_seq(2:end); for j = 1:L word = code{j}; WL = length (word); idx = find (word == 0)(1); q = sum (word(1:idx)); idx2 = (WL-idx); word_tail = word(idx+1:end); if (length (word_tail) == C) r = sum (word_tail.*power_seq); r = r- (partition_limit); else r = sum (word_tail.*power_seq_mod); endif quot(j) = q; rem(j) = r; endfor sig_op = quot.*m + rem; endfunction %!assert (golombdeco (golombenco (1:4, 2), 2), [1:4]) %% Test input validation %!error golombdeco () %!error golombdeco (1) %!error golombdeco (1, 2) %!error golombdeco ({}, 0) communications-1.2.1/inst/PaxHeaders.3802/ammod.m0000644000000000000000000000013212510010473016435 xustar0030 mtime=1428164923.862512023 30 atime=1428164924.054507646 30 ctime=1428164983.712815029 communications-1.2.1/inst/ammod.m0000644000000000000000000000233712510010473016767 0ustar00rootroot00000000000000## Copyright (C) 2007 Sylvain Pelissier ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## -*- texinfo -*- ## @deftypefn {Function File} {} ammod (@var{x}, @var{fc}, @var{fs}) ## Create the AM modulation of the signal x with carrier frequency fs. Where ## x is sample at frequency fs. ## @seealso{amdemod, fmmod, fmdemod} ## @end deftypefn function y = ammod (x, fc, fs) if (nargin != 3) print_usage (); endif l = length (x); t = 0:1./fs:(l-1)./fs; y = x .* cos (2.*pi.*fc.*t); endfunction %% Test input validation %!error ammod () %!error ammod (1) %!error ammod (1, 2) %!error ammod (1, 2, 3, 4) communications-1.2.1/PaxHeaders.3802/doc0000644000000000000000000000013212510010565014677 xustar0030 mtime=1428164981.412890769 30 atime=1428164983.712815029 30 ctime=1428164983.712815029 communications-1.2.1/doc/0000755000000000000000000000000012510010565015301 5ustar00rootroot00000000000000communications-1.2.1/doc/PaxHeaders.3802/Makefile0000644000000000000000000000013212510010473016412 xustar0030 mtime=1428164923.850512296 30 atime=1428164923.982509294 30 ctime=1428164983.712815029 communications-1.2.1/doc/Makefile0000644000000000000000000000374712510010473016752 0ustar00rootroot00000000000000DVIPS = dvips LN_S = ln -s MAKEINFO = makeinfo OCTAVE = octave PERL = perl TEXI2DVI = texi2dvi TEXI2HTML = makeinfo --html TEXI2PDF = texi2pdf INFODOC = comms.info DVIDOC = $(patsubst %.info,%.dvi,$(INFODOC)) PSDOC = $(patsubst %.info,%.ps,$(INFODOC)) PDFDOC = $(patsubst %.info,%.pdf,$(INFODOC)) HTMLDOC = $(patsubst %.info,%.html,$(INFODOC)) TEXIDOC = $(patsubst %.info,%.texi,$(INFODOC)) DOCSTRINGS = DOCSTRINGS INDEX = ../INDEX all: info info: $(INFODOC) dvi: $(DVIDOC) html: $(HTMLDOC) pdf: $(PDFDOC) ps: $(PSDOC) %.dvi: %.texi $(TEXI2DVI) --clean -o $@ $< %.info: %.texi $(MAKEINFO) --no-split -o $@ $< %.pdf: %.texi $(TEXI2PDF) --clean -o $@ $< %.ps: %.dvi $(DVIPS) -o $@ $< %.html: %.texi rm -rf $(@:.html=.htp) if $(TEXI2HTML) -o $(@:.html=.htp) $<; then \ rm -rf $@ && mv $(@:.html=.htp) $@; \ else \ rm -rf $(@:.html=.htp); exit 1; \ fi .PRECIOUS: %.texi %.texi : %.txi @echo "Making texinfo $@"; \ $(RM) -f $(DOCSTRINGS); \ $(PERL) ./mkdoc.pl ../ > $(DOCSTRINGS); \ $(PERL) ./mktexi.pl $< $(DOCSTRINGS) $(INDEX) > $@ ; \ $(RM) -f $(DOCSTRINGS); # Auxiliary make file defines build rules for generated images for the manual -include images.mk images.mk: images.sh $(SHELL) $< > $@ $(DVIDOC): $(IMAGES_EPS) $(PDFDOC): $(IMAGES_PDF) HTMLDIR_IMAGES = $(addprefix $(HTMLDOC)/,$(IMAGES_PNG)) $(HTMLDIR_IMAGES): $(IMAGES_PNG) | $(HTMLDOC) cp $(@F) $@ html: $(HTMLDIR_IMAGES) # The images included in the HTML manual must be present before the makeinfo # command is invoked or it will fall back on incorrect file names. $(HTMLDOC): $(IMAGES_PNG) # The texi2dvi script (used to create both PDF and DVI output formats) # uses some fixed temporary file names. In order to avoid a race condition # the DVI and PDF builds are forced to run serially through a Makefile rule. $(PDFDOC): $(DVIDOC) clean: rm -rf comms.t2d comms.t2p maintainer-clean: clean rm -rf *.dvi *.eps *.html *.info *.pdf *.ps *.png *.texi rm -f images.mk .PHONY: all clean dvi html info maintainer-clean pdf ps communications-1.2.1/doc/PaxHeaders.3802/images.sh0000644000000000000000000000013212510010473016553 xustar0030 mtime=1428164923.854512206 30 atime=1428164923.990509112 30 ctime=1428164983.712815029 communications-1.2.1/doc/images.sh0000755000000000000000000000112412510010473017101 0ustar00rootroot00000000000000#!/bin/sh images="awgn eyediagram scatterplot" formats="eps pdf png" script=commsimages.m printf "IMAGES =" for fmt in $formats; do for img in $images; do printf " $img.$fmt" done done printf "\n" for fmt in $formats; do fmtupcase=`echo $fmt | awk '{print toupper($0)}'` printf "IMAGES_$fmtupcase =" for img in $images; do printf " $img.$fmt" done printf "\n" done for fmt in $formats; do for img in $images; do printf "$img.$fmt: commsimages.m\n" printf "\t\$(OCTAVE) --path=\$(CURDIR)/../inst -f -q -H --eval \"commsimages ('$img', '$fmt');\"\n" done done communications-1.2.1/doc/PaxHeaders.3802/mktexi.pl0000644000000000000000000000013212510010473016610 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/doc/mktexi.pl0000755000000000000000000003022612510010473017143 0ustar00rootroot00000000000000#!/usr/bin/env perl # # David Bateman Feb 02 2003 # # Extracts the help in texinfo format for particular function for use # in documentation. Based on make_index script from octave_forge. use strict; use File::Find; use File::Basename; use Text::Wrap; use FileHandle; use IPC::Open3; use POSIX ":sys_wait_h"; my $file = shift @ARGV; my $docfile = shift @ARGV; my $indexfile = shift @ARGV; my $line; if ( open(IN,$file) ) { $line = ; my $tex = 0; while ($line) { if ($line =~ /^\@DOCSTRING/) { my $found = 0; my $func = $line; $func =~ s/\@DOCSTRING\(//; $func =~ s/\)[\n\r]+//; my $func0 = $func; my $func1 = $func; $func0 =~ s/,.*$//; $func1 =~ s/^.*,//; if ( open(DOC,$docfile) ) { while () { next unless /\037/; my $function = $_; $function =~ s/\037//; $function =~ s/[\n\r]+//; if ($function =~ /^$func0$/) { my $desc = ""; my $docline; my $doctex = 0; while (($docline = ) && ($docline !~ /^\037/)) { $docline =~ s/^\s*-[*]- texinfo -[*]-\s*//; if ($docline =~ /\@tex/) { $doctex = 1; } if ($doctex) { $docline =~ s/\\\\/\\/g; } if ($docline =~ /\@end tex/) { $doctex = 0; } $desc .= $docline; } $desc =~ s/$func0/$func1/g; $desc =~ s/\@seealso\{(.*[^}])\}/See also: \1/g; print "$desc", "\n"; $found = 1; last; } } close (DOC); if (! $found) { print "\@emph{Not implemented}\n"; } } else { print STDERR "Could not open file $docfile\n"; exit 1; } } elsif ($line =~ /^\@REFERENCE_SECTION/) { my $secfound = 0; my $sec = $line; $sec =~ s/\@REFERENCE_SECTION\(//; $sec =~ s/\)[\n\r]+//; my @listfunc = (); my $nfunc = 0; my $seccat = 0; if ( open(IND,$indexfile) ) { while () { next unless /^[^ ]/; my $section = $_; $section =~ s/[\n\r]+//; if ($section =~ /^(.*?)\s*>>\s*(.*?)$/) { $section =~ s/.*>>(.*)/\1/; $seccat = 1; } $section =~ s/^ *//; $section =~ s/ *$//; if ($section =~ /^$sec$/) { if ($seccat) { print "\@iftex\n"; print "\@section Functions by Category\n"; # Get the list of categories to index my $firstcat = 1; my $category; while () { last if />>/; if (/^[^ ]/) { if (! $firstcat) { print "\@end table\n"; } else { $firstcat = 0; } $category = $_; $category =~ s/[\n\r]+//; print "\@subsection $category\n"; print "\@table \@asis\n"; } elsif (/^\s+(\S.*\S)\s*=\s*(\S.*\S)\s*$/) { my $func = $1; my $desc = $2; print "\@item $func\n"; print "$desc\n"; print "\n"; } else { if ($firstcat) { print STDERR "Error parsing index file\n"; exit 1; } s/^\s+//; my @funcs = split /\s+/; while ($#funcs >= 0) { my $func = shift @funcs; $func =~ s/^ *//; $func =~ s/[\n\r]+//; push @listfunc, $func; $nfunc = $nfunc + 1; print "\@item $func\n"; print func_summary($func, $docfile); print "\n"; } } } if (! $firstcat) { print "\@end table\n"; } print "\@end iftex\n\n"; print "\n\@section Functions Alphabetically\n"; } else { # Get the list of functions to index my $indline; while (($indline = ) && ($indline =~ /^ /)) { if ($indline =~ /^\s+(\S.*\S)\s*=\s*(\S.*\S)\s*$/) { next; } $indline =~ s/^\s+//; my @funcs = split(/\s+/,$indline); while ($#funcs >= 0) { my $func = shift @funcs; $func =~ s/^ *//; $func =~ s/[\n\r]+//; push @listfunc, $func; $nfunc = $nfunc + 1; } } } $secfound = 1; last; } } close (IND); if (! $secfound) { print STDERR "Did not find section $sec\n"; } } else { print STDERR "Could not open file $indexfile\n"; exit 1; } @listfunc = sort(@listfunc); my @listfunc2 = (); my $indent = 16 - 3; print "\@menu\n"; foreach my $func (@listfunc) { if ( open(DOC,$docfile) ) { my $found = 0; while () { next unless /\037/; my $function = $_; $function =~ s/\037//; $function =~ s/[\n\r]+//; if ($function =~ /^$func$/) { $found = 1; last; } } close (DOC); if ($found) { push @listfunc2, $func; my $func0 = "${func}::"; my $entry = sprintf("* %-*s %s",$indent,$func0,func_summary($func,$docfile)); print wrap("","\t\t","$entry"), "\n"; } } else { print STDERR "Could not open file $indexfile\n"; exit 1; } } print "\@end menu\n"; my $up = "Function Reference"; my $next; my $prev; my $mfunc = 1; foreach my $func (@listfunc2) { if ($mfunc == $nfunc) { $next = ""; } else { $next = @listfunc2[$mfunc]; $mfunc = $mfunc + 1; } print "\n\@node $func, $next, $prev, $up\n"; if ($seccat) { print "\@subsection $func\n\n"; } else { print "\@section $func\n\n"; } $prev = $func; my $found = 0; my $desc = ""; if ( open(DOC,$docfile) ) { while () { next unless /\037/; my $function = $_; $function =~ s/\037//; $function =~ s/[\n\r]+//; if ($function =~ /^$func$/) { my $docline; my $doctex = 0; while (($docline = ) && ($docline !~ /^\037/)) { $docline =~ s/^\s*-[*]- texinfo -[*]-\s*//; if ($docline =~ /\@tex/) { $doctex = 1; } if ($doctex) { $docline =~ s/\\\\/\\/g; } if ($docline =~ /\@end tex/) { $doctex = 0; } $desc .= $docline; } $desc =~ s/\@seealso\{(.*[^}])\}/See also: \1/g; print "$desc", "\n"; $found = 1; last; } } close (DOC); if (! $found) { print "\@emph{Not implemented}\n"; } } else { print STDERR "Could not open file $docfile\n"; exit 1; } } } else { if ($line =~ /\@tex/) { $tex = 1; } if ($tex) { $line =~ s/\\\\/\\/g; } print "$line"; if ($line =~ /\@end tex/) { $tex = 0; } } $line = ; } } else { print STDERR "Could not open file $file\n"; exit 1; } sub func_summary { # {{{1 my ($func, # in function name $docfile # in DOCSTRINGS ) = @_; my $desc = ""; my $found = 0; if ( open(DOC,$docfile) ) { while () { next unless /\037/; my $function = $_; $function =~ s/\037//; $function =~ s/[\n\r]+//; if ($function =~ /^$func$/) { my $docline; my $doctex = 0; while (($docline = ) && ($docline !~ /^\037/)) { if ($docline =~ /\@tex/) { $doctex = 1; } if ($doctex) { $docline =~ s/\\\\/\\/g; } if ($docline =~ /\@end tex/) { $doctex = 0; } $desc .= $docline; } $desc =~ s/\@seealso\{(.*[^}])\}/See also: \1/g; $found = 1; last; } } close (DOC); if (! $found) { $desc = "\@emph{Not implemented}"; } } else { print STDERR "Could not open file $docfile\n"; exit 1; } return first_sentence($desc); } # 1}}} sub first_sentence { # {{{1 # grab the first real sentence from the function documentation my ($desc) = @_; my $retval = ''; my $line; my $next; my @lines; my $trace = 0; # $trace = 1 if $desc =~ /Levenberg/; return "" unless defined $desc; if ($desc =~ /^\s*-[*]- texinfo -[*]-/) { # help text contains texinfo. Strip the indicator and run it # through makeinfo. (XXX FIXME XXX this needs to be a function) $desc =~ s/^\s*-[*]- texinfo -[*]-\s*//; my $cmd = "makeinfo --fill-column 1600 --no-warn --no-validate --no-headers --force --ifinfo"; open3(*Writer, *Reader, *Errer, $cmd) or die "Could not run info"; print Writer "\@macro seealso {args}\n\n\@noindent\nSee also: \\args\\.\n\@end macro\n"; print Writer "$desc"; close(Writer); @lines = ; close(Reader); my @err = ; close(Errer); waitpid(-1,&WNOHANG); # Display source and errors, if any if (@err) { my $n = 1; foreach $line ( split(/\n/,$desc) ) { printf "%2d: %s\n",$n++,$line; } print ">>> @err"; } # Print trace showing formatted output # print "\n"; # Skip prototype and blank lines while (1) { return "" unless @lines; $line = shift @lines; next if $line =~ /^\s*-/; next if $line =~ /^\s*$/; last; } } else { # print "\n"; # Skip prototype and blank lines @lines = split(/\n/,$desc); while (1) { return "" if ($#lines < 0); $line = shift @lines; next if $line =~ /^\s*[Uu][Ss][Aa][Gg][Ee]/; # skip " usage " $line =~ s/^\s*\w+\s*://; # chop " blah : " print "strip blah: $line\n" if $trace; $line =~ s/^\s*[Ff]unction\s+//; # chop " function " print "strip function $line\n" if $trace; $line =~ s/^\s*\[.*\]\s*=\s*//; # chop " [a,b] = " print "strip []= $line\n" if $trace; $line =~ s/^\s*\w+\s*=\s*//; # chop " a = " print "strip a= $line\n" if $trace; $line =~ s/^\s*\w+\s*\([^\)]*\)\s*//; # chop " f(x) " print "strip f(x) $line\n" if $trace; $line =~ s/^\s*[;:]\s*//; # chop " ; " print "strip ; $line\n" if $trace; $line =~ s/^\s*[[:upper:]][[:upper:]0-9_]+//; # chop " BLAH" print "strip BLAH $line\n" if $trace; $line =~ s/^\s*\w*\s*[-]+\s+//; # chop " blah --- " print "strip blah --- $line\n" if $trace; $line =~ s/^\s*\w+ *\t\s*//; # chop " blah " print "strip blah $line\n" if $trace; $line =~ s/^\s*\w+\s\s+//; # chop " blah " print "strip blah $line\n" if $trace; # next if $line =~ /^\s*\[/; # skip [a,b] = f(x) # next if $line =~ /^\s*\w+\s*(=|\()/; # skip a = f(x) OR f(x) next if $line =~ /^\s*or\s*$/; # skip blah \n or \n blah next if $line =~ /^\s*$/; # skip blank line next if $line =~ /^\s?!\//; # skip # !/usr/bin/octave # XXX FIXME XXX should be testing for unmatched () in proto # before going to the next line! last; } } # Try to make a complete sentence, including the '.' if ( "$line " !~ /[^.][.]\s/ && $#lines >= 0) { my $next = $lines[0]; $line =~ s/\s*$//; # trim trailing blanks on last $next =~ s/^\s*//; # trim leading blanks on next $line .= " $next" if "$next " =~ /[^.][.]\s/; # ends the sentence } # Tidy up the sentence. chomp $line; # trim trailing newline, if there is one $line =~ s/^\s*//; # trim leading blanks on line $line =~ s/([^.][.])\s.*$/$1/; # trim everything after the sentence print "Skipping:\n$desc---\n" if $line eq ""; # And return it. return $line; } # 1}}} __END__ This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, see . This program is granted to the public domain. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. communications-1.2.1/doc/PaxHeaders.3802/mkdoc.pl0000644000000000000000000000013212510010473016404 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.006508748 30 ctime=1428164983.712815029 communications-1.2.1/doc/mkdoc.pl0000755000000000000000000001240112510010473016732 0ustar00rootroot00000000000000#!/usr/bin/env perl # # David Bateman Feb 02 2003 # # Extracts the help in texinfo format from *.cc and *.m files for use # in documentation. Based on make_index script from octave_forge. use strict; use File::Find; use File::Basename; use FileHandle; my $docdir = "."; if (@ARGV) { $docdir = @ARGV[0]; } # locate all C++ and m-files in current directory my @m_files = (); my @C_files = (); find(\&cc_and_m_files, $docdir); sub cc_and_m_files { # {{{1 populates global array @files return unless -f and /\.(m|cc)$/; # .m and .cc files my $path = "$File::Find::dir/$_"; $path =~ s|^[.]/||; if (/\.m$/) { push @m_files, $path; } else { push @C_files, $path; } } # 1}}} # grab help from C++ files foreach my $f ( @C_files ) { # XXX FIXME XXX. Should run the preprocessor over the file first, since # the help might include defines that are compile dependent. if ( open(IN,$f) ) { while () { # skip to the next function next unless /^DEFUN_DLD/; # extract function name to pattern space /\((\w*)\s*,/; # remember function name my $function = $1; # skip to next line if comment doesn't start on this line # XXX FIXME XXX maybe we want a loop here? $_ = unless /\"/; # skip to the beginning of the comment string by # chopping everything up to opening " my $desc = $_; $desc =~ s/^[^\"]*\"//; # join lines until you get the end of the comment string # plus a bit more. You need the "plus a bit more" because # C compilers allow implicitly concatenated string constants # "A" "B" ==> "AB". while ($desc !~ /[^\\]\"\s*\S/ && $desc !~ /^\"/) { # if line ends in '\', chop it and the following '\n' $desc =~ s/\\\s*\n//; # join with the next line $desc .= ; # eliminate consecutive quotes, being careful to ignore # preceding slashes. XXX FIXME XXX what about \\" ? $desc =~ s/([^\\])\"\s*\"/$1/; } $desc = "" if $desc =~ /^\"/; # chop everything if it was "" $desc =~ s/\\n/\n/g; # insert fake line ends $desc =~ s/([^\"])\".*$/$1/; # chop everything after final '"' $desc =~ s/\\\"/\"/; # convert \"; XXX FIXME XXX \\" $desc =~ s/$//g; # chop trailing ... if (!($desc =~ /^\s*-[*]- texinfo -[*]-/)) { my $err = sprintf("Function %s, does not contain texinfo help\n", $function); print STDERR "$err"; } my $entry = sprintf("\037%s\n%s", $function, $desc); print "$entry", "\n"; } close (IN); } else { print STDERR "Could not open file ($f): $!\n"; } } # grab help from m-files foreach my $f ( @m_files ) { my $desc = extract_description($f); my $function = basename($f, ('.m')); die "Null function?? [$f]\n" unless $function; if (!($desc =~ /^\s*-[*]- texinfo -[*]-/)) { my $err = sprintf("Function %s, does not contain texinfo help\n", $function); print STDERR "$err"; } my $entry = sprintf("\037%s\n%s", $function, $desc); print "$entry", "\n"; } sub extract_description { # {{{1 # grab the entire documentation comment from an m-file my ($file) = @_; my $retval = ''; if( open( IN, "$file")) { # skip leading blank lines while () { last if /\S/; } if( m/\s*[%\#][\s\#%]* Copyright/) { # next block is copyright statement, skip it while () { last unless /^\s*[%\#]/; } } # Skip everything until the next comment block while ( !/^\s*[\#%]+\s/ ) { $_ = ; last if not defined $_; } # Return the next comment block as the documentation while (/^\s*[\#%]+\s/) { s/^\s*[%\#]+\s//; # strip leading comment characters s/[\cM\s]*$//; # strip trailing spaces. s/[\.*]$//; $retval .= "$_\n"; $_ = ; last if not defined $_; } close(IN); return $retval; } else { print STDERR "Could not open file ($file): $!\n"; } } # 1}}} __END__ This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, see . This program is granted to the public domain. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. communications-1.2.1/doc/PaxHeaders.3802/comms.txi0000644000000000000000000000013112510010473016615 xustar0030 mtime=1428164923.850512296 29 atime=1428164924.09050682 30 ctime=1428164983.712815029 communications-1.2.1/doc/comms.txi0000644000000000000000000023123712510010473017153 0ustar00rootroot00000000000000\input texinfo @setfilename comms.info @settitle Communications Package for Octave @titlepage @title Communications Package for Octave @subtitle November 2013 @author David Bateman @author Paul Kienzle @author Laurent Mazet @author Mike Miller @page @vskip 0pt plus 1filll Copyright @copyright{} 2003-2013 Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the same conditions as for modified versions. @end titlepage @contents @ifnottex @node Top, Introduction @top @end ifnottex @menu * Introduction:: * Random Signals:: * Source Coding:: * Block Coding:: * Convolutional Coding:: * Modulations:: * Special Filters:: * Galois Fields:: * Function Reference:: @end menu @node Introduction, Random Signals, Top, Top @chapter Introduction This is the manual for the Communications Package for GNU Octave. All functions provided by this package are described in this manual. In addition many functions from Octave and other Octave packages are useful to or required by this package, and so they may also be explained or shown in examples in this manual. This documentation is a work in progress, you are invited to help improve it and submit patches. @node Random Signals, Source Coding, Introduction, Top @chapter Random Signals The purpose of the functions described here is to create and add random noise to a signal, to create random data and to analyze the eventually errors in a received signal. The functions to perform these tasks can be considered as either related to the creation or analysis of signals and are treated separately below. It should be noted that the examples below are based on the output of a random number generator, and so the user can not expect to exactly recreate the examples below. @menu * Signal Creation:: * Signal Analysis:: @end menu @node Signal Creation, Signal Analysis, , Random Signals @section Signal Creation The signal creation functions here fall into to two classes. Those that treat discrete data and those that treat continuous data. The basic function to create discrete data is @code{randint}, that creates a random matrix of equi-probable integers in a desired range. For example @example octave:1> a = randint (3, 3, [-1, 1]) a = 0 1 0 -1 -1 1 0 1 1 @end example @noindent creates a 3-by-3 matrix of random integers in the range -1 to 1. To allow for repeated analysis with the same random data, the function @code{randint} allows the seed-value of the random number generator to be set. For instance @example octave:1> a = randint (3, 3, [-1, 1], 1) a = 0 1 1 0 -1 0 1 -1 -1 @end example @noindent will always produce the same set of random data. The range of the integers to produce can either be a two element vector or an integer. In the case of a two element vector all elements within the defined range can be produced. In the case of an integer range @var{M}, @code{randint} returns the equi-probable integers in the range @tex $[0:2^m-1]$. @end tex @ifnottex [0:2^@var{m}-1]. @end ifnottex The function @code{randsrc} differs from @code{randint} in that it allows a random set of symbols to be created with a given probability. The symbols can be real, complex or even characters. However characters and scalars can not be mixed. For example @example octave:1> a = randsrc (2, 2, "ab"); octave:2> b = randsrc (4, 4, [1, 1i, -1, -1i]); @end example @noindent are both legal, while @example octave:1> a = randsrc (2, 2, [1, "a"]); @end example @noindent is not legal. The alphabet from which the symbols are chosen can be either a row vector or two row matrix. In the case of a row vector, all of the elements of the alphabet are chosen with an equal probability. In the case of a two row matrix, the values in the second row define the probability that each of the symbols are chosen. For example @example octave:1> a = randsrc (5, 5, [1, 1i, -1, -1i; 0.6 0.2 0.1 0.1]) a = 1 + 0i 0 + 1i 0 + 1i 0 + 1i 1 + 0i 1 + 0i 1 + 0i 0 + 1i 0 + 1i 1 + 0i -0 - 1i 1 + 0i -1 + 0i 1 + 0i 0 + 1i 1 + 0i 1 + 0i 1 + 0i 1 + 0i 1 + 0i -1 + 0i -1 + 0i 1 + 0i 1 + 0i 1 + 0i @end example @noindent defines that the symbol '1' has a 60% probability, the symbol '1i' has a 20% probability and the remaining symbols have 10% probability each. The sum of the probabilities must equal one. Like @code{randint}, @code{randsrc} accepts a fourth argument as the seed of the random number generator allowing the same random set of data to be reproduced. The function @code{randerr} allows a matrix of random bit errors to be created, for binary encoded messages. By default, @code{randerr} creates exactly one errors per row, flagged by a non-zero value in the returned matrix. That is @example octave:1> a = randerr (5, 10) a = 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 @end example The number of errors per row can be specified as the third argument to @code{randerr}. This argument can be either a scalar, a row vector or a two row matrix. In the case of a scalar value, exactly this number of errors will be created per row in the returned matrix. In the case of a row vector, each element of the row vector gives a possible number of equi-probable bit errors. The second row of a two row matrix defines the probability of each number of errors occurring. For example @example octave:1> n = 15; k = 11; nsym = 100; octave:2> msg = randint (nsym, k); ## Binary vector of message octave:3> code = encode (msg, n, k, "bch"); octave:4> berrs = randerr (nsym, n, [0, 1; 0.7, 0.3]); octave:5> noisy = mod (code + berrs, 2) ## Add errors to coded message @end example @noindent creates a vector @var{msg}, encodes it with a [15,11] BCH code, and then add either none or one error per symbol with the chances of an error being 30%. As previously, @code{randerr} accepts a fourth argument as the seed of the random number generator allowing the same random set of data to be reproduced. All of the above functions work on discrete random signals. The functions @code{wgn} and @code{awgn} create and add white Gaussian noise to continuous signals. The function @code{wgn} creates a matrix of white Gaussian noise of a certain power. A typical call to @code{wgn} is then @example octave:1> nse = wgn (10, 10, 0); @end example @noindent which creates a 10-by-10 matrix of noise with a root mean squared power of 0dBW relative to an impedance of @tex $1\Omega$. @end tex @ifnottex 1 Ohm. @end ifnottex This effectively means that an equivalent result to the above can be obtained with @example octave:1> nse = randn (10, 10); @end example The reference impedance and units of power to the function @code{wgn} can however be modified, for example @example octave:1> nse_30dBm_50Ohm = wgn (10000, 1, 30, 50, "dBm"); octave:2> nse_0dBW_50Ohm = wgn (10000, 1, 0, 50, "dBW"); octave:3> nse_1W_50Ohm = wgn (10000, 1, 1, 50, "linear"); octave:4> [std(nse_30dBm_50Ohm), std(nse_0dBW_50Ohm), std(nse_1W_50Ohm)] ans = 7.0805 7.1061 7.0730 @end example Each of these produces a 1W signal referenced to a @tex $50\Omega$ @end tex @ifnottex 50 Ohm @end ifnottex impedance. @sc{matlab} uses the misnomer "dB" for "dBW", so "dB" is an accepted type for @code{wgn} and is treated as a synonym for "dBW". In all cases, the returned matrix @var{v}, will be related to the input power @var{p} and the impedance @var{Z} as @tex $$p = {\\sum_i \\sum_j v(i,j)^2 \\over Z} Watts$$ @end tex @ifnottex @var{p} = sum (@var{v}(:) .^ 2 ) / @var{imp} Watts @end ifnottex By default @code{wgn} produces real vectors of white noise. However, it can produce both real and complex vectors like @example octave:1> rnse = wgn (10000, 1, 0, "dBm", "real"); octave:2> cnse = wgn (10000, 1, 0, "dBm", "complex"); octave:3> [std(rnse), std(real (cnse)), std(imag (cnse)), std(cnse)] ans = 0.031615 0.022042 0.022241 0.031313 @end example @noindent which shows that with a complex return value that the total power is the same as a real vector, but that it is equally shared between the real and imaginary parts. As previously, @code{wgn} accepts a fourth numerical argument as the seed of the random number generator allowing the same random set of data to be reproduced. That is @example octave:1> nse = wgn (10, 10, 0, 0); @end example @noindent will always produce the same set of data. The final function to deal with the creation of random signals is @code{awgn}, that adds noise at a certain level relative to a desired signal. This function adds noise at a certain level to a desired signal. An example call to @code{awgn} is @example octave:1> x = [0:0.1:2*pi]; octave:2> y = sin (x); octave:3> noisy = awgn (y, 10, "measured") @end example @ifnotinfo @noindent which produces a sine-wave with noise added as seen in Figure 1. @center @image{awgn} @center Figure 1: Sine-wave with 10dB signal-to-noise ratio @end ifnotinfo @noindent which adds noise with a 10dB signal-to-noise ratio to the measured power in the desired signal. By default @code{awgn} assumes that the desired signal is at 0dBW, and the noise is added relative to this assumed power. This behavior can be modified by the third argument to @code{awgn}. If the third argument is a numerical value, it is assumed to define the power in the input signal, otherwise if the third argument is the string "measured", as above, the power in the signal is measured prior to the addition of the noise. The final argument to @code{awgn} defines the definition of the power and signal-to-noise ratio in a similar manner to @code{wgn}. This final argument can be either "dB" or "linear". In the first case the numerical value of the input power is assumed to be in dBW and the signal-to-noise ratio in dB. In the second case, the power is assumed to be in Watts and the signal-to-noise ratio is expressed as a ratio. The return value of @code{awgn} will be in the same form as the input signal. In addition if the input signal is real, the additive noise will be real. Otherwise the additive noise will also be complex and the noise will be equally split between the real and imaginary parts. As previously the seed to the random number generator can be specified as the last argument to @code{awgn} to allow repetition of the same scenario. That is @example octave:1> x = [0:0.1:2*pi]; octave:2> y = sin (x); octave:3> noisy = awgn (y, 10, "dB", 0, "measured") @end example @noindent which uses the seed-value of 0 for the random number generator. @node Signal Analysis, , Signal Creation, Random Signals @section Signal Analysis It is important to be able to evaluate the performance of a communications system in terms of its bit-error and symbol-error rates. Two functions @code{biterr} and @code{symerr} exist within this package to calculate these values, both taking as arguments the expected and the actually received data. The data takes the form of matrices or vectors, with each element representing a single symbol. They are compared in the following manner @table @asis @item Both matrices In this case both matrices must be the same size and then by default the return values are the overall number of errors and the overall error rate. @item One column vector In this case the column vector is used for comparison column-wise with the matrix. The return values are row vectors containing the number of errors and the error rate for each column-wise comparison. The number of rows in the matrix must be the same as the length of the column vector. @item One row vector In this case the row vector is used for comparison row-wise with the matrix. The return values are column vectors containing the number of errors and the error rate for each row-wise comparison. The number of columns in the matrix must be the same as the length of the row vector. @end table For the bit-error comparison, the size of the symbol is assumed to be the minimum number of bits needed to represent the largest element in the two matrices supplied. However, the number of bits per symbol can (and in the case of random data should) be specified. As an example of the use of @code{biterr} and @code{symerr}, consider the example @example octave:1> m = 8; octave:2> msg = randint (10, 10, 2^m); octave:3> noisy = mod (msg + diag (1:10), 2^m); octave:4> [berr, brate] = biterr (msg, noisy, m) berr = 32 brate = 0.040000 octave:5> [serr, srate] = symerr (msg, noisy) serr = 10 srate = 0.10000 @end example @noindent which creates a 10-by-10 matrix adds 10 symbols errors to the data and then finds the bit and symbol error-rates. Two other means of displaying the integrity of a signal are the eye-diagram and the scatterplot. Although the functions @code{eyediagram} and @code{scatterplot} have different appearance, the information presented is similar and so are their inputs. The difference between @code{eyediagram} and @code{scatterplot} is that @code{eyediagram} segments the data into time intervals and plots the in-phase and quadrature components of the signal against this time interval. While @code{scatterplot} uses a parametric plot of quadrature versus in-phase components. Both functions can accept real or complex signals in the following forms. @table @asis @item A real vector In this case the signal is assumed to be real and represented by the vector @var{x}. @item A complex vector In this case the in-phase and quadrature components of the signal are assumed to be the real and imaginary parts of the signal. @item A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal. @end table An example of the use of the function @code{eyediagram} is @example octave:1> n = 50; octave:2> ovsp = 50; octave:3> x = 1:n; octave:4> xi = 1:1/ovsp:n-0.1; octave:5> y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); octave:6> yi = interp1 (x, y, xi); octave:7> noisy = awgn (yi, 15, "measured"); octave:8> eyediagram (noisy, ovsp); @end example @ifnotinfo @noindent which produces a eye-diagram of a noisy signal as seen in Figure 2. Similarly an example of the use of the function @code{scatterplot} is @center @image{eyediagram} @center Figure 2: Eye-diagram of a QPSK like signal with 15dB signal-to-noise ratio @end ifnotinfo @ifinfo Similarly an example of the use of the function @code{scatterplot} is @end ifinfo @example octave:1> n = 200; octave:2> ovsp = 5; octave:3> x = 1:n; octave:4> xi = 1:1/ovsp:n-0.1; octave:5> y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); octave:6> yi = interp1 (x, y, xi); octave:7> noisy = awgn (yi, 15, "measured"); octave:8> f = scatterplot (noisy, 1, 0, "b"); octave:9> hold on; octave:10> scatterplot (noisy, ovsp, 0, "r+", f); @end example @ifnotinfo @noindent which produces a scatterplot of a noisy signal as seen in Figure 3. @center @image{scatterplot} @center Figure 3: Scatterplot of a QPSK like signal with 15dB signal-to-noise ratio @end ifnotinfo @node Source Coding, Block Coding, Random Signals, Top @chapter Source Coding @menu * Quantization:: * PCM Coding:: * Arithmetic Coding:: * Dynamic Range Compression:: @end menu @node Quantization, PCM Coding, , Source Coding @section Quantization An important aspect of converting an analog signal to the digital domain is quantization. This is the process of mapping a continuous signal to a set of defined values. Octave contains two functions to perform quantization, @code{lloyds} creates an optimal mapping of the continuous signal to a fixed number of levels and @code{quantiz} performs the actual quantization. The set of quantization points to use is represented by a partitioning table (@var{table}) of the data and the signal levels (@var{codes} to which they are mapped. The partitioning @var{table} is monotonically increasing and if x falls within the range given by two points of this table then it is mapped to the corresponding code as seen in Table 1. @center Table 1: Table quantization partitioning and coding @multitable @columnfractions 0.1 0.4 0.4 0.1 @item @tab x < table(1) @tab codes(1) @tab @item @tab table(1) <= x < table(2) @tab codes(2) @tab @item @tab @dots{} @tab @dots{} @tab @item @tab table(i-1) <= x < table(i) @tab codes(i) @tab @item @tab @dots{} @tab @dots{} @tab @item @tab table(n-1) <= x < table(n) @tab codes(n) @tab @item @tab table(n-1) <= x @tab codes(n+1) @tab @end multitable These partition and coding tables can either be created by the user of using the function @code{lloyds}. For instance the use of a linear mapping can be seen in the following example. @example octave:1> m = 8; octave:2> n = 1024; octave:3> table = 2*[0:m-1]/m - 1 + 1/m; octave:4> codes = 2*[0:m]/m - 1; octave:5> x = 4*pi*[0:(n-1)]/(n-1); octave:6> y = cos (x); octave:7> [i, z] = quantiz (y, table, codes); @end example If a training signal is known that well represents the expected signals, the quantization levels can be optimized using the @code{lloyds} function. For example the above example can be continued @example octave:8> [table2, codes2] = lloyds (y, table, codes); octave:9> [i, z2] = quantiz (y, table2, codes2); @end example @noindent to use the mapping suggested by the function @code{lloyds}. It should be noted that the mapping given by @code{lloyds} is highly dependent on the training signal used. So if this signal does not represent a realistic signal to be quantized, then the partitioning suggested by @code{lloyds} will be sub-optimal. @node PCM Coding, Arithmetic Coding, Quantization, Source Coding @section PCM Coding The DPCM function @code{dpcmenco}, @code{dpcmdeco} and @code{dpcmopt} implement a form of predictive quantization, where the predictability of the signal is used to further compress it. These functions are not yet implemented. @node Arithmetic Coding, Dynamic Range Compression, PCM Coding, Source Coding @section Arithmetic Coding The arithmetic coding functions @code{arithenco} and @code{arithdeco} are not yet implemented. @node Dynamic Range Compression, , Arithmetic Coding, Source Coding @section Dynamic Range Compression The final source coding function is @code{compand} which is used to compress and expand the dynamic range of a signal. For instance consider a logarithm quantized by a linear partitioning. Such a partitioning is very poor for this large dynamic range. @code{compand} can then be used to compress the signal prior to quantization, with the signal being expanded afterwards. For example @example octave:1> mu = 1.95; octave:2> x = [0.01:0.01:2]; octave:3> y = log (x); octave:4> V = max (abs (y)); octave:5> [i, z, d] = quantiz (y, [-4.875:0.25:0.875], [-5:0.25:1]); octave:6> c = compand (y, minmu, V, "mu/compressor"); octave:7> [i2, c2] = quantiz (c, [-4.875:0.25:0.875], [-5:0.25:1]); octave:8> z2 = compand (c2, minmu, max (abs (c2)), "mu/expander"); octave:9> d2 = sumsq (y - z2) / length (y); octave:10> [d, d2] ans = 0.0053885 0.0029935 @end example @noindent which demonstrates that the use of @code{compand} can significantly reduce the distortion due to the quantization of signals with a large dynamic range. @node Block Coding, Convolutional Coding, Source Coding, Top @chapter Block Coding The error-correcting codes available in this package are discussed here. These codes work with blocks of data, with no relation between one block and the next. These codes create codewords based on the messages to transmit that contain redundant information that allow the recovery of the original message in the presence of errors. @menu * Data Formats:: * Binary Block Codes:: * BCH Codes:: * Reed-Solomon Codes:: @end menu @node Data Formats, Binary Block Codes, , Block Coding @section Data Formats All of the codes described in this section are binary and share similar data formats. The exception is the Reed-Solomon coder which has a significantly longer codeword length in general and therefore uses a different representation to efficiently pass data. The user should refer to the section about the Reed-Solomon codes for the data format used for Reed-Solomon codes. In general @var{k} bits of data are considered to represent a single message symbol. These @var{k} bits are coded into @var{n} bits of data representing the codeword. The data can therefore be grouped in one of three manners, to emphasis this grouping into bits, messages and codewords @table @asis @item A binary vector Each element of the vector is either one or zero. If the data represents an uncoded message the vector length should be an integer number of @var{k} in length. @item A binary matrix In this case the data is ones and zeros grouped into rows, with each representing a single message or codeword. The number of columns in the matrix should be equal to @var{k} in the case of a uncoded message or @var{n} in the case of a coded message. @item A non-binary vector In this case each element of the vector represents a message or codeword in an integer format. The bits of the message or codeword are represented by the bits of the vector elements with the least-significant bit representing the first element in the message or codeword. @end table An example demonstrating the relationship between the three data formats can be seen below. @example octave:1> k = 4; octave:2> bin_vec = randint (k*10, 1); # Binary vector format octave:3> bin_mat = reshape (bin_vec, k, 10)'; # Binary matrix format octave:4> dec_vec = bi2de (bin_mat); # Decimal vector format @end example The functions within this package will return data in the same format to which it is given. It should be noted that internally the binary matrix format is used, and thus if the message or codeword length is large it is preferable to use the binary format to avoid internal rounding errors. @node Binary Block Codes, BCH Codes, Data Formats, Block Coding @section Binary Block Codes All of the codes presented here can be characterized by their @table @asis @item Generator Matrix A @var{k}-by-@var{n} matrix @var{G} to generate the codewords @var{C} from the messages @var{T} by the matrix multiplication @tex $ {\bf C} = {\bf T} {\bf G}$. @end tex @ifnottex @var{C} = @var{T} * @var{G}. @end ifnottex @item Parity Check Matrix A '@var{n}-@var{k}'-by-@var{n} matrix @var{H} to check the parity of the received symbols. If @tex $ {\bf H} {\bf R} = {\bf S} \ne 0$, @end tex @ifnottex @var{H} * @var{R} = @var{S} != 0, @end ifnottex then an error has been detected. @var{S} can be used with the syndrome table to correct this error @item Syndrome Table A 2^@var{k}-by-@var{n} matrix @var{ST} with the relationship of the error vectors to the non-zero parities of the received symbols. That is, if the received symbol is represented as @tex $ {\bf R} = ( {\bf T} + {\bf E} )\ mod\ 2$, @end tex @ifnottex @var{R} = mod (@var{T} + @var{E}, 2), @end ifnottex then the error vector @var{E} is @tex ${\bf ST}({\bf S})$. @end tex @ifnottex @var{ST}(@var{S}). @end ifnottex @end table It is assumed for most of the functions in this package that the generator matrix will be in a 'standard' form. That is the generator matrix can be represented by @tex $$ {\bf G} = \left[\matrix{g_{11} & g_{12} & \ldots & g_{1k} & 1 & 0 & \ldots & 0 \cr g_{21} & g_{22} & & g_{2k} & 0 & 1 & & 0 \cr \vdots & & & \vdots & \vdots& & & \vdots \cr g_{k1} & g_{k2} & \ldots & g_{kk} & 0 & 0 & \ldots & 1}\right] $$ @end tex @ifnottex @example @group g(1,1) g(1,2) ... g(1,k) 1 0 ... 0 g(2,1) g(2,2) g(2,k) 0 1 ... 0 . . . . . . . . . . . . g(k,1) g(k,2) ... g(k,k) 0 0 ... 1 @end group @end example @end ifnottex @noindent or @tex $$ {\bf G} = \left[\matrix{1 & 0 & \ldots & 0 & g_{11} & g_{12} & \ldots & g_{1k} \cr 0 & 1 & & 0 & g_{21} & g_{22} & & g_{2k} \cr \vdots & & & \vdots & \vdots & & & \vdots \cr 0 & 0 & \ldots & 1 & g_{k1} & g_{k2} & \ldots & g_{kk}}\right] $$ @end tex @ifnottex @example @group 1 0 ... 0 g(1,1) g(1,2) ... g(1,k) 0 1 ... 0 g(2,1) g(2,2) g(2,k) . . . . . . . . . . . . 0 0 ... 1 g(k,1) g(k,2) ... g(k,k) @end group @end example @end ifnottex @noindent and similarly the parity check matrix can be represented by a combination of an identity matrix and a square matrix. Some of the codes can also have their representation in terms of a generator polynomial that can be used to create the generator and parity check matrices. In the case of BCH codes, this generator polynomial is used directly in the encoding and decoding without ever explicitly forming the generator or parity check matrix. The user can create their own generator and parity check matrices, or they can rely on the functions @code{hammgen}, @code{cyclgen} and @code{cyclpoly}. The function @code{hammgen} creates parity check and generator matrices for Hamming codes, while @code{cyclpoly} and @code{cyclgen} create generator polynomials and matrices for generic cyclic codes. An example of their use is @example octave:1> m = 3; octave:2> n = 2^m - 1; octave:2> k = 4; octave:3> [par, gen] = hammgen (m); octave:4> [par2, gen2] = cyclgen (n, cyclpoly (n, k)); @end example @noindent which create identical parity check and generator matrices for the [7,4] Hamming code. The syndrome table of the codes can be created with the function @code{syndtable}, in the following manner @example octave:1> [par, gen] = hammgen (3); octave:2> st = syndtable (par); @end example There exists two auxiliary functions @code{gen2par} and @code{gfweight}, that convert between generator and parity check matrices and calculate the Hamming distance of the codes. For instance @example octave:1> par = hammgen (3); octave:2> gen = gen2par (par); octave:3> gfweight (gen) ans = 3 @end example It should be noted that for large values of @var{n}, the generator, parity check and syndrome table matrices are very large. There is therefore an internal limitation on the size of the block codes that can be created that limits the codeword length @var{n} to less than 64. This is still excessively large for the syndrome table, so use caution with these codes. These limitations do not apply to the Reed-Solomon or BCH codes. The top-level encode and decode functions are @code{encode} and @code{decode}, which can be used with all codes, except the Reed-Solomon code. The basic call to both of these functions passes the message to code/decode, the codeword length, the message length and the type of coding to use. There are four basic types that are available with these functions @table @asis @item "linear" Generic linear block codes @item "cyclic" Cyclic linear block codes @item "hamming" Hamming codes @item "bch" Bose Chaudhuri Hocquenghem (BCH) block codes @end table It is not possible to distinguish between a binary vector and a decimal vector coding of the messages that just happens to only have ones and zeros. Therefore the functions @code{encode} and @code{decode} must be told the format of the messages in the following manner. @example octave:1> m = 3; octave:2> n = 7; octave:3> k = 4; octave:4> msg_bin = randint (10, k); octave:5> cbin = encode (msg_bin, n, k, "hamming/binary"); octave:5> cdec = encode (bi2de (msg), n, k, "hamming/decimal"); @end example @noindent which codes a binary matrix and a non-binary vector representation of a message, returning the coded message in the same format. The functions @code{encode} and @code{decode} by default accept binary coded messages. Therefore "hamming" is equivalent to "hamming/binary". Except for the BCH codes, the function @code{encode} and @code{decode} internally create the generator, parity check and syndrome table matrices. Therefore if repeated calls to @code{encode} and @code{decode} are made, it will often be faster to create these matrices externally and pass them as an argument. For example @example n = 15; k = 11; [par, gen] = hammgen (4); code1 = code2 = zeros (100, 15) for i = 1:100 msg = get_msg (i); code1(i,:) = encode (msg, n, k, "linear", gen); # This is faster code2(i,:) = encode (msg, n, k, "hamming"); # than this !!! endfor @end example In the case of the BCH codes the low-level functions described in the next section are used directly by the @code{encode} and @code{decode} functions. @node BCH Codes, Reed-Solomon Codes, Binary Block Codes, Block Coding @section BCH Codes The BCH coder used here is based on code written by Robert Morelos-Zaragoza (r.morelos-zaragoza@@ieee.org). This code was originally written in C and has been converted for use as an Octave oct-file. @iftex Called without arguments, @code{bchpoly} returns a table of valid BCH error correcting codes and their error-correction capability as seen in Table 1. @center Table 2: Table of valid BCH codes with codeword length less than 511. @multitable @columnfractions .083 .083 .083 .083 .083 .083 .083 .083 .083 .083 .083 .083 @item N @tab K @tab T @tab N @tab K @tab T @tab N @tab K @tab T @tab N @tab K @tab T @item 7 @tab 4 @tab 1 @tab 127 @tab 36 @tab 15 @tab 255 @tab 45 @tab 43 @tab 511 @tab 268 @tab 29 @item 15 @tab 11 @tab 1 @tab 127 @tab 29 @tab 21 @tab 255 @tab 37 @tab 45 @tab 511 @tab 259 @tab 30 @item 15 @tab 7 @tab 2 @tab 127 @tab 22 @tab 23 @tab 255 @tab 29 @tab 47 @tab 511 @tab 250 @tab 31 @item 15 @tab 5 @tab 3 @tab 127 @tab 15 @tab 27 @tab 255 @tab 21 @tab 55 @tab 511 @tab 241 @tab 36 @item 31 @tab 26 @tab 1 @tab 127 @tab 8 @tab 31 @tab 255 @tab 13 @tab 59 @tab 511 @tab 238 @tab 37 @item 31 @tab 21 @tab 2 @tab 255 @tab 247 @tab 1 @tab 255 @tab 9 @tab 63 @tab 511 @tab 229 @tab 38 @item 31 @tab 16 @tab 3 @tab 255 @tab 239 @tab 2 @tab 511 @tab 502 @tab 1 @tab 511 @tab 220 @tab 39 @item 31 @tab 11 @tab 5 @tab 255 @tab 231 @tab 3 @tab 511 @tab 493 @tab 2 @tab 511 @tab 211 @tab 41 @item 31 @tab 6 @tab 7 @tab 255 @tab 223 @tab 4 @tab 511 @tab 484 @tab 3 @tab 511 @tab 202 @tab 42 @item 63 @tab 57 @tab 1 @tab 255 @tab 215 @tab 5 @tab 511 @tab 475 @tab 4 @tab 511 @tab 193 @tab 43 @item 63 @tab 51 @tab 2 @tab 255 @tab 207 @tab 6 @tab 511 @tab 466 @tab 5 @tab 511 @tab 184 @tab 45 @item 63 @tab 45 @tab 3 @tab 255 @tab 199 @tab 7 @tab 511 @tab 457 @tab 6 @tab 511 @tab 175 @tab 46 @item 63 @tab 39 @tab 4 @tab 255 @tab 191 @tab 8 @tab 511 @tab 448 @tab 7 @tab 511 @tab 166 @tab 47 @item 63 @tab 36 @tab 5 @tab 255 @tab 187 @tab 9 @tab 511 @tab 439 @tab 8 @tab 511 @tab 157 @tab 51 @item 63 @tab 30 @tab 6 @tab 255 @tab 179 @tab 10 @tab 511 @tab 430 @tab 9 @tab 511 @tab 148 @tab 53 @item 63 @tab 24 @tab 7 @tab 255 @tab 171 @tab 11 @tab 511 @tab 421 @tab 10 @tab 511 @tab 139 @tab 54 @item 63 @tab 18 @tab 10 @tab 255 @tab 163 @tab 12 @tab 511 @tab 412 @tab 11 @tab 511 @tab 130 @tab 55 @item 63 @tab 16 @tab 11 @tab 255 @tab 155 @tab 13 @tab 511 @tab 403 @tab 12 @tab 511 @tab 121 @tab 58 @item 63 @tab 10 @tab 13 @tab 255 @tab 147 @tab 14 @tab 511 @tab 394 @tab 13 @tab 511 @tab 112 @tab 59 @item 63 @tab 7 @tab 15 @tab 255 @tab 139 @tab 15 @tab 511 @tab 385 @tab 14 @tab 511 @tab 103 @tab 61 @item 127 @tab 120 @tab 1 @tab 255 @tab 131 @tab 18 @tab 511 @tab 376 @tab 15 @tab 511 @tab 94 @tab 62 @item 127 @tab 113 @tab 2 @tab 255 @tab 123 @tab 19 @tab 511 @tab 367 @tab 17 @tab 511 @tab 85 @tab 63 @item 127 @tab 106 @tab 3 @tab 255 @tab 115 @tab 21 @tab 511 @tab 358 @tab 18 @tab 511 @tab 76 @tab 85 @item 127 @tab 99 @tab 4 @tab 255 @tab 107 @tab 22 @tab 511 @tab 349 @tab 19 @tab 511 @tab 67 @tab 87 @item 127 @tab 92 @tab 5 @tab 255 @tab 99 @tab 23 @tab 511 @tab 340 @tab 20 @tab 511 @tab 58 @tab 91 @item 127 @tab 85 @tab 6 @tab 255 @tab 91 @tab 25 @tab 511 @tab 331 @tab 21 @tab 511 @tab 49 @tab 93 @item 127 @tab 78 @tab 7 @tab 255 @tab 87 @tab 26 @tab 511 @tab 322 @tab 22 @tab 511 @tab 40 @tab 95 @item 127 @tab 71 @tab 9 @tab 255 @tab 79 @tab 27 @tab 511 @tab 313 @tab 23 @tab 511 @tab 31 @tab 109 @item 127 @tab 64 @tab 10 @tab 255 @tab 71 @tab 29 @tab 511 @tab 304 @tab 25 @tab 511 @tab 28 @tab 111 @item 127 @tab 57 @tab 11 @tab 255 @tab 63 @tab 30 @tab 511 @tab 295 @tab 26 @tab 511 @tab 19 @tab 119 @item 127 @tab 50 @tab 13 @tab 255 @tab 55 @tab 31 @tab 511 @tab 286 @tab 27 @tab 511 @tab 10 @tab 127 @item 127 @tab 43 @tab 14 @tab 255 @tab 47 @tab 42 @tab 511 @tab 277 @tab 28 @tab @tab @tab @end multitable @end iftex @ifnottex Called without arguments, @code{bchpoly} returns a table of valid BCH error correcting codes and their error-correction capability. @end ifnottex The first returned column of @code{bchpoly} is the codeword length, the second the message length and the third the error correction capability of the code. Called with one argument, @code{bchpoly} returns similar output, but only for the specified codeword length. In this manner codes with codeword length greater than 511 can be found. In general the codeword length is of the form @code{2^@var{m} - 1}, where @var{m} is an integer. However if [@var{n},@var{k}] is a valid BCH code, then it is also possible to use a shortened BCH form of the form @code{[@var{n}-@var{x},@var{k}-@var{x}]}. With two or more arguments, @code{bchpoly} is used to find the generator polynomial of a valid BCH code. For instance @example octave:1> bchpoly (15, 7) ans = 1 0 0 0 1 0 1 1 1 octave:2> bchpoly (14, 6) ans = 1 0 0 0 1 0 1 1 1 @end example @noindent show that the generator polynomial of a [15,7] BCH code with the default primitive polynomial is @tex $$ 1 + x^4 + x^6 + x^7 + x^8 $$ @end tex @ifnottex 1 + @var{x} ^ 4 + @var{x} ^ 6 + @var{x} ^ 7 + @var{x} ^ 8 @end ifnottex Using a different primitive polynomial to define the Galois Field over which the BCH code is defined results in a different generator polynomial as can be seen in the example. @example octave:1> bchpoly ([1 1 0 0 1], 7) ans = 1 0 0 0 1 0 1 1 1 octave:2> bchpoly ([1 0 0 1 1], 7) ans = 1 1 1 0 1 0 0 0 1 @end example It is recommend not to convert the generator polynomials created by @code{bchpoly} into generator and parity check matrices with the BCH codes, as the underlying BCH software is faster than the generic coding software and can treat significantly longer codes. As well as using the @code{encode} and @code{decode} functions previously discussed, the user can directly use the low-level BCH functions @code{bchenco} and @code{bchdeco}. In this case the messages must be in the format of a binary matrix with @var{k} columns @example octave:1> n = 31; octave:2> pgs = bchpoly (n); octave:3> pg = pgs(floor (rand () * (rows (pgs) + 1)),:); # Pick a poly octave:4> k = pg(2); octave:5> t = pg(3); octave:6> msg = randint (10, k); octave:7> code = bchenco (msg, n, k); octave:8> noisy = code + [ones(10, 1), zeros(10, n-1)]; octave:9> dec = bchdeco (code, k, t); @end example @node Reed-Solomon Codes, , BCH Codes, Block Coding @section Reed-Solomon Codes @menu * Representation of Reed-Solomon Messages:: * Creating and Decoding Messages:: * Shortened Reed-Solomon Codes:: @end menu @node Representation of Reed-Solomon Messages, Creating and Decoding Messages, , Reed-Solomon Codes @subsection Representation of Reed-Solomon Messages The Reed-Solomon coder used in this package is based on code written by Phil Karn (http://www.ka9q.net/code/fec). This code was originally written in C and has been converted for use as an Octave oct-file. Reed-Solomon codes are based on Galois Fields of even characteristics GF(2^M). Many of the properties of Galois Fields are therefore important when considering Reed-Solomon coders. The representation of the symbols of the Reed-Solomon code differs from the other block codes, in that the other block codes use a binary representation, while the Reed-Solomon code represents each m-bit symbol by an integer. The elements of the message and codeword must be elements of the Galois Field corresponding to the Reed-Solomon code. Thus to code a message with a [7,5] Reed-Solomon code an example is @example octave:1> m = 3; octave:2> n = 7; octave:3> k = 5; octave:4> msg = gf (floor (2^m * rand (2, k)), m) msg = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 5 0 6 3 2 4 1 3 1 2 octave:5> code = rsenc (msg, n, k) code = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 5 0 6 3 2 3 5 4 1 3 1 2 6 3 @end example The variable @var{n} is the codeword length of the Reed-Solomon coder, while @var{k} is the message length. It should be noted that @var{k} should be less than @var{n} and that @code{@var{n} - @var{k}} should be even. The error correcting capability of the Reed-Solomon code is then @code{(@var{n} - @var{k})/2} symbols. @var{m} is the number of bits per symbol, and is related to @var{n} by @code{@var{n} = 2^@var{m} - 1}. For a valid Reed-Solomon coder, @var{m} should be between 3 and 16. @node Creating and Decoding Messages, Shortened Reed-Solomon Codes, Representation of Reed-Solomon Messages, Reed-Solomon Codes @subsection Creating and Decoding Messages The Reed-Solomon encoding function requires at least three arguments. The first @var{msg} is the message in encodes, the second is @var{n} the codeword length and @var{k} is the message length. Therefore @var{msg} must have @var{k} columns and the output will have @var{n} columns of symbols. The message itself is many up of elements of a Galois Field GF(2^M). Normally, The order of the Galois Field (M), is related to the codeword length by @code{@var{n} = 2^@var{m} - 1}. Another important parameter when determining the behavior of the Reed-Solomon coder is the primitive polynomial of the Galois Field (see @code{gf}). Thus the messages @example octave:1> msg0 = gf ([0, 1, 2, 3], 3); octave:2> msg1 = gf ([0, 1, 2, 3], 3, 13); @end example @noindent will not result in the same Reed-Solomon coding. Finally, the parity of the Reed-Solomon code are generated with the use of a generator polynomial. The parity symbols are then generated by treating the message to encode as a polynomial and finding the remainder of the division of this polynomial by the generator polynomial. Therefore the generator polynomial must have as many roots as @code{@var{n} - @var{k}}. Whether the parity symbols are placed before or afterwards the message will then determine which end of the message is the most-significant term of the polynomial representing the message. The parity symbols are therefore different in these two cases. The position of the parity symbols can be chosen by specifying "beginning" or "end" to @code{rsenc} and @code{rsdec}. By default the parity symbols are placed after the message. Valid generator polynomials can be constructed with the @code{rsgenpoly} function. The roots of the generator polynomial are then defined by @tex $$ g = (x - A^{bs}) (x - A^{(b+1)s}) \cdots (x - A ^{(b+2t-1)s}). $$ @end tex @ifnottex @example @var{g} = (@var{x} - A^(@var{b}*@var{s})) * (@var{x} - A^((@var{b}+1)*@var{s})) * @dots{} * (@var{x} - A^((@var{b}+2*@var{t}-1)*@var{s})). @end example @end ifnottex @noindent where @var{t} is @code{(@var{n} - @var{k})/2}, A is the primitive element of the Galois Field, @var{b} is the first consecutive root, and @var{s} is the step between roots. Generator polynomial of this form are constructed by @code{rsgenpoly} and can be passed to both @code{rsenc} and @code{rsdec}. It is also possible to pass the @var{b} and @var{s} values directly to @code{rsenc} and @code{rsdec}. In the case of @code{rsdec} passing @var{b} and @var{s} can make the decoding faster. Consider the example below. @example octave:1> m = 8; octave:2> n = 2^m - 1; octave:3> k = 223; octave:4> prim = 391; octave:5> b = 112; octave:6> s = 11; octave:7> gg = rsgenpoly (n, k, prim, b, s); octave:8> msg = gf (floor (2^m * rand (17, k)), m, prim); octave:9> code = rsenc (msg, n, k, gg); octave:10> noisy = code + [toeplitz([ones(1,17)], zeros(1,17)), zeros(17,238)]; octave:11> [dec, nerr] = rsdec (msg, n, k, b, s); octave:12> nerr' ans = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -1 octave:13> any (msg' != dec') ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 @end example This is an interesting example in that it demonstrates many of the additional arguments of the Reed-Solomon functions. In particular this example approximates the CCSDS standard Reed-Solomon coder, lacking only the dual-basis lookup tables used in this standard. The CCSDS uses non-default values to all of the basic functions involved in the Reed-Solomon encoding, since it has a non-default primitive polynomial, generator polynomial, etc. The example creates 17 message blocks and adds between 1 and 17 error symbols to these block. As can be seen @var{nerr} gives the number of errors corrected. In the case of 17 introduced errors @var{nerr} equals -1, indicating a decoding failure. This is normal as the correction ability of this code is up to 16 error symbols. Comparing the input message and the decoding it can be seen that as expected, only the case of 17 errors has not been correctly decoded. @node Shortened Reed-Solomon Codes, , Creating and Decoding Messages, Reed-Solomon Codes @subsection Shortened Reed-Solomon Codes In general the codeword length of the Reed-Solomon coder is chosen so that it is related directly to the order of the Galois Field by the formula @code{@var{n} = 2^@var{m} - 1}. Although, the underlying Reed-Solomon coding must operate over valid codeword length, there are sometimes reasons to assume that the codeword length will be shorter. In this case the message is padded with zeros before coding, and the zeros are stripped from the returned block. For example consider the shortened [6,4] Reed-Solomon below @example octave:1> m = 3; octave:2> n = 6; octave:3> k = 4; octave:4> msg = gf (floor (2^m * rand (2, k)), m) msg = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 2 5 1 5 7 1 octave:5> code = rsenc (msg, n, k) code = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 2 5 2 3 1 5 7 1 0 2 @end example @node Convolutional Coding, Modulations, Block Coding, Top @chapter Convolutional Coding Some initial support for convolutional codes is provided by the functions described in this chapter. Convolutional codes are different from block codes in that the sequence of preceding symbols is taken into account when computing the output symbol of the coder. @menu * Trellis Structure:: * Convolutional Encoding:: @end menu @node Trellis Structure, Convolutional Encoding, , Convolutional Coding @section Trellis Structure Like block codes, convolutional codes can be described by a set of generator polynomials. Each polynomial describes the combination of current and previous input symbols used to compute one output bit of the encoder. The state transitions and outputs of a convolutional encoder can also be described by a trellis diagram. This diagram describes the transitions between states and the outputs of the encoder as a function of the current state and the current input symbol. A trellis structure can be created from a set of generator polynomials, specified as octal numbers by convention, @example octave:1> g0 = 13; octave:2> g1 = 17; octave:3> trellis = poly2trellis (4, [g0, g1]); @end example @noindent where @var{g0} and @var{g1} are the two polynomials of a rate 1/2 encoder with a constraint length of 4. The returned trellis structure contains the following fields @table @samp @item numInputSymbols The number of possible input symbols in the input sequence. @item numOutputSymbols The number of possible output symbols in the encoded sequence. @item numStates The number of possible states that the encoder can take. @item nextStates The state transition table for the encoder. Each row contains the (zero-based) indices of the states reachable from the state represented by that row for each possible input symbol. @item outputs The output table for the encoder. Each row contains the (octal-encoded) output symbols produced by the encoder in the state represented by that row for each possible input symbol. @end table To check if a variable references a structure that is a valid trellis describing a convolutional encoder, use the @code{istrellis} function. @node Convolutional Encoding, , Trellis Structure, Convolutional Coding @section Convolutional Encoding The convolutional encoding function takes the message to be encoded and a trellis describing the encoder. The message must be a binary vector containing an even number of symbols. For example, using the encoder from the previous section, @example octave:1> trellis = poly2trellis (4, [13, 17]); octave:2> msg = [1 1 0 1 1 0 0 0]; octave:3> out = convenc (msg, trellis) out = 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 @end example The initial state of the encoder can also be passed in to @code{convenc}, and the ending state can be read with an optional output argument. Encoding a different vector with a different initial state using the same encoder, @example octave:4> msg = [0 1 1 0 1 0 1 1]; octave:5> [out, state] = convenc (msg, trellis, [], 4) out = 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 state = 6 @end example @noindent returns both the encoded array and the final state of the convolutional encoder. This can be used to encode data in blocks, for example, saving and restoring the internal state of the encoder for each subsequent input block. @node Modulations, Special Filters, Convolutional Coding, Top @chapter Modulations To be written. Currently have functions amodce, ademodce, apkconst, demodmap, modmap, qaskdeco, qaskenco, genqammod, pamdemod, pammod, pskdemod and pskmod. @node Special Filters, Galois Fields, Modulations, Top @chapter Special Filters To be written. @node Galois Fields, Function Reference, Special Filters, Top @chapter Galois Fields @menu * Galois Field Basics:: * Manipulating Galois Fields:: @end menu @node Galois Field Basics, Manipulating Galois Fields, , Galois Fields @section Galois Field Basics A Galois Field is a finite algebraic field. This package implements a Galois Field type in Octave having 2^M members where M is an integer between 1 and 16. Such fields are denoted as GF(2^M) and are used in error correcting codes in communications systems. Galois Fields having odd numbers of elements are not implemented. The @emph{primitive element} of a Galois Field has the property that all elements of the Galois Field can be represented as a power of this element. The @emph{primitive polynomial} is the minimum polynomial of some primitive element in GF(2^M) and is irreducible and of order M. This means that the primitive element is a root of the primitive polynomial. The elements of the Galois Field GF(2^M) are represented as the values 0 to 2^M -1 by Octave. The first two elements represent the zero and unity values of the Galois Field and are unique in all fields. The element represented by 2 is the primitive element of the field and all elements can be represented as combinations of the primitive element and unity as follows @multitable @columnfractions .33 .33 .33 @item Integer @tab Binary @tab Element of GF(2^M) @item 0 @tab 000 @tab @code{0} @item 1 @tab 001 @tab @code{1} @item 2 @tab 010 @tab @code{A} @item 3 @tab 011 @tab @code{A + 1} @item 4 @tab 100 @tab @code{A^2} @item 5 @tab 101 @tab @code{A^2 + 1} @item 6 @tab 110 @tab @code{A^2 + A} @item 7 @tab 111 @tab @code{A^2 + A + 1} @end multitable It should be noted that there is often more than a single primitive polynomial of GF(2^M). Each Galois Field over a different primitive polynomial represents a different realization of the Field. The representations above however rest valid. @menu * Creating Galois Fields:: * Primitive Polynomials:: * Accessing Internal Fields:: * Function Overloading:: * Known Problems:: @end menu @node Creating Galois Fields, Primitive Polynomials, , Galois Field Basics @subsection Creating Galois Fields To work with a Galois Field GF(2^M) in Octave, you must first create a variable that Octave recognizes as a Galois Field. This is done with the function @code{gf (@var{a}, @var{m})} as follows. @example octave:1> a = [0:7]; octave:2> b = gf (a, 4) b = GF(2^4) array. Primitive Polynomial = D^4+D+1 (decimal 19) Array elements = 0 1 2 3 4 5 6 7 @end example This creates an array @var{b} with 8 elements that Octave recognizes as a Galois Field. The field is created with the default primitive polynomial for the field GF(2^4). It can be verified that a variable is in fact a Galois Field with the functions @code{isgalois} or @code{whos}. @example octave:3> isgalois (a) ans = 0 octave:4> isgalois (b) ans = 1 octave:5> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x8 24 double b 1x8 32 galois Total is 16 elements using 56 bytes @end example It is also possible to create a Galois Field with an arbitrary primitive polynomial. However, if the polynomial is not a primitive polynomial of the field, and error message is returned. For instance. @example octave:1> a = [0:7]; octave:2> b = gf (a, 4, 25) b = GF(2^4) array. Primitive Polynomial = D^4+D^3+1 (decimal 25) Array elements = 0 1 2 3 4 5 6 7 octave:3> c = gf (a, 4, 21) error: gf: primitive polynomial (21) of Galois Field must be irreducible @end example The function @code{gftable} is included for compatibility with @sc{matlab}. In @sc{matlab} this function is used to create the lookup tables used to accelerate the computations over the Galois Field and store them to a file. However Octave stores these parameters for all of the fields currently in use and so this function is not required, although it is silently accepted. @node Primitive Polynomials, Accessing Internal Fields, Creating Galois Fields, Galois Field Basics @subsection Primitive Polynomials The function @code{gf (@var{a}, @var{m})} creates a Galois Field using the default primitive polynomial. However there exists many possible primitive polynomials for most Galois Fields. Two functions exist for identifying primitive polynomials, @code{isprimitive} and @code{primpoly}. @code{primpoly (@var{m}, @var{opt})} is used to identify the primitive polynomials of the fields GF(2^M). For example @example octave:1> primpoly (4) Primitive polynomial(s) = D^4+D+1 ans = 19 @end example @noindent identifies the default primitive polynomials of the field GF(2^M), which is the same as @code{primpoly (4, "min")}. All of the primitive polynomials of a field can be identified with the function @code{primpoly (@var{m}, "all")}. For example @example octave:1> primpoly (4, "all") Primitive polynomial(s) = D^4+D+1 D^4+D^3+1 ans = 19 25 @end example @noindent while @code{primpoly (@var{m}, "max")} returns the maximum primitive polynomial of the field, which for the case above is 25. The function @code{primpoly} can also be used to identify the primitive polynomials having only a certain number of non-zero terms. For instance @example octave:1> primpoly (5, 3) Primitive polynomial(s) = D^5+D^2+1 D^5+D^3+1 ans = 37 41 @end example @noindent identifies the polynomials with only three terms that can be used as primitive polynomials of GF(2^5). If no primitive polynomials existing having the requested number of terms then @code{primpoly} returns an empty vector. That is @example octave:1> primpoly (5, 2) warning: primpoly: No primitive polynomial satisfies the given constraints ans = [](1x0) @end example As can be seen above, @code{primpoly} displays the polynomial forms the the polynomials that it finds. This output can be suppressed with the "nodisplay" option, while the returned value is left unchanged. @example octave:1> primpoly (4, "all", "nodisplay") ans = 19 25 @end example @code{isprimitive (@var{a})} identifies whether the elements of @var{a} can be used as primitive polynomials of the Galois Fields GF(2^M). Consider as an example the fields GF(2^4). The primitive polynomials of these fields must have an order m and so their integer representation must be between 16 and 31. Therefore @code{isprimitive} can be used in a similar manner to @code{primpoly} as follows @example octave:1> find (isprimitive (16:31)) + 15 ans = 19 25 @end example @noindent which finds all of the primitive polynomials of GF(2^4). @node Accessing Internal Fields, Function Overloading, Primitive Polynomials, Galois Field Basics @subsection Accessing Internal Fields Once a variable has been defined as a Galois Field, the parameters of the field of this structure can be obtained by adding a suffix to the variable. Valid suffixes are '.m', '.prim_poly' and '.x', which return the order of the Galois Field, its primitive polynomial and the data the variable contains respectively. For instance @example octave:1> a = [0:7]; octave:2> b = gf (a, 4); octave:3> b.m ans = 4 octave:4> b.prim_poly ans = 19 octave:5> c = b.x; octave:6> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x8 24 double b 1x8 32 galois c 1x8 64 double Total is 24 elements using 120 bytes @end example @c Note that if code compiled with GALOIS_DISP_PRIVATES then '.n', '.alpha_to' @c and '.index_of' are also available. These give 2^m-1, the lookup table @c and its inverse respectively. Please note that it is explicitly forbidden to modify the Galois field by accessing these variables. For instance @example octave:1> a = gf ([0:7], 3); octave:2> a.prim_poly = 13; @end example @noindent is explicitly forbidden. The result of this will be to replace the Galois array @var{a} with a structure @var{a} with a single element called '.prim_poly'. To modify the order or primitive polynomial of a field, a new field must be created and the data copied. That is @example octave:1> a = gf ([0:7], 3); octave:2> a = gf (a.x, a.m, 13); @end example @node Function Overloading, Known Problems, Accessing Internal Fields, Galois Field Basics @subsection Function Overloading An important consideration in the use of the Galois Field package is that many of the internal functions of Octave, such as @code{roots}, can not accept Galois Fields as an input. This package therefore uses Octave classes to @emph{overload} the internal Octave functions with equivalent functions that work with Galois Fields, so that the standard function names can be used. The version of the function that is chosen is determined by the first argument of the function. This is a temporary situation until the Galois Field class constructor can be rewritten to allow the use of the @code{superiorto} function to define the galois class with a higher precedence. So, considering the @code{filter} function, if the first argument is a @emph{Matrix}, then the normal version of the function is called regardless of whether the other arguments of the function are Galois vectors or not. Other Octave functions work correctly with Galois Fields and so overloaded versions are not necessary. This include such functions as @code{size} and @code{polyval}. It is also useful to use the '.x' option discussed in the previous section, to extract the raw data of the Galois field for use with some functions. An example is @example octave:1> a = minpol (gf (14, 5)); octave:2> b = de2bi (a.x, [], "left-msb"); @end example @noindent converts the polynomial form of the minimum polynomial of 14 in GF(2^5) into an integer. Finally help for the Galois specific versions of the functions must explicitly call the correct function as @example octave:1> help @@galois/conv @end example @node Known Problems, , Function Overloading, Galois Field Basics @subsection Known Problems Please review the following list of known problems with the Galois type before reporting a bug against this package. @table @asis @item Saving and loading Galois variables Saving a Galois variable to a file is as simple as @example octave:1> a = gf (@dots{}); octave:2> save a.mat a @end example @noindent where @var{a} is any Galois variable. Galois variables can be saved in the Octave binary and ASCII formats, as well as the HDF5 format. To load a Galois variable from a file, the Galois type must already be registered to the Octave interpreter prior to the call to @code{load}. If no Galois variables have been created yet, you will have to do something like @example octave:1> dummy = gf (1); octave:2> load a.mat @end example @item Logarithm of zero does not return NaN The logarithm of zero in a Galois field is not defined. However, to avoid segmentation faults in later calculations the logarithm of zero is defined as @code{2^@var{m} - 1}, whose value is not the logarithm of any other value in the Galois field. A warning is also shown to tell the user about the problem. For example @example octave:1> m = 3; octave:2> a = log (gf ([0:2^m-1], m)) warning: log of zero undefined in Galois field a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 1 3 2 6 4 5 @end example To fix this problem would require a major rewrite of all code, adding an exception for the case of NaN to all basic operators. These exceptions will certainly slow the code down. @item Speed The code was written piecemeal with no attention to optimization. Some operations may be slower than they could be. Contributions are welcome. @end table @node Manipulating Galois Fields, , Galois Field Basics, Galois Fields @section Manipulating Galois Fields @menu * Expressions manipulation and assignment:: * Unary operations:: * Arithmetic operations:: * Comparison operations:: * Polynomial manipulations:: * Linear Algebra:: * Signal Processing:: @end menu @node Expressions manipulation and assignment, Unary operations, , Manipulating Galois Fields @subsection Expressions, manipulation and assignment Galois variables can be treated in similar manner to other variables within Octave. For instance Galois fields can be accessed using index expressions in a similar manner to all other Octave matrices. For example @example octave:1> a = gf ([[0:7]; [7:-1:0]], 3) a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0 octave:2> b = a(1,:) b = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 1 2 3 4 5 6 7 @end example Galois arrays can equally use indexed assignments. That is, the data in the array can be partially replaced, on the condition that the two fields are identical. An example is @example octave:1> a = gf (ones (2, 8), 3); octave:2> b = gf (zeros (1, 8), 3); octave:3> a(1,:) = b a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 @end example Implicit conversions between normal matrices and Galois arrays are possible. For instance data can be directly copied from a Galois array to a real matrix as follows. @example octave:1> a = gf (ones (2, 8), 3); octave:2> b = zeros (2, 8); octave:3> b(2,:) = a(2,:) b = 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 @end example The inverse is equally possible, with the proviso that the data in the matrix is valid in the Galois field. For instance @example octave:1> a = gf ([0:7], 3); octave:2> a(1) = 1; @end example @noindent is valid, while @example octave:1> a = gf ([0:7], 3); octave:2> a(1) = 8; @end example @noindent is not, since 8 is not an element of GF(2^3). This is a basic rule of manipulating Galois arrays. That is matrices and scalars can be used in conjunction with a Galois array as long as they contain valid data within the Galois field. In this case they will be assumed to be of the same field. Galois arrays can also be concatenated with real matrices or with other Galois arrays in the same field. For example @example octave:1> a = [gf([0:7], 3); gf([7:-1:0], 3)]; octave:2> b = [a, a]; octave:3> c = [a, eye(2)]; octave:3> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 2x8 64 galois b 2x16 128 galois c 2x10 80 galois Total is 68 elements using 272 bytes @end example Other basic manipulations of Galois arrays are @table @code @item isempty Returns true if the Galois array is empty. @item size Returns the number of rows and columns in the Galois array. @item length Returns the length of a Galois vector, or the maximum of rows or columns of Galois arrays. @item find Find the indexes of the non-zero elements of a Galois array. @item diag Create a diagonal Galois array from a Galois vector, or extract a diagonal from a Galois array. @item reshape Change the shape of the Galois array. @end table @node Unary operations, Arithmetic operations, Expressions manipulation and assignment, Manipulating Galois Fields @subsection Unary operations The same unary operators that are available for normal Octave matrices are also available for Galois arrays. These operations are @table @code @item +@var{x} Unary plus. This operator has no effect on the operand. @item -@var{x} Unary minus. Note that in a Galois Field this operator also has no effect on the operand. @item !@var{x} Returns true for zero elements of Galois Array. @item @var{x}' Complex conjugate transpose. As the Galois Field only contains integer values, this is equivalent to the transpose operator. @item @var{x}.' Transpose of the Galois array. @end table @node Arithmetic operations, Comparison operations, Unary operations, Manipulating Galois Fields @subsection Arithmetic operations The available arithmetic operations on Galois arrays are the same as on other Octave matrices. It should be noted that both operands must be in the same Galois Field. If one operand is a Galois array and the second is a matrix or scalar, then the second operand is silently converted to the same Galois Field. The element(s) of these matrix or scalar must however be valid members of the Galois field. Thus @example octave:1> a = gf ([0:7], 3); octave:2> b = a + [0:7]; @end example @noindent is valid, while @example octave:1> a = gf ([0:7], 3); octave:2> b = a + [1:8]; @end example @noindent is not, since 8 is not a valid element of GF(2^3). The available arithmetic operators are @table @code @item @var{x} + @var{y} Addition. If both operands are Galois arrays or matrices, the number of rows and columns must both agree. If one operand is a is a Galois array with a single element or a scalar, its value is added to all the elements of the other operand. The @code{+} operator on a Galois Field is equivalent to an exclusive-or on normal integers. @item @var{x} .+ @var{y} Element by element addition. This operator is equivalent to @code{+}. @item @var{x} - @var{y} As both @code{+} and @code{-} in a Galois Field are equivalent to an exclusive-or for normal integers, @code{-} is equivalent to the @code{+} operator @item @var{x} .- @var{y} Element by element subtraction. This operator is equivalent to @code{-}. @item @var{x} * @var{y} Matrix multiplication. The number of columns of @var{x} must agree with the number of rows of @var{y}. @item @var{x} .* @var{y} Element by element multiplication. If both operands are matrices, the number of rows and columns must both agree. @item @var{x} / @var{y} Right division. This is conceptually equivalent to the expression @example (inverse (y') * x')' @end example @noindent but it is computed without forming the inverse of @var{y'}. If the matrix is singular then an error occurs. If the matrix is under-determined, then a particular solution is found (but not minimum norm). If the solution is over-determined, then an attempt is made to find a solution, but this is not guaranteed to work. @item @var{x} ./ @var{y} Element by element right division. @item @var{x} \ @var{y} Left division. This is conceptually equivalent to the expression @example inverse (x) * y @end example @noindent but it is computed without forming the inverse of @var{x}. If the matrix is singular then an error occurs. If the matrix is under-determined, then a particular solution is found (but not minimum norm). If the solution is over-determined, then an attempt is made to find a solution, but this is not guaranteed to work. @item @var{x} .\ @var{y} Element by element left division. Each element of @var{y} is divided by each corresponding element of @var{x}. @item @var{x} ^ @var{y} @itemx @var{x} ** @var{y} Power operator. If @var{x} and @var{y} are both scalars, this operator returns @var{x} raised to the power @var{y}. Otherwise @var{x} must be a square matrix raised to an integer power. @item @var{x} .^ @var{y} @item @var{x} .** @var{y} Element by element power operator. If both operands are matrices, the number of rows and columns must both agree. @end table @node Comparison operations, Polynomial manipulations, Arithmetic operations, Manipulating Galois Fields @subsection Comparison operations Galois variables can be tested for equality in the usual manner. That is @example octave:1> a = gf ([0:7], 3); octave:2> a == ones (1, 8) ans = 0 1 0 0 0 0 0 0 octave:3> a != zeros (1, 8) ans = 0 1 1 1 1 1 1 1 @end example Likewise, Galois vectors can be tested against scalar values (whether they are Galois or not). For instance @example octave:4> a == 1 ans = 0 1 0 0 0 0 0 0 @end example To test if any or all of the values in a Galois array are non-zero, the functions @code{any} and @code{all} can be used as normally. In addition the comparison operators @code{>}, @code{>=}, @code{<} and @code{<=} are available. As elements of the Galois Field are modulus 2^@var{m}, all elements of the field are both greater than and less than all others at the same time. Thus these comparison operators don't make that much sense and are only included for completeness. The comparison is done relative to the integer value of the Galois Field elements. @node Polynomial manipulations, Linear Algebra, Comparison operations, Manipulating Galois Fields @subsection Polynomial manipulations A polynomial in GF(2^M) can be expressed as a vector in GF(2^M). For instance if @var{a} is the @emph{primitive element}, then the example @example octave:1> poly = gf ([2, 4, 5, 1], 3); @end example @noindent represents the polynomial @tex $$ poly = a x^3 + a^2 x^2 + (a^2 + 1) x + 1 $$ @end tex @ifnottex @example poly = @var{a} * x^3 + @var{a}^2 * x^2 + (@var{a}^2 + 1) * x + 1 @end example @end ifnottex Arithmetic can then be performed on these vectors. For instance to add to polynomials an example is @example octave:1> poly1 = gf ([2, 4, 5, 1], 3); octave:2> poly2 = gf ([1, 2], 3); octave:3> sumpoly = poly1 + [0, 0, poly2] sumpoly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 4 3 @end example Note that @var{poly2} must be zero padded to the same length as poly1 to allow the addition to take place. Multiplication and division of Galois polynomials is equivalent to convolution and de-convolution of vectors of Galois elements. Thus to multiply two polynomials in GF(2^3). @example octave:4> mulpoly = conv (poly1, poly2) mulpoly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 0 6 0 2 @end example Likewise the division of two polynomials uses the de-convolution function as follows @example octave:5> [poly, remd] = deconv (mulpoly, poly2) poly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 5 1 remd = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 0 0 @end example Note that the remainder of this division is zero, as we performed the inverse operation to the multiplication. To evaluate a polynomial for a certain value in GF(2^M), use the Octave function @code{polyval}. @example octave:1> poly1 = gf ([2, 4, 5, 1], 3); ## a*x^3+a^2*x^2+(a^2+1)*x+1 octave:2> x0 = gf ([0, 1, 2], 3); octave:3> y0 = polyval (poly1, x0); y0 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 2 0 octave:4> a = gf (2, 3); ## The primitive element octave:5> y1 = a .* x0.^3 + a.^2 .* x0.^2 + (a.^2 + 1) .* x0 + 1 y1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 2 0 @end example It is equally possible to find the roots of Galois polynomials with the @code{roots} function. Using the polynomial above over GF(2^3), we can find its roots in the following manner @example octave:1> poly1 = gf ([2, 4, 5, 1], 3); octave:2> root1 = roots (poly1) root1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 5 5 @end example Thus the example polynomial has 3 roots in GF(2^3) with one root of multiplicity 2. We can check this answer with the @code{polyval} function as follows @example octave:3> check1 = polyval (poly1, root1) check1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 @end example @noindent which as expected gives a zero vector. It should be noted that both the number of roots and their value, will depend on the chosen field. Thus for instance @example octave:1> poly3 = gf ([2, 4, 5, 1], 3, 13); octave:2> root3 = roots (poly3) root3 = GF(2^3) array. Primitive Polynomial = D^3+D^2+1 (decimal 13) Array elements = 5 @end example @noindent shows that in the field GF(2^3) with a different primitive polynomial, has only one root exists. The minimum polynomial of an element of GF(2^M) is the minimum degree polynomial in GF(2), excluding the trivial zero polynomial, that has that element as a root. The fact that the minimum polynomial is in GF(2) means that its coefficients are one or zero only. The @code{minpol} function can be used to find the minimum polynomial as follows @example octave:1> a = gf (2, 3); ## The primitive element octave:2> b = minpol (a) b = GF(2) array. Array elements = 1 0 1 1 @end example Note that the minimum polynomial of the primitive element is the primitive polynomial. Elements of GF(2^M) sharing the same minimum polynomial form a partitioning of the field. This partitioning can be found with the @code{cosets} function as follows @example octave:1> c = cosets (3) c = @{ [1,1] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 [1,2] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 6 [1,3] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 3 5 7 @} @end example @noindent which returns a cell array containing all of the elements of the GF(2^3), partitioned into groups sharing the same minimum polynomial. The function @code{cosets} can equally accept a second argument defining the primitive polynomial to use in its calculations (i.e. @code{cosets (@var{a}, @var{p})}). @node Linear Algebra, Signal Processing, Polynomial manipulations, Manipulating Galois Fields @subsection Linear Algebra The basic linear algebra operation of this package is the LU factorization of a Galois array. That is the Galois array @var{a} is factorized in the following way @example octave:2> [l, u, p] = lu (a) @end example @noindent such that @code{@var{p} * @var{a} = @var{l} * @var{u}}. The matrix @var{p} contains row permutations of @var{a}, such that @var{l} and @var{u} are strictly upper and low triangular. The Galois array @var{a} can be rectangular. All other linear algebra operations within this package are based on this LU factorization of a Galois array. An important consequence of this is that no solution can be found for singular matrices, only a particular solution will be found for under-determined systems of equation and the solution found for over-determined systems is not always correct. This is identical to the way @sc{matlab} performs linear algebra on Galois arrays. For instance consider the under-determined linear equation @example octave:1> A = gf ([2, 0, 3, 3; 3, 1, 3, 1; 3, 1, 1, 0], 2); octave:2> b = [0:2]'; octave:3> x = A \ b; @end example @noindent gives the solution @code{@var{x} = [2, 0, 3, 2]}. There are in fact 4 possible solutions to this linear system; @code{@var{x} = [3, 2, 2, 0]}, @code{@var{x} = [0, 3, 1, 1]}, @code{@var{x} = [2, 0, 3, 2]} and @code{@var{x} = [1, 1, 0, 3]}. No particular selection criteria are applied to the chosen solution. In addition, because singular matrices cannot be solved, unless you know the matrix is not singular, you should test the determinant of the matrix prior to solving the linear system. For instance @example octave:1> A = gf (floor (2^m * rand (3)), 2); octave:2> b = [0:2]'; octave:3> if (det (A) != 0); x = A \ b; y = b' / A; endif; octave:4> r = rank (A); @end example @noindent solves the linear systems @code{@var{A} * @var{x} = @var{b}} and @code{@var{y} * @var{A} = @var{b}}. Note that you do not need to take into account rounding errors in the determinant, as the determinant can only take values within the Galois Field. So if the determinant equals zero, the array is singular. @node Signal Processing, , Linear Algebra, Manipulating Galois Fields @subsection Signal Processing with Galois Fields Signal processing functions such as filtering, convolution, de-convolution and Fourier transforms can be performed over Galois Fields. For instance the @code{filter} function can be used with Galois vectors in the same manner as usual. For instance @example octave:1> b = gf ([2, 0, 0, 1, 0, 2, 0, 1], 2); octave:2> a = gf ([2, 0, 1, 1], 2); octave:3> x = gf ([1, zeros(1, 20)], 2); octave:4> y = filter (b, a, x) y = GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7) Array elements = 1 0 3 0 2 3 1 0 1 3 3 1 0 1 3 3 1 0 1 3 3 @end example @noindent gives the impulse response of the filter defined by @var{a} and @var{b}. Two equivalent ways are given to perform the convolution of two Galois vectors. Firstly the function @code{conv} can be used, or alternatively the function @code{convmtx} can be used. The first of these function is identical to the convolution function over real vectors, and has been described in the section about multiplying two Galois polynomials. In the case where many Galois vectors will be convolved with the same vector, the second function @code{convmtx} offers an alternative method to calculate the convolution. If @var{a} is a column vector and @var{x} is a column vector of length @var{n}, then @example octave:1> m = 3; octave:2> a = gf (floor (2^m * rand (4, 1)), m); octave:3> b = gf (floor (2^m * rand (4, 1)), m); octave:4> c0 = conv (a, b)'; octave:5> c1 = convmtx (a, length (b)) * b; octave:6> check = all (c0 == c1) check = 1 @end example @noindent shows the equivalence of the two functions. The de-convolution function has been previously described above. The final signal processing function available in this package are the functions to perform Fourier transforms over a Galois field. Three functions are available, @code{fft}, @code{ifft} and @code{dftmtx}. The first two functions use the third to perform their work. Given an element @var{a} of the Galois field GF(2^M), @code{dftmtx} returns the @code{2^M - 1} square matrix used in the Fourier transforms with respect to @var{a}. The minimum polynomial of @var{a} must be primitive in GF(2^M). In the case of the @code{fft} function @code{dftmtx} is called with the primitive element of the Galois Field as an argument. As an example @example octave:1> m = 4; octave:2> n = 2^m - 1; octave:2> alph = gf (2, m); octave:3> x = gf (floor (2^m * rand (n, 1)), m); octave:4> y0 = fft (x); octave:5> y1 = dftmtx (alph) * x; octave:6> z0 = ifft (y0); octave:7> z1 = dftmtx (1/alph) * y1; octave:8> check = all (y0 == y1) & all (z0 == x) & all (z1 == x) check = 1 @end example In all cases, the length of the vector to be transformed must be @code{2^M -1}. As the @code{dftmtx} creates a matrix representing the Fourier transform, to limit the computational task only Fourier transforms in GF(2^M), where M is less than or equal to 8, are supported. @node Function Reference, , Galois Fields, Top @chapter Function Reference @REFERENCE_SECTION(Communications) @bye communications-1.2.1/doc/PaxHeaders.3802/comms.texi0000644000000000000000000000013012510010564016762 xustar0029 mtime=1428164980.71691355 29 atime=1428164980.91690702 30 ctime=1428164983.712815029 communications-1.2.1/doc/comms.texi0000644000000000000000000065447112510010564017332 0ustar00rootroot00000000000000\input texinfo @setfilename comms.info @settitle Communications Package for Octave @titlepage @title Communications Package for Octave @subtitle November 2013 @author David Bateman @author Paul Kienzle @author Laurent Mazet @author Mike Miller @page @vskip 0pt plus 1filll Copyright @copyright{} 2003-2013 Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the same conditions as for modified versions. @end titlepage @contents @ifnottex @node Top, Introduction @top @end ifnottex @menu * Introduction:: * Random Signals:: * Source Coding:: * Block Coding:: * Convolutional Coding:: * Modulations:: * Special Filters:: * Galois Fields:: * Function Reference:: @end menu @node Introduction, Random Signals, Top, Top @chapter Introduction This is the manual for the Communications Package for GNU Octave. All functions provided by this package are described in this manual. In addition many functions from Octave and other Octave packages are useful to or required by this package, and so they may also be explained or shown in examples in this manual. This documentation is a work in progress, you are invited to help improve it and submit patches. @node Random Signals, Source Coding, Introduction, Top @chapter Random Signals The purpose of the functions described here is to create and add random noise to a signal, to create random data and to analyze the eventually errors in a received signal. The functions to perform these tasks can be considered as either related to the creation or analysis of signals and are treated separately below. It should be noted that the examples below are based on the output of a random number generator, and so the user can not expect to exactly recreate the examples below. @menu * Signal Creation:: * Signal Analysis:: @end menu @node Signal Creation, Signal Analysis, , Random Signals @section Signal Creation The signal creation functions here fall into to two classes. Those that treat discrete data and those that treat continuous data. The basic function to create discrete data is @code{randint}, that creates a random matrix of equi-probable integers in a desired range. For example @example octave:1> a = randint (3, 3, [-1, 1]) a = 0 1 0 -1 -1 1 0 1 1 @end example @noindent creates a 3-by-3 matrix of random integers in the range -1 to 1. To allow for repeated analysis with the same random data, the function @code{randint} allows the seed-value of the random number generator to be set. For instance @example octave:1> a = randint (3, 3, [-1, 1], 1) a = 0 1 1 0 -1 0 1 -1 -1 @end example @noindent will always produce the same set of random data. The range of the integers to produce can either be a two element vector or an integer. In the case of a two element vector all elements within the defined range can be produced. In the case of an integer range @var{M}, @code{randint} returns the equi-probable integers in the range @tex $[0:2^m-1]$. @end tex @ifnottex [0:2^@var{m}-1]. @end ifnottex The function @code{randsrc} differs from @code{randint} in that it allows a random set of symbols to be created with a given probability. The symbols can be real, complex or even characters. However characters and scalars can not be mixed. For example @example octave:1> a = randsrc (2, 2, "ab"); octave:2> b = randsrc (4, 4, [1, 1i, -1, -1i]); @end example @noindent are both legal, while @example octave:1> a = randsrc (2, 2, [1, "a"]); @end example @noindent is not legal. The alphabet from which the symbols are chosen can be either a row vector or two row matrix. In the case of a row vector, all of the elements of the alphabet are chosen with an equal probability. In the case of a two row matrix, the values in the second row define the probability that each of the symbols are chosen. For example @example octave:1> a = randsrc (5, 5, [1, 1i, -1, -1i; 0.6 0.2 0.1 0.1]) a = 1 + 0i 0 + 1i 0 + 1i 0 + 1i 1 + 0i 1 + 0i 1 + 0i 0 + 1i 0 + 1i 1 + 0i -0 - 1i 1 + 0i -1 + 0i 1 + 0i 0 + 1i 1 + 0i 1 + 0i 1 + 0i 1 + 0i 1 + 0i -1 + 0i -1 + 0i 1 + 0i 1 + 0i 1 + 0i @end example @noindent defines that the symbol '1' has a 60% probability, the symbol '1i' has a 20% probability and the remaining symbols have 10% probability each. The sum of the probabilities must equal one. Like @code{randint}, @code{randsrc} accepts a fourth argument as the seed of the random number generator allowing the same random set of data to be reproduced. The function @code{randerr} allows a matrix of random bit errors to be created, for binary encoded messages. By default, @code{randerr} creates exactly one errors per row, flagged by a non-zero value in the returned matrix. That is @example octave:1> a = randerr (5, 10) a = 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 @end example The number of errors per row can be specified as the third argument to @code{randerr}. This argument can be either a scalar, a row vector or a two row matrix. In the case of a scalar value, exactly this number of errors will be created per row in the returned matrix. In the case of a row vector, each element of the row vector gives a possible number of equi-probable bit errors. The second row of a two row matrix defines the probability of each number of errors occurring. For example @example octave:1> n = 15; k = 11; nsym = 100; octave:2> msg = randint (nsym, k); ## Binary vector of message octave:3> code = encode (msg, n, k, "bch"); octave:4> berrs = randerr (nsym, n, [0, 1; 0.7, 0.3]); octave:5> noisy = mod (code + berrs, 2) ## Add errors to coded message @end example @noindent creates a vector @var{msg}, encodes it with a [15,11] BCH code, and then add either none or one error per symbol with the chances of an error being 30%. As previously, @code{randerr} accepts a fourth argument as the seed of the random number generator allowing the same random set of data to be reproduced. All of the above functions work on discrete random signals. The functions @code{wgn} and @code{awgn} create and add white Gaussian noise to continuous signals. The function @code{wgn} creates a matrix of white Gaussian noise of a certain power. A typical call to @code{wgn} is then @example octave:1> nse = wgn (10, 10, 0); @end example @noindent which creates a 10-by-10 matrix of noise with a root mean squared power of 0dBW relative to an impedance of @tex $1\Omega$. @end tex @ifnottex 1 Ohm. @end ifnottex This effectively means that an equivalent result to the above can be obtained with @example octave:1> nse = randn (10, 10); @end example The reference impedance and units of power to the function @code{wgn} can however be modified, for example @example octave:1> nse_30dBm_50Ohm = wgn (10000, 1, 30, 50, "dBm"); octave:2> nse_0dBW_50Ohm = wgn (10000, 1, 0, 50, "dBW"); octave:3> nse_1W_50Ohm = wgn (10000, 1, 1, 50, "linear"); octave:4> [std(nse_30dBm_50Ohm), std(nse_0dBW_50Ohm), std(nse_1W_50Ohm)] ans = 7.0805 7.1061 7.0730 @end example Each of these produces a 1W signal referenced to a @tex $50\Omega$ @end tex @ifnottex 50 Ohm @end ifnottex impedance. @sc{matlab} uses the misnomer "dB" for "dBW", so "dB" is an accepted type for @code{wgn} and is treated as a synonym for "dBW". In all cases, the returned matrix @var{v}, will be related to the input power @var{p} and the impedance @var{Z} as @tex $$p = {\sum_i \sum_j v(i,j)^2 \over Z} Watts$$ @end tex @ifnottex @var{p} = sum (@var{v}(:) .^ 2 ) / @var{imp} Watts @end ifnottex By default @code{wgn} produces real vectors of white noise. However, it can produce both real and complex vectors like @example octave:1> rnse = wgn (10000, 1, 0, "dBm", "real"); octave:2> cnse = wgn (10000, 1, 0, "dBm", "complex"); octave:3> [std(rnse), std(real (cnse)), std(imag (cnse)), std(cnse)] ans = 0.031615 0.022042 0.022241 0.031313 @end example @noindent which shows that with a complex return value that the total power is the same as a real vector, but that it is equally shared between the real and imaginary parts. As previously, @code{wgn} accepts a fourth numerical argument as the seed of the random number generator allowing the same random set of data to be reproduced. That is @example octave:1> nse = wgn (10, 10, 0, 0); @end example @noindent will always produce the same set of data. The final function to deal with the creation of random signals is @code{awgn}, that adds noise at a certain level relative to a desired signal. This function adds noise at a certain level to a desired signal. An example call to @code{awgn} is @example octave:1> x = [0:0.1:2*pi]; octave:2> y = sin (x); octave:3> noisy = awgn (y, 10, "measured") @end example @ifnotinfo @noindent which produces a sine-wave with noise added as seen in Figure 1. @center @image{awgn} @center Figure 1: Sine-wave with 10dB signal-to-noise ratio @end ifnotinfo @noindent which adds noise with a 10dB signal-to-noise ratio to the measured power in the desired signal. By default @code{awgn} assumes that the desired signal is at 0dBW, and the noise is added relative to this assumed power. This behavior can be modified by the third argument to @code{awgn}. If the third argument is a numerical value, it is assumed to define the power in the input signal, otherwise if the third argument is the string "measured", as above, the power in the signal is measured prior to the addition of the noise. The final argument to @code{awgn} defines the definition of the power and signal-to-noise ratio in a similar manner to @code{wgn}. This final argument can be either "dB" or "linear". In the first case the numerical value of the input power is assumed to be in dBW and the signal-to-noise ratio in dB. In the second case, the power is assumed to be in Watts and the signal-to-noise ratio is expressed as a ratio. The return value of @code{awgn} will be in the same form as the input signal. In addition if the input signal is real, the additive noise will be real. Otherwise the additive noise will also be complex and the noise will be equally split between the real and imaginary parts. As previously the seed to the random number generator can be specified as the last argument to @code{awgn} to allow repetition of the same scenario. That is @example octave:1> x = [0:0.1:2*pi]; octave:2> y = sin (x); octave:3> noisy = awgn (y, 10, "dB", 0, "measured") @end example @noindent which uses the seed-value of 0 for the random number generator. @node Signal Analysis, , Signal Creation, Random Signals @section Signal Analysis It is important to be able to evaluate the performance of a communications system in terms of its bit-error and symbol-error rates. Two functions @code{biterr} and @code{symerr} exist within this package to calculate these values, both taking as arguments the expected and the actually received data. The data takes the form of matrices or vectors, with each element representing a single symbol. They are compared in the following manner @table @asis @item Both matrices In this case both matrices must be the same size and then by default the return values are the overall number of errors and the overall error rate. @item One column vector In this case the column vector is used for comparison column-wise with the matrix. The return values are row vectors containing the number of errors and the error rate for each column-wise comparison. The number of rows in the matrix must be the same as the length of the column vector. @item One row vector In this case the row vector is used for comparison row-wise with the matrix. The return values are column vectors containing the number of errors and the error rate for each row-wise comparison. The number of columns in the matrix must be the same as the length of the row vector. @end table For the bit-error comparison, the size of the symbol is assumed to be the minimum number of bits needed to represent the largest element in the two matrices supplied. However, the number of bits per symbol can (and in the case of random data should) be specified. As an example of the use of @code{biterr} and @code{symerr}, consider the example @example octave:1> m = 8; octave:2> msg = randint (10, 10, 2^m); octave:3> noisy = mod (msg + diag (1:10), 2^m); octave:4> [berr, brate] = biterr (msg, noisy, m) berr = 32 brate = 0.040000 octave:5> [serr, srate] = symerr (msg, noisy) serr = 10 srate = 0.10000 @end example @noindent which creates a 10-by-10 matrix adds 10 symbols errors to the data and then finds the bit and symbol error-rates. Two other means of displaying the integrity of a signal are the eye-diagram and the scatterplot. Although the functions @code{eyediagram} and @code{scatterplot} have different appearance, the information presented is similar and so are their inputs. The difference between @code{eyediagram} and @code{scatterplot} is that @code{eyediagram} segments the data into time intervals and plots the in-phase and quadrature components of the signal against this time interval. While @code{scatterplot} uses a parametric plot of quadrature versus in-phase components. Both functions can accept real or complex signals in the following forms. @table @asis @item A real vector In this case the signal is assumed to be real and represented by the vector @var{x}. @item A complex vector In this case the in-phase and quadrature components of the signal are assumed to be the real and imaginary parts of the signal. @item A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal. @end table An example of the use of the function @code{eyediagram} is @example octave:1> n = 50; octave:2> ovsp = 50; octave:3> x = 1:n; octave:4> xi = 1:1/ovsp:n-0.1; octave:5> y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); octave:6> yi = interp1 (x, y, xi); octave:7> noisy = awgn (yi, 15, "measured"); octave:8> eyediagram (noisy, ovsp); @end example @ifnotinfo @noindent which produces a eye-diagram of a noisy signal as seen in Figure 2. Similarly an example of the use of the function @code{scatterplot} is @center @image{eyediagram} @center Figure 2: Eye-diagram of a QPSK like signal with 15dB signal-to-noise ratio @end ifnotinfo @ifinfo Similarly an example of the use of the function @code{scatterplot} is @end ifinfo @example octave:1> n = 200; octave:2> ovsp = 5; octave:3> x = 1:n; octave:4> xi = 1:1/ovsp:n-0.1; octave:5> y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); octave:6> yi = interp1 (x, y, xi); octave:7> noisy = awgn (yi, 15, "measured"); octave:8> f = scatterplot (noisy, 1, 0, "b"); octave:9> hold on; octave:10> scatterplot (noisy, ovsp, 0, "r+", f); @end example @ifnotinfo @noindent which produces a scatterplot of a noisy signal as seen in Figure 3. @center @image{scatterplot} @center Figure 3: Scatterplot of a QPSK like signal with 15dB signal-to-noise ratio @end ifnotinfo @node Source Coding, Block Coding, Random Signals, Top @chapter Source Coding @menu * Quantization:: * PCM Coding:: * Arithmetic Coding:: * Dynamic Range Compression:: @end menu @node Quantization, PCM Coding, , Source Coding @section Quantization An important aspect of converting an analog signal to the digital domain is quantization. This is the process of mapping a continuous signal to a set of defined values. Octave contains two functions to perform quantization, @code{lloyds} creates an optimal mapping of the continuous signal to a fixed number of levels and @code{quantiz} performs the actual quantization. The set of quantization points to use is represented by a partitioning table (@var{table}) of the data and the signal levels (@var{codes} to which they are mapped. The partitioning @var{table} is monotonically increasing and if x falls within the range given by two points of this table then it is mapped to the corresponding code as seen in Table 1. @center Table 1: Table quantization partitioning and coding @multitable @columnfractions 0.1 0.4 0.4 0.1 @item @tab x < table(1) @tab codes(1) @tab @item @tab table(1) <= x < table(2) @tab codes(2) @tab @item @tab @dots{} @tab @dots{} @tab @item @tab table(i-1) <= x < table(i) @tab codes(i) @tab @item @tab @dots{} @tab @dots{} @tab @item @tab table(n-1) <= x < table(n) @tab codes(n) @tab @item @tab table(n-1) <= x @tab codes(n+1) @tab @end multitable These partition and coding tables can either be created by the user of using the function @code{lloyds}. For instance the use of a linear mapping can be seen in the following example. @example octave:1> m = 8; octave:2> n = 1024; octave:3> table = 2*[0:m-1]/m - 1 + 1/m; octave:4> codes = 2*[0:m]/m - 1; octave:5> x = 4*pi*[0:(n-1)]/(n-1); octave:6> y = cos (x); octave:7> [i, z] = quantiz (y, table, codes); @end example If a training signal is known that well represents the expected signals, the quantization levels can be optimized using the @code{lloyds} function. For example the above example can be continued @example octave:8> [table2, codes2] = lloyds (y, table, codes); octave:9> [i, z2] = quantiz (y, table2, codes2); @end example @noindent to use the mapping suggested by the function @code{lloyds}. It should be noted that the mapping given by @code{lloyds} is highly dependent on the training signal used. So if this signal does not represent a realistic signal to be quantized, then the partitioning suggested by @code{lloyds} will be sub-optimal. @node PCM Coding, Arithmetic Coding, Quantization, Source Coding @section PCM Coding The DPCM function @code{dpcmenco}, @code{dpcmdeco} and @code{dpcmopt} implement a form of predictive quantization, where the predictability of the signal is used to further compress it. These functions are not yet implemented. @node Arithmetic Coding, Dynamic Range Compression, PCM Coding, Source Coding @section Arithmetic Coding The arithmetic coding functions @code{arithenco} and @code{arithdeco} are not yet implemented. @node Dynamic Range Compression, , Arithmetic Coding, Source Coding @section Dynamic Range Compression The final source coding function is @code{compand} which is used to compress and expand the dynamic range of a signal. For instance consider a logarithm quantized by a linear partitioning. Such a partitioning is very poor for this large dynamic range. @code{compand} can then be used to compress the signal prior to quantization, with the signal being expanded afterwards. For example @example octave:1> mu = 1.95; octave:2> x = [0.01:0.01:2]; octave:3> y = log (x); octave:4> V = max (abs (y)); octave:5> [i, z, d] = quantiz (y, [-4.875:0.25:0.875], [-5:0.25:1]); octave:6> c = compand (y, minmu, V, "mu/compressor"); octave:7> [i2, c2] = quantiz (c, [-4.875:0.25:0.875], [-5:0.25:1]); octave:8> z2 = compand (c2, minmu, max (abs (c2)), "mu/expander"); octave:9> d2 = sumsq (y - z2) / length (y); octave:10> [d, d2] ans = 0.0053885 0.0029935 @end example @noindent which demonstrates that the use of @code{compand} can significantly reduce the distortion due to the quantization of signals with a large dynamic range. @node Block Coding, Convolutional Coding, Source Coding, Top @chapter Block Coding The error-correcting codes available in this package are discussed here. These codes work with blocks of data, with no relation between one block and the next. These codes create codewords based on the messages to transmit that contain redundant information that allow the recovery of the original message in the presence of errors. @menu * Data Formats:: * Binary Block Codes:: * BCH Codes:: * Reed-Solomon Codes:: @end menu @node Data Formats, Binary Block Codes, , Block Coding @section Data Formats All of the codes described in this section are binary and share similar data formats. The exception is the Reed-Solomon coder which has a significantly longer codeword length in general and therefore uses a different representation to efficiently pass data. The user should refer to the section about the Reed-Solomon codes for the data format used for Reed-Solomon codes. In general @var{k} bits of data are considered to represent a single message symbol. These @var{k} bits are coded into @var{n} bits of data representing the codeword. The data can therefore be grouped in one of three manners, to emphasis this grouping into bits, messages and codewords @table @asis @item A binary vector Each element of the vector is either one or zero. If the data represents an uncoded message the vector length should be an integer number of @var{k} in length. @item A binary matrix In this case the data is ones and zeros grouped into rows, with each representing a single message or codeword. The number of columns in the matrix should be equal to @var{k} in the case of a uncoded message or @var{n} in the case of a coded message. @item A non-binary vector In this case each element of the vector represents a message or codeword in an integer format. The bits of the message or codeword are represented by the bits of the vector elements with the least-significant bit representing the first element in the message or codeword. @end table An example demonstrating the relationship between the three data formats can be seen below. @example octave:1> k = 4; octave:2> bin_vec = randint (k*10, 1); # Binary vector format octave:3> bin_mat = reshape (bin_vec, k, 10)'; # Binary matrix format octave:4> dec_vec = bi2de (bin_mat); # Decimal vector format @end example The functions within this package will return data in the same format to which it is given. It should be noted that internally the binary matrix format is used, and thus if the message or codeword length is large it is preferable to use the binary format to avoid internal rounding errors. @node Binary Block Codes, BCH Codes, Data Formats, Block Coding @section Binary Block Codes All of the codes presented here can be characterized by their @table @asis @item Generator Matrix A @var{k}-by-@var{n} matrix @var{G} to generate the codewords @var{C} from the messages @var{T} by the matrix multiplication @tex $ {\bf C} = {\bf T} {\bf G}$. @end tex @ifnottex @var{C} = @var{T} * @var{G}. @end ifnottex @item Parity Check Matrix A '@var{n}-@var{k}'-by-@var{n} matrix @var{H} to check the parity of the received symbols. If @tex $ {\bf H} {\bf R} = {\bf S} \ne 0$, @end tex @ifnottex @var{H} * @var{R} = @var{S} != 0, @end ifnottex then an error has been detected. @var{S} can be used with the syndrome table to correct this error @item Syndrome Table A 2^@var{k}-by-@var{n} matrix @var{ST} with the relationship of the error vectors to the non-zero parities of the received symbols. That is, if the received symbol is represented as @tex $ {\bf R} = ( {\bf T} + {\bf E} )\ mod\ 2$, @end tex @ifnottex @var{R} = mod (@var{T} + @var{E}, 2), @end ifnottex then the error vector @var{E} is @tex ${\bf ST}({\bf S})$. @end tex @ifnottex @var{ST}(@var{S}). @end ifnottex @end table It is assumed for most of the functions in this package that the generator matrix will be in a 'standard' form. That is the generator matrix can be represented by @tex $$ {\bf G} = \left[\matrix{g_{11} & g_{12} & \ldots & g_{1k} & 1 & 0 & \ldots & 0 \cr g_{21} & g_{22} & & g_{2k} & 0 & 1 & & 0 \cr \vdots & & & \vdots & \vdots& & & \vdots \cr g_{k1} & g_{k2} & \ldots & g_{kk} & 0 & 0 & \ldots & 1}\right] $$ @end tex @ifnottex @example @group g(1,1) g(1,2) ... g(1,k) 1 0 ... 0 g(2,1) g(2,2) g(2,k) 0 1 ... 0 . . . . . . . . . . . . g(k,1) g(k,2) ... g(k,k) 0 0 ... 1 @end group @end example @end ifnottex @noindent or @tex $$ {\bf G} = \left[\matrix{1 & 0 & \ldots & 0 & g_{11} & g_{12} & \ldots & g_{1k} \cr 0 & 1 & & 0 & g_{21} & g_{22} & & g_{2k} \cr \vdots & & & \vdots & \vdots & & & \vdots \cr 0 & 0 & \ldots & 1 & g_{k1} & g_{k2} & \ldots & g_{kk}}\right] $$ @end tex @ifnottex @example @group 1 0 ... 0 g(1,1) g(1,2) ... g(1,k) 0 1 ... 0 g(2,1) g(2,2) g(2,k) . . . . . . . . . . . . 0 0 ... 1 g(k,1) g(k,2) ... g(k,k) @end group @end example @end ifnottex @noindent and similarly the parity check matrix can be represented by a combination of an identity matrix and a square matrix. Some of the codes can also have their representation in terms of a generator polynomial that can be used to create the generator and parity check matrices. In the case of BCH codes, this generator polynomial is used directly in the encoding and decoding without ever explicitly forming the generator or parity check matrix. The user can create their own generator and parity check matrices, or they can rely on the functions @code{hammgen}, @code{cyclgen} and @code{cyclpoly}. The function @code{hammgen} creates parity check and generator matrices for Hamming codes, while @code{cyclpoly} and @code{cyclgen} create generator polynomials and matrices for generic cyclic codes. An example of their use is @example octave:1> m = 3; octave:2> n = 2^m - 1; octave:2> k = 4; octave:3> [par, gen] = hammgen (m); octave:4> [par2, gen2] = cyclgen (n, cyclpoly (n, k)); @end example @noindent which create identical parity check and generator matrices for the [7,4] Hamming code. The syndrome table of the codes can be created with the function @code{syndtable}, in the following manner @example octave:1> [par, gen] = hammgen (3); octave:2> st = syndtable (par); @end example There exists two auxiliary functions @code{gen2par} and @code{gfweight}, that convert between generator and parity check matrices and calculate the Hamming distance of the codes. For instance @example octave:1> par = hammgen (3); octave:2> gen = gen2par (par); octave:3> gfweight (gen) ans = 3 @end example It should be noted that for large values of @var{n}, the generator, parity check and syndrome table matrices are very large. There is therefore an internal limitation on the size of the block codes that can be created that limits the codeword length @var{n} to less than 64. This is still excessively large for the syndrome table, so use caution with these codes. These limitations do not apply to the Reed-Solomon or BCH codes. The top-level encode and decode functions are @code{encode} and @code{decode}, which can be used with all codes, except the Reed-Solomon code. The basic call to both of these functions passes the message to code/decode, the codeword length, the message length and the type of coding to use. There are four basic types that are available with these functions @table @asis @item "linear" Generic linear block codes @item "cyclic" Cyclic linear block codes @item "hamming" Hamming codes @item "bch" Bose Chaudhuri Hocquenghem (BCH) block codes @end table It is not possible to distinguish between a binary vector and a decimal vector coding of the messages that just happens to only have ones and zeros. Therefore the functions @code{encode} and @code{decode} must be told the format of the messages in the following manner. @example octave:1> m = 3; octave:2> n = 7; octave:3> k = 4; octave:4> msg_bin = randint (10, k); octave:5> cbin = encode (msg_bin, n, k, "hamming/binary"); octave:5> cdec = encode (bi2de (msg), n, k, "hamming/decimal"); @end example @noindent which codes a binary matrix and a non-binary vector representation of a message, returning the coded message in the same format. The functions @code{encode} and @code{decode} by default accept binary coded messages. Therefore "hamming" is equivalent to "hamming/binary". Except for the BCH codes, the function @code{encode} and @code{decode} internally create the generator, parity check and syndrome table matrices. Therefore if repeated calls to @code{encode} and @code{decode} are made, it will often be faster to create these matrices externally and pass them as an argument. For example @example n = 15; k = 11; [par, gen] = hammgen (4); code1 = code2 = zeros (100, 15) for i = 1:100 msg = get_msg (i); code1(i,:) = encode (msg, n, k, "linear", gen); # This is faster code2(i,:) = encode (msg, n, k, "hamming"); # than this !!! endfor @end example In the case of the BCH codes the low-level functions described in the next section are used directly by the @code{encode} and @code{decode} functions. @node BCH Codes, Reed-Solomon Codes, Binary Block Codes, Block Coding @section BCH Codes The BCH coder used here is based on code written by Robert Morelos-Zaragoza (r.morelos-zaragoza@@ieee.org). This code was originally written in C and has been converted for use as an Octave oct-file. @iftex Called without arguments, @code{bchpoly} returns a table of valid BCH error correcting codes and their error-correction capability as seen in Table 1. @center Table 2: Table of valid BCH codes with codeword length less than 511. @multitable @columnfractions .083 .083 .083 .083 .083 .083 .083 .083 .083 .083 .083 .083 @item N @tab K @tab T @tab N @tab K @tab T @tab N @tab K @tab T @tab N @tab K @tab T @item 7 @tab 4 @tab 1 @tab 127 @tab 36 @tab 15 @tab 255 @tab 45 @tab 43 @tab 511 @tab 268 @tab 29 @item 15 @tab 11 @tab 1 @tab 127 @tab 29 @tab 21 @tab 255 @tab 37 @tab 45 @tab 511 @tab 259 @tab 30 @item 15 @tab 7 @tab 2 @tab 127 @tab 22 @tab 23 @tab 255 @tab 29 @tab 47 @tab 511 @tab 250 @tab 31 @item 15 @tab 5 @tab 3 @tab 127 @tab 15 @tab 27 @tab 255 @tab 21 @tab 55 @tab 511 @tab 241 @tab 36 @item 31 @tab 26 @tab 1 @tab 127 @tab 8 @tab 31 @tab 255 @tab 13 @tab 59 @tab 511 @tab 238 @tab 37 @item 31 @tab 21 @tab 2 @tab 255 @tab 247 @tab 1 @tab 255 @tab 9 @tab 63 @tab 511 @tab 229 @tab 38 @item 31 @tab 16 @tab 3 @tab 255 @tab 239 @tab 2 @tab 511 @tab 502 @tab 1 @tab 511 @tab 220 @tab 39 @item 31 @tab 11 @tab 5 @tab 255 @tab 231 @tab 3 @tab 511 @tab 493 @tab 2 @tab 511 @tab 211 @tab 41 @item 31 @tab 6 @tab 7 @tab 255 @tab 223 @tab 4 @tab 511 @tab 484 @tab 3 @tab 511 @tab 202 @tab 42 @item 63 @tab 57 @tab 1 @tab 255 @tab 215 @tab 5 @tab 511 @tab 475 @tab 4 @tab 511 @tab 193 @tab 43 @item 63 @tab 51 @tab 2 @tab 255 @tab 207 @tab 6 @tab 511 @tab 466 @tab 5 @tab 511 @tab 184 @tab 45 @item 63 @tab 45 @tab 3 @tab 255 @tab 199 @tab 7 @tab 511 @tab 457 @tab 6 @tab 511 @tab 175 @tab 46 @item 63 @tab 39 @tab 4 @tab 255 @tab 191 @tab 8 @tab 511 @tab 448 @tab 7 @tab 511 @tab 166 @tab 47 @item 63 @tab 36 @tab 5 @tab 255 @tab 187 @tab 9 @tab 511 @tab 439 @tab 8 @tab 511 @tab 157 @tab 51 @item 63 @tab 30 @tab 6 @tab 255 @tab 179 @tab 10 @tab 511 @tab 430 @tab 9 @tab 511 @tab 148 @tab 53 @item 63 @tab 24 @tab 7 @tab 255 @tab 171 @tab 11 @tab 511 @tab 421 @tab 10 @tab 511 @tab 139 @tab 54 @item 63 @tab 18 @tab 10 @tab 255 @tab 163 @tab 12 @tab 511 @tab 412 @tab 11 @tab 511 @tab 130 @tab 55 @item 63 @tab 16 @tab 11 @tab 255 @tab 155 @tab 13 @tab 511 @tab 403 @tab 12 @tab 511 @tab 121 @tab 58 @item 63 @tab 10 @tab 13 @tab 255 @tab 147 @tab 14 @tab 511 @tab 394 @tab 13 @tab 511 @tab 112 @tab 59 @item 63 @tab 7 @tab 15 @tab 255 @tab 139 @tab 15 @tab 511 @tab 385 @tab 14 @tab 511 @tab 103 @tab 61 @item 127 @tab 120 @tab 1 @tab 255 @tab 131 @tab 18 @tab 511 @tab 376 @tab 15 @tab 511 @tab 94 @tab 62 @item 127 @tab 113 @tab 2 @tab 255 @tab 123 @tab 19 @tab 511 @tab 367 @tab 17 @tab 511 @tab 85 @tab 63 @item 127 @tab 106 @tab 3 @tab 255 @tab 115 @tab 21 @tab 511 @tab 358 @tab 18 @tab 511 @tab 76 @tab 85 @item 127 @tab 99 @tab 4 @tab 255 @tab 107 @tab 22 @tab 511 @tab 349 @tab 19 @tab 511 @tab 67 @tab 87 @item 127 @tab 92 @tab 5 @tab 255 @tab 99 @tab 23 @tab 511 @tab 340 @tab 20 @tab 511 @tab 58 @tab 91 @item 127 @tab 85 @tab 6 @tab 255 @tab 91 @tab 25 @tab 511 @tab 331 @tab 21 @tab 511 @tab 49 @tab 93 @item 127 @tab 78 @tab 7 @tab 255 @tab 87 @tab 26 @tab 511 @tab 322 @tab 22 @tab 511 @tab 40 @tab 95 @item 127 @tab 71 @tab 9 @tab 255 @tab 79 @tab 27 @tab 511 @tab 313 @tab 23 @tab 511 @tab 31 @tab 109 @item 127 @tab 64 @tab 10 @tab 255 @tab 71 @tab 29 @tab 511 @tab 304 @tab 25 @tab 511 @tab 28 @tab 111 @item 127 @tab 57 @tab 11 @tab 255 @tab 63 @tab 30 @tab 511 @tab 295 @tab 26 @tab 511 @tab 19 @tab 119 @item 127 @tab 50 @tab 13 @tab 255 @tab 55 @tab 31 @tab 511 @tab 286 @tab 27 @tab 511 @tab 10 @tab 127 @item 127 @tab 43 @tab 14 @tab 255 @tab 47 @tab 42 @tab 511 @tab 277 @tab 28 @tab @tab @tab @end multitable @end iftex @ifnottex Called without arguments, @code{bchpoly} returns a table of valid BCH error correcting codes and their error-correction capability. @end ifnottex The first returned column of @code{bchpoly} is the codeword length, the second the message length and the third the error correction capability of the code. Called with one argument, @code{bchpoly} returns similar output, but only for the specified codeword length. In this manner codes with codeword length greater than 511 can be found. In general the codeword length is of the form @code{2^@var{m} - 1}, where @var{m} is an integer. However if [@var{n},@var{k}] is a valid BCH code, then it is also possible to use a shortened BCH form of the form @code{[@var{n}-@var{x},@var{k}-@var{x}]}. With two or more arguments, @code{bchpoly} is used to find the generator polynomial of a valid BCH code. For instance @example octave:1> bchpoly (15, 7) ans = 1 0 0 0 1 0 1 1 1 octave:2> bchpoly (14, 6) ans = 1 0 0 0 1 0 1 1 1 @end example @noindent show that the generator polynomial of a [15,7] BCH code with the default primitive polynomial is @tex $$ 1 + x^4 + x^6 + x^7 + x^8 $$ @end tex @ifnottex 1 + @var{x} ^ 4 + @var{x} ^ 6 + @var{x} ^ 7 + @var{x} ^ 8 @end ifnottex Using a different primitive polynomial to define the Galois Field over which the BCH code is defined results in a different generator polynomial as can be seen in the example. @example octave:1> bchpoly ([1 1 0 0 1], 7) ans = 1 0 0 0 1 0 1 1 1 octave:2> bchpoly ([1 0 0 1 1], 7) ans = 1 1 1 0 1 0 0 0 1 @end example It is recommend not to convert the generator polynomials created by @code{bchpoly} into generator and parity check matrices with the BCH codes, as the underlying BCH software is faster than the generic coding software and can treat significantly longer codes. As well as using the @code{encode} and @code{decode} functions previously discussed, the user can directly use the low-level BCH functions @code{bchenco} and @code{bchdeco}. In this case the messages must be in the format of a binary matrix with @var{k} columns @example octave:1> n = 31; octave:2> pgs = bchpoly (n); octave:3> pg = pgs(floor (rand () * (rows (pgs) + 1)),:); # Pick a poly octave:4> k = pg(2); octave:5> t = pg(3); octave:6> msg = randint (10, k); octave:7> code = bchenco (msg, n, k); octave:8> noisy = code + [ones(10, 1), zeros(10, n-1)]; octave:9> dec = bchdeco (code, k, t); @end example @node Reed-Solomon Codes, , BCH Codes, Block Coding @section Reed-Solomon Codes @menu * Representation of Reed-Solomon Messages:: * Creating and Decoding Messages:: * Shortened Reed-Solomon Codes:: @end menu @node Representation of Reed-Solomon Messages, Creating and Decoding Messages, , Reed-Solomon Codes @subsection Representation of Reed-Solomon Messages The Reed-Solomon coder used in this package is based on code written by Phil Karn (http://www.ka9q.net/code/fec). This code was originally written in C and has been converted for use as an Octave oct-file. Reed-Solomon codes are based on Galois Fields of even characteristics GF(2^M). Many of the properties of Galois Fields are therefore important when considering Reed-Solomon coders. The representation of the symbols of the Reed-Solomon code differs from the other block codes, in that the other block codes use a binary representation, while the Reed-Solomon code represents each m-bit symbol by an integer. The elements of the message and codeword must be elements of the Galois Field corresponding to the Reed-Solomon code. Thus to code a message with a [7,5] Reed-Solomon code an example is @example octave:1> m = 3; octave:2> n = 7; octave:3> k = 5; octave:4> msg = gf (floor (2^m * rand (2, k)), m) msg = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 5 0 6 3 2 4 1 3 1 2 octave:5> code = rsenc (msg, n, k) code = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 5 0 6 3 2 3 5 4 1 3 1 2 6 3 @end example The variable @var{n} is the codeword length of the Reed-Solomon coder, while @var{k} is the message length. It should be noted that @var{k} should be less than @var{n} and that @code{@var{n} - @var{k}} should be even. The error correcting capability of the Reed-Solomon code is then @code{(@var{n} - @var{k})/2} symbols. @var{m} is the number of bits per symbol, and is related to @var{n} by @code{@var{n} = 2^@var{m} - 1}. For a valid Reed-Solomon coder, @var{m} should be between 3 and 16. @node Creating and Decoding Messages, Shortened Reed-Solomon Codes, Representation of Reed-Solomon Messages, Reed-Solomon Codes @subsection Creating and Decoding Messages The Reed-Solomon encoding function requires at least three arguments. The first @var{msg} is the message in encodes, the second is @var{n} the codeword length and @var{k} is the message length. Therefore @var{msg} must have @var{k} columns and the output will have @var{n} columns of symbols. The message itself is many up of elements of a Galois Field GF(2^M). Normally, The order of the Galois Field (M), is related to the codeword length by @code{@var{n} = 2^@var{m} - 1}. Another important parameter when determining the behavior of the Reed-Solomon coder is the primitive polynomial of the Galois Field (see @code{gf}). Thus the messages @example octave:1> msg0 = gf ([0, 1, 2, 3], 3); octave:2> msg1 = gf ([0, 1, 2, 3], 3, 13); @end example @noindent will not result in the same Reed-Solomon coding. Finally, the parity of the Reed-Solomon code are generated with the use of a generator polynomial. The parity symbols are then generated by treating the message to encode as a polynomial and finding the remainder of the division of this polynomial by the generator polynomial. Therefore the generator polynomial must have as many roots as @code{@var{n} - @var{k}}. Whether the parity symbols are placed before or afterwards the message will then determine which end of the message is the most-significant term of the polynomial representing the message. The parity symbols are therefore different in these two cases. The position of the parity symbols can be chosen by specifying "beginning" or "end" to @code{rsenc} and @code{rsdec}. By default the parity symbols are placed after the message. Valid generator polynomials can be constructed with the @code{rsgenpoly} function. The roots of the generator polynomial are then defined by @tex $$ g = (x - A^{bs}) (x - A^{(b+1)s}) \cdots (x - A ^{(b+2t-1)s}). $$ @end tex @ifnottex @example @var{g} = (@var{x} - A^(@var{b}*@var{s})) * (@var{x} - A^((@var{b}+1)*@var{s})) * @dots{} * (@var{x} - A^((@var{b}+2*@var{t}-1)*@var{s})). @end example @end ifnottex @noindent where @var{t} is @code{(@var{n} - @var{k})/2}, A is the primitive element of the Galois Field, @var{b} is the first consecutive root, and @var{s} is the step between roots. Generator polynomial of this form are constructed by @code{rsgenpoly} and can be passed to both @code{rsenc} and @code{rsdec}. It is also possible to pass the @var{b} and @var{s} values directly to @code{rsenc} and @code{rsdec}. In the case of @code{rsdec} passing @var{b} and @var{s} can make the decoding faster. Consider the example below. @example octave:1> m = 8; octave:2> n = 2^m - 1; octave:3> k = 223; octave:4> prim = 391; octave:5> b = 112; octave:6> s = 11; octave:7> gg = rsgenpoly (n, k, prim, b, s); octave:8> msg = gf (floor (2^m * rand (17, k)), m, prim); octave:9> code = rsenc (msg, n, k, gg); octave:10> noisy = code + [toeplitz([ones(1,17)], zeros(1,17)), zeros(17,238)]; octave:11> [dec, nerr] = rsdec (msg, n, k, b, s); octave:12> nerr' ans = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -1 octave:13> any (msg' != dec') ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 @end example This is an interesting example in that it demonstrates many of the additional arguments of the Reed-Solomon functions. In particular this example approximates the CCSDS standard Reed-Solomon coder, lacking only the dual-basis lookup tables used in this standard. The CCSDS uses non-default values to all of the basic functions involved in the Reed-Solomon encoding, since it has a non-default primitive polynomial, generator polynomial, etc. The example creates 17 message blocks and adds between 1 and 17 error symbols to these block. As can be seen @var{nerr} gives the number of errors corrected. In the case of 17 introduced errors @var{nerr} equals -1, indicating a decoding failure. This is normal as the correction ability of this code is up to 16 error symbols. Comparing the input message and the decoding it can be seen that as expected, only the case of 17 errors has not been correctly decoded. @node Shortened Reed-Solomon Codes, , Creating and Decoding Messages, Reed-Solomon Codes @subsection Shortened Reed-Solomon Codes In general the codeword length of the Reed-Solomon coder is chosen so that it is related directly to the order of the Galois Field by the formula @code{@var{n} = 2^@var{m} - 1}. Although, the underlying Reed-Solomon coding must operate over valid codeword length, there are sometimes reasons to assume that the codeword length will be shorter. In this case the message is padded with zeros before coding, and the zeros are stripped from the returned block. For example consider the shortened [6,4] Reed-Solomon below @example octave:1> m = 3; octave:2> n = 6; octave:3> k = 4; octave:4> msg = gf (floor (2^m * rand (2, k)), m) msg = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 2 5 1 5 7 1 octave:5> code = rsenc (msg, n, k) code = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 2 5 2 3 1 5 7 1 0 2 @end example @node Convolutional Coding, Modulations, Block Coding, Top @chapter Convolutional Coding Some initial support for convolutional codes is provided by the functions described in this chapter. Convolutional codes are different from block codes in that the sequence of preceding symbols is taken into account when computing the output symbol of the coder. @menu * Trellis Structure:: * Convolutional Encoding:: @end menu @node Trellis Structure, Convolutional Encoding, , Convolutional Coding @section Trellis Structure Like block codes, convolutional codes can be described by a set of generator polynomials. Each polynomial describes the combination of current and previous input symbols used to compute one output bit of the encoder. The state transitions and outputs of a convolutional encoder can also be described by a trellis diagram. This diagram describes the transitions between states and the outputs of the encoder as a function of the current state and the current input symbol. A trellis structure can be created from a set of generator polynomials, specified as octal numbers by convention, @example octave:1> g0 = 13; octave:2> g1 = 17; octave:3> trellis = poly2trellis (4, [g0, g1]); @end example @noindent where @var{g0} and @var{g1} are the two polynomials of a rate 1/2 encoder with a constraint length of 4. The returned trellis structure contains the following fields @table @samp @item numInputSymbols The number of possible input symbols in the input sequence. @item numOutputSymbols The number of possible output symbols in the encoded sequence. @item numStates The number of possible states that the encoder can take. @item nextStates The state transition table for the encoder. Each row contains the (zero-based) indices of the states reachable from the state represented by that row for each possible input symbol. @item outputs The output table for the encoder. Each row contains the (octal-encoded) output symbols produced by the encoder in the state represented by that row for each possible input symbol. @end table To check if a variable references a structure that is a valid trellis describing a convolutional encoder, use the @code{istrellis} function. @node Convolutional Encoding, , Trellis Structure, Convolutional Coding @section Convolutional Encoding The convolutional encoding function takes the message to be encoded and a trellis describing the encoder. The message must be a binary vector containing an even number of symbols. For example, using the encoder from the previous section, @example octave:1> trellis = poly2trellis (4, [13, 17]); octave:2> msg = [1 1 0 1 1 0 0 0]; octave:3> out = convenc (msg, trellis) out = 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 @end example The initial state of the encoder can also be passed in to @code{convenc}, and the ending state can be read with an optional output argument. Encoding a different vector with a different initial state using the same encoder, @example octave:4> msg = [0 1 1 0 1 0 1 1]; octave:5> [out, state] = convenc (msg, trellis, [], 4) out = 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 state = 6 @end example @noindent returns both the encoded array and the final state of the convolutional encoder. This can be used to encode data in blocks, for example, saving and restoring the internal state of the encoder for each subsequent input block. @node Modulations, Special Filters, Convolutional Coding, Top @chapter Modulations To be written. Currently have functions amodce, ademodce, apkconst, demodmap, modmap, qaskdeco, qaskenco, genqammod, pamdemod, pammod, pskdemod and pskmod. @node Special Filters, Galois Fields, Modulations, Top @chapter Special Filters To be written. @node Galois Fields, Function Reference, Special Filters, Top @chapter Galois Fields @menu * Galois Field Basics:: * Manipulating Galois Fields:: @end menu @node Galois Field Basics, Manipulating Galois Fields, , Galois Fields @section Galois Field Basics A Galois Field is a finite algebraic field. This package implements a Galois Field type in Octave having 2^M members where M is an integer between 1 and 16. Such fields are denoted as GF(2^M) and are used in error correcting codes in communications systems. Galois Fields having odd numbers of elements are not implemented. The @emph{primitive element} of a Galois Field has the property that all elements of the Galois Field can be represented as a power of this element. The @emph{primitive polynomial} is the minimum polynomial of some primitive element in GF(2^M) and is irreducible and of order M. This means that the primitive element is a root of the primitive polynomial. The elements of the Galois Field GF(2^M) are represented as the values 0 to 2^M -1 by Octave. The first two elements represent the zero and unity values of the Galois Field and are unique in all fields. The element represented by 2 is the primitive element of the field and all elements can be represented as combinations of the primitive element and unity as follows @multitable @columnfractions .33 .33 .33 @item Integer @tab Binary @tab Element of GF(2^M) @item 0 @tab 000 @tab @code{0} @item 1 @tab 001 @tab @code{1} @item 2 @tab 010 @tab @code{A} @item 3 @tab 011 @tab @code{A + 1} @item 4 @tab 100 @tab @code{A^2} @item 5 @tab 101 @tab @code{A^2 + 1} @item 6 @tab 110 @tab @code{A^2 + A} @item 7 @tab 111 @tab @code{A^2 + A + 1} @end multitable It should be noted that there is often more than a single primitive polynomial of GF(2^M). Each Galois Field over a different primitive polynomial represents a different realization of the Field. The representations above however rest valid. @menu * Creating Galois Fields:: * Primitive Polynomials:: * Accessing Internal Fields:: * Function Overloading:: * Known Problems:: @end menu @node Creating Galois Fields, Primitive Polynomials, , Galois Field Basics @subsection Creating Galois Fields To work with a Galois Field GF(2^M) in Octave, you must first create a variable that Octave recognizes as a Galois Field. This is done with the function @code{gf (@var{a}, @var{m})} as follows. @example octave:1> a = [0:7]; octave:2> b = gf (a, 4) b = GF(2^4) array. Primitive Polynomial = D^4+D+1 (decimal 19) Array elements = 0 1 2 3 4 5 6 7 @end example This creates an array @var{b} with 8 elements that Octave recognizes as a Galois Field. The field is created with the default primitive polynomial for the field GF(2^4). It can be verified that a variable is in fact a Galois Field with the functions @code{isgalois} or @code{whos}. @example octave:3> isgalois (a) ans = 0 octave:4> isgalois (b) ans = 1 octave:5> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x8 24 double b 1x8 32 galois Total is 16 elements using 56 bytes @end example It is also possible to create a Galois Field with an arbitrary primitive polynomial. However, if the polynomial is not a primitive polynomial of the field, and error message is returned. For instance. @example octave:1> a = [0:7]; octave:2> b = gf (a, 4, 25) b = GF(2^4) array. Primitive Polynomial = D^4+D^3+1 (decimal 25) Array elements = 0 1 2 3 4 5 6 7 octave:3> c = gf (a, 4, 21) error: gf: primitive polynomial (21) of Galois Field must be irreducible @end example The function @code{gftable} is included for compatibility with @sc{matlab}. In @sc{matlab} this function is used to create the lookup tables used to accelerate the computations over the Galois Field and store them to a file. However Octave stores these parameters for all of the fields currently in use and so this function is not required, although it is silently accepted. @node Primitive Polynomials, Accessing Internal Fields, Creating Galois Fields, Galois Field Basics @subsection Primitive Polynomials The function @code{gf (@var{a}, @var{m})} creates a Galois Field using the default primitive polynomial. However there exists many possible primitive polynomials for most Galois Fields. Two functions exist for identifying primitive polynomials, @code{isprimitive} and @code{primpoly}. @code{primpoly (@var{m}, @var{opt})} is used to identify the primitive polynomials of the fields GF(2^M). For example @example octave:1> primpoly (4) Primitive polynomial(s) = D^4+D+1 ans = 19 @end example @noindent identifies the default primitive polynomials of the field GF(2^M), which is the same as @code{primpoly (4, "min")}. All of the primitive polynomials of a field can be identified with the function @code{primpoly (@var{m}, "all")}. For example @example octave:1> primpoly (4, "all") Primitive polynomial(s) = D^4+D+1 D^4+D^3+1 ans = 19 25 @end example @noindent while @code{primpoly (@var{m}, "max")} returns the maximum primitive polynomial of the field, which for the case above is 25. The function @code{primpoly} can also be used to identify the primitive polynomials having only a certain number of non-zero terms. For instance @example octave:1> primpoly (5, 3) Primitive polynomial(s) = D^5+D^2+1 D^5+D^3+1 ans = 37 41 @end example @noindent identifies the polynomials with only three terms that can be used as primitive polynomials of GF(2^5). If no primitive polynomials existing having the requested number of terms then @code{primpoly} returns an empty vector. That is @example octave:1> primpoly (5, 2) warning: primpoly: No primitive polynomial satisfies the given constraints ans = [](1x0) @end example As can be seen above, @code{primpoly} displays the polynomial forms the the polynomials that it finds. This output can be suppressed with the "nodisplay" option, while the returned value is left unchanged. @example octave:1> primpoly (4, "all", "nodisplay") ans = 19 25 @end example @code{isprimitive (@var{a})} identifies whether the elements of @var{a} can be used as primitive polynomials of the Galois Fields GF(2^M). Consider as an example the fields GF(2^4). The primitive polynomials of these fields must have an order m and so their integer representation must be between 16 and 31. Therefore @code{isprimitive} can be used in a similar manner to @code{primpoly} as follows @example octave:1> find (isprimitive (16:31)) + 15 ans = 19 25 @end example @noindent which finds all of the primitive polynomials of GF(2^4). @node Accessing Internal Fields, Function Overloading, Primitive Polynomials, Galois Field Basics @subsection Accessing Internal Fields Once a variable has been defined as a Galois Field, the parameters of the field of this structure can be obtained by adding a suffix to the variable. Valid suffixes are '.m', '.prim_poly' and '.x', which return the order of the Galois Field, its primitive polynomial and the data the variable contains respectively. For instance @example octave:1> a = [0:7]; octave:2> b = gf (a, 4); octave:3> b.m ans = 4 octave:4> b.prim_poly ans = 19 octave:5> c = b.x; octave:6> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x8 24 double b 1x8 32 galois c 1x8 64 double Total is 24 elements using 120 bytes @end example @c Note that if code compiled with GALOIS_DISP_PRIVATES then '.n', '.alpha_to' @c and '.index_of' are also available. These give 2^m-1, the lookup table @c and its inverse respectively. Please note that it is explicitly forbidden to modify the Galois field by accessing these variables. For instance @example octave:1> a = gf ([0:7], 3); octave:2> a.prim_poly = 13; @end example @noindent is explicitly forbidden. The result of this will be to replace the Galois array @var{a} with a structure @var{a} with a single element called '.prim_poly'. To modify the order or primitive polynomial of a field, a new field must be created and the data copied. That is @example octave:1> a = gf ([0:7], 3); octave:2> a = gf (a.x, a.m, 13); @end example @node Function Overloading, Known Problems, Accessing Internal Fields, Galois Field Basics @subsection Function Overloading An important consideration in the use of the Galois Field package is that many of the internal functions of Octave, such as @code{roots}, can not accept Galois Fields as an input. This package therefore uses Octave classes to @emph{overload} the internal Octave functions with equivalent functions that work with Galois Fields, so that the standard function names can be used. The version of the function that is chosen is determined by the first argument of the function. This is a temporary situation until the Galois Field class constructor can be rewritten to allow the use of the @code{superiorto} function to define the galois class with a higher precedence. So, considering the @code{filter} function, if the first argument is a @emph{Matrix}, then the normal version of the function is called regardless of whether the other arguments of the function are Galois vectors or not. Other Octave functions work correctly with Galois Fields and so overloaded versions are not necessary. This include such functions as @code{size} and @code{polyval}. It is also useful to use the '.x' option discussed in the previous section, to extract the raw data of the Galois field for use with some functions. An example is @example octave:1> a = minpol (gf (14, 5)); octave:2> b = de2bi (a.x, [], "left-msb"); @end example @noindent converts the polynomial form of the minimum polynomial of 14 in GF(2^5) into an integer. Finally help for the Galois specific versions of the functions must explicitly call the correct function as @example octave:1> help @@galois/conv @end example @node Known Problems, , Function Overloading, Galois Field Basics @subsection Known Problems Please review the following list of known problems with the Galois type before reporting a bug against this package. @table @asis @item Saving and loading Galois variables Saving a Galois variable to a file is as simple as @example octave:1> a = gf (@dots{}); octave:2> save a.mat a @end example @noindent where @var{a} is any Galois variable. Galois variables can be saved in the Octave binary and ASCII formats, as well as the HDF5 format. To load a Galois variable from a file, the Galois type must already be registered to the Octave interpreter prior to the call to @code{load}. If no Galois variables have been created yet, you will have to do something like @example octave:1> dummy = gf (1); octave:2> load a.mat @end example @item Logarithm of zero does not return NaN The logarithm of zero in a Galois field is not defined. However, to avoid segmentation faults in later calculations the logarithm of zero is defined as @code{2^@var{m} - 1}, whose value is not the logarithm of any other value in the Galois field. A warning is also shown to tell the user about the problem. For example @example octave:1> m = 3; octave:2> a = log (gf ([0:2^m-1], m)) warning: log of zero undefined in Galois field a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 1 3 2 6 4 5 @end example To fix this problem would require a major rewrite of all code, adding an exception for the case of NaN to all basic operators. These exceptions will certainly slow the code down. @item Speed The code was written piecemeal with no attention to optimization. Some operations may be slower than they could be. Contributions are welcome. @end table @node Manipulating Galois Fields, , Galois Field Basics, Galois Fields @section Manipulating Galois Fields @menu * Expressions manipulation and assignment:: * Unary operations:: * Arithmetic operations:: * Comparison operations:: * Polynomial manipulations:: * Linear Algebra:: * Signal Processing:: @end menu @node Expressions manipulation and assignment, Unary operations, , Manipulating Galois Fields @subsection Expressions, manipulation and assignment Galois variables can be treated in similar manner to other variables within Octave. For instance Galois fields can be accessed using index expressions in a similar manner to all other Octave matrices. For example @example octave:1> a = gf ([[0:7]; [7:-1:0]], 3) a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0 octave:2> b = a(1,:) b = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 1 2 3 4 5 6 7 @end example Galois arrays can equally use indexed assignments. That is, the data in the array can be partially replaced, on the condition that the two fields are identical. An example is @example octave:1> a = gf (ones (2, 8), 3); octave:2> b = gf (zeros (1, 8), 3); octave:3> a(1,:) = b a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 @end example Implicit conversions between normal matrices and Galois arrays are possible. For instance data can be directly copied from a Galois array to a real matrix as follows. @example octave:1> a = gf (ones (2, 8), 3); octave:2> b = zeros (2, 8); octave:3> b(2,:) = a(2,:) b = 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 @end example The inverse is equally possible, with the proviso that the data in the matrix is valid in the Galois field. For instance @example octave:1> a = gf ([0:7], 3); octave:2> a(1) = 1; @end example @noindent is valid, while @example octave:1> a = gf ([0:7], 3); octave:2> a(1) = 8; @end example @noindent is not, since 8 is not an element of GF(2^3). This is a basic rule of manipulating Galois arrays. That is matrices and scalars can be used in conjunction with a Galois array as long as they contain valid data within the Galois field. In this case they will be assumed to be of the same field. Galois arrays can also be concatenated with real matrices or with other Galois arrays in the same field. For example @example octave:1> a = [gf([0:7], 3); gf([7:-1:0], 3)]; octave:2> b = [a, a]; octave:3> c = [a, eye(2)]; octave:3> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 2x8 64 galois b 2x16 128 galois c 2x10 80 galois Total is 68 elements using 272 bytes @end example Other basic manipulations of Galois arrays are @table @code @item isempty Returns true if the Galois array is empty. @item size Returns the number of rows and columns in the Galois array. @item length Returns the length of a Galois vector, or the maximum of rows or columns of Galois arrays. @item find Find the indexes of the non-zero elements of a Galois array. @item diag Create a diagonal Galois array from a Galois vector, or extract a diagonal from a Galois array. @item reshape Change the shape of the Galois array. @end table @node Unary operations, Arithmetic operations, Expressions manipulation and assignment, Manipulating Galois Fields @subsection Unary operations The same unary operators that are available for normal Octave matrices are also available for Galois arrays. These operations are @table @code @item +@var{x} Unary plus. This operator has no effect on the operand. @item -@var{x} Unary minus. Note that in a Galois Field this operator also has no effect on the operand. @item !@var{x} Returns true for zero elements of Galois Array. @item @var{x}' Complex conjugate transpose. As the Galois Field only contains integer values, this is equivalent to the transpose operator. @item @var{x}.' Transpose of the Galois array. @end table @node Arithmetic operations, Comparison operations, Unary operations, Manipulating Galois Fields @subsection Arithmetic operations The available arithmetic operations on Galois arrays are the same as on other Octave matrices. It should be noted that both operands must be in the same Galois Field. If one operand is a Galois array and the second is a matrix or scalar, then the second operand is silently converted to the same Galois Field. The element(s) of these matrix or scalar must however be valid members of the Galois field. Thus @example octave:1> a = gf ([0:7], 3); octave:2> b = a + [0:7]; @end example @noindent is valid, while @example octave:1> a = gf ([0:7], 3); octave:2> b = a + [1:8]; @end example @noindent is not, since 8 is not a valid element of GF(2^3). The available arithmetic operators are @table @code @item @var{x} + @var{y} Addition. If both operands are Galois arrays or matrices, the number of rows and columns must both agree. If one operand is a is a Galois array with a single element or a scalar, its value is added to all the elements of the other operand. The @code{+} operator on a Galois Field is equivalent to an exclusive-or on normal integers. @item @var{x} .+ @var{y} Element by element addition. This operator is equivalent to @code{+}. @item @var{x} - @var{y} As both @code{+} and @code{-} in a Galois Field are equivalent to an exclusive-or for normal integers, @code{-} is equivalent to the @code{+} operator @item @var{x} .- @var{y} Element by element subtraction. This operator is equivalent to @code{-}. @item @var{x} * @var{y} Matrix multiplication. The number of columns of @var{x} must agree with the number of rows of @var{y}. @item @var{x} .* @var{y} Element by element multiplication. If both operands are matrices, the number of rows and columns must both agree. @item @var{x} / @var{y} Right division. This is conceptually equivalent to the expression @example (inverse (y') * x')' @end example @noindent but it is computed without forming the inverse of @var{y'}. If the matrix is singular then an error occurs. If the matrix is under-determined, then a particular solution is found (but not minimum norm). If the solution is over-determined, then an attempt is made to find a solution, but this is not guaranteed to work. @item @var{x} ./ @var{y} Element by element right division. @item @var{x} \ @var{y} Left division. This is conceptually equivalent to the expression @example inverse (x) * y @end example @noindent but it is computed without forming the inverse of @var{x}. If the matrix is singular then an error occurs. If the matrix is under-determined, then a particular solution is found (but not minimum norm). If the solution is over-determined, then an attempt is made to find a solution, but this is not guaranteed to work. @item @var{x} .\ @var{y} Element by element left division. Each element of @var{y} is divided by each corresponding element of @var{x}. @item @var{x} ^ @var{y} @itemx @var{x} ** @var{y} Power operator. If @var{x} and @var{y} are both scalars, this operator returns @var{x} raised to the power @var{y}. Otherwise @var{x} must be a square matrix raised to an integer power. @item @var{x} .^ @var{y} @item @var{x} .** @var{y} Element by element power operator. If both operands are matrices, the number of rows and columns must both agree. @end table @node Comparison operations, Polynomial manipulations, Arithmetic operations, Manipulating Galois Fields @subsection Comparison operations Galois variables can be tested for equality in the usual manner. That is @example octave:1> a = gf ([0:7], 3); octave:2> a == ones (1, 8) ans = 0 1 0 0 0 0 0 0 octave:3> a != zeros (1, 8) ans = 0 1 1 1 1 1 1 1 @end example Likewise, Galois vectors can be tested against scalar values (whether they are Galois or not). For instance @example octave:4> a == 1 ans = 0 1 0 0 0 0 0 0 @end example To test if any or all of the values in a Galois array are non-zero, the functions @code{any} and @code{all} can be used as normally. In addition the comparison operators @code{>}, @code{>=}, @code{<} and @code{<=} are available. As elements of the Galois Field are modulus 2^@var{m}, all elements of the field are both greater than and less than all others at the same time. Thus these comparison operators don't make that much sense and are only included for completeness. The comparison is done relative to the integer value of the Galois Field elements. @node Polynomial manipulations, Linear Algebra, Comparison operations, Manipulating Galois Fields @subsection Polynomial manipulations A polynomial in GF(2^M) can be expressed as a vector in GF(2^M). For instance if @var{a} is the @emph{primitive element}, then the example @example octave:1> poly = gf ([2, 4, 5, 1], 3); @end example @noindent represents the polynomial @tex $$ poly = a x^3 + a^2 x^2 + (a^2 + 1) x + 1 $$ @end tex @ifnottex @example poly = @var{a} * x^3 + @var{a}^2 * x^2 + (@var{a}^2 + 1) * x + 1 @end example @end ifnottex Arithmetic can then be performed on these vectors. For instance to add to polynomials an example is @example octave:1> poly1 = gf ([2, 4, 5, 1], 3); octave:2> poly2 = gf ([1, 2], 3); octave:3> sumpoly = poly1 + [0, 0, poly2] sumpoly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 4 3 @end example Note that @var{poly2} must be zero padded to the same length as poly1 to allow the addition to take place. Multiplication and division of Galois polynomials is equivalent to convolution and de-convolution of vectors of Galois elements. Thus to multiply two polynomials in GF(2^3). @example octave:4> mulpoly = conv (poly1, poly2) mulpoly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 0 6 0 2 @end example Likewise the division of two polynomials uses the de-convolution function as follows @example octave:5> [poly, remd] = deconv (mulpoly, poly2) poly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 5 1 remd = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 0 0 @end example Note that the remainder of this division is zero, as we performed the inverse operation to the multiplication. To evaluate a polynomial for a certain value in GF(2^M), use the Octave function @code{polyval}. @example octave:1> poly1 = gf ([2, 4, 5, 1], 3); ## a*x^3+a^2*x^2+(a^2+1)*x+1 octave:2> x0 = gf ([0, 1, 2], 3); octave:3> y0 = polyval (poly1, x0); y0 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 2 0 octave:4> a = gf (2, 3); ## The primitive element octave:5> y1 = a .* x0.^3 + a.^2 .* x0.^2 + (a.^2 + 1) .* x0 + 1 y1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 2 0 @end example It is equally possible to find the roots of Galois polynomials with the @code{roots} function. Using the polynomial above over GF(2^3), we can find its roots in the following manner @example octave:1> poly1 = gf ([2, 4, 5, 1], 3); octave:2> root1 = roots (poly1) root1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 5 5 @end example Thus the example polynomial has 3 roots in GF(2^3) with one root of multiplicity 2. We can check this answer with the @code{polyval} function as follows @example octave:3> check1 = polyval (poly1, root1) check1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 @end example @noindent which as expected gives a zero vector. It should be noted that both the number of roots and their value, will depend on the chosen field. Thus for instance @example octave:1> poly3 = gf ([2, 4, 5, 1], 3, 13); octave:2> root3 = roots (poly3) root3 = GF(2^3) array. Primitive Polynomial = D^3+D^2+1 (decimal 13) Array elements = 5 @end example @noindent shows that in the field GF(2^3) with a different primitive polynomial, has only one root exists. The minimum polynomial of an element of GF(2^M) is the minimum degree polynomial in GF(2), excluding the trivial zero polynomial, that has that element as a root. The fact that the minimum polynomial is in GF(2) means that its coefficients are one or zero only. The @code{minpol} function can be used to find the minimum polynomial as follows @example octave:1> a = gf (2, 3); ## The primitive element octave:2> b = minpol (a) b = GF(2) array. Array elements = 1 0 1 1 @end example Note that the minimum polynomial of the primitive element is the primitive polynomial. Elements of GF(2^M) sharing the same minimum polynomial form a partitioning of the field. This partitioning can be found with the @code{cosets} function as follows @example octave:1> c = cosets (3) c = @{ [1,1] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 [1,2] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 6 [1,3] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 3 5 7 @} @end example @noindent which returns a cell array containing all of the elements of the GF(2^3), partitioned into groups sharing the same minimum polynomial. The function @code{cosets} can equally accept a second argument defining the primitive polynomial to use in its calculations (i.e. @code{cosets (@var{a}, @var{p})}). @node Linear Algebra, Signal Processing, Polynomial manipulations, Manipulating Galois Fields @subsection Linear Algebra The basic linear algebra operation of this package is the LU factorization of a Galois array. That is the Galois array @var{a} is factorized in the following way @example octave:2> [l, u, p] = lu (a) @end example @noindent such that @code{@var{p} * @var{a} = @var{l} * @var{u}}. The matrix @var{p} contains row permutations of @var{a}, such that @var{l} and @var{u} are strictly upper and low triangular. The Galois array @var{a} can be rectangular. All other linear algebra operations within this package are based on this LU factorization of a Galois array. An important consequence of this is that no solution can be found for singular matrices, only a particular solution will be found for under-determined systems of equation and the solution found for over-determined systems is not always correct. This is identical to the way @sc{matlab} performs linear algebra on Galois arrays. For instance consider the under-determined linear equation @example octave:1> A = gf ([2, 0, 3, 3; 3, 1, 3, 1; 3, 1, 1, 0], 2); octave:2> b = [0:2]'; octave:3> x = A \ b; @end example @noindent gives the solution @code{@var{x} = [2, 0, 3, 2]}. There are in fact 4 possible solutions to this linear system; @code{@var{x} = [3, 2, 2, 0]}, @code{@var{x} = [0, 3, 1, 1]}, @code{@var{x} = [2, 0, 3, 2]} and @code{@var{x} = [1, 1, 0, 3]}. No particular selection criteria are applied to the chosen solution. In addition, because singular matrices cannot be solved, unless you know the matrix is not singular, you should test the determinant of the matrix prior to solving the linear system. For instance @example octave:1> A = gf (floor (2^m * rand (3)), 2); octave:2> b = [0:2]'; octave:3> if (det (A) != 0); x = A \ b; y = b' / A; endif; octave:4> r = rank (A); @end example @noindent solves the linear systems @code{@var{A} * @var{x} = @var{b}} and @code{@var{y} * @var{A} = @var{b}}. Note that you do not need to take into account rounding errors in the determinant, as the determinant can only take values within the Galois Field. So if the determinant equals zero, the array is singular. @node Signal Processing, , Linear Algebra, Manipulating Galois Fields @subsection Signal Processing with Galois Fields Signal processing functions such as filtering, convolution, de-convolution and Fourier transforms can be performed over Galois Fields. For instance the @code{filter} function can be used with Galois vectors in the same manner as usual. For instance @example octave:1> b = gf ([2, 0, 0, 1, 0, 2, 0, 1], 2); octave:2> a = gf ([2, 0, 1, 1], 2); octave:3> x = gf ([1, zeros(1, 20)], 2); octave:4> y = filter (b, a, x) y = GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7) Array elements = 1 0 3 0 2 3 1 0 1 3 3 1 0 1 3 3 1 0 1 3 3 @end example @noindent gives the impulse response of the filter defined by @var{a} and @var{b}. Two equivalent ways are given to perform the convolution of two Galois vectors. Firstly the function @code{conv} can be used, or alternatively the function @code{convmtx} can be used. The first of these function is identical to the convolution function over real vectors, and has been described in the section about multiplying two Galois polynomials. In the case where many Galois vectors will be convolved with the same vector, the second function @code{convmtx} offers an alternative method to calculate the convolution. If @var{a} is a column vector and @var{x} is a column vector of length @var{n}, then @example octave:1> m = 3; octave:2> a = gf (floor (2^m * rand (4, 1)), m); octave:3> b = gf (floor (2^m * rand (4, 1)), m); octave:4> c0 = conv (a, b)'; octave:5> c1 = convmtx (a, length (b)) * b; octave:6> check = all (c0 == c1) check = 1 @end example @noindent shows the equivalence of the two functions. The de-convolution function has been previously described above. The final signal processing function available in this package are the functions to perform Fourier transforms over a Galois field. Three functions are available, @code{fft}, @code{ifft} and @code{dftmtx}. The first two functions use the third to perform their work. Given an element @var{a} of the Galois field GF(2^M), @code{dftmtx} returns the @code{2^M - 1} square matrix used in the Fourier transforms with respect to @var{a}. The minimum polynomial of @var{a} must be primitive in GF(2^M). In the case of the @code{fft} function @code{dftmtx} is called with the primitive element of the Galois Field as an argument. As an example @example octave:1> m = 4; octave:2> n = 2^m - 1; octave:2> alph = gf (2, m); octave:3> x = gf (floor (2^m * rand (n, 1)), m); octave:4> y0 = fft (x); octave:5> y1 = dftmtx (alph) * x; octave:6> z0 = ifft (y0); octave:7> z1 = dftmtx (1/alph) * y1; octave:8> check = all (y0 == y1) & all (z0 == x) & all (z1 == x) check = 1 @end example In all cases, the length of the vector to be transformed must be @code{2^M -1}. As the @code{dftmtx} creates a matrix representing the Fourier transform, to limit the computational task only Fourier transforms in GF(2^M), where M is less than or equal to 8, are supported. @node Function Reference, , Galois Fields, Top @chapter Function Reference @iftex @section Functions by Category @subsection Random Signals @table @asis @item awgn Add white Gaussian noise to a voltage signal @item biterr Compares two matrices and returns the number of bit errors and the bit error rate. @item eyediagram Plot the eye-diagram of a signal. @item randerr Generate a matrix of random bit errors. @item randint Generate a matrix of random binary numbers. @item randsrc Generate a matrix of random symbols. @item scatterplot Display the scatter plot of a signal. @item symerr Compares two matrices and returns the number of symbol errors and the symbol error rate. @item wgn Returns a M-by-N matrix Y of white Gaussian noise. @item bsc Send DATA into a binary symmetric channel with probability P of @end table @subsection Source Coding @table @asis @item arithenco @emph{Not implemented} @item arithdeco @emph{Not implemented} @item compand Compresses and expanding the dynamic range of a signal using a @item dpcmdeco Decode using differential pulse code modulation (DPCM) @item dpcmenco PREDICTOR) @item dpcmopt (TRAINING_SET, ORD, CB) @item huffmandeco Decode signal encoded by 'huffmanenco' @item huffmandict Builds a Huffman code, given a probability list. @item huffmanenco Returns the Huffman encoded signal using DICT. @item lloyds Optimize the quantization table and codes to reduce distortion. @item lz77deco Lempel-Ziv 77 source algorithm decoding implementation. @item lz77enco Lempel-Ziv 77 source algorithm implementation. @item quantiz Quantization of an arbitrary signal relative to a partitioning @item shannonfanodict Returns the code dictionary for source using Shannon-Fano algorithm @item shannonfanoenco Returns the Shannon-Fano encoded signal using DICT This function @item shannonfanodeco Returns the original signal that was Shannon-Fano encoded. @item rleenco Returns run-length encoded MESSAGE. @item rledeco Returns decoded run-length MESSAGE. @item riceenco Returns the Rice encoded signal using K or optimal K Default optimal K is chosen between 0-7. @item ricedeco Returns the Rice decoded signal vector using CODE and K Compulsory @item fiboenco Returns the cell-array of encoded Fibonacci value from the column @item fibodeco Returns the decoded Fibonacci value from the binary vectors CODE @item fibosplitstream Returns the split data stream at the word boundaries Assuming the @item golombenco Returns the Golomb coded signal as cell array Also total length of @item golombdeco Returns the Golomb decoded signal vector using CODE and M Compulsory m is need to be specified. @end table @subsection Block Interleavers @table @asis @item intrlv Interleaved elements of DATA according to ELEMENTS See also: @item algintrlv @emph{Not implemented} @item helscanintrlv NROWS-by-NCOLS See also: helscandeintrlv @item matintrlv Interleaved elements of DATA with a temporary matrix of size @item randintrlv Interleaves elements of DATA with a random permutation See also: @item deintrlv Restore elements of DATA according to ELEMENTS See also: intrlv @item matdeintrlv Restore elements of DATA with a temporary matrix of size @item randdeintrlv Restore elements of DATA with a random permutation See also: @end table @subsection Block Coding @table @asis @item bchdeco Decodes the coded message CODE using a BCH coder. @item bchenco Encodes the message MSG using a [N,K] BCH coding. @item bchpoly Calculates the generator polynomials for a BCH coder. @item convenc Encode the binary vector MSG with the convolutional encoder @item cyclgen Produce the parity check and generator matrix of a cyclic code. @item cyclpoly This function returns the cyclic generator polynomials of the code [N,K]. @item decode Top level block decoder. @item encode Top level block encoder. @item egolaydec Decode Extended Golay code @item egolayenc Encode with Extended Golay code @item egolaygen Extended Golay code generator matrix @item gen2par Converts binary generator matrix GEN to the parity check matrix PAR and visa-versa. @item hammgen Produce the parity check and generator matrices of a Hamming code. @item reedmullerdec Decode the received code word VV using the RM-generator matrix G, of order R, M, returning the code-word C. @item reedmullerenc Definition type construction of Reed-Muller code, of order R, length 2^M. @item reedmullergen Definition type construction of Reed-Muller code, of order R, length 2^M. @item rsgenpoly Creates a generator polynomial for a Reed-Solomon coding with message length of K and codelength of N. @item rsdec Decodes the message contained in CODE using a [N,K] Reed-Solomon code. @item rsdecof Decodes an ASCII file using a Reed-Solomon coder. @item rsenc Encodes the message MSG using a [N,K] Reed-Solomon coding. @item rsencof Encodes an ASCII file using a Reed-Solomon coder. @item systematize Given G, extract P parity check matrix. @item syndtable Create the syndrome decoding table from the parity check matrix H. @item vitdec @emph{Not implemented} @end table @subsection Modulations @table @asis @item ademod @emph{Not implemented} @item ademodce Baseband demodulator for analog signals. @item amod @emph{Not implemented} @item amodce Baseband modulator for analog signals. @item ammod Create the AM modulation of the signal x with carrier frequency fs. @item amdemod Compute the amplitude demodulation of the signal S with a carrier @item apkconst Plots a ASK/PSK signal constellation. @item ddemod @emph{Not implemented} @item ddemodce @emph{Not implemented} @item demodmap Demapping of an analog signal to a digital signal. @item dmod @emph{Not implemented} @item dmodce @emph{Not implemented} @item fmmod Create the FM modulation of the signal x with carrier frequency fs. @item fmdemod Create the FM demodulation of the signal x with carrier frequency @item genqammod Modulates an information sequence of integers X in the range '[0 @item genqamdemod General quadrature amplitude demodulation. @item modmap Mapping of a digital signal to an analog signal. @item pamdemod Demodulates a pulse amplitude modulated signal X into an @item pammod Modulates an information sequence of integers X in the range '[0 @item pskdemod Demodulates a complex-baseband phase shift keying modulated signal @item pskmod Modulates an information sequence of integers X in the range '[0 @item qaskdeco Demaps an analog signal using a square QASK constellation. @item qaskenco Map a digital signal using a square QASK constellation. @item qammod Create the QAM modulation of x with a size of alphabet m See also: @item qamdemod Create the QAM demodulation of x with a size of alphabet m See @end table @subsection Special Filters @table @asis @item hank2sys @emph{Not implemented} @item hilbiir @emph{Not implemented} @item rcosflt @emph{Not implemented} @item rcosiir @emph{Not implemented} @item rcosine @emph{Not implemented} @item rcosfir @emph{Not implemented} @end table @subsection Galois Fields of Even Characteristic @table @asis @item + - Addition and subtraction in a Galois Field. @item * / \ Matrix multiplication and division of Galois arrays. @item .* ./ .\ Element by element multiplication and division of Galois arrays. @item ** ^ Matrix exponentiation of Galois arrays. @item .** .^ Element by element matrix exponentiation of Galois arrays. @item ' .' Matrix transpose of Galois arrays. @item == ~= != > >= < <= Logical operators on Galois arrays. @item all @emph{Not implemented} @item any @emph{Not implemented} @item cosets Finds the elements of GF(2^M) with primitive polynomial PRIM, that share the same minimum polynomial. @item conv Convolve two Galois vectors @item convmtx Create matrix to perform repeated convolutions with the same vector in a Galois Field. @item deconv Deconvolve two Galois vectors @item det Compute the determinant of the Galois array A @item dftmtx Form a matrix, that can be used to perform Fourier transforms in a @item diag Return a diagonal matrix with Galois vector V on diagonal K The second argument is optional. @item exp Compute the anti-logarithm for each element of X for a Galois array @item gf Creates a Galois field array GF(2^M) from the matrix X. @item fft If X is a column vector, finds the FFT over the primitive element of the Galois Field of X. @item filter Digital filtering of vectors in a Galois Field. @item gftable This function exists for compatibility with matlab. @item gfweight Calculate the minimum weight or distance of a linear block code. @item ifft If X is a column vector, finds the IFFT over the primitive element of the Galois Field of X. @item inv Compute the inverse of the square matrix A. @item inverse See inv @item isequal Return true if all of X1, X2, ... are equal See also: @item log Compute the natural logarithm for each element of X for a Galois @item lu Compute the LU decomposition of A in a Galois Field. @item prod Product of elements along dimension DIM of Galois array. @item sqrt Compute the square root of X, element by element, in a Galois Field @item rank Compute the rank of the Galois array A by counting the independent @item reshape Return a matrix with M rows and N columns whose elements are taken from the Galois array A. @item roots For a vector V with N components, return the roots of the @item sum Sum of elements along dimension DIM of Galois array. @item sumsq Sum of squares of elements along dimension DIM of Galois array If @item isempty @emph{Not implemented} @item isgalois Return 1 if the value of the expression EXPR is a Galois Field. @item isprimitive Returns 1 is the polynomial represented by A is a primitive polynomial of GF(2). @item length @emph{Not implemented} @item minpol Finds the minimum polynomial for elements of a Galois Field. @item polyval @emph{Not implemented} @item primpoly Finds the primitive polynomials in GF(2^M). @item size @emph{Not implemented} @end table @subsection Galois Fields of Odd Characteristic @table @asis @item gfadd @emph{Not implemented} @item gfconv @emph{Not implemented} @item gfcosets @emph{Not implemented} @item gfdeconv @emph{Not implemented} @item gfdiv @emph{Not implemented} @item gffilter @emph{Not implemented} @item gflineq @emph{Not implemented} @item gfminpol @emph{Not implemented} @item gfmul @emph{Not implemented} @item gfpretty @emph{Not implemented} @item gfprimck @emph{Not implemented} @item gfprimdf @emph{Not implemented} @item gfprimfd @emph{Not implemented} @item gfrank @emph{Not implemented} @item gfrepcov @emph{Not implemented} @item gfroots @emph{Not implemented} @item gfsub @emph{Not implemented} @item gftrunc @emph{Not implemented} @item gftuple @emph{Not implemented} @end table @subsection Utility Functions @table @asis @item comms Manual and test code for the Octave Communications toolbox. @item bi2de Convert bit matrix to a vector of integers @item de2bi Convert a non-negative integer to bit vector @item oct2dec Convert octal to decimal values @item istrellis Return true if T is a valid trellis structure @item poly2trellis Convert convolutional code generator polynomials into trellis form @item vec2mat Converts the vector V into a C column matrix with row priority @item qfunc Compute the Q function See also: erfc, erf @item qfuncinv Compute the inverse Q function See also: erfc, erf @end table @end iftex @section Functions Alphabetically @menu * ademodce:: Baseband demodulator for analog signals. * amdemod:: Compute the amplitude demodulation of the signal S with a carrier * ammod:: Create the AM modulation of the signal x with carrier frequency fs. * amodce:: Baseband modulator for analog signals. * apkconst:: Plots a ASK/PSK signal constellation. * awgn:: Add white Gaussian noise to a voltage signal * bchdeco:: Decodes the coded message CODE using a BCH coder. * bchenco:: Encodes the message MSG using a [N,K] BCH coding. * bchpoly:: Calculates the generator polynomials for a BCH coder. * bi2de:: Convert bit matrix to a vector of integers * biterr:: Compares two matrices and returns the number of bit errors and the bit error rate. * bsc:: Send DATA into a binary symmetric channel with probability P of * comms:: Manual and test code for the Octave Communications toolbox. * compand:: Compresses and expanding the dynamic range of a signal using a * conv:: Convolve two Galois vectors * convenc:: Encode the binary vector MSG with the convolutional encoder * convmtx:: Create matrix to perform repeated convolutions with the same vector in a Galois Field. * cosets:: Finds the elements of GF(2^M) with primitive polynomial PRIM, that share the same minimum polynomial. * cyclgen:: Produce the parity check and generator matrix of a cyclic code. * cyclpoly:: This function returns the cyclic generator polynomials of the code [N,K]. * de2bi:: Convert a non-negative integer to bit vector * decode:: Top level block decoder. * deconv:: Deconvolve two Galois vectors * deintrlv:: Restore elements of DATA according to ELEMENTS See also: intrlv * demodmap:: Demapping of an analog signal to a digital signal. * det:: Compute the determinant of the Galois array A * dftmtx:: Form a matrix, that can be used to perform Fourier transforms in a * diag:: Return a diagonal matrix with Galois vector V on diagonal K The second argument is optional. * dpcmdeco:: Decode using differential pulse code modulation (DPCM) * dpcmenco:: PREDICTOR) * dpcmopt:: (TRAINING_SET, ORD, CB) * egolaydec:: Decode Extended Golay code * egolayenc:: Encode with Extended Golay code * egolaygen:: Extended Golay code generator matrix * encode:: Top level block encoder. * exp:: Compute the anti-logarithm for each element of X for a Galois array * eyediagram:: Plot the eye-diagram of a signal. * fft:: If X is a column vector, finds the FFT over the primitive element of the Galois Field of X. * fibodeco:: Returns the decoded Fibonacci value from the binary vectors CODE * fiboenco:: Returns the cell-array of encoded Fibonacci value from the column * fibosplitstream:: Returns the split data stream at the word boundaries Assuming the * filter:: Digital filtering of vectors in a Galois Field. * fmdemod:: Create the FM demodulation of the signal x with carrier frequency * fmmod:: Create the FM modulation of the signal x with carrier frequency fs. * gen2par:: Converts binary generator matrix GEN to the parity check matrix PAR and visa-versa. * genqamdemod:: General quadrature amplitude demodulation. * genqammod:: Modulates an information sequence of integers X in the range '[0 * gf:: Creates a Galois field array GF(2^M) from the matrix X. * gftable:: This function exists for compatibility with matlab. * gfweight:: Calculate the minimum weight or distance of a linear block code. * golombdeco:: Returns the Golomb decoded signal vector using CODE and M Compulsory m is need to be specified. * golombenco:: Returns the Golomb coded signal as cell array Also total length of * hammgen:: Produce the parity check and generator matrices of a Hamming code. * helscanintrlv:: NROWS-by-NCOLS See also: helscandeintrlv * huffmandeco:: Decode signal encoded by 'huffmanenco' * huffmandict:: Builds a Huffman code, given a probability list. * huffmanenco:: Returns the Huffman encoded signal using DICT. * ifft:: If X is a column vector, finds the IFFT over the primitive element of the Galois Field of X. * intrlv:: Interleaved elements of DATA according to ELEMENTS See also: * inv:: Compute the inverse of the square matrix A. * inverse:: See inv * isequal:: Return true if all of X1, X2, ... are equal See also: * isgalois:: Return 1 if the value of the expression EXPR is a Galois Field. * isprimitive:: Returns 1 is the polynomial represented by A is a primitive polynomial of GF(2). * istrellis:: Return true if T is a valid trellis structure * lloyds:: Optimize the quantization table and codes to reduce distortion. * log:: Compute the natural logarithm for each element of X for a Galois * lu:: Compute the LU decomposition of A in a Galois Field. * lz77deco:: Lempel-Ziv 77 source algorithm decoding implementation. * lz77enco:: Lempel-Ziv 77 source algorithm implementation. * matdeintrlv:: Restore elements of DATA with a temporary matrix of size * matintrlv:: Interleaved elements of DATA with a temporary matrix of size * minpol:: Finds the minimum polynomial for elements of a Galois Field. * modmap:: Mapping of a digital signal to an analog signal. * oct2dec:: Convert octal to decimal values * pamdemod:: Demodulates a pulse amplitude modulated signal X into an * pammod:: Modulates an information sequence of integers X in the range '[0 * poly2trellis:: Convert convolutional code generator polynomials into trellis form * primpoly:: Finds the primitive polynomials in GF(2^M). * prod:: Product of elements along dimension DIM of Galois array. * pskdemod:: Demodulates a complex-baseband phase shift keying modulated signal * pskmod:: Modulates an information sequence of integers X in the range '[0 * qamdemod:: Create the QAM demodulation of x with a size of alphabet m See * qammod:: Create the QAM modulation of x with a size of alphabet m See also: * qaskdeco:: Demaps an analog signal using a square QASK constellation. * qaskenco:: Map a digital signal using a square QASK constellation. * qfunc:: Compute the Q function See also: erfc, erf * qfuncinv:: Compute the inverse Q function See also: erfc, erf * quantiz:: Quantization of an arbitrary signal relative to a partitioning * randdeintrlv:: Restore elements of DATA with a random permutation See also: * randerr:: Generate a matrix of random bit errors. * randint:: Generate a matrix of random binary numbers. * randintrlv:: Interleaves elements of DATA with a random permutation See also: * randsrc:: Generate a matrix of random symbols. * rank:: Compute the rank of the Galois array A by counting the independent * reedmullerdec:: Decode the received code word VV using the RM-generator matrix G, of order R, M, returning the code-word C. * reedmullerenc:: Definition type construction of Reed-Muller code, of order R, length 2^M. * reedmullergen:: Definition type construction of Reed-Muller code, of order R, length 2^M. * reshape:: Return a matrix with M rows and N columns whose elements are taken from the Galois array A. * ricedeco:: Returns the Rice decoded signal vector using CODE and K Compulsory * riceenco:: Returns the Rice encoded signal using K or optimal K Default optimal K is chosen between 0-7. * rledeco:: Returns decoded run-length MESSAGE. * rleenco:: Returns run-length encoded MESSAGE. * roots:: For a vector V with N components, return the roots of the * rsdec:: Decodes the message contained in CODE using a [N,K] Reed-Solomon code. * rsdecof:: Decodes an ASCII file using a Reed-Solomon coder. * rsenc:: Encodes the message MSG using a [N,K] Reed-Solomon coding. * rsencof:: Encodes an ASCII file using a Reed-Solomon coder. * rsgenpoly:: Creates a generator polynomial for a Reed-Solomon coding with message length of K and codelength of N. * scatterplot:: Display the scatter plot of a signal. * shannonfanodeco:: Returns the original signal that was Shannon-Fano encoded. * shannonfanodict:: Returns the code dictionary for source using Shannon-Fano algorithm * shannonfanoenco:: Returns the Shannon-Fano encoded signal using DICT This function * sqrt:: Compute the square root of X, element by element, in a Galois Field * sum:: Sum of elements along dimension DIM of Galois array. * sumsq:: Sum of squares of elements along dimension DIM of Galois array If * symerr:: Compares two matrices and returns the number of symbol errors and the symbol error rate. * syndtable:: Create the syndrome decoding table from the parity check matrix H. * systematize:: Given G, extract P parity check matrix. * vec2mat:: Converts the vector V into a C column matrix with row priority * wgn:: Returns a M-by-N matrix Y of white Gaussian noise. @end menu @node ademodce, amdemod, , Function Reference @subsection ademodce @deftypefn {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-tc", offset) @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-tc/costas", offset) @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-sc") @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amdsb-sc/costas") @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "amssb") @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "qam") @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "qam/cmplx") @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "fm", @var{dev}) @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, @var{Fs}, "pm", @var{dev}) @deftypefnx {Function File} {@var{y} =} ademodce (@var{x}, [@var{Fs}, @var{iphs}], @dots{}) @deftypefnx {Function File} {@var{y} =} ademodce (@dots{}, @var{num}, @var{den}) Baseband demodulator for analog signals. The input signal is specified by @var{x}, its sampling frequency by @var{Fs} and the type of modulation by the third argument, @var{typ}. The default values of @var{Fs} is 1 and @var{typ} is "amdsb-tc" If the argument @var{Fs} is a two element vector, the first element represents the sampling rate and the second the initial phase The different types of demodulations that are available are @table @asis @item "am" @itemx "amdsb-tc" Double-sideband with carrier @item "amdsb-tc/costas" Double-sideband with carrier and Costas phase locked loop @item "amdsb-sc" Double-sideband with suppressed carrier @item "amssb" Single-sideband with frequency domain Hilbert filtering @item "qam" Quadrature amplitude demodulation. In-phase in odd-columns and quadrature in even-columns @item "qam/cmplx" Quadrature amplitude demodulation with complex return value @item "fm" Frequency demodulation @item "pm" Phase demodulation @end table Additional arguments are available for the demodulations "amdsb-tc", "fm", "pm". These arguments are @table @code @item offset The offset in the input signal for the transmitted carrier @item dev The deviation of the phase and frequency modulation @end table It is possible to specify a low-pass filter, by the numerator @var{num} and denominator @var{den} that will be applied to the returned vector See also: ademodce, dmodce @end deftypefn @node amdemod, ammod, ademodce, Function Reference @subsection amdemod @deftypefn {Function File} {@var{m} =} amdemod (@var{s}, @var{fc}, @var{fs}) Compute the amplitude demodulation of the signal @var{s} with a carrier frequency of @var{fc} and a sample frequency of @var{fs} See also: ammod @end deftypefn @node ammod, amodce, amdemod, Function Reference @subsection ammod @deftypefn {Function File} {} ammod (@var{x}, @var{fc}, @var{fs}) Create the AM modulation of the signal x with carrier frequency fs. Where x is sample at frequency fs See also: amdemod, fmmod, fmdemod @end deftypefn @node amodce, apkconst, ammod, Function Reference @subsection amodce @deftypefn {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amdsb-tc", offset) @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amdsb-sc") @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amssb") @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "amssb/time", @var{num}, @var{den}) @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "qam") @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "fm", @var{dev}) @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, @var{Fs}, "pm", @var{dev}) @deftypefnx {Function File} {@var{y} =} amodce (@var{x}, [@var{Fs}, @var{iphs}], @dots{}) Baseband modulator for analog signals. The input signal is specified by @var{x}, its sampling frequency by @var{Fs} and the type of modulation by the third argument, @var{typ}. The default values of @var{Fs} is 1 and @var{typ} is "amdsb-tc" If the argument @var{Fs} is a two element vector, the first element represents the sampling rate and the second the initial phase The different types of modulations that are available are @table @asis @item "am" @itemx "amdsb-tc" Double-sideband with carrier @item "amdsb-sc" Double-sideband with suppressed carrier @item "amssb" Single-sideband with frequency domain Hilbert filtering @item "amssb/time" Single-sideband with time domain filtering. Hilbert filter is used by default, but the filter can be specified @item "qam" Quadrature amplitude modulation @item "fm" Frequency modulation @item "pm" Phase modulation @end table Additional arguments are available for the modulations "amdsb-tc", "fm", "pm" and "amssb/time". These arguments are @table @code @item offset The offset in the input signal for the transmitted carrier @item dev The deviation of the phase and frequency modulation @item num @itemx den The numerator and denominator of the filter transfer function for the time domain filtering of the SSB modulation @end table See also: ademodce, dmodce @end deftypefn @node apkconst, awgn, amodce, Function Reference @subsection apkconst @deftypefn {Function File} {} apkconst (@var{nsig}) @deftypefnx {Function File} {} apkconst (@var{nsig}, @var{amp}) @deftypefnx {Function File} {} apkconst (@var{nsig}, @var{amp}, @var{phs}) @deftypefnx {Function File} {} apkconst (@dots{}, "n") @deftypefnx {Function File} {} apkconst (@dots{}, @var{str}) @deftypefnx {Function File} {@var{y} =} apkconst (@dots{}) Plots a ASK/PSK signal constellation. Argument @var{nsig} is a real vector whose length determines the number of ASK radii in the constellation The values of vector @var{nsig} determine the number of points in each ASK radii By default the radii of each ASK modulated level is given by the index of @var{nsig}. The amplitudes can be defined explicitly in the variable @var{amp}, which is a vector of the same length as @var{nsig} By default the first point in each ASK radii has zero phase, and following points are coding in an anti-clockwise manner. If @var{phs} is defined then it is a vector of the same length as @var{nsig} defining the initial phase in each ASK radii In addition @code{apkconst} takes two string arguments "n" and @var{str} If the string "n" is included in the arguments, then a number is printed next to each constellation point giving the symbol value that would be mapped to this point by the @code{modmap} function. The argument @var{str} is a plot style string (example "r+") and determines the default gnuplot point style to use for plot points in the constellation If @code{apkconst} is called with a return argument, then no plot is created. However the return value is a vector giving the in-phase and quadrature values of the symbols in the constellation See also: dmod, ddemod, modmap, demodmap @end deftypefn @node awgn, bchdeco, apkconst, Function Reference @subsection awgn @deftypefn {Function File} {@var{y} =} awgn (@var{x}, @var{snr}) @deftypefnx {Function File} {@var{y} =} awgn (@var{x}, @var{snr}, @var{pwr}) @deftypefnx {Function File} {@var{y} =} awgn (@var{x}, @var{snr}, @var{pwr}, @var{seed}) @deftypefnx {Function File} {@var{y} =} awgn (@dots{}, @var{type}) Add white Gaussian noise to a voltage signal The input @var{x} is assumed to be a real or complex voltage signal. The returned value @var{y} will be the same form and size as @var{x} but with Gaussian noise added. Unless the power is specified in @var{pwr}, the signal power is assumed to be 0dBW, and the noise of @var{snr} dB will be added with respect to this. If @var{pwr} is a numeric value then the signal @var{x} is assumed to be @var{pwr} dBW, otherwise if @var{pwr} is "measured", then the power in the signal will be measured and the noise added relative to this measured power If @var{seed} is specified, then the random number generator seed is initialized with this value By default the @var{snr} and @var{pwr} are assumed to be in dB and dBW respectively. This default behavior can be chosen with @var{type} set to "dB". In the case where @var{type} is set to "linear", @var{pwr} is assumed to be in Watts and @var{snr} is a ratio See also: randn, wgn @end deftypefn @node bchdeco, bchenco, awgn, Function Reference @subsection bchdeco @deftypefn {Loadable Function} {@var{msg} =} bchdeco (@var{code}, @var{k}, @var{t}) @deftypefnx {Loadable Function} {@var{msg} =} bchdeco (@var{code}, @var{k}, @var{t}, @var{prim}) @deftypefnx {Loadable Function} {@var{msg} =} bchdeco (@dots{}, @var{parpos}) @deftypefnx {Loadable Function} {[@var{msg}, @var{err}] =} bchdeco (@dots{}) @deftypefnx {Loadable Function} {[@var{msg}, @var{err}, @var{ccode}] =} bchdeco (@dots{}) Decodes the coded message @var{code} using a BCH coder. The message length of the coder is defined in variable @var{k}, and the error correction capability of the code is defined in @var{t}. The variable @var{code} is a binary array with @var{n} columns and an arbitrary number of rows. Each row of @var{code} represents a single symbol to be decoded by the BCH coder. The decoded message is returned in the binary array @var{msg} containing @var{k} columns and the same number of rows as @var{code}. The use of @code{bchdeco} can be seen in the following short example. @example m = 3; n = 2^m -1; k = 4; t = 1; msg = randint (10, k); code = bchenco (msg, n, k); noisy = mod (randerr (10,n) + code, 2); [dec, err] = bchdeco (msg, k, t); @end example Valid codes can be found using @code{bchpoly}. In general the codeword length @var{n} should be of the form @code{2^@var{m}-1}, where m is an integer. However, shortened BCH codes can be used such that if @code{[2^@var{m}-1,@var{k}]} is a valid code @code{[2^@var{m}-1-@var{x},@var{k}-@var{x}]} is also a valid code using the same generator polynomial. By default the BCH coding is based on the properties of the Galois Field GF(2^@var{m}). The primitive polynomial used in the Galois can be overridden by a primitive polynomial in @var{prim}. Suitable primitive polynomials can be constructed with @code{primpoly}. The form of @var{prim} maybe be either a integer representation of the primitive polynomial as given by @code{primpoly}, or a binary representation that might be constructed like @example m = 3; prim = de2bi (primpoly (m)); @end example By default the parity symbols are assumed to be placed at the beginning of the coded message. The variable @var{parpos} controls this positioning and can take the values @code{"beginning\"} or @code{\"end\"}. See also: bchpoly, bchenco, decode, primpoly @end deftypefn @node bchenco, bchpoly, bchdeco, Function Reference @subsection bchenco @deftypefn {Loadable Function} {@var{code} =} bchenco (@var{msg}, @var{n}, @var{k}) @deftypefnx {Loadable Function} {@var{code} =} bchenco (@var{msg}, @var{n}, @var{k}, @var{g}) @deftypefnx {Loadable Function} {@var{code} =} bchenco (@dots{}, @var{parpos}) Encodes the message @var{msg} using a [@var{n},@var{k}] BCH coding. The variable @var{msg} is a binary array with @var{k} columns and an arbitrary number of rows. Each row of @var{msg} represents a single symbol to be coded by the BCH coder. The coded message is returned in the binary array @var{code} containing @var{n} columns and the same number of rows as @var{msg}. The use of @code{bchenco} can be seen in the following short example. @example m = 3; n = 2^m -1; k = 4; msg = randint (10,k); code = bchenco (msg, n, k); @end example Valid codes can be found using @code{bchpoly}. In general the codeword length @var{n} should be of the form @code{2^@var{m}-1}, where m is an integer. However, shortened BCH codes can be used such that if @code{[2^@var{m}-1,@var{k}]} is a valid code @code{[2^@var{m}-1-@var{x},@var{k}-@var{x}]} is also a valid code using the same generator polynomial. By default the generator polynomial used in the BCH coding is based on the properties of the Galois Field GF(2^@var{m}). This default generator polynomial can be overridden by a polynomial in @var{g}. Suitable generator polynomials can be constructed with @code{bchpoly}. By default the parity symbols are placed at the beginning of the coded message. The variable @var{parpos} controls this positioning and can take the values @code{"beginning\"} or @code{\"end\"}. See also: bchpoly, bchdeco, encode @end deftypefn @node bchpoly, bi2de, bchenco, Function Reference @subsection bchpoly @deftypefn {Function File} {@var{p} =} bchpoly () @deftypefnx {Function File} {@var{p} =} bchpoly (@var{n}) @deftypefnx {Function File} {@var{p} =} bchpoly (@var{n}, @var{k}) @deftypefnx {Function File} {@var{p} =} bchpoly (@var{prim}, @var{k}) @deftypefnx {Function File} {@var{p} =} bchpoly (@var{n}, @var{k}, @var{prim}) @deftypefnx {Function File} {@var{p} =} bchpoly (@dots{}, @var{probe}) @deftypefnx {Function File} {[@var{p}, @var{f}] =} bchpoly (@dots{}) @deftypefnx {Function File} {[@var{p}, @var{f}, @var{c}] =} bchpoly (@dots{}) @deftypefnx {Function File} {[@var{p}, @var{f}, @var{c}, @var{par}] =} bchpoly (@dots{}) @deftypefnx {Function File} {[@var{p}, @var{f}, @var{c}, @var{par}, @var{t}] =} bchpoly (@dots{}) Calculates the generator polynomials for a BCH coder. Called with no input arguments @code{bchpoly} returns a list of all of the valid BCH codes for the codeword length 7, 15, 31, 63, 127, 255 and 511. A three column matrix is returned with each row representing a separate valid BCH code. The first column is the codeword length, the second the message length and the third the error correction capability of the code Called with a single input argument, @code{bchpoly} returns the valid BCH codes for the specified codeword length @var{n}. The output format is the same as above When called with two or more arguments, @code{bchpoly} calculates the generator polynomial of a particular BCH code. The generator polynomial is returned in @var{p} as a vector representation of a polynomial in GF(2). The terms of the polynomial are listed least-significant term first The desired BCH code can be specified by its codeword length @var{n} and its message length @var{k}. Alternatively, the primitive polynomial over which to calculate the polynomial can be specified as @var{prim} If a vector representation of the primitive polynomial is given, then @var{prim} can be specified as the first argument of two arguments, or as the third argument. However, if an integer representation of the primitive polynomial is used, then the primitive polynomial must be specified as the third argument When called with two or more arguments, @code{bchpoly} can also return the factors @var{f} of the generator polynomial @var{p}, the cyclotomic coset for the Galois field over which the BCH code is calculated, the parity check matrix @var{par} and the error correction capability @var{t}. It should be noted that the parity check matrix is calculated with @code{cyclgen} and limitations in this function means that the parity check matrix is only available for codeword length up to 63. For codeword length longer than this @var{par} returns an empty matrix With a string argument @var{probe} defined, the action of @code{bchpoly} is to calculate the error correcting capability of the BCH code defined by @var{n}, @var{k} and @var{prim} and return it in @var{p}. This is similar to a call to @code{bchpoly} with zero or one argument, except that only a single code is checked. Any string value for @var{probe} will force this action In general the codeword length @var{n} can be expressed as @code{2^@var{m}-1}, where @var{m} is an integer. However, if [@var{n},@var{k}] is a valid BCH code, then a shortened BCH code of the form [@var{n}-@var{x},@var{k}-@var{x}] can be created with the same generator polynomial See also: cyclpoly, encode, decode, cosets @end deftypefn @node bi2de, biterr, bchpoly, Function Reference @subsection bi2de @deftypefn {Function File} {@var{d} =} bi2de (@var{b}) @deftypefnx {Function File} {@var{d} =} bi2de (@var{b}, @var{f}) @deftypefnx {Function File} {@var{d} =} bi2de (@var{b}, @var{p}) @deftypefnx {Function File} {@var{d} =} bi2de (@var{b}, @var{p}, @var{f}) Convert bit matrix to a vector of integers Each row of the matrix @var{b} is treated as a single integer represented in binary form. The elements of @var{b}, must therefore be '0' or '1' If @var{p} is defined then it is treated as the base of the decomposition and the elements of @var{b} must then lie between '0' and 'p-1' The variable @var{f} defines whether the first or last element of @var{b} is considered to be the most-significant. Valid values of @var{f} are "right-msb" or "left-msb". By default @var{f} is "right-msb" See also: de2bi @end deftypefn @node biterr, bsc, bi2de, Function Reference @subsection biterr @deftypefn {Function File} {[@var{num}, @var{rate}] =} biterr (@var{a}, @var{b}) @deftypefnx {Function File} {[@var{num}, @var{rate}] =} biterr (@dots{}, @var{k}) @deftypefnx {Function File} {[@var{num}, @var{rate}] =} biterr (@dots{}, @var{flag}) @deftypefnx {Function File} {[@var{num}, @var{rate} @var{ind}] =} biterr (@dots{}) Compares two matrices and returns the number of bit errors and the bit error rate. The binary representations of the variables @var{a} and @var{b} are treated and @var{a} and @var{b} can be either: @table @asis @item Both matrices In this case both matrices must be the same size and then by default the return values @var{num} and @var{rate} are the overall number of bit errors and the overall bit error rate @item One column vector In this case the column vector is used for bit error comparison column-wise with the matrix. The returned values @var{num} and @var{rate} are then row vectors containing the number of bit errors and the bit error rate for each of the column-wise comparisons. The number of rows in the matrix must be the same as the length of the column vector @item One row vector In this case the row vector is used for bit error comparison row-wise with the matrix. The returned values @var{num} and @var{rate} are then column vectors containing the number of bit errors and the bit error rate for each of the row-wise comparisons. The number of columns in the matrix must be the same as the length of the row vector @end table This behavior can be overridden with the variable @var{flag}. @var{flag} can take the value "column-wise", "row-wise" or "overall". A column-wise comparison is not possible with a row vector and visa-versa By default the number of bits in each symbol is assumed to be give by the number required to represent the maximum value of @var{a} and @var{b} The number of bits to represent a symbol can be overridden by the variable @var{k} @end deftypefn @node bsc, comms, biterr, Function Reference @subsection bsc @deftypefn {Function File} {@var{y} =} bsc (@var{data}, @var{p}) Send @var{data} into a binary symmetric channel with probability @var{p} of error one each symbol @end deftypefn @node comms, compand, bsc, Function Reference @subsection comms @deftypefn {Function File} {} comms ("help") @deftypefnx {Function File} {} comms ("info") @deftypefnx {Function File} {} comms ("info", @var{mod}) @deftypefnx {Function File} {} comms ("test") @deftypefnx {Function File} {} comms ("test", @var{mod}) Manual and test code for the Octave Communications toolbox. There are 5 possible ways to call this function @table @code @item comms ("help") Display this help message. Called with no arguments, this function also displays this help message @item comms ("info") Open the Communications toolbox manual @item comms ("info", @var{mod}) Open the Communications toolbox manual at the section specified by @var{mod} @item comms ("test") Run all of the test code for the Communications toolbox @item comms ("test", @var{mod}) Run only the test code for the Communications toolbox in the module @var{mod} @end table Valid values for the variable @var{mod} are @table @asis @item "all" All of the toolbox @item "random" The random signal generation and analysis package @item "source" The source coding functions of the package @item "block" The block coding functions @item "convol" The convolution coding package @item "modulation" The modulation package @item "special" The special filter functions @item "galois" The Galois fields package @end table Please note that this function file should be used as an example of the use of this toolbox @end deftypefn @node compand, conv, comms, Function Reference @subsection compand @deftypefn {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "mu/compressor") @deftypefnx {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "mu/expander") @deftypefnx {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "A/compressor") @deftypefnx {Function File} {@var{y} =} compand (@var{x}, @var{mu}, @var{V}, "A/expander") Compresses and expanding the dynamic range of a signal using a mu-law or or A-law algorithm The mu-law compressor/expander for reducing the dynamic range, is used if the fourth argument of @code{compand} starts with "mu/". Whereas the A-law compressor/expander is used if @code{compand} starts with "A/" The mu-law algorithm uses the formulation @tex $$ y = {V log (1 + \mu / V \|x\|) \over log (1 + \mu)} sgn(x) $$ @end tex @ifnottex @example @group V log (1 + \mu/V |x|) y = -------------------- sgn(x) log (1 + \mu) @end group @end example @end ifnottex while the A-law algorithm used the formulation @tex $$ y = { \left\{ \matrix{ {A / (1 + log A) x}, & 0 <= \|x\| <= V/A \cr & \cr {V log (1 + log(A/V \|x\|) ) \over 1 + logA}, & V/A < \|x\| <= V} \right. } $$ @end tex @ifnottex @example @group / A / (1 + log A) x, 0 <= |x| <= V/A | y = < V ( 1 + log (A/V |x|) ) | ----------------------- sgn(x), V/A < |x| <= V \ 1 + log A @end group @end example @end ifnottex Neither converts from or to audio file ulaw format. Use mu2lin or lin2mu instead See also: m2ulin, lin2mu @end deftypefn @node conv, convenc, compand, Function Reference @subsection conv @deftypefn {Function File} {} conv (@var{a}, @var{b}) Convolve two Galois vectors @code{y = conv (a, b)} returns a vector of length equal to @code{length (a) + length (b) - 1} If @var{a} and @var{b} are polynomial coefficient vectors, @code{conv} returns the coefficients of the product polynomial See also: deconv @end deftypefn @node convenc, convmtx, conv, Function Reference @subsection convenc @deftypefn {Function File} {@var{y} =} convenc (@var{msg}, @var{t}) @deftypefnx {Function File} {@var{y} =} convenc (@var{msg}, @var{t}, @var{punct}) @deftypefnx {Function File} {@var{y} =} convenc (@var{msg}, @var{t}, @var{punct}, @var{s0}) @deftypefnx {Function File} {[@var{y}, @var{state_end}] =} convenc (@dots{}) Encode the binary vector @var{msg} with the convolutional encoder described by the trellis structure @var{t} The rate @math{k/n} convolutional encoder encodes @math{k} bits at a time from the input vector and produces @math{n} bits at a time into the output vector. The input @var{msg} must have a length that is a multiple of @math{k} If the initial state @var{s0} is specified, it indicates the internal state of the encoder when the first @math{k} input bits are fed in. The default value of @var{s0} is 0 The optional output argument @var{state_end} indicates the internal state of the encoder after the last bits are encoded. This allows the state of the encoder to be saved and applied to the next call to @code{convenc} to process data in blocks See also: poly2trellis @end deftypefn @node convmtx, cosets, convenc, Function Reference @subsection convmtx @deftypefn {Function File} {} convmtx (@var{a}, @var{n}) Create matrix to perform repeated convolutions with the same vector in a Galois Field. If @var{a} is a column vector and @var{x} is a column vector of length @var{n}, in a Galois Field then @code{convmtx (@var{a}, @var{n}) * @var{x}} gives the convolution of of @var{a} and @var{x} and is the same as @code{conv (@var{a}, @var{x})}. The difference is if many vectors are to be convolved with the same vector, then this technique is possibly faster Similarly, if @var{a} is a row vector and @var{x} is a row vector of length @var{n}, then @code{@var{x} * convmtx (@var{a}, @var{n})} is the same as @code{conv (@var{x}, @var{a})} See also: conv @end deftypefn @node cosets, cyclgen, convmtx, Function Reference @subsection cosets @deftypefn {Function File} {} cosets (@var{m}, @var{prim}) Finds the elements of GF(2^@var{m}) with primitive polynomial @var{prim}, that share the same minimum polynomial. Returns a cell array of the partitioning of GF(2^@var{m}) @end deftypefn @node cyclgen, cyclpoly, cosets, Function Reference @subsection cyclgen @deftypefn {Loadable Function} {@var{h} =} cyclgen (@var{n}, @var{p}) @deftypefnx {Loadable Function} {@var{h} =} cyclgen (@var{n}, @var{p}, @var{typ}) @deftypefnx {Loadable Function} {[@var{h}, @var{g}] =} cyclgen (@dots{}) @deftypefnx {Loadable Function} {[@var{h}, @var{g}, @var{k}] =} cyclgen (@dots{}) Produce the parity check and generator matrix of a cyclic code. The parity check matrix is returned as a @var{m} by @var{n} matrix, representing the [@var{n},@var{k}] cyclic code. @var{m} is the order of the generator polynomial @var{p} and the message length @var{k} is given by @code{@var{n} - @var{m}}. The generator polynomial can either be a vector of ones and zeros, and length @var{m} representing, @tex $$ p_0 + p_1 x + p_2 x^2 + \cdots + p_m x^{m-1} $$ @end tex @ifnottex @example @var{p}(1) + @var{p}(2) * x + @var{p}(3) * x^2 + ... + @var{p}(@var{m}) * x^(m-1) @end example @end ifnottex The terms of the polynomial are stored least-significant term first. Alternatively, @var{p} can be an integer representation of the same polynomial. The form of the parity check matrix is determined by @var{typ}. If @var{typ} is 'system', a systematic parity check matrix is produced. If @var{typ} is 'nosys' and non-systematic parity check matrix is produced. If requested @code{cyclgen} also returns the @var{k} by @var{n} generator matrix @var{g}. See also: hammgen, gen2par, cyclpoly @end deftypefn @node cyclpoly, de2bi, cyclgen, Function Reference @subsection cyclpoly @deftypefn {Loadable Function} {@var{y} =} cyclpoly (@var{n}, @var{k}) @deftypefnx {Loadable Function} {@var{y} =} cyclpoly (@var{n}, @var{k}, @var{opt}) @deftypefnx {Loadable Function} {@var{y} =} cyclpoly (@var{n}, @var{k}, @var{opt}, @var{rep}) This function returns the cyclic generator polynomials of the code [@var{n},@var{k}]. By default the polynomial with the smallest weight is returned. However this behavior can be overridden with the @var{opt} flag. Valid values of @var{opt} are: @table @asis @item @code{"all\"} Returns all of the polynomials of the code [@var{n},@var{k}] @item @code{\"min\"} Returns the polynomial of minimum weight of the code [@var{n},@var{k}] @item @code{\"max\"} Returns the polynomial of the maximum weight of the code [@var{n},@var{k}] @item @var{l} Returns the polynomials having exactly the weight @var{l} @end table The polynomials are returns as row-vectors in the variable @var{y}. Each row of @var{y} represents a polynomial with the least-significant term first. The polynomials can be returned with an integer representation if @var{rep} is @code{\"integer\"}. The default behavior is given if @var{rep} is @code{\"polynomial\"}. See also: gf, isprimitive @end deftypefn @node de2bi, decode, cyclpoly, Function Reference @subsection de2bi @deftypefn {Function File} {@var{b} =} de2bi (@var{d}) @deftypefnx {Function File} {@var{b} =} de2bi (@var{d}, @var{n}) @deftypefnx {Function File} {@var{b} =} de2bi (@var{d}, @var{n}, @var{p}) @deftypefnx {Function File} {@var{b} =} de2bi (@var{d}, @var{n}, @var{p}, @var{f}) Convert a non-negative integer to bit vector The variable @var{d} must be a vector of non-negative integers. @code{de2bi} then returns a matrix where each row represents the binary representation of elements of @var{d}. If @var{n} is defined then the returned matrix will have @var{n} columns. This number of columns can be either larger than the minimum needed and zeros will be added to the msb of the binary representation or smaller than the minimum in which case the least-significant part of the element is returned If @var{p} is defined then it is used as the base for the decomposition of the returned values. That is the elements of the returned value are between '0' and 'p-1' The variable @var{f} defines whether the first or last element of @var{b} is considered to be the most-significant. Valid values of @var{f} are "right-msb" or "left-msb". By default @var{f} is "right-msb" See also: bi2de @end deftypefn @node decode, deconv, de2bi, Function Reference @subsection decode @deftypefn {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}) @deftypefnx {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}, @var{typ}) @deftypefnx {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}, @var{typ}, @var{opt1}) @deftypefnx {Function File} {@var{msg} =} decode (@var{code}, @var{n}, @var{k}, @var{typ}, @var{opt1}, @var{opt2}) @deftypefnx {Function File} {[@var{msg}, @var{err}] =} decode (@dots{}) @deftypefnx {Function File} {[@var{msg}, @var{err}, @var{ccode}] =} decode (@dots{}) @deftypefnx {Function File} {[@var{msg}, @var{err}, @var{ccode}, @var{cerr}] =} decode (@dots{}) Top level block decoder. This function makes use of the lower level functions such as @code{cyclpoly}, @code{cyclgen}, @code{hammgen}, and @code{bchenco}. The coded message to decode is pass in @var{code}, the codeword length is @var{n} and the message length is @var{k}. This function is used to decode messages using either: @table @asis @item A [n,k] linear block code defined by a generator matrix @item A [n,k] cyclic code defined by a generator polynomial @item A [n,k] Hamming code defined by a primitive polynomial @item A [n,k] BCH code code defined by a generator polynomial @end table The type of coding to use is defined by the variable @var{typ}. This variable is a string taking one of the values @table @code @item "linear" @itemx "linear/binary" A linear block code is assumed with the message @var{msg} being in a binary format. In this case the argument @var{opt1} is the generator matrix, and is required. Additionally, @var{opt2} containing the syndrome lookup table (see @code{syndtable}) can also be passed @item "cyclic" @itemx "cyclic/binary" A cyclic code is assumed with the message @var{msg} being in a binary format. The generator polynomial to use can be defined in @var{opt1} The default generator polynomial to use will be @code{cyclpoly (@var{n}, @var{k})}. Additionally, @var{opt2} containing the syndrome lookup table (see @code{syndtable}) can also be passed @item "hamming" @itemx "hamming/binary" A Hamming code is assumed with the message @var{msg} being in a binary format. In this case @var{n} must be of an integer of the form @code{2^@var{m}-1}, where @var{m} is an integer. In addition @var{k} must be @code{@var{n}-@var{m}}. The primitive polynomial to use can be defined in @var{opt1}. The default primitive polynomial to use is the same as defined by @code{hammgen}. The variable @var{opt2} should not be defined @item "bch" @itemx "bch/binary" A BCH code is assumed with the message @var{msg} being in a binary format. The primitive polynomial to use can be defined in @var{opt2} The error correction capability of the code can also be defined in @var{opt1}. Use the empty matrix [] to let the error correction capability take the default value @end table In addition the argument "binary" above can be replaced with "decimal", in which case the message is assumed to be a decimal vector, with each value representing a symbol to be coded. The binary format can be in two forms @table @code @item An @var{x}-by-@var{n} matrix Each row of this matrix represents a symbol to be decoded @item A vector with length divisible by @var{n} The coded symbols are created from groups of @var{n} elements of this vector @end table The decoded message is return in @var{msg}. The number of errors encountered is returned in @var{err}. If the coded message format is "decimal" or a "binary" matrix, then @var{err} is a column vector having a length equal to the number of decoded symbols. If @var{code} is a "binary" vector, then @var{err} is the same length as @var{msg} and indicated the number of errors in each symbol. If the value @var{err} is positive it indicates the number of errors corrected in the corresponding symbol. A negative value indicates an uncorrectable error. The corrected code is returned in @var{ccode} in a similar format to the coded message @var{msg}. The variable @var{cerr} contains similar data to @var{err} for @var{ccode} It should be noted that all internal calculations are performed in the binary format. Therefore for large values of @var{n}, it is preferable to use the binary format to pass the messages to avoid possible rounding errors. Additionally, if repeated calls to @code{decode} will be performed, it is often faster to create a generator matrix externally with the functions @code{hammgen} or @code{cyclgen}, rather than let @code{decode} recalculate this matrix at each iteration. In this case @var{typ} should be "linear". The exception to this case is BCH codes, where the required syndrome table is too large. The BCH decoder, decodes directly from the polynomial never explicitly forming the syndrome table See also: encode, cyclgen, cyclpoly, hammgen, bchdeco, bchpoly, syndtable @end deftypefn @node deconv, deintrlv, decode, Function Reference @subsection deconv @deftypefn {Function File} {} deconv (@var{y}, @var{a}) Deconvolve two Galois vectors @code{[b, r] = deconv (y, a)} solves for @var{b} and @var{r} such that @code{y = conv (a, b) + r} If @var{y} and @var{a} are polynomial coefficient vectors, @var{b} will contain the coefficients of the polynomial quotient and @var{r} will be a remainder polynomial of lowest order See also: conv @end deftypefn @node deintrlv, demodmap, deconv, Function Reference @subsection deintrlv @deftypefn {Function File} {@var{deintrlvd} =} deintrlv (@var{data}, @var{elements}) Restore elements of @var{data} according to @var{elements} See also: intrlv @end deftypefn @node demodmap, det, deintrlv, Function Reference @subsection demodmap @deftypefn {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "ask", @var{m}) @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "fsk", @var{m}, @var{tone}) @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "msk") @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "psk", @var{m}) @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask", @var{m}) @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask/cir", @var{nsig}, @var{amp}, @var{phs}) @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask/arb", @var{inphase}, @var{quadr}) @deftypefnx {Function File} {z =} demodmap (@var{y}, @var{fd}, @var{fs}, "qask/arb", @var{map}) @deftypefnx {Function File} {z =} demodmap (@var{y}, [@var{fd}, @var{off}], @dots{}) Demapping of an analog signal to a digital signal. The function @code{demodmap} must have at least three input arguments and one output argument. Argument @var{y} is a complex variable representing the analog signal to be demapped. The variables @var{fd} and @var{fs} are the sampling rate of the of digital signal and the sampling rate of the analog signal respectively. It is required that @code{@var{fs}/@var{fd}} is an integer The available mapping of the digital signal are @table @asis @item "ask" Amplitude shift keying @item "fsk" Frequency shift keying @item "msk" Minimum shift keying @item "psk" Phase shift keying @item "qask" @itemx "qsk" @itemx "qam" Quadrature amplitude shift keying @end table In addition the "qask", "qsk" and "qam" method can be modified with the flags "/cir" or "/arb". That is "qask/cir" and "qask/arb", etc are valid methods and give circular- and arbitrary-qask mappings respectively. Also the method "fsk" and "msk" can be modified with the flag "/max", in which case @var{y} is assumed to be a matrix with @var{m} columns, representing the symbol correlations The variable @var{m} is the order of the modulation to use. By default this is 2, and in general should be specified For "qask/cir", the additional arguments are the same as for @code{apkconst}, and you are referred to @code{apkconst} for the definitions of the additional variables For "qask/arb", the additional arguments @var{inphase} and @var{quadr} give the in-phase and quadrature components of the mapping, in a similar mapping to the outputs of @code{qaskenco} with one argument. Similar @var{map} represents the in-phase and quadrature components of the mapping as the real and imaginary parts of the variable @var{map} See also: modmap, ddemodce, ademodce, apkconst, qaskenco @end deftypefn @node det, dftmtx, demodmap, Function Reference @subsection det @deftypefn {Loadable Function} {@var{d} =} det (@var{a}) Compute the determinant of the Galois array @var{a} @end deftypefn @node dftmtx, diag, det, Function Reference @subsection dftmtx @deftypefn {Function File} {@var{d} =} dftmtx (@var{a}) Form a matrix, that can be used to perform Fourier transforms in a Galois Field Given that @var{a} is an element of the Galois Field GF(2^m), and that the minimum value for @var{k} for which @code{@var{a} ^ @var{k}} is equal to one is @code{2^m - 1}, then this function produces a @var{k}-by-@var{k} matrix representing the discrete Fourier transform over a Galois Field with respect to @var{a}. The Fourier transform of a column vector is then given by @code{dftmtx (@var{a}) * @var{x}} The inverse Fourier transform is given by @code{dftmtx (1 / @var{a})} @end deftypefn @node diag, dpcmdeco, dftmtx, Function Reference @subsection diag @deftypefn {Loadable Function} {} diag (@var{v}, @var{k}) Return a diagonal matrix with Galois vector @var{v} on diagonal @var{k} The second argument is optional. If it is positive, the vector is placed on the @var{k}-th super-diagonal. If it is negative, it is placed on the @var{-k}-th sub-diagonal. The default value of @var{k} is 0, and the vector is placed on the main diagonal. For example, @example diag (gf ([1, 2, 3], 2), 1) ans = GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7) Array elements = 0 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 @end example @end deftypefn @node dpcmdeco, dpcmenco, diag, Function Reference @subsection dpcmdeco @deftypefn {Function File} {@var{sig} =} dpcmdeco (@var{indx}, @var{codebook}, @var{predictor}) Decode using differential pulse code modulation (DPCM) @table @code @item sig = dpcmdeco (indx, codebook, predictor) Decode the signal coded by DPCM Use the prediction model and the coded prediction error given by a codebook and the index of each sample in this codebook @end table See also: dpcmenco, dpcmopt @end deftypefn @node dpcmenco, dpcmopt, dpcmdeco, Function Reference @subsection dpcmenco @deftypefn {Function File} {@var{qidx} =} dpcmenco (@var{sig}, @var{codebook}, @var{partition}, @var{predictor}) @deftypefnx {Function File} {[@var{qidx}, @var{q}] =} dpcmenco (@var{sig}, @var{codebook}, @var{partition}, @var{predictor}) @deftypefnx {Function File} {[@var{qidx}, @var{q}, @var{d}] =} dpcmenco (@dots{}) Encode using differential pulse code modulation (DPCM) @table @code @item qidx = dpcmenco (sig, codebook, partition, predictor) Determine position of the prediction error in a strictly monotonic table (partition) The predictor vector describes a m-th order prediction for the output according to the following equation y(k) = p(1)sig(k-1) + p(2)sig(k-2) + ... + p(m-1)sig(k-m+1) + p(m)sig(k-m) , where the predictor vector is given by predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)] @item [qidx, q] = dpcmenco (sig, codebook, partition, predictor) Also return the quantized values @item [qidx, q, d] = dpcmenco (...) Also compute distortion: mean squared distance of original sig from the corresponding quantized values @end table See also: dpcmdeco, dpcmopt, quantiz @end deftypefn @node dpcmopt, egolaydec, dpcmenco, Function Reference @subsection dpcmopt @deftypefn {Function File} {@var{predictor} =} dpcmopt (@var{training_set}, @var{ord}) @deftypefnx {Function File} {[@var{predictor}, @var{partition}, @var{codebook}] =} dpcmopt (@var{training_set}, @var{ord}, @var{cb}) Optimize the DPCM parameters and codebook It uses the Levinson-Durbin algorithm to find the all-pole IIR filter using the autocorrelation sequence. After the best predictor is found, it uses the Lloyds algorithm to find the best codebook and partition for the interval @table @code @item predictor = dpcmopt (training_set, ord) Optimize the DPCM parameters using the Levinson-Durbin algorithm The predictor vector describes a m-th order prediction for the output according to the following equation y(k) = p(1)sig(k-1) + p(2)sig(k-2) + ... + p(m-1)sig(k-m+1) + p(m)sig(k-m) where the predictor vector is given by predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)] training_set is the training data used to find the best predictor ord is the order of the desired prediction model @item [predictor, partition, codebook] = dpcmopt (training_set,ord,cb) Optimize the DPCM parameters and also uses the Lloyds algorithm to find the best codebook and partition for the given training signal cb might be the initial codebook used by Lloyds algorithm or the length of the desired codebook @end table See also: dpcmenco, dpcmdeco, levinson, lloyds @end deftypefn @node egolaydec, egolayenc, dpcmopt, Function Reference @subsection egolaydec @deftypefn {Function File} {[@var{C}, @var{err}] =} egolaydec (@var{R}) Decode Extended Golay code Given @var{R}, the received Extended Golay code, this function tries to decode it using the Extended Golay code parity check matrix Extended Golay code (24,12) which can correct up to 3 errors The received code @var{R}, needs to be of length Nx24, for encoding. We can decode several codes at once, if they are stacked as a matrix of 24 columns, each code in a separate row The generator used in here is same as obtained from the function @code{egolaygen} The function returns @var{C}, the error-corrected code word from the received word. If decoding failed, @var{err} value is 1, otherwise it is 0 Extended Golay code (24,12) which can correct up to 3 errors. Decoding algorithm follows from Lin & Costello Ref: Lin & Costello, pg 128, Ch4, "Error Control Coding", 2nd ed, Pearson @example @group msg = rand (10, 12) > 0.5; c1 = egolayenc (msg); c1(:,1) = mod (c1(:,1) + 1, 2) c2 = egolaydec (c1) @end group @end example See also: egolaygen, egolayenc @end deftypefn @node egolayenc, egolaygen, egolaydec, Function Reference @subsection egolayenc @deftypefn {Function File} {@var{C} =} egolayenc (@var{M}) Encode with Extended Golay code The message @var{M}, needs to be of size Nx12, for encoding We can encode several messages, into codes at once, if they are stacked in the order suggested The generator used in here is same as obtained from the function @code{egolaygen}. Extended Golay code (24,12) which can correct up to 3 errors @example @group msg = rand (10, 12) > 0.5; c = egolayenc (msg) @end group @end example See also: egolaygen, egolaydec @end deftypefn @node egolaygen, encode, egolayenc, Function Reference @subsection egolaygen @deftypefn {Function File} {[@var{G}, @var{P}] =} egolaygen () Extended Golay code generator matrix Returns @var{G}, the Extended Golay code (24,12) generator matrix, which can correct up to 3 errors. @var{P} is the parity check matrix, for this code See also: egolaydec, egolayenc @end deftypefn @node encode, exp, egolaygen, Function Reference @subsection encode @deftypefn {Function File} {@var{code} =} encode (@var{msg}, @var{n}, @var{k}) @deftypefnx {Function File} {@var{code} =} encode (@var{msg}, @var{n}, @var{k}, @var{typ}) @deftypefnx {Function File} {@var{code} =} encode (@var{msg}, @var{n}, @var{k}, @var{typ}, @var{opt}) @deftypefnx {Function File} {[@var{code}, @var{added}] =} encode (@dots{}) Top level block encoder. This function makes use of the lower level functions such as @code{cyclpoly}, @code{cyclgen}, @code{hammgen}, and @code{bchenco}. The message to code is pass in @var{msg}, the codeword length is @var{n} and the message length is @var{k}. This function is used to encode messages using either: @table @asis @item A [n,k] linear block code defined by a generator matrix @item A [n,k] cyclic code defined by a generator polynomial @item A [n,k] Hamming code defined by a primitive polynomial @item A [n,k] BCH code code defined by a generator polynomial @end table The type of coding to use is defined by the variable @var{typ}. This variable is a string taking one of the values @table @code @item "linear" @itemx "linear/binary" A linear block code is assumed with the coded message @var{code} being in a binary format. In this case the argument @var{opt} is the generator matrix, and is required @item "cyclic" @itemx "cyclic/binary" A cyclic code is assumed with the coded message @var{code} being in a binary format. The generator polynomial to use can be defined in @var{opt} The default generator polynomial to use will be @code{cyclpoly (@var{n}, @var{k})} @item "hamming" @itemx "hamming/binary" A Hamming code is assumed with the coded message @var{code} being in a binary format. In this case @var{n} must be of an integer of the form @code{2^@var{m}-1}, where @var{m} is an integer. In addition @var{k} must be @code{@var{n}-@var{m}}. The primitive polynomial to use can be defined in @var{opt}. The default primitive polynomial to use is the same as defined by @code{hammgen} @item "bch" @itemx "bch/binary" A BCH code is assumed with the coded message @var{code} being in a binary format. The generator polynomial to use can be defined in @var{opt} The default generator polynomial to use will be @code{bchpoly (@var{n}, @var{k})} @end table In addition the argument "binary" above can be replaced with "decimal", in which case the message is assumed to be a decimal vector, with each value representing a symbol to be coded. The binary format can be in two forms @table @code @item An @var{x}-by-@var{k} matrix Each row of this matrix represents a symbol to be coded @item A vector The symbols are created from groups of @var{k} elements of this vector If the vector length is not divisible by @var{k}, then zeros are added and the number of zeros added is returned in @var{added} @end table It should be noted that all internal calculations are performed in the binary format. Therefore for large values of @var{n}, it is preferable to use the binary format to pass the messages to avoid possible rounding errors. Additionally, if repeated calls to @code{encode} will be performed, it is often faster to create a generator matrix externally with the functions @code{hammgen} or @code{cyclgen}, rather than let @code{encode} recalculate this matrix at each iteration. In this case @var{typ} should be "linear". The exception to this case is BCH codes, whose encoder is implemented directly from the polynomial and is significantly faster See also: decode, cyclgen, cyclpoly, hammgen, bchenco, bchpoly @end deftypefn @node exp, eyediagram, encode, Function Reference @subsection exp @deftypefn {Loadable Function} {} exp (@var{x}) Compute the anti-logarithm for each element of @var{x} for a Galois array @end deftypefn @node eyediagram, fft, exp, Function Reference @subsection eyediagram @deftypefn {Function File} {} eyediagram (@var{x}, @var{n}) @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}) @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}, @var{off}) @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}, @var{off}, @var{str}) @deftypefnx {Function File} {} eyediagram (@var{x}, @var{n}, @var{per}, @var{off}, @var{str}, @var{h}) @deftypefnx {Function File} {@var{h} =} eyediagram (@dots{}) Plot the eye-diagram of a signal. The signal @var{x} can be either in one of three forms @table @asis @item A real vector In this case the signal is assumed to be real and represented by the vector @var{x}. A single eye-diagram representing this signal is plotted @item A complex vector In this case the in-phase and quadrature components of the signal are plotted separately @item A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal @end table Each line of the eye-diagram has @var{n} elements and the period is assumed to be given by @var{per}. The time axis is then [-@var{per}/2 @var{per}/2] By default @var{per} is 1 By default the signal is assumed to start at -@var{per}/2. This can be overridden by the @var{off} variable, which gives the number of samples to delay the signal The string @var{str} is a plot style string (example "r+"), and by default is the default gnuplot line style The figure handle to use can be defined by @var{h}. If @var{h} is not given, then the next available figure handle is used. The figure handle used in returned on @var{hout} See also: scatterplot @end deftypefn @node fft, fibodeco, eyediagram, Function Reference @subsection fft @deftypefn {Function File} {} fft (@var{x}) If @var{x} is a column vector, finds the FFT over the primitive element of the Galois Field of @var{x}. If @var{x} is in the Galois Field GF(2^@var{m}), then @var{x} must have @code{2^@var{m} - 1} elements @end deftypefn @node fibodeco, fiboenco, fft, Function Reference @subsection fibodeco @deftypefn {Function File} {} fibodeco (@var{code}) Returns the decoded Fibonacci value from the binary vectors @var{code} Universal codes like Fibonacci codes have a useful synchronization property, only for 255 maximum value we have designed these routines. We assume user has partitioned the code into several unique segments based on the suffix property of unique strings "11" and we just decode the parts. Partitioning the stream is as simple as identifying the "11" pairs that occur, at the terminating ends. This system implements the standard binary Fibonacci codes, which means that row vectors can only contain 0 or 1. Ref: @url{http://en.wikipedia.org/wiki/Fibonacci_coding} @example @group fibodeco (@{[0 1 0 0 1 1]@}) @result{} 10 fibodeco (@{[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]@}) @result{} [1, 2, 3, 4] @end group @end example See also: fiboenco @end deftypefn @node fiboenco, fibosplitstream, fibodeco, Function Reference @subsection fiboenco @deftypefn {Function File} {} fiboenco (@var{num}) Returns the cell-array of encoded Fibonacci value from the column vectors @var{num} Universal codes like Fibonacci codes have a useful synchronization property, only for 255 maximum value we have designed these routines. We assume user has partitioned the code into several unique segments based on the suffix property of unique elements [1 1] and we just decode the parts. Partitioning the stream is as simple as identifying the [1 1] pairs that occur, at the terminating ends. This system implements the standard binary Fibonacci codes, which means that row vectors can only contain 0 or 1. Ref: http://en.wikipedia.org/wiki/Fibonacci_coding Ugly O(k.N^2) encoder.Ref: Wikipedia article accessed March, 2006 @url{http://en.wikipedia.org/wiki/Fibonacci_coding}, UCI Data Compression Book, @url{http://www.ics.uci.edu/~dan/pubs/DC-Sec3.html}, (accessed October 2006) @example @group fiboenco (10) @result{} @{[ 0 1 0 0 1 1]@} fiboenco (1:4) @result{} @{[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]@} @end group @end example See also: fibodeco @end deftypefn @node fibosplitstream, filter, fiboenco, Function Reference @subsection fibosplitstream @deftypefn {Function File} {} fibosplitstream (@var{code}) Returns the split data stream at the word boundaries Assuming the stream was originally encoded using @code{fiboenco} and this routine splits the stream at the points where "11" occur together & gives us the code-words which can later be decoded from the @code{fibodeco} This however doesn't mean that we intend to verify if all the codewords are correct, and in fact the last symbol in the return list can or can not be a valid codeword A example use of @code{fibosplitstream} would be @example @group fibodeco (fibosplitstream ([fiboenco(randint (1, 100, [0, 255]))@{:@}])) fibodeco (fibosplitstream ([fiboenco(1:10)@{:@}])) @end group @end example See also: fiboenco, fibodeco @end deftypefn @node filter, fmdemod, fibosplitstream, Function Reference @subsection filter @deftypefn {Loadable Function} {y =} filter (@var{b}, @var{a}, @var{x}) @deftypefnx {Loadable Function} {[@var{y}, @var{sf}] =} filter (@var{b}, @var{a}, @var{x}, @var{si}) Digital filtering of vectors in a Galois Field. Returns the solution to the following linear, time-invariant difference equation over a Galois Field: @tex $$ \sum_{k=0}^N a_{k+1} y_{n-k} = \sum_{k=0}^M b_{k+1} x_{n-k}, \qquad 1 \le n \le P $$ @end tex @ifnottex @smallexample @group N M SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k) for 1<=n<=length(x) k=0 k=0 @end group @end smallexample @end ifnottex @noindent where @tex $a \in \Re^{N-1}$, $b \in \Re^{M-1}$, and $x \in \Re^P$ @end tex @ifnottex N=length(a)-1 and M=length(b)-1 @end ifnottex An equivalent form of this equation is: @tex $$ y_n = -\sum_{k=1}^N c_{k+1} y_{n-k} + \sum_{k=0}^M d_{k+1} x_{n-k}, \qquad 1 \le n \le P $$ @end tex @ifnottex @smallexample @group N M y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k) for 1<=n<=length(x) k=1 k=0 @end group @end smallexample @end ifnottex @noindent where @tex $c = a/a_1$ and $d = b/a_1$ @end tex @ifnottex c = a/a(1) and d = b/a(1) @end ifnottex If the fourth argument @var{si} is provided, it is taken as the initial state of the system and the final state is returned as @var{sf}. The state vector is a column vector whose length is equal to the length of the longest coefficient vector minus one If @var{si} is not supplied, the initial state vector is set to all zeros @end deftypefn @node fmdemod, fmmod, filter, Function Reference @subsection fmdemod @deftypefn {Function File} {} fmdemod (@var{x}, @var{fc}, @var{fs}) Create the FM demodulation of the signal x with carrier frequency fs Where x is sample at frequency fs See also: ammod, amdemod, fmmod @end deftypefn @node fmmod, gen2par, fmdemod, Function Reference @subsection fmmod @deftypefn {Function File} {} fmmod (@var{x}, @var{fc}, @var{fs}) Create the FM modulation of the signal x with carrier frequency fs. Where x is sample at frequency fs See also: ammod, fmdemod, amdemod @end deftypefn @node gen2par, genqamdemod, fmmod, Function Reference @subsection gen2par @deftypefn {Function File} {@var{par} =} gen2par (@var{gen}) @deftypefnx {Function File} {@var{gen} =} gen2par (@var{par}) Converts binary generator matrix @var{gen} to the parity check matrix @var{par} and visa-versa. The input matrix must be in standard form That is a generator matrix must be k-by-n and in the form [eye(k) P] or [P eye(k)], and the parity matrix must be (n-k)-by-n and of the form [eye(n-k) P'] or [P' eye(n-k)] See also: cyclgen, hammgen @end deftypefn @node genqamdemod, genqammod, gen2par, Function Reference @subsection genqamdemod @deftypefn {Loadable Function} {@var{y} =} genqamdemod (@var{x}, @var{C}) General quadrature amplitude demodulation. The complex envelope quadrature amplitude modulated signal @var{x} is demodulated using a constellation mapping specified by the 1D vector @var{C}. @end deftypefn @node genqammod, gf, genqamdemod, Function Reference @subsection genqammod @deftypefn {Function File} {@var{y} =} genqammod (@var{x}, @var{c}) Modulates an information sequence of integers @var{x} in the range @code{[0 @dots{} M-1]} onto a quadrature amplitude modulated signal @var{y}, where @code{M = length (c) - 1} and @var{c} is a 1D vector specifying the signal constellation mapping to be used. An example of combined 4PAM-4PSK is @example @group d = randint (1, 1e4, 8); c = [1+j -1+j -1-j 1-j 1+sqrt(3) j*(1+sqrt(3)) -1-sqrt(3) -j*(1+sqrt(3))]; y = genqammod (d, c); z = awgn (y, 20); plot (z, "rx") @end group @end example See also: genqamdemod @end deftypefn @node gf, gftable, genqammod, Function Reference @subsection gf @deftypefn {Loadable Function} {@var{y} =} gf (@var{x}) @deftypefnx {Loadable Function} {@var{y} =} gf (@var{x}, @var{m}) @deftypefnx {Loadable Function} {@var{y} =} gf (@var{x}, @var{m}, @var{primpoly}) Creates a Galois field array GF(2^@var{m}) from the matrix @var{x}. The Galois field has 2^@var{m} elements, where @var{m} must be between 1 and 16. The elements of @var{x} must be between 0 and 2^@var{m} - 1. If @var{m} is undefined it defaults to the value 1. The primitive polynomial to use in the creation of Galois field can be specified with the @var{primpoly} variable. If this is undefined a default primitive polynomial is used. It should be noted that the primitive polynomial must be of the degree @var{m} and it must be irreducible. The output of this function is recognized as a Galois field by Octave and other matrices will be converted to the same Galois field when used in an arithmetic operation with a Galois field. See also: isprimitive, primpoly @end deftypefn @node gftable, gfweight, gf, Function Reference @subsection gftable @deftypefn {Function File} {} gftable (@var{m}, @var{primpoly}) This function exists for compatibility with matlab. As the Octave Galois fields store a copy of the lookup tables for every field in use internally, there is no need to use this function See also: gf @end deftypefn @node gfweight, golombdeco, gftable, Function Reference @subsection gfweight @deftypefn {Function File} {@var{w} =} gfweight (@var{gen}) @deftypefnx {Function File} {@var{w} =} gfweight (@var{gen}, "gen") @deftypefnx {Function File} {@var{w} =} gfweight (@var{par}, "par") @deftypefnx {Function File} {@var{w} =} gfweight (@var{p}, n) Calculate the minimum weight or distance of a linear block code. The code can be either defined by its generator or parity check matrix, or its generator polynomial. By default if the first argument is a matrix, it is assumed to be the generator matrix of the code. The type of the matrix can be defined by a flag "gen" for the generator matrix or "par" for the parity check matrix If the first argument is a vector, it is assumed that it defines the generator polynomial of the code. In this case a second argument is required that defines the codeword length See also: hammgen, cyclpoly, bchpoly @end deftypefn @node golombdeco, golombenco, gfweight, Function Reference @subsection golombdeco @deftypefn {Function File} {} golombdeco (@var{code}, @var{m}) Returns the Golomb decoded signal vector using @var{code} and @var{m} Compulsory m is need to be specified. A restrictions is that a signal set must strictly be non-negative. The value of code is a cell array of row-vectors which have the encoded Golomb value for a single sample. The Golomb algorithm is used to encode the "code" and only that can be meaningfully decoded. @var{code} is assumed to have been of format generated by the function @code{golombenco}. Also the parameter @var{m} need to be a non-zero number, unless which it makes divide-by-zero errors This function works backward the Golomb algorithm see @code{golombenco} for more details on that Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info Theory An example of the use of @code{golombdeco} is @example @group golombdeco (golombenco (1:4, 2), 2) @result{} [1 2 3 4] @end group @end example See also: golombenco @end deftypefn @node golombenco, hammgen, golombdeco, Function Reference @subsection golombenco @deftypefn {Function File} {} golombenco (@var{sig}, @var{m}) Returns the Golomb coded signal as cell array Also total length of output code in bits can be obtained This function uses a @var{m} need to be supplied for encoding signal vector into a Golomb coded vector. A restrictions is that a signal set must strictly be non-negative. Also the parameter @var{m} need to be a non-zero number, unless which it makes divide-by-zero errors The Golomb algorithm [1], is used to encode the data into unary coded quotient part which is represented as a set of 1's separated from the K-part (binary) using a zero. This scheme doesn't need any kind of dictionaries, it is a parameterized prefix codes Implementation is close to O(N^2), but this implementation *may be* sluggish, though correct. Details of the scheme are, to encode the remainder(r of number N) using the floor(log2(m)) bits when rem is in range 0:(2^ceil(log2(m)) - N), and encode it as r+(2^ceil(log2(m)) - N), using total of 2^ceil(log2(m)) bits in other instance it doesn't belong to case 1. Quotient is coded simply just using the unary code. Also according to [2] Golomb codes are optimal for sequences using the Bernoulli probability model: P(n)=p^n-1.q & p+q=1, and when M=[1/log2(p)], or P=2^(1/M) Reference: 1. Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info' Theory. 2. Khalid Sayood, Data Compression, 3rd Edition An example of the use of @code{golombenco} is @example @group golombenco (1:4, 2) @result{} @{[0 1], [1 0 0], [1 0 1], [1 1 0 0]@} golombenco (1:10, 2) @result{} @{[0 1], [1 0 0], [1 0 1], [1 1 0 0], [1 1 0 1], [1 1 1 0 0], [1 1 1 0 1], [1 1 1 1 0 0], [1 1 1 1 0 1], [1 1 1 1 1 0 0]@} @end group @end example See also: golombdeco @end deftypefn @node hammgen, helscanintrlv, golombenco, Function Reference @subsection hammgen @deftypefn {Function File} {@var{h} =} hammgen (@var{m}) @deftypefnx {Function File} {@var{h} =} hammgen (@var{m}, @var{p}) @deftypefnx {Function File} {[@var{h}, @var{g}] =} hammgen (@dots{}) @deftypefnx {Function File} {[@var{h}, @var{g}, @var{n}, @var{k}] =} hammgen (@dots{}) Produce the parity check and generator matrices of a Hamming code. The variable @var{m} defines the [@var{n},@var{k}] Hamming code where @code{@var{n} = 2 ^ @var{m} - 1} and @code{@var{k} = @var{n} - @var{m}} @var{m} must be between 3 and 16 The parity check matrix is generated relative to the primitive polynomial of GF(2^@var{m}). If @var{p} is specified the default primitive polynomial of GF(2^@var{m}) is overridden. @var{p} must be a valid primitive polynomial of the correct order for GF(2^@var{m}) The parity check matrix is returned in the @var{m} by @var{n} matrix @var{h}, and if requested the generator matrix is returned in the @var{k} by @var{n} matrix @var{g} See also: gen2par @end deftypefn @node helscanintrlv, huffmandeco, hammgen, Function Reference @subsection helscanintrlv @deftypefn {Function File} {@var{outdata} =} helscanintrlv (@var{data}, @var{nrows}, @var{ncols}, @var{Nshift}) @var{nrows}-by-@var{ncols} See also: helscandeintrlv @end deftypefn @node huffmandeco, huffmandict, helscanintrlv, Function Reference @subsection huffmandeco @deftypefn {Function File} {@var{sig} =} huffmandeco (@var{hcode}, @var{dict}) Decode signal encoded by @code{huffmanenco} This function uses a dict built from the @code{huffmandict} and uses it to decode a signal list into a Huffman list. A restriction is that @var{hcode} is expected to be a binary code The returned @var{sig} set that strictly belongs in the range @code{[1,N]} with @code{N = length (@var{dict})}. Also @var{dict} can only be from the @code{huffmandict} routine. Whenever decoding fails, those signal values a re indicated by @code{-1}, and we successively try to restart decoding from the next bit that hasn't failed in decoding, ad-infinitum. An example of the use of @code{huffmandeco} is: @example @group hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]); hcode = huffmanenco (1:4, hd); back = huffmandeco (hcode, hd) @result{} [1 2 3 4] @end group @end example See also: huffmandict, huffmanenco @end deftypefn @node huffmandict, huffmanenco, huffmandeco, Function Reference @subsection huffmandict @deftypefn {Function File} {} huffmandict (@var{symb}, @var{prob}) @deftypefnx {Function File} {} huffmandict (@var{symb}, @var{prob}, @var{toggle}) @deftypefnx {Function File} {} huffmandict (@var{symb}, @var{prob}, @var{toggle}, @var{minvar}) Builds a Huffman code, given a probability list. The Huffman codes per symbol are output as a list of strings-per-source symbol. A zero probability symbol is NOT assigned any codeword as this symbol doesn't occur in practice anyway @var{toggle} is an optional argument with values 1 or 0, that starts building a code based on 1s or 0s, defaulting to 0. Also @var{minvar} is a boolean value that is useful in choosing if you want to optimize buffer for transmission in the applications of Huffman coding, however it doesn't affect the type or average codeword length of the generated code. An example of the use of @code{huffmandict} is @example @group huffmandict (symbols, [0.5 0.25 0.15 0.1], 1) @result{} @{[0], [1 0], [1 1 1], [1 1 0]@} huffmandict (symbols, 0.25 * ones (1,4), 1) @result{} @{[1 1], [1 0], [0 1], [0 0]@} prob = [0.5 0 0.25 0.15 0.1]; dict = huffmandict (1:5, prob, 1); entropy (prob) @result{} 2.3219 laverage (dict, prob) @result{} 1.8500 x = [0.2 0.4 0.2 0.1 0.1]; huffmandict (1, x, 0, true) @result{} @{[1 0], [0 0], [1 1], [0 1 0], [0 1 1]@} huffmandict (1, x) @result{} @{[0 1], [1], [0 0 1], [0 0 0 0], [0 0 0 1]@} @end group @end example Reference: Dr.Rao's course EE5351 Digital Video Coding, at UT-Arlington See also: huffmandeco, huffmanenco @end deftypefn @node huffmanenco, ifft, huffmandict, Function Reference @subsection huffmanenco @deftypefn {Function File} {} huffmanenco (@var{sig}, @var{dict}) Returns the Huffman encoded signal using @var{dict}. This function uses a @var{dict} built from the @code{huffmandict} and uses it to encode a signal list into a Huffman list. A restrictions is that a signal set must strictly belong in the range @code{[1,N]} with @code{N = length (dict)} Also @var{dict} can only be from the @code{huffmandict} routine An example of the use of @code{huffmanenco} is @example @group hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]); huffmanenco (1:4, hd) @result{} [1 0 1 0 0 0 0 0 1] @end group @end example See also: huffmandict, huffmandeco @end deftypefn @node ifft, intrlv, huffmanenco, Function Reference @subsection ifft @deftypefn {Function File} {} ifft (@var{x}) If @var{x} is a column vector, finds the IFFT over the primitive element of the Galois Field of @var{x}. If @var{x} is in the Galois Field GF(2^@var{m}), then @var{x} must have @code{2^@var{m} - 1} elements See also: ifft @end deftypefn @node intrlv, inv, ifft, Function Reference @subsection intrlv @deftypefn {Function File} {@var{intrlvd} =} intrlv (@var{data}, @var{elements}) Interleaved elements of @var{data} according to @var{elements} See also: deintrlv @end deftypefn @node inv, inverse, intrlv, Function Reference @subsection inv @deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inv (@var{a}) Compute the inverse of the square matrix @var{a}. Return an estimate of the reciprocal condition number if requested, otherwise warn of an ill-conditioned matrix if the reciprocal condition number is small @end deftypefn @node inverse, isequal, inv, Function Reference @subsection inverse @deftypefn {Loadable Function} {[@var{x}, @var{rcond}] =} inverse (@var{a}) See inv @end deftypefn @node isequal, isgalois, inverse, Function Reference @subsection isequal @deftypefn {Function File} {} isequal (@var{x1}, @var{x2}, @dots{}) Return true if all of @var{x1}, @var{x2}, @dots{} are equal See also: isequalwithequalnans @end deftypefn @node isgalois, isprimitive, isequal, Function Reference @subsection isgalois @deftypefn {Loadable Function} {} isgalois (@var{expr}) Return 1 if the value of the expression @var{expr} is a Galois Field. @end deftypefn @node isprimitive, istrellis, isgalois, Function Reference @subsection isprimitive @deftypefn {Loadable Function} {@var{y} =} isprimitive (@var{a}) Returns 1 is the polynomial represented by @var{a} is a primitive polynomial of GF(2). Otherwise it returns zero. See also: gf, primpoly @end deftypefn @node istrellis, lloyds, isprimitive, Function Reference @subsection istrellis @deftypefn {Function File} {} istrellis (@var{t}) @deftypefnx {Function File} {[@var{status}, @var{text}] =} istrellis (@var{t}) Return true if @var{t} is a valid trellis structure If called with two output arguments, @var{text} contains a string indicating a reason if @var{status} is false or an empty string if @var{status} is true See also: poly2trellis, struct @end deftypefn @node lloyds, log, istrellis, Function Reference @subsection lloyds @deftypefn {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @var{init_codes}) @deftypefnx {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @var{len}) @deftypefnx {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @dots{}, @var{tol}) @deftypefnx {Function File} {[@var{table}, @var{codes}] =} lloyds (@var{sig}, @dots{}, @var{tol}, @var{type}) @deftypefnx {Function File} {[@var{table}, @var{codes}, @var{dist}] =} lloyds (@dots{}) @deftypefnx {Function File} {[@var{table}, @var{codes}, @var{dist}, @var{reldist}] =} lloyds (@dots{}) Optimize the quantization table and codes to reduce distortion. This is based on the article by Lloyd S. Lloyd @emph{Least squared quantization in PCM}, IEEE Trans Inform Theory, Mar 1982, no 2, p129-137 which describes an iterative technique to reduce the quantization error by making the intervals of the table such that each interval has the same area under the PDF of the training signal @var{sig}. The initial codes to try can either be given in the vector @var{init_codes} or as scalar @var{len}. In the case of a scalar the initial codes will be an equi-spaced vector of length @var{len} between the minimum and maximum value of the training signal The stopping criteria of the iterative algorithm is given by @example abs(@var{dist}(n) - @var{dist}(n-1)) < max(@var{tol}, abs(@var{eps}*max(@var{sig})) @end example By default @var{tol} is 1.e-7. The final input argument determines how the updated table is created. By default the centroid of the values of the training signal that fall within the interval described by @var{codes} are used to update @var{table}. If @var{type} is any other string than "centroid", this behavior is overridden and @var{table} is updated as follows @example @var{table} = (@var{code}(2:length(@var{code})) + @var{code}(1:length(@var{code}-1))) / 2 @end example The optimized values are returned as @var{table} and @var{code}. In addition the distortion of the optimized codes representing the training signal is returned as @var{dist}. The relative distortion in the final iteration is also returned as @var{reldist} See also: quantiz @end deftypefn @node log, lu, lloyds, Function Reference @subsection log @deftypefn {Loadable Function} {} log (@var{x}) Compute the natural logarithm for each element of @var{x} for a Galois array @end deftypefn @node lu, lz77deco, log, Function Reference @subsection lu @deftypefn {Loadable Function} {[@var{l}, @var{u}, @var{p}] =} lu (@var{a}) @cindex LU decomposition of Galois matrix Compute the LU decomposition of @var{a} in a Galois Field. The result is returned in a permuted form, according to the optional return value @var{p}. For example, given the matrix @code{a = gf ([1, 2; 3, 4], 3)}, @example [l, u, p] = lu (a) @end example @noindent returns @example l = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 0 6 1 u = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 3 4 0 7 p = Permutation Matrix 0 1 1 0 @end example Such that @code{@var{p} * @var{a} = @var{l} * @var{u}}. If the argument @var{p} is not included then the permutations are applied to @var{l} so that @code{@var{a} = @var{l} * @var{u}}. @var{l} is then a pseudo- lower triangular matrix. The matrix @var{a} can be rectangular @end deftypefn @node lz77deco, lz77enco, lu, Function Reference @subsection lz77deco @deftypefn {Function File} {@var{m} =} lz77deco (@var{c}, @var{alph}, @var{la}, @var{n}) Lempel-Ziv 77 source algorithm decoding implementation. Where @table @asis @item @var{m} message decoded (1xN) @item @var{c} encoded message (Mx3) @item @var{alph} size of alphabet @item @var{la} lookahead buffer size @item @var{n} sliding window buffer size @end table See also: lz77enco @end deftypefn @node lz77enco, matdeintrlv, lz77deco, Function Reference @subsection lz77enco @deftypefn {Function File} {@var{c} =} lz77enco (@var{m}, @var{alph}, @var{la}, @var{n}) Lempel-Ziv 77 source algorithm implementation. Where @table @asis @item @var{c} encoded message (Mx3) @item @var{alph} size of alphabet @item @var{la} lookahead buffer size @item @var{n} sliding window buffer size @end table See also: lz77deco @end deftypefn @node matdeintrlv, matintrlv, lz77enco, Function Reference @subsection matdeintrlv @deftypefn {Function File} {@var{intrlvd} =} matdeintrlv (@var{data}, @var{nrows}, @var{ncols}) Restore elements of @var{data} with a temporary matrix of size @var{nrows}-by-@var{ncols} See also: matintrlv @end deftypefn @node matintrlv, minpol, matdeintrlv, Function Reference @subsection matintrlv @deftypefn {Function File} {@var{intrlvd} =} matintrlv (@var{data}, @var{nrows}, @var{ncols}) Interleaved elements of @var{data} with a temporary matrix of size @var{nrows}-by-@var{ncols} See also: matdeintrlv @end deftypefn @node minpol, modmap, matintrlv, Function Reference @subsection minpol @deftypefn {Function File} {} minpol (@var{v}) Finds the minimum polynomial for elements of a Galois Field. For a vector @var{v} with @math{N} components, representing @math{N} values in a Galois Field GF(2^@var{m}), return the minimum polynomial in GF(2) representing those values @end deftypefn @node modmap, oct2dec, minpol, Function Reference @subsection modmap @deftypefn {Function File} {} modmap (@var{method}, @dots{}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "ask", @var{m}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "fsk", @var{m}, @var{tone}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "msk") @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "psk", @var{m}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask", @var{m}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask/cir", @var{nsig}, @var{amp}, @var{phs}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask/arb", @var{inphase}, @var{quadr}) @deftypefnx {Function File} {y =} modmap (@var{x}, @var{fd}, @var{fs}, "qask/arb", @var{map}) Mapping of a digital signal to an analog signal. With no output arguments @code{modmap} plots the constellation of the mapping. In this case the first argument must be the string @var{method} defining one of "ask", "fsk", "msk", "qask", "qask/cir" or "qask/arb". The arguments following the string @var{method} are generally the same as those after the corresponding string in the function call without output arguments The exception is @code{modmap ("msk", @var{Fd})} With an output argument, @var{y} is the complex mapped analog signal. In this case the arguments @var{x}, @var{fd} and @var{fs} are required. The variable @var{x} is the digital signal to be mapped, @var{fd} is the sampling rate of the of digital signal and the @var{fs} is the sampling rate of the analog signal. It is required that @code{@var{fs}/@var{fd}} is an integer The available mapping of the digital signal are @table @asis @item "ask" Amplitude shift keying @item "fsk" Frequency shift keying @item "msk" Minimum shift keying @item "psk" Phase shift keying @item "qask" @itemx "qsk" @itemx "qam" Quadrature amplitude shift keying @end table In addition the "qask", "qsk" and "qam" method can be modified with the flags "/cir" or "/arb". That is "qask/cir" and "qask/arb", etc are valid methods and give circular- and arbitrary-qask mappings respectively The additional argument @var{m} is the order of the modulation to use @var{m} must be larger than the largest element of @var{x}. The variable @var{tone} is the FSK tone to use in the modulation For "qask/cir", the additional arguments are the same as for @code{apkconst}, and you are referred to @code{apkconst} for the definitions of the additional variables For "qask/arb", the additional arguments @var{inphase} and @var{quadr} give the in-phase and quadrature components of the mapping, in a similar mapping to the outputs of @code{qaskenco} with one argument. Similar @var{map} represents the in-phase and quadrature components of the mapping as the real and imaginary parts of the variable @var{map} See also: demodmap, dmodce, amodce, apkconst, qaskenco @end deftypefn @node oct2dec, pamdemod, modmap, Function Reference @subsection oct2dec @deftypefn {Function File} {@var{d} =} oct2dec (@var{c}) Convert octal to decimal values Each element of the octal matrix @var{c} is converted to a decimal value See also: base2dec, bin2dec, dec2bin @end deftypefn @node pamdemod, pammod, oct2dec, Function Reference @subsection pamdemod @deftypefn {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}) @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}) @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}, @var{type}) Demodulates a pulse amplitude modulated signal @var{x} into an information sequence of integers in the range @code{[0 @dots{} M-1]} @var{phi} controls the initial phase and @var{type} controls the constellation mapping. If @var{type} is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding An example of Gray-encoded 8-PAM is @example @group d = randint (1, 1e4, 8); y = pammod (d, 8, 0, "gray"); z = awgn (y, 20); d_est = pamdemod (z, 8, 0, "gray"); plot (z, "rx") biterr (d, d_est) @end group @end example See also: pammod @end deftypefn @node pammod, poly2trellis, pamdemod, Function Reference @subsection pammod @deftypefn {Function File} {@var{y} =} pammod (@var{x}, @var{m}) @deftypefnx {Function File} {@var{y} =} pammod (@var{x}, @var{m}, @var{phi}) @deftypefnx {Function File} {@var{y} =} pammod (@var{x}, @var{m}, @var{phi}, @var{type}) Modulates an information sequence of integers @var{x} in the range @code{[0 @dots{} M-1]} onto a pulse amplitude modulated signal @var{y} @var{phi} controls the initial phase and @var{type} controls the constellation mapping. If @var{type} is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding An example of Gray-encoded 8-PAM is @example @group d = randint (1, 1e4, 8); y = pammod (d, 8, 0, "gray"); z = awgn (y, 20); plot (z, "rx") @end group @end example See also: pamdemod @end deftypefn @node poly2trellis, primpoly, pammod, Function Reference @subsection poly2trellis @deftypefn {Function File} {@var{t} =} poly2trellis (@var{m}, @var{g}) Convert convolutional code generator polynomials into trellis form The arguments @var{m} and @var{g} together describe a rate k/n feedforward convolutional encoder. The output @var{t} is a trellis structure describing the same encoder with the fields listed below The vector @var{m} is a k-by-1 array containing the lengths of each of the shift registers for the k input bits to the encoder The matrix @var{g} is a k-by-n octal-value matrix describing the generation of each of the n outputs from each of the k inputs. For a particular entry of @var{g}, the least-significant bit corresponds to the most-delayed input bit in the kth shift-register The returned trellis structure contains the following fields: @table @samp @item numInputSymbols The number of k-bit input symbols possible, i.e. 2^k @item numOutputSymbols The number of n-bit output symbols possible, i.e. 2^n @item numStates The number of states in the trellis @item nextStates The state transition table for the trellis. The ith row contains the indices of the states reachable from the (i-1)th state for each possible input symbol @item outputs A table of octal-encoded output values for the trellis. The ith row contains values representing the output symbols produced in the (i-1)th state for each possible input symbol @end table Input symbols, output symbols, and encoder states are all interpreted with the lowest indices being the most significant bits References: [1] S. Lin and D. J. Costello, "Convolutional codes," in @cite{Error Control Coding}, 2nd ed. Upper Saddle River, NJ: Pearson, 2004, ch. 11, pp. 453-513 See also: istrellis @end deftypefn @node primpoly, prod, poly2trellis, Function Reference @subsection primpoly @deftypefn {Loadable Function} {@var{y} =} primpoly (@var{m}) @deftypefnx {Loadable Function} {@var{y} =} primpoly (@var{m}, @var{opt}) @deftypefnx {Loadable Function} {@var{y} =} primpoly (@dots{}, "nodisplay\") Finds the primitive polynomials in GF(2^@var{m}). The first form of this function returns the default primitive polynomial of GF(2^@var{m}). This is the minimum primitive polynomial of the field. The polynomial representation is printed and an integer representation of the polynomial is returned The call @code{primpoly (@var{m}, @var{opt})} returns one or more primitive polynomials. The output of the function is dependent of the value of @var{opt}. Valid values of @var{opt} are: @table @asis @item @code{\"all\"} Returns all of the primitive polynomials of GF(2^@var{m}) @item @code{\"min\"} Returns the minimum primitive polynomial of GF(2^@var{m}) @item @code{\"max\"} Returns the maximum primitive polynomial of GF(2^@var{m}) @item @var{k} Returns the primitive polynomials having exactly @var{k} non-zero terms @end table The call @code{primpoly (@dots{}, \"nodisplay\")} disables the output of the polynomial forms of the primitives. The return value is not affected. See also: gf, isprimitive @end deftypefn @node prod, pskdemod, primpoly, Function Reference @subsection prod @deftypefn {Loadable Function} {} prod (@var{x}, @var{dim}) Product of elements along dimension @var{dim} of Galois array. If @var{dim} is omitted, it defaults to 1 (column-wise products) @end deftypefn @node pskdemod, pskmod, prod, Function Reference @subsection pskdemod @deftypefn {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}) @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}) @deftypefnx {Function File} {@var{y} =} pamdemod (@var{x}, @var{m}, @var{phi}, @var{type}) Demodulates a complex-baseband phase shift keying modulated signal into an information sequence of integers in the range @code{[0 @dots{} M-1]}. @var{phi} controls the initial phase and @var{type} controls the constellation mapping. If @var{type} is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding. An example of Gray-encoded 8-PSK is @example @group d = randint (1, 1e3, 8); y = pskmod (d, 8, 0, "gray"); z = awgn (y, 20); d_est = pskdemod (z, 8, 0, "gray"); plot (z, "rx") biterr (d, d_est) @end group @end example See also: pskmod @end deftypefn @node pskmod, qamdemod, pskdemod, Function Reference @subsection pskmod @deftypefn {Function File} {@var{y} =} pskmod (@var{x}, @var{m}) @deftypefnx {Function File} {@var{y} =} pskmod (@var{x}, @var{m}, @var{phi}) @deftypefnx {Function File} {@var{y} =} pskmod (@var{x}, @var{m}, @var{phi}, @var{type}) Modulates an information sequence of integers @var{x} in the range @code{[0 @dots{} M-1]} onto a complex baseband phase shift keying modulated signal @var{y}. @var{phi} controls the initial phase and @var{type} controls the constellation mapping. If @var{type} is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding. An example of Gray-encoded QPSK is @example @group d = randint (1, 5e3, 4); y = pskmod (d, 4, 0, "gray"); z = awgn (y, 30); plot (z, "rx") @end group @end example See also: pskdemod @end deftypefn @node qamdemod, qammod, pskmod, Function Reference @subsection qamdemod @deftypefn {Function File} {} qamdemod (@var{x}, @var{m}) Create the QAM demodulation of x with a size of alphabet m See also: qammod, pskmod, pskdemod @end deftypefn @node qammod, qaskdeco, qamdemod, Function Reference @subsection qammod @deftypefn {Function File} {} qammod (@var{x}, @var{m}) Create the QAM modulation of x with a size of alphabet m See also: qamdemod, pskmod, pskdemod @end deftypefn @node qaskdeco, qaskenco, qammod, Function Reference @subsection qaskdeco @deftypefn {Function File} {@var{msg} =} qaskdeco (@var{c}, @var{m}) @deftypefnx {Function File} {@var{msg} =} qaskdeco (@var{inphase}, @var{quadr}, @var{m}) @deftypefnx {Function File} {@var{msg} =} qaskdeco (@dots{}, @var{mnmx}) Demaps an analog signal using a square QASK constellation. The input signal maybe either a complex variable @var{c}, or as two real variables @var{inphase} and @var{quadr} representing the in-phase and quadrature components of the signal The argument @var{m} must be a positive integer power of 2. By default the same constellation as created in @code{qaskenco} is used by @code{qaskdeco} If is possible to change the values of the minimum and maximum of the in-phase and quadrature components of the constellation to account for linear changes in the signal values in the received signal. The variable @var{mnmx} is a 2-by-2 matrix of the following form @multitable @columnfractions 0.125 0.05 0.25 0.05 0.25 0.05 @item @tab | @tab min in-phase @tab , @tab max in-phase @tab | @item @tab | @tab min quadrature @tab , @tab max quadrature @tab | @end multitable If @code{sqrt (@var{m})} is an integer, then @code{qaskenco} uses a Gray mapping. Otherwise, an attempt is made to create a nearly square mapping with a minimum Hamming distance between adjacent constellation points See also: qaskenco @end deftypefn @node qaskenco, qfunc, qaskdeco, Function Reference @subsection qaskenco @deftypefn {Function File} {} qaskenco (@var{m}) @deftypefnx {Function File} {} qaskenco (@var{msg}, @var{m}) @deftypefnx {Function File} {@var{y} =} qaskenco (@dots{}) @deftypefnx {Function File} {[@var{inphase}, @var{quadr}] =} qaskenco (@dots{}) Map a digital signal using a square QASK constellation. The argument @var{m} must be a positive integer power of 2. With two input arguments the variable @var{msg} represents the message to be encoded. The values of @var{msg} must be between 0 and @code{@var{m}-1}. In all cases @code{qaskenco (@var{M})} is equivalent to @code{qaskenco (1:@var{m}, @var{m})} Three types of outputs can be created depending on the number of output arguments. That is @table @asis @item No output arguments In this case @code{qaskenco} plots the constellation. Only the points in @var{msg} are plotted, which in the case of a single input argument is all constellation points @item A single output argument The returned variable is a complex variable representing the in-phase and quadrature components of the mapped message @var{msg}. With, a single input argument this effectively gives the mapping from symbols to constellation points @item Two output arguments This is the same as one output argument, expect that the in-phase and quadrature components are returned explicitly. That is @example c = qaskenco (msg, m); [a, b] = qaskenco (msg, m); all (c == a + 1i*b) @result{} 1 @end example @end table If @code{sqrt (@var{m})} is an integer, then @code{qaskenco} uses a Gray mapping. Otherwise, an attempt is made to create a nearly square mapping with a minimum Hamming distance between adjacent constellation points See also: qaskdeco @end deftypefn @node qfunc, qfuncinv, qaskenco, Function Reference @subsection qfunc @deftypefn {Function File} {@var{y} =} qfunc (@var{x}) Compute the Q function See also: erfc, erf @end deftypefn @node qfuncinv, quantiz, qfunc, Function Reference @subsection qfuncinv @deftypefn {Function File} {@var{y} =} qfuncinv (@var{x}) Compute the inverse Q function See also: erfc, erf @end deftypefn @node quantiz, randdeintrlv, qfuncinv, Function Reference @subsection quantiz @deftypefn {Function File} {@var{qidx} =} quantiz (@var{x}, @var{table}) @deftypefnx {Function File} {[@var{qidx}, @var{q}] =} quantiz (@var{x}, @var{table}, @var{codes}) @deftypefnx {Function File} {[ @var{qidx}, @var{q}, @var{d}] =} quantiz (@dots{}) Quantization of an arbitrary signal relative to a partitioning @table @code @item qidx = quantiz (x, table) Determine position of x in strictly monotonic table. The first interval, using index 0, corresponds to x <= table(1) Subsequent intervals are table(i-1) < x <= table(i) @item [qidx, q] = quantiz (x, table, codes) Associate each interval of the table with a code. Use codes(1) for x <= table(1) and codes(n+1) for table(n) < x <= table(n+1) @item [qidx, q, d] = quantiz (...) Compute distortion as mean squared distance of x from the corresponding quantization values @end table @end deftypefn @node randdeintrlv, randerr, quantiz, Function Reference @subsection randdeintrlv @deftypefn {Function File} {@var{intrlvd} =} randdeintrlv (@var{data}, @var{state}) Restore elements of @var{data} with a random permutation See also: randintrlv, intrlv, deintrlv @end deftypefn @node randerr, randint, randdeintrlv, Function Reference @subsection randerr @deftypefn {Function File} {@var{b} =} randerr (@var{n}) @deftypefnx {Function File} {@var{b} =} randerr (@var{n}, @var{m}) @deftypefnx {Function File} {@var{b} =} randerr (@var{n}, @var{m}, @var{err}) @deftypefnx {Function File} {@var{b} =} randerr (@var{n}, @var{m}, @var{err}, @var{seed}) Generate a matrix of random bit errors. The size of the matrix is @var{n} rows by @var{m} columns. By default @var{m} is equal to @var{n} Bit errors in the matrix are indicated by a 1 The variable @var{err} determines the number of errors per row. By default the return matrix @var{b} has exactly one bit error per row If @var{err} is a scalar, there each row of @var{b} has exactly this number of errors per row. If @var{err} is a vector then each row has a number of errors that is in this vector. Each number of errors has an equal probability. If @var{err} is a matrix with two rows, then the first row determines the number of errors and the second their probabilities The variable @var{seed} allows the random number generator to be seeded with a fixed value. The initial seed will be restored when returning @end deftypefn @node randint, randintrlv, randerr, Function Reference @subsection randint @deftypefn {Function File} {@var{b} =} randint (@var{n}) @deftypefnx {Function File} {@var{b} =} randint (@var{n}, @var{m}) @deftypefnx {Function File} {@var{b} =} randint (@var{n}, @var{m}, @var{range}) @deftypefnx {Function File} {@var{b} =} randint (@var{n}, @var{m}, @var{range}, @var{seed}) Generate a matrix of random binary numbers. The size of the matrix is @var{n} rows by @var{m} columns. By default @var{m} is equal to @var{n} The range in which the integers are generated will is determined by the variable @var{range}. If @var{range} is an integer, the value will lie in the range [0,@var{range}-1], or [@var{range}+1,0] if @var{range} is negative. If @var{range} contains two elements the integers will lie within these two elements, inclusive. By default @var{range} is assumed to be [0:1] The variable @var{seed} allows the random number generator to be seeded with a fixed value. The initial seed will be restored when returning @end deftypefn @node randintrlv, randsrc, randint, Function Reference @subsection randintrlv @deftypefn {Function File} {@var{intrlvd} =} randintrlv (@var{data}, @var{state}) Interleaves elements of @var{data} with a random permutation See also: intrlv, deintrlv @end deftypefn @node randsrc, rank, randintrlv, Function Reference @subsection randsrc @deftypefn {Function File} {@var{b} =} randsrc (@var{n}) @deftypefnx {Function File} {@var{b} =} randsrc (@var{n}, @var{m}) @deftypefnx {Function File} {@var{b} =} randsrc (@var{n}, @var{m}, @var{alphabet}) @deftypefnx {Function File} {@var{b} =} randsrc (@var{n}, @var{m}, @var{alphabet}, @var{seed}) Generate a matrix of random symbols. The size of the matrix is @var{n} rows by @var{m} columns. By default @var{m} is equal to @var{n} The variable @var{alphabet} can be either a row vector or a matrix with two rows. When @var{alphabet} is a row vector the symbols returned in @var{b} are chosen with equal probability from @var{alphabet}. When @var{alphabet} has two rows, the second row determines the probability with which each of the symbols is chosen. The sum of the probabilities must equal 1. By default @var{alphabet} is [-1 1] The variable @var{seed} allows the random number generator to be seeded with a fixed value. The initial seed will be restored when returning @end deftypefn @node rank, reedmullerdec, randsrc, Function Reference @subsection rank @deftypefn {Loadable Function} {@var{d} =} rank (@var{a}) Compute the rank of the Galois array @var{a} by counting the independent rows and columns @end deftypefn @node reedmullerdec, reedmullerenc, rank, Function Reference @subsection reedmullerdec @deftypefn {Function File} {} reedmullerdec (@var{VV}, @var{G}, @var{R}, @var{M}) Decode the received code word @var{VV} using the RM-generator matrix @var{G}, of order @var{R}, @var{M}, returning the code-word C. We use the standard majority logic vote method due to Irving S. Reed. The received word has to be a matrix of column size equal to to code-word size (i.e @math{2^m}). Each row is treated as a separate received word The second return value is the message @var{M} got from @var{C} G is obtained from definition type construction of Reed-Muller code, of order @var{R}, length @math{2^M}. Use the function reedmullergen, for the generator matrix for the (@var{R},@var{M}) order RM code Faster code constructions (also easier) exist, but since finding permutation order of the basis vectors, is important, we stick with the standard definitions. To use decoder function reedmullerdec, you need to use this specific generator function see: Lin & Costello, Ch.4, "Error Control Coding", 2nd Ed, Pearson @example @group g = reedmullergen (2, 4); msg = rand (1, 11) > 0.5; c = mod (msg * g, 2); [dec_c, dec_m] = reedmullerdec (c, g, 2, 4) @end group @end example See also: reedmullergen, reedmullerenc @end deftypefn @node reedmullerenc, reedmullergen, reedmullerdec, Function Reference @subsection reedmullerenc @deftypefn {Function File} {} reedmullerenc (@var{MSG}, @var{R}, @var{M}) Definition type construction of Reed-Muller code, of order @var{R}, length @math{2^M}. This function returns the generator matrix for the said order RM code Encodes the given message word/block, of column size k, corresponding to the RM(@var{R},@var{M}), and outputs a code matrix @var{C}, on each row with corresponding codeword The second return value is the @var{G}, which is generator matrix used for this code @example @group msg = rand (10, 11) > 0.5; [c, g] = reedmullerenc (msg, 2, 4); @end group @end example See also: reedmullerdec, reedmullergen @end deftypefn @node reedmullergen, reshape, reedmullerenc, Function Reference @subsection reedmullergen @deftypefn {Function File} {} reedmullergen (@var{R}, @var{M}) Definition type construction of Reed-Muller code, of order @var{R}, length @math{2^M}. This function returns the generator matrix for the said order RM code RM(r,m) codes are characterized by codewords, @code{sum ( (m,0) + (m,1) + @dots{} + (m,r)} Each of the codeword is got through spanning the space, using the finite set of m-basis codewords Each codeword is @math{2^M} elements long see: Lin & Costello, "Error Control Coding", 2nd Ed Faster code constructions (also easier) exist, but since finding permutation order of the basis vectors, is important, we stick with the standard definitions. To use decoder function reedmullerdec, you need to use this specific generator function @example @group g = reedmullergen (2, 4); @end group @end example See also: reedmullerdec, reedmullerenc @end deftypefn @node reshape, ricedeco, reedmullergen, Function Reference @subsection reshape @deftypefn {Loadable Function} {} reshape (@var{a}, @var{m}, @var{n}) Return a matrix with @var{m} rows and @var{n} columns whose elements are taken from the Galois array @var{a}. To decide how to order the elements, Octave pretends that the elements of a matrix are stored in column-major order (like Fortran arrays are stored) For example, @example reshape (gf ([1, 2, 3, 4], 3), 2, 2) ans = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 3 2 4 @end example The @code{reshape} function is equivalent to @example @group retval = gf (zeros (m, n), a.m, a.prim_poly); retval(:) = a; @end group @end example @noindent but it is somewhat less cryptic to use @code{reshape} instead of the colon operator. Note that the total number of elements in the original matrix must match the total number of elements in the new matrix See also: : @end deftypefn @node ricedeco, riceenco, reshape, Function Reference @subsection ricedeco @deftypefn {Function File} {} ricedeco (@var{code}, @var{K}) Returns the Rice decoded signal vector using @var{code} and @var{K} Compulsory K is need to be specified A restrictions is that a signal set must strictly be non-negative The value of code is a cell array of row-vectors which have the encoded rice value for a single sample. The Rice algorithm is used to encode the "code" and only that can be meaningfully decoded. @var{code} is assumed to have been of format generated by the function @code{riceenco} Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info Theory An example of the use of @code{ricedeco} is @example @group ricedeco (riceenco (1:4, 2), 2) @result{} [1 2 3 4] @end group @end example See also: riceenco @end deftypefn @node riceenco, rledeco, ricedeco, Function Reference @subsection riceenco @deftypefn {Function File} {} riceenco (@var{sig}, @var{K}) Returns the Rice encoded signal using @var{K} or optimal K Default optimal K is chosen between 0-7. Currently no other way to increase the range except to specify explicitly. Also returns @var{K} parameter used (in case it were to be chosen optimally) and @var{Ltot} the total length of output code in bits This function uses a @var{K} if supplied or by default chooses the optimal K for encoding signal vector into a rice coded vector A restrictions is that a signal set must strictly be non-negative The Rice algorithm is used to encode the data into unary coded quotient part which is represented as a set of 1's separated from the K-part (binary) using a zero. This scheme doesn't need any kind of dictionaries and its close to O(N), but this implementation *may be* sluggish, though correct Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info' Theory An example of the use of @code{riceenco} is @example @group riceenco (1:4) @result{} @{[0 1], [1 0 0], [1 0 1], [1 1 0 0]@} riceenco (1:10, 2) @result{} @{[0 0 1], [0 1 0], [0 1 1], [1 0 0 0], [1 0 0 1], [1 0 1 0], [1 0 1 1], [1 1 0 0 0], [1 1 0 0 1], [1 1 0 1 0]@} @end group @end example See also: ricedeco @end deftypefn @node rledeco, rleenco, riceenco, Function Reference @subsection rledeco @deftypefn {Function File} {} rledeco (@var{message}) Returns decoded run-length @var{message}. The RLE encoded @var{message} has to be in the form of a row-vector. The message format (encoded RLE) is like repetition [factor, value]+ An example use of @code{rledeco} is @example @group message = [1 5 2 4 3 1]; rledeco (message) @result{} [5 4 4 1 1 1] @end group @end example See also: rledeco @end deftypefn @node rleenco, roots, rledeco, Function Reference @subsection rleenco @deftypefn {Function File} {} rleenco (@var{message}) Returns run-length encoded @var{message}. The RLE form is built from @var{message}. The original @var{message} has to be in the form of a row-vector. The encoded @var{message} format (encoded RLE) is like [repetition factor]+, values An example use of @code{rleenco} is @example @group message = [5 4 4 1 1 1] rleenco (message) @result{} [1 5 2 4 3 1]; @end group @end example See also: rleenco @end deftypefn @node roots, rsdec, rleenco, Function Reference @subsection roots @deftypefn {Function File} {} roots (@var{v}) For a vector @var{v} with @math{N} components, return the roots of the polynomial over a Galois Field @tex $$ v_1 z^{N-1} + \cdots + v_{N-1} z + v_N $$ @end tex @ifnottex @example v(1) * z^(N-1) + ... + v(N-1) * z + v(N) @end example @end ifnottex The number of roots returned and their value will be determined by the order and primitive polynomial of the Galois Field @end deftypefn @node rsdec, rsdecof, roots, Function Reference @subsection rsdec @deftypefn {Loadable Function} {@var{msg} =} rsdec (@var{code}, @var{n}, @var{k}) @deftypefnx {Loadable Function} {@var{msg} =} rsdec (@var{code}, @var{n}, @var{k}, @var{g}) @deftypefnx {Loadable Function} {@var{msg} =} rsdec (@var{code}, @var{n}, @var{k}, @var{fcr}, @var{prim}) @deftypefnx {Loadable Function} {@var{msg} =} rsdec (@dots{}, @var{parpos}) @deftypefnx {Loadable Function} {[@var{msg}, @var{nerr}] =} rsdec (@dots{}) @deftypefnx {Loadable Function} {[@var{msg}, @var{nerr}, @var{ccode}] =} rsdec (@dots{}) Decodes the message contained in @var{code} using a [@var{n},@var{k}] Reed-Solomon code. The variable @var{code} must be a Galois array with @var{n} columns and an arbitrary number of rows. Each row of @var{code} represents a single block to be decoded by the Reed-Solomon coder. The decoded message is returned in the variable @var{msg} containing @var{k} columns and the same number of rows as @var{code}. If @var{n} does not equal @code{2^@var{m}-1}, where m is an integer, then a shorten Reed-Solomon decoding is used where zeros are added to the start of each row to obtain an allowable codeword length. The returned @var{msg} has these prepending zeros stripped. By default the generator polynomial used in the Reed-Solomon coding is based on the properties of the Galois Field in which @var{msg} is given. This default generator polynomial can be overridden by a polynomial in @var{g}. Suitable generator polynomials can be constructed with @code{rsgenpoly}. @var{fcr} is an integer value, and it is taken to be the first consecutive root of the generator polynomial. The variable @var{prim} is then the primitive element used to construct the generator polynomial. By default @var{fcr} and @var{prim} are both 1. It is significantly faster to specify the generator polynomial in terms of @var{fcr} and @var{prim}, since @var{g} is converted to this form in any case. By default the parity symbols are placed at the end of the coded message. The variable @var{parpos} controls this positioning and can take the values @code{"beginning\"} or @code{\"end\"}. If the parity symbols are at the end, the message is treated with the most-significant symbol first, otherwise the message is treated with the least-significant symbol first. See also: gf, rsenc, rsgenpoly @end deftypefn @node rsdecof, rsenc, rsdec, Function Reference @subsection rsdecof @deftypefn {Function File} {} rsdecof (@var{in}, @var{out}) @deftypefnx {Function File} {} rsdecof (@var{in}, @var{out}, @var{t}) Decodes an ASCII file using a Reed-Solomon coder. The input file is defined by @var{in} and the result is written to the output file @var{out} The type of coding to use is determined by whether the input file is 7- or 8-bit. If the input file is 7-bit, the default coding is [127,117] while the default coding for an 8-bit file is a [255, 235]. This allows for 5 or 10 error characters in 127 or 255 symbols to be corrected respectively. The number of errors that can be corrected can be overridden by the variable @var{t} If the file is not an integer multiple of the message size (127 or 255) in length, then the file is padded with the EOT (ASCII character 4) character before decoding See also: rsencof @end deftypefn @node rsenc, rsencof, rsdecof, Function Reference @subsection rsenc @deftypefn {Loadable Function} {@var{code} =} rsenc (@var{msg}, @var{n}, @var{k}) @deftypefnx {Loadable Function} {@var{code} =} rsenc (@var{msg}, @var{n}, @var{k}, @var{g}) @deftypefnx {Loadable Function} {@var{code} =} rsenc (@var{msg}, @var{n}, @var{k}, @var{fcr}, @var{prim}) @deftypefnx {Loadable Function} {@var{code} =} rsenc (@dots{}, @var{parpos}) Encodes the message @var{msg} using a [@var{n},@var{k}] Reed-Solomon coding. The variable @var{msg} is a Galois array with @var{k} columns and an arbitrary number of rows. Each row of @var{msg} represents a single block to be coded by the Reed-Solomon coder. The coded message is returned in the Galois array @var{code} containing @var{n} columns and the same number of rows as @var{msg}. The use of @code{rsenc} can be seen in the following short example. @example m = 3; n = 2^m -1; k = 3; msg = gf ([1 2 3; 4 5 6], m); code = rsenc (msg, n, k); @end example If @var{n} does not equal @code{2^@var{m}-1}, where m is an integer, then a shorten Reed-Solomon coding is used where zeros are added to the start of each row to obtain an allowable codeword length. The returned @var{code} has these prepending zeros stripped. By default the generator polynomial used in the Reed-Solomon coding is based on the properties of the Galois Field in which @var{msg} is given. This default generator polynomial can be overridden by a polynomial in @var{g}. Suitable generator polynomials can be constructed with @code{rsgenpoly}. @var{fcr} is an integer value, and it is taken to be the first consecutive root of the generator polynomial. The variable @var{prim} is then the primitive element used to construct the generator polynomial, such that @tex $g = (x - A^b) (x - A^{b+p}) \cdots (x - A ^{b+2tp-1})$. @end tex @ifnottex @var{g} = (@var{x} - A^@var{b}) * (@var{x} - A^(@var{b}+@var{prim})) * ... * (@var{x} - A^(@var{b}+2*@var{t}*@var{prim}-1)). @end ifnottex where @var{b} is equal to @code{@var{fcr} * @var{prim}}. By default @var{fcr} and @var{prim} are both 1. By default the parity symbols are placed at the end of the coded message. The variable @var{parpos} controls this positioning and can take the values @code{"beginning\"} or @code{\"end\"}. See also: gf, rsdec, rsgenpoly @end deftypefn @node rsencof, rsgenpoly, rsenc, Function Reference @subsection rsencof @deftypefn {Function File} {} rsencof (@var{in}, @var{out}) @deftypefnx {Function File} {} rsencof (@var{in}, @var{out}, @var{t}) @deftypefnx {Function File} {} rsencof (@dots{}, @var{pad}) Encodes an ASCII file using a Reed-Solomon coder. The input file is defined by @var{in} and the result is written to the output file @var{out} The type of coding to use is determined by whether the input file is 7- or 8-bit. If the input file is 7-bit, the default coding is [127,117] while the default coding for an 8-bit file is a [255, 235]. This allows for 5 or 10 error characters in 127 or 255 symbols to be corrected respectively. The number of errors that can be corrected can be overridden by the variable @var{t} If the file is not an integer multiple of the message size (127 or 255) in length, then the file is padded with the EOT (ASCII character 4) characters before coding. Whether these characters are written to the output is defined by the @var{pad} variable. Valid values for @var{pad} are "pad" (the default) and "nopad", which write or not the padding respectively See also: rsdecof @end deftypefn @node rsgenpoly, scatterplot, rsencof, Function Reference @subsection rsgenpoly @deftypefn {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}) @deftypefnx {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}, @var{p}) @deftypefnx {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}, @var{p}, @var{b}, @var{s}) @deftypefnx {Function File} {@var{g} =} rsgenpoly (@var{n}, @var{k}, @var{p}, @var{b}) @deftypefnx {Function File} {[@var{g}, @var{t}] =} rsgenpoly (@dots{}) Creates a generator polynomial for a Reed-Solomon coding with message length of @var{k} and codelength of @var{n}. @var{n} must be greater than @var{k} and their difference must be even. The generator polynomial is returned on @var{g} as a polynomial over the Galois Field GF(2^@var{m}) where @var{n} is equal to @code{2^@var{m}-1}. If @var{m} is not integer the next highest integer value is used and a generator for a shorten Reed-Solomon code is returned The elements of @var{g} represent the coefficients of the polynomial in descending order. If the length of @var{g} is lg, then the generator polynomial is given by @tex $$ g_0 x^{lg-1} + g_1 x^{lg-2} + \cdots + g_{lg-1} x + g_lg $$ @end tex @ifnottex @example @var{g}(0) * x^(lg-1) + @var{g}(1) * x^(lg-2) + ... + @var{g}(lg-1) * x + @var{g}(lg) @end example @end ifnottex If @var{p} is defined then it is used as the primitive polynomial of the Galois Field GF(2^@var{m}). The default primitive polynomial will be used if @var{p} is equal to [] The variables @var{b} and @var{s} determine the form of the generator polynomial in the following manner @tex $$ g = (x - A^{bs}) (x - A^{(b+1)s}) \cdots (x - A ^{(b+2t-1)s}) $$ @end tex @ifnottex @example @var{g} = (@var{x} - A^(@var{b}*@var{s})) * (@var{x} - A^((@var{b}+1)*@var{s})) * ... * (@var{x} - A^((@var{b}+2*@var{t}-1)*@var{s})) @end example @end ifnottex where @var{t} is @code{(@var{n}-@var{k})/2}, and A is the primitive element of the Galois Field. Therefore @var{b} is the first consecutive root of the generator polynomial and @var{s} is the primitive element to generate the polynomial roots If requested the variable @var{t}, which gives the error correction capability of the Reed-Solomon code See also: gf, rsenc, rsdec @end deftypefn @node scatterplot, shannonfanodeco, rsgenpoly, Function Reference @subsection scatterplot @deftypefn {Function File} {} scatterplot (@var{x}) @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}) @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}, @var{off}) @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}, @var{off}, @var{str}) @deftypefnx {Function File} {} scatterplot (@var{x}, @var{n}, @var{off}, @var{str}, @var{h}) @deftypefnx {Function File} {@var{h} =} scatterplot (@dots{}) Display the scatter plot of a signal. The signal @var{x} can be either in one of three forms @table @asis @item A real vector In this case the signal is assumed to be real and represented by the vector @var{x}. The scatterplot is plotted along the x axis only @item A complex vector In this case the in-phase and quadrature components of the signal are plotted separately on the x and y axes respectively @item A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal and are plotted on the x and y axes respectively @end table Each point of the scatter plot is assumed to be separated by @var{n} elements in the signal. The first element of the signal to plot is determined by @var{off}. By default @var{n} is 1 and @var{off} is 0 The string @var{str} is a plot style string (example "r+"), and by default is the default gnuplot point style The figure handle to use can be defined by @var{h}. If @var{h} is not given, then the next available figure handle is used. The figure handle used in returned on @var{hout} See also: eyediagram @end deftypefn @node shannonfanodeco, shannonfanodict, scatterplot, Function Reference @subsection shannonfanodeco @deftypefn {Function File} {} shannonfanodeco (@var{hcode}, @var{dict}) Returns the original signal that was Shannon-Fano encoded. The signal was encoded using @code{shannonfanoenco}. This function uses a dict built from the @code{shannonfanodict} and uses it to decode a signal list into a Shannon-Fano list. Restrictions include hcode is expected to be a binary code; returned signal set that strictly belongs in the @code{range [1,N]}, with @code{N = length (dict)}. Also dict can only be from the @code{shannonfanodict (...)} routine. Whenever decoding fails, those signal values are indicated by -1, and we successively try to restart decoding from the next bit that hasn't failed in decoding, ad-infinitum An example use of @code{shannonfanodeco} is @example @group hd = shannonfanodict (1:4, [0.5 0.25 0.15 0.10]); hcode = shannonfanoenco (1:4, hd) @result{} hcode = [0 1 0 1 1 0 1 1 1 0] shannonfanodeco (hcode, hd) @result{} [1 2 3 4] @end group @end example See also: shannonfanoenco, shannonfanodict @end deftypefn @node shannonfanodict, shannonfanoenco, shannonfanodeco, Function Reference @subsection shannonfanodict @deftypefn {Function File} {} shannonfanodict (@var{symbols}, @var{symbol_probabilites}) Returns the code dictionary for source using Shannon-Fano algorithm Dictionary is built from @var{symbol_probabilities} using the Shannon-Fano scheme. Output is a dictionary cell-array, which are codewords, and correspond to the order of input probability @example @group cw = shannonfanodict (1:4, [0.5 0.25 0.15 0.1]); assert (redundancy (cw, [0.5 0.25 0.15 0.1]), 0.25841, 0.001) shannonfanodict (1:5, [0.35 0.17 0.17 0.16 0.15]) shannonfanodict (1:8, [8 7 6 5 5 4 3 2] / 40) @end group @end example See also: shannonfanoenc, shannonfanodec @end deftypefn @node shannonfanoenco, sqrt, shannonfanodict, Function Reference @subsection shannonfanoenco @deftypefn {Function File} {} shannonfanoenco (@var{hcode}, @var{dict}) Returns the Shannon-Fano encoded signal using @var{dict} This function uses a @var{dict} built from the @code{shannonfanodict} and uses it to encode a signal list into a Shannon-Fano code Restrictions include a signal set that strictly belongs in the @code{range [1,N]} with @code{N = length (dict)}. Also dict can only be from the @code{shannonfanodict} routine An example use of @code{shannonfanoenco} is @example @group hd = shannonfanodict (1:4, [0.5 0.25 0.15 0.10]); shannonfanoenco (1:4, hd) @result{} [0 1 0 1 1 0 1 1 1 0] @end group @end example See also: shannonfanodeco, shannonfanodict @end deftypefn @node sqrt, sum, shannonfanoenco, Function Reference @subsection sqrt @deftypefn {Loadable Function} {} sqrt (@var{x}) Compute the square root of @var{x}, element by element, in a Galois Field See also: exp @end deftypefn @node sum, sumsq, sqrt, Function Reference @subsection sum @deftypefn {Loadable Function} {} sum (@var{x}, @var{dim}) Sum of elements along dimension @var{dim} of Galois array. If @var{dim} is omitted, it defaults to 1 (column-wise sum) @end deftypefn @node sumsq, symerr, sum, Function Reference @subsection sumsq @deftypefn {Loadable Function} {} sumsq (@var{x}, @var{dim}) Sum of squares of elements along dimension @var{dim} of Galois array If @var{dim} is omitted, it defaults to 1 (column-wise sum of squares) This function is equivalent to computing @example gsum (x .* conj (x), dim) @end example but it uses less memory @end deftypefn @node symerr, syndtable, sumsq, Function Reference @subsection symerr @deftypefn {Function File} {[@var{num}, @var{rate}] =} symerr (@var{a}, @var{b}) @deftypefnx {Function File} {[@var{num}, @var{rate}] =} symerr (@dots{}, @var{flag}) @deftypefnx {Function File} {[@var{num}, @var{rate} @var{ind}] =} symerr (@dots{}) Compares two matrices and returns the number of symbol errors and the symbol error rate. The variables @var{a} and @var{b} can be either: @table @asis @item Both matrices In this case both matrices must be the same size and then by default the return values @var{num} and @var{rate} are the overall number of symbol errors and the overall symbol error rate @item One column vector In this case the column vector is used for symbol error comparison column-wise with the matrix. The returned values @var{num} and @var{rate} are then row vectors containing the number of symbol errors and the symbol error rate for each of the column-wise comparisons. The number of rows in the matrix must be the same as the length of the column vector @item One row vector In this case the row vector is used for symbol error comparison row-wise with the matrix. The returned values @var{num} and @var{rate} are then column vectors containing the number of symbol errors and the symbol error rate for each of the row-wise comparisons. The number of columns in the matrix must be the same as the length of the row vector @end table This behavior can be overridden with the variable @var{flag}. @var{flag} can take the value "column-wise", "row-wise" or "overall". A column-wise comparison is not possible with a row vector and visa-versa @end deftypefn @node syndtable, systematize, symerr, Function Reference @subsection syndtable @deftypefn {Loadable Function} {@var{t} =} syndtable (@var{h}) Create the syndrome decoding table from the parity check matrix @var{h}. Each row of the returned matrix @var{t} represents the error vector in a received symbol for a certain syndrome. The row selected is determined by a conversion of the syndrome to an integer representation, and using this to reference each row of @var{t}. See also: hammgen, cyclgen @end deftypefn @node systematize, vec2mat, syndtable, Function Reference @subsection systematize @deftypefn {Function File} {} systematize (@var{G}) Given @var{G}, extract P parity check matrix. Assume row-operations in GF(2) @var{G} is of size KxN, when decomposed through row-operations into a @var{I} of size KxK identity matrix, and a parity check matrix @var{P} of size Kx(N-K) Most arbitrary code with a given generator matrix @var{G}, can be converted into its systematic form using this function This function returns 2 values, first is default being @var{Gx} the systematic version of the @var{G} matrix, and then the parity check matrix @var{P} @example @group g = [1 1 1 1; 1 1 0 1; 1 0 0 1]; [gx, p] = systematize (g); @result{} gx = [1 0 0 1; 0 1 0 0; 0 0 1 0]; @result{} p = [1 0 0]; @end group @end example See also: bchpoly, biterr @end deftypefn @node vec2mat, wgn, systematize, Function Reference @subsection vec2mat @deftypefn {Function File} {@var{m} =} vec2mat (@var{v}, @var{c}) @deftypefnx {Function File} {@var{m} =} vec2mat (@var{v}, @var{c}, @var{d}) @deftypefnx {Function File} {[@var{m}, @var{add}] =} vec2mat (@dots{}) Converts the vector @var{v} into a @var{c} column matrix with row priority arrangement and with the final column padded with the value @var{d} to the correct length. By default @var{d} is 0. The amount of padding added to the matrix is returned in @var{add} @end deftypefn @node wgn, , vec2mat, Function Reference @subsection wgn @deftypefn {Function File} {@var{y} =} wgn (@var{m}, @var{n}, @var{p}) @deftypefnx {Function File} {@var{y} =} wgn (@var{m}, @var{n}, @var{p}, @var{imp}) @deftypefnx {Function File} {@var{y} =} wgn (@var{m}, @var{n}, @var{p}, @var{imp}, @var{seed}) @deftypefnx {Function File} {@var{y} =} wgn (@dots{}, @var{type}) @deftypefnx {Function File} {@var{y} =} wgn (@dots{}, @var{output}) Returns a M-by-N matrix @var{y} of white Gaussian noise. @var{p} specifies the power of the output noise, which is assumed to be referenced to an impedance of 1 Ohm, unless @var{imp} explicitly defines the impedance If @var{seed} is defined then the randn function is seeded with this value The arguments @var{type} and @var{output} must follow the above numerical arguments, but can be specified in any order. @var{type} specifies the units of @var{p}, and can be "dB", "dBW", "dBm" or "linear". "dB" is in fact the same as "dBW" and is keep as a misnomer of Matlab. The units of "linear" are in Watts The @var{output} variable should be either "real" or "complex". If the output is complex then the power @var{p} is divided equally between the real and imaginary parts See also: randn, awgn @end deftypefn @bye communications-1.2.1/doc/PaxHeaders.3802/commsimages.m0000644000000000000000000000013212510010473017434 xustar0030 mtime=1428164923.854512206 30 atime=1428164924.058507554 30 ctime=1428164983.712815029 communications-1.2.1/doc/commsimages.m0000644000000000000000000000533412510010473017766 0ustar00rootroot00000000000000## Copyright (C) 2007-2012 David Bateman ## Copyright (C) 2013 Mike Miller ## ## This program 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. ## ## This program 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 ## this program; if not, see . ## . function commsimages (nm, typ) graphics_toolkit ("gnuplot"); set_print_size (); hide_output (); if (strcmp (typ, "png")) set (0, "defaulttextfontname", "*"); endif if (strcmp (typ, "eps")) d_typ = "-depsc2"; else d_typ = ["-d", typ]; endif if (strcmp (nm, "awgn")) x = 0:0.1:2*pi; y = sin (x); noisy = awgn (y, 10, "measured"); plot (x, y, "r"); hold on; plot (x, noisy, "g--"); axis ([0, 2*pi, -1.5, 1.5]); print ([nm "." typ], d_typ); elseif (strcmp (nm, "eyediagram")) n = 50; ovsp = 50; x = 1:n; xi = 1:1/ovsp:n-0.1; y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); yi = interp1 (x, y, xi); noisy = awgn (yi, 15, "measured"); cf = gcf (); set (cf, "tag", "eyediagram"); eyediagram (noisy, ovsp, [], [], [], cf); print ([nm "." typ], d_typ); elseif (strcmp (nm, "scatterplot")) n = 200; ovsp = 5; x = 1:n; xi = 1:1/ovsp:n-0.1; y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); yi = interp1 (x, y, xi); noisy = awgn (yi, 15, "measured"); cf = gcf (); set (cf, "tag", "scatterplot"); f = scatterplot (noisy, 1, 0, "b", cf); hold on; scatterplot (noisy, ovsp, 0, "r+", f); print ([nm "." typ], d_typ); else error ("unrecognized plot requested"); endif hide_output (); endfunction function set_print_size () image_size = [5.0, 3.5]; # in inches, 16:9 format border = 0; # For postscript use 50/72 set (0, "defaultfigurepapertype", ""); set (0, "defaultfigurepaperorientation", "landscape"); set (0, "defaultfigurepapersize", image_size + 2*border); set (0, "defaultfigurepaperposition", [border, border, image_size]); endfunction ## Use this function before plotting commands and after every call to ## print since print resets output to stdout (unfortunately, gnuplot ## can't pop output as it can the terminal type). function hide_output () f = figure (1); set (f, "visible", "off"); endfunction communications-1.2.1/doc/PaxHeaders.3802/comms.info0000644000000000000000000000013212510010567016751 xustar0030 mtime=1428164983.408825079 30 atime=1428164981.412890769 30 ctime=1428164983.712815029 communications-1.2.1/doc/comms.info0000644000000000000000000061026712510010567017312 0ustar00rootroot00000000000000This is comms.info, produced by makeinfo version 5.2 from comms.texi.  File: comms.info, Node: Top, Next: Introduction Communications Package for Octave ********************************* * Menu: * Introduction:: * Random Signals:: * Source Coding:: * Block Coding:: * Convolutional Coding:: * Modulations:: * Special Filters:: * Galois Fields:: * Function Reference::  File: comms.info, Node: Introduction, Next: Random Signals, Prev: Top, Up: Top 1 Introduction ************** This is the manual for the Communications Package for GNU Octave. All functions provided by this package are described in this manual. In addition many functions from Octave and other Octave packages are useful to or required by this package, and so they may also be explained or shown in examples in this manual. This documentation is a work in progress, you are invited to help improve it and submit patches.  File: comms.info, Node: Random Signals, Next: Source Coding, Prev: Introduction, Up: Top 2 Random Signals **************** The purpose of the functions described here is to create and add random noise to a signal, to create random data and to analyze the eventually errors in a received signal. The functions to perform these tasks can be considered as either related to the creation or analysis of signals and are treated separately below. It should be noted that the examples below are based on the output of a random number generator, and so the user can not expect to exactly recreate the examples below. * Menu: * Signal Creation:: * Signal Analysis::  File: comms.info, Node: Signal Creation, Next: Signal Analysis, Up: Random Signals 2.1 Signal Creation =================== The signal creation functions here fall into to two classes. Those that treat discrete data and those that treat continuous data. The basic function to create discrete data is 'randint', that creates a random matrix of equi-probable integers in a desired range. For example octave:1> a = randint (3, 3, [-1, 1]) a = 0 1 0 -1 -1 1 0 1 1 creates a 3-by-3 matrix of random integers in the range -1 to 1. To allow for repeated analysis with the same random data, the function 'randint' allows the seed-value of the random number generator to be set. For instance octave:1> a = randint (3, 3, [-1, 1], 1) a = 0 1 1 0 -1 0 1 -1 -1 will always produce the same set of random data. The range of the integers to produce can either be a two element vector or an integer. In the case of a two element vector all elements within the defined range can be produced. In the case of an integer range M, 'randint' returns the equi-probable integers in the range [0:2^M-1]. The function 'randsrc' differs from 'randint' in that it allows a random set of symbols to be created with a given probability. The symbols can be real, complex or even characters. However characters and scalars can not be mixed. For example octave:1> a = randsrc (2, 2, "ab"); octave:2> b = randsrc (4, 4, [1, 1i, -1, -1i]); are both legal, while octave:1> a = randsrc (2, 2, [1, "a"]); is not legal. The alphabet from which the symbols are chosen can be either a row vector or two row matrix. In the case of a row vector, all of the elements of the alphabet are chosen with an equal probability. In the case of a two row matrix, the values in the second row define the probability that each of the symbols are chosen. For example octave:1> a = randsrc (5, 5, [1, 1i, -1, -1i; 0.6 0.2 0.1 0.1]) a = 1 + 0i 0 + 1i 0 + 1i 0 + 1i 1 + 0i 1 + 0i 1 + 0i 0 + 1i 0 + 1i 1 + 0i -0 - 1i 1 + 0i -1 + 0i 1 + 0i 0 + 1i 1 + 0i 1 + 0i 1 + 0i 1 + 0i 1 + 0i -1 + 0i -1 + 0i 1 + 0i 1 + 0i 1 + 0i defines that the symbol '1' has a 60% probability, the symbol '1i' has a 20% probability and the remaining symbols have 10% probability each. The sum of the probabilities must equal one. Like 'randint', 'randsrc' accepts a fourth argument as the seed of the random number generator allowing the same random set of data to be reproduced. The function 'randerr' allows a matrix of random bit errors to be created, for binary encoded messages. By default, 'randerr' creates exactly one errors per row, flagged by a non-zero value in the returned matrix. That is octave:1> a = randerr (5, 10) a = 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 The number of errors per row can be specified as the third argument to 'randerr'. This argument can be either a scalar, a row vector or a two row matrix. In the case of a scalar value, exactly this number of errors will be created per row in the returned matrix. In the case of a row vector, each element of the row vector gives a possible number of equi-probable bit errors. The second row of a two row matrix defines the probability of each number of errors occurring. For example octave:1> n = 15; k = 11; nsym = 100; octave:2> msg = randint (nsym, k); ## Binary vector of message octave:3> code = encode (msg, n, k, "bch"); octave:4> berrs = randerr (nsym, n, [0, 1; 0.7, 0.3]); octave:5> noisy = mod (code + berrs, 2) ## Add errors to coded message creates a vector MSG, encodes it with a [15,11] BCH code, and then add either none or one error per symbol with the chances of an error being 30%. As previously, 'randerr' accepts a fourth argument as the seed of the random number generator allowing the same random set of data to be reproduced. All of the above functions work on discrete random signals. The functions 'wgn' and 'awgn' create and add white Gaussian noise to continuous signals. The function 'wgn' creates a matrix of white Gaussian noise of a certain power. A typical call to 'wgn' is then octave:1> nse = wgn (10, 10, 0); which creates a 10-by-10 matrix of noise with a root mean squared power of 0dBW relative to an impedance of 1 Ohm. This effectively means that an equivalent result to the above can be obtained with octave:1> nse = randn (10, 10); The reference impedance and units of power to the function 'wgn' can however be modified, for example octave:1> nse_30dBm_50Ohm = wgn (10000, 1, 30, 50, "dBm"); octave:2> nse_0dBW_50Ohm = wgn (10000, 1, 0, 50, "dBW"); octave:3> nse_1W_50Ohm = wgn (10000, 1, 1, 50, "linear"); octave:4> [std(nse_30dBm_50Ohm), std(nse_0dBW_50Ohm), std(nse_1W_50Ohm)] ans = 7.0805 7.1061 7.0730 Each of these produces a 1W signal referenced to a 50 Ohm impedance. MATLAB uses the misnomer "dB" for "dBW", so "dB" is an accepted type for 'wgn' and is treated as a synonym for "dBW". In all cases, the returned matrix V, will be related to the input power P and the impedance Z as P = sum (V(:) .^ 2 ) / IMP Watts By default 'wgn' produces real vectors of white noise. However, it can produce both real and complex vectors like octave:1> rnse = wgn (10000, 1, 0, "dBm", "real"); octave:2> cnse = wgn (10000, 1, 0, "dBm", "complex"); octave:3> [std(rnse), std(real (cnse)), std(imag (cnse)), std(cnse)] ans = 0.031615 0.022042 0.022241 0.031313 which shows that with a complex return value that the total power is the same as a real vector, but that it is equally shared between the real and imaginary parts. As previously, 'wgn' accepts a fourth numerical argument as the seed of the random number generator allowing the same random set of data to be reproduced. That is octave:1> nse = wgn (10, 10, 0, 0); will always produce the same set of data. The final function to deal with the creation of random signals is 'awgn', that adds noise at a certain level relative to a desired signal. This function adds noise at a certain level to a desired signal. An example call to 'awgn' is octave:1> x = [0:0.1:2*pi]; octave:2> y = sin (x); octave:3> noisy = awgn (y, 10, "measured") which adds noise with a 10dB signal-to-noise ratio to the measured power in the desired signal. By default 'awgn' assumes that the desired signal is at 0dBW, and the noise is added relative to this assumed power. This behavior can be modified by the third argument to 'awgn'. If the third argument is a numerical value, it is assumed to define the power in the input signal, otherwise if the third argument is the string "measured", as above, the power in the signal is measured prior to the addition of the noise. The final argument to 'awgn' defines the definition of the power and signal-to-noise ratio in a similar manner to 'wgn'. This final argument can be either "dB" or "linear". In the first case the numerical value of the input power is assumed to be in dBW and the signal-to-noise ratio in dB. In the second case, the power is assumed to be in Watts and the signal-to-noise ratio is expressed as a ratio. The return value of 'awgn' will be in the same form as the input signal. In addition if the input signal is real, the additive noise will be real. Otherwise the additive noise will also be complex and the noise will be equally split between the real and imaginary parts. As previously the seed to the random number generator can be specified as the last argument to 'awgn' to allow repetition of the same scenario. That is octave:1> x = [0:0.1:2*pi]; octave:2> y = sin (x); octave:3> noisy = awgn (y, 10, "dB", 0, "measured") which uses the seed-value of 0 for the random number generator.  File: comms.info, Node: Signal Analysis, Prev: Signal Creation, Up: Random Signals 2.2 Signal Analysis =================== It is important to be able to evaluate the performance of a communications system in terms of its bit-error and symbol-error rates. Two functions 'biterr' and 'symerr' exist within this package to calculate these values, both taking as arguments the expected and the actually received data. The data takes the form of matrices or vectors, with each element representing a single symbol. They are compared in the following manner Both matrices In this case both matrices must be the same size and then by default the return values are the overall number of errors and the overall error rate. One column vector In this case the column vector is used for comparison column-wise with the matrix. The return values are row vectors containing the number of errors and the error rate for each column-wise comparison. The number of rows in the matrix must be the same as the length of the column vector. One row vector In this case the row vector is used for comparison row-wise with the matrix. The return values are column vectors containing the number of errors and the error rate for each row-wise comparison. The number of columns in the matrix must be the same as the length of the row vector. For the bit-error comparison, the size of the symbol is assumed to be the minimum number of bits needed to represent the largest element in the two matrices supplied. However, the number of bits per symbol can (and in the case of random data should) be specified. As an example of the use of 'biterr' and 'symerr', consider the example octave:1> m = 8; octave:2> msg = randint (10, 10, 2^m); octave:3> noisy = mod (msg + diag (1:10), 2^m); octave:4> [berr, brate] = biterr (msg, noisy, m) berr = 32 brate = 0.040000 octave:5> [serr, srate] = symerr (msg, noisy) serr = 10 srate = 0.10000 which creates a 10-by-10 matrix adds 10 symbols errors to the data and then finds the bit and symbol error-rates. Two other means of displaying the integrity of a signal are the eye-diagram and the scatterplot. Although the functions 'eyediagram' and 'scatterplot' have different appearance, the information presented is similar and so are their inputs. The difference between 'eyediagram' and 'scatterplot' is that 'eyediagram' segments the data into time intervals and plots the in-phase and quadrature components of the signal against this time interval. While 'scatterplot' uses a parametric plot of quadrature versus in-phase components. Both functions can accept real or complex signals in the following forms. A real vector In this case the signal is assumed to be real and represented by the vector X. A complex vector In this case the in-phase and quadrature components of the signal are assumed to be the real and imaginary parts of the signal. A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal. An example of the use of the function 'eyediagram' is octave:1> n = 50; octave:2> ovsp = 50; octave:3> x = 1:n; octave:4> xi = 1:1/ovsp:n-0.1; octave:5> y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); octave:6> yi = interp1 (x, y, xi); octave:7> noisy = awgn (yi, 15, "measured"); octave:8> eyediagram (noisy, ovsp); Similarly an example of the use of the function 'scatterplot' is octave:1> n = 200; octave:2> ovsp = 5; octave:3> x = 1:n; octave:4> xi = 1:1/ovsp:n-0.1; octave:5> y = randsrc (1, n, [1 + 1i, 1 - 1i, -1 - 1i, -1 + 1i]); octave:6> yi = interp1 (x, y, xi); octave:7> noisy = awgn (yi, 15, "measured"); octave:8> f = scatterplot (noisy, 1, 0, "b"); octave:9> hold on; octave:10> scatterplot (noisy, ovsp, 0, "r+", f);  File: comms.info, Node: Source Coding, Next: Block Coding, Prev: Random Signals, Up: Top 3 Source Coding *************** * Menu: * Quantization:: * PCM Coding:: * Arithmetic Coding:: * Dynamic Range Compression::  File: comms.info, Node: Quantization, Next: PCM Coding, Up: Source Coding 3.1 Quantization ================ An important aspect of converting an analog signal to the digital domain is quantization. This is the process of mapping a continuous signal to a set of defined values. Octave contains two functions to perform quantization, 'lloyds' creates an optimal mapping of the continuous signal to a fixed number of levels and 'quantiz' performs the actual quantization. The set of quantization points to use is represented by a partitioning table (TABLE) of the data and the signal levels (CODES to which they are mapped. The partitioning TABLE is monotonically increasing and if x falls within the range given by two points of this table then it is mapped to the corresponding code as seen in Table 1. Table 1: Table quantization partitioning and coding x < table(1) codes(1) table(1) <= x < table(2) codes(2) ... ... table(i-1) <= x < table(i) codes(i) ... ... table(n-1) <= x < table(n) codes(n) table(n-1) <= x codes(n+1) These partition and coding tables can either be created by the user of using the function 'lloyds'. For instance the use of a linear mapping can be seen in the following example. octave:1> m = 8; octave:2> n = 1024; octave:3> table = 2*[0:m-1]/m - 1 + 1/m; octave:4> codes = 2*[0:m]/m - 1; octave:5> x = 4*pi*[0:(n-1)]/(n-1); octave:6> y = cos (x); octave:7> [i, z] = quantiz (y, table, codes); If a training signal is known that well represents the expected signals, the quantization levels can be optimized using the 'lloyds' function. For example the above example can be continued octave:8> [table2, codes2] = lloyds (y, table, codes); octave:9> [i, z2] = quantiz (y, table2, codes2); to use the mapping suggested by the function 'lloyds'. It should be noted that the mapping given by 'lloyds' is highly dependent on the training signal used. So if this signal does not represent a realistic signal to be quantized, then the partitioning suggested by 'lloyds' will be sub-optimal.  File: comms.info, Node: PCM Coding, Next: Arithmetic Coding, Prev: Quantization, Up: Source Coding 3.2 PCM Coding ============== The DPCM function 'dpcmenco', 'dpcmdeco' and 'dpcmopt' implement a form of predictive quantization, where the predictability of the signal is used to further compress it. These functions are not yet implemented.  File: comms.info, Node: Arithmetic Coding, Next: Dynamic Range Compression, Prev: PCM Coding, Up: Source Coding 3.3 Arithmetic Coding ===================== The arithmetic coding functions 'arithenco' and 'arithdeco' are not yet implemented.  File: comms.info, Node: Dynamic Range Compression, Prev: Arithmetic Coding, Up: Source Coding 3.4 Dynamic Range Compression ============================= The final source coding function is 'compand' which is used to compress and expand the dynamic range of a signal. For instance consider a logarithm quantized by a linear partitioning. Such a partitioning is very poor for this large dynamic range. 'compand' can then be used to compress the signal prior to quantization, with the signal being expanded afterwards. For example octave:1> mu = 1.95; octave:2> x = [0.01:0.01:2]; octave:3> y = log (x); octave:4> V = max (abs (y)); octave:5> [i, z, d] = quantiz (y, [-4.875:0.25:0.875], [-5:0.25:1]); octave:6> c = compand (y, minmu, V, "mu/compressor"); octave:7> [i2, c2] = quantiz (c, [-4.875:0.25:0.875], [-5:0.25:1]); octave:8> z2 = compand (c2, minmu, max (abs (c2)), "mu/expander"); octave:9> d2 = sumsq (y - z2) / length (y); octave:10> [d, d2] ans = 0.0053885 0.0029935 which demonstrates that the use of 'compand' can significantly reduce the distortion due to the quantization of signals with a large dynamic range.  File: comms.info, Node: Block Coding, Next: Convolutional Coding, Prev: Source Coding, Up: Top 4 Block Coding ************** The error-correcting codes available in this package are discussed here. These codes work with blocks of data, with no relation between one block and the next. These codes create codewords based on the messages to transmit that contain redundant information that allow the recovery of the original message in the presence of errors. * Menu: * Data Formats:: * Binary Block Codes:: * BCH Codes:: * Reed-Solomon Codes::  File: comms.info, Node: Data Formats, Next: Binary Block Codes, Up: Block Coding 4.1 Data Formats ================ All of the codes described in this section are binary and share similar data formats. The exception is the Reed-Solomon coder which has a significantly longer codeword length in general and therefore uses a different representation to efficiently pass data. The user should refer to the section about the Reed-Solomon codes for the data format used for Reed-Solomon codes. In general K bits of data are considered to represent a single message symbol. These K bits are coded into N bits of data representing the codeword. The data can therefore be grouped in one of three manners, to emphasis this grouping into bits, messages and codewords A binary vector Each element of the vector is either one or zero. If the data represents an uncoded message the vector length should be an integer number of K in length. A binary matrix In this case the data is ones and zeros grouped into rows, with each representing a single message or codeword. The number of columns in the matrix should be equal to K in the case of a uncoded message or N in the case of a coded message. A non-binary vector In this case each element of the vector represents a message or codeword in an integer format. The bits of the message or codeword are represented by the bits of the vector elements with the least-significant bit representing the first element in the message or codeword. An example demonstrating the relationship between the three data formats can be seen below. octave:1> k = 4; octave:2> bin_vec = randint (k*10, 1); # Binary vector format octave:3> bin_mat = reshape (bin_vec, k, 10)'; # Binary matrix format octave:4> dec_vec = bi2de (bin_mat); # Decimal vector format The functions within this package will return data in the same format to which it is given. It should be noted that internally the binary matrix format is used, and thus if the message or codeword length is large it is preferable to use the binary format to avoid internal rounding errors.  File: comms.info, Node: Binary Block Codes, Next: BCH Codes, Prev: Data Formats, Up: Block Coding 4.2 Binary Block Codes ====================== All of the codes presented here can be characterized by their Generator Matrix A K-by-N matrix G to generate the codewords C from the messages T by the matrix multiplication C = T * G. Parity Check Matrix A 'N-K'-by-N matrix H to check the parity of the received symbols. If H * R = S != 0, then an error has been detected. S can be used with the syndrome table to correct this error Syndrome Table A 2^K-by-N matrix ST with the relationship of the error vectors to the non-zero parities of the received symbols. That is, if the received symbol is represented as R = mod (T + E, 2), then the error vector E is ST(S). It is assumed for most of the functions in this package that the generator matrix will be in a 'standard' form. That is the generator matrix can be represented by g(1,1) g(1,2) ... g(1,k) 1 0 ... 0 g(2,1) g(2,2) g(2,k) 0 1 ... 0 . . . . . . . . . . . . g(k,1) g(k,2) ... g(k,k) 0 0 ... 1 or 1 0 ... 0 g(1,1) g(1,2) ... g(1,k) 0 1 ... 0 g(2,1) g(2,2) g(2,k) . . . . . . . . . . . . 0 0 ... 1 g(k,1) g(k,2) ... g(k,k) and similarly the parity check matrix can be represented by a combination of an identity matrix and a square matrix. Some of the codes can also have their representation in terms of a generator polynomial that can be used to create the generator and parity check matrices. In the case of BCH codes, this generator polynomial is used directly in the encoding and decoding without ever explicitly forming the generator or parity check matrix. The user can create their own generator and parity check matrices, or they can rely on the functions 'hammgen', 'cyclgen' and 'cyclpoly'. The function 'hammgen' creates parity check and generator matrices for Hamming codes, while 'cyclpoly' and 'cyclgen' create generator polynomials and matrices for generic cyclic codes. An example of their use is octave:1> m = 3; octave:2> n = 2^m - 1; octave:2> k = 4; octave:3> [par, gen] = hammgen (m); octave:4> [par2, gen2] = cyclgen (n, cyclpoly (n, k)); which create identical parity check and generator matrices for the [7,4] Hamming code. The syndrome table of the codes can be created with the function 'syndtable', in the following manner octave:1> [par, gen] = hammgen (3); octave:2> st = syndtable (par); There exists two auxiliary functions 'gen2par' and 'gfweight', that convert between generator and parity check matrices and calculate the Hamming distance of the codes. For instance octave:1> par = hammgen (3); octave:2> gen = gen2par (par); octave:3> gfweight (gen) ans = 3 It should be noted that for large values of N, the generator, parity check and syndrome table matrices are very large. There is therefore an internal limitation on the size of the block codes that can be created that limits the codeword length N to less than 64. This is still excessively large for the syndrome table, so use caution with these codes. These limitations do not apply to the Reed-Solomon or BCH codes. The top-level encode and decode functions are 'encode' and 'decode', which can be used with all codes, except the Reed-Solomon code. The basic call to both of these functions passes the message to code/decode, the codeword length, the message length and the type of coding to use. There are four basic types that are available with these functions "linear" Generic linear block codes "cyclic" Cyclic linear block codes "hamming" Hamming codes "bch" Bose Chaudhuri Hocquenghem (BCH) block codes It is not possible to distinguish between a binary vector and a decimal vector coding of the messages that just happens to only have ones and zeros. Therefore the functions 'encode' and 'decode' must be told the format of the messages in the following manner. octave:1> m = 3; octave:2> n = 7; octave:3> k = 4; octave:4> msg_bin = randint (10, k); octave:5> cbin = encode (msg_bin, n, k, "hamming/binary"); octave:5> cdec = encode (bi2de (msg), n, k, "hamming/decimal"); which codes a binary matrix and a non-binary vector representation of a message, returning the coded message in the same format. The functions 'encode' and 'decode' by default accept binary coded messages. Therefore "hamming" is equivalent to "hamming/binary". Except for the BCH codes, the function 'encode' and 'decode' internally create the generator, parity check and syndrome table matrices. Therefore if repeated calls to 'encode' and 'decode' are made, it will often be faster to create these matrices externally and pass them as an argument. For example n = 15; k = 11; [par, gen] = hammgen (4); code1 = code2 = zeros (100, 15) for i = 1:100 msg = get_msg (i); code1(i,:) = encode (msg, n, k, "linear", gen); # This is faster code2(i,:) = encode (msg, n, k, "hamming"); # than this !!! endfor In the case of the BCH codes the low-level functions described in the next section are used directly by the 'encode' and 'decode' functions.  File: comms.info, Node: BCH Codes, Next: Reed-Solomon Codes, Prev: Binary Block Codes, Up: Block Coding 4.3 BCH Codes ============= The BCH coder used here is based on code written by Robert Morelos-Zaragoza (r.morelos-zaragoza@ieee.org). This code was originally written in C and has been converted for use as an Octave oct-file. Called without arguments, 'bchpoly' returns a table of valid BCH error correcting codes and their error-correction capability. The first returned column of 'bchpoly' is the codeword length, the second the message length and the third the error correction capability of the code. Called with one argument, 'bchpoly' returns similar output, but only for the specified codeword length. In this manner codes with codeword length greater than 511 can be found. In general the codeword length is of the form '2^M - 1', where M is an integer. However if [N,K] is a valid BCH code, then it is also possible to use a shortened BCH form of the form '[N-X,K-X]'. With two or more arguments, 'bchpoly' is used to find the generator polynomial of a valid BCH code. For instance octave:1> bchpoly (15, 7) ans = 1 0 0 0 1 0 1 1 1 octave:2> bchpoly (14, 6) ans = 1 0 0 0 1 0 1 1 1 show that the generator polynomial of a [15,7] BCH code with the default primitive polynomial is 1 + X ^ 4 + X ^ 6 + X ^ 7 + X ^ 8 Using a different primitive polynomial to define the Galois Field over which the BCH code is defined results in a different generator polynomial as can be seen in the example. octave:1> bchpoly ([1 1 0 0 1], 7) ans = 1 0 0 0 1 0 1 1 1 octave:2> bchpoly ([1 0 0 1 1], 7) ans = 1 1 1 0 1 0 0 0 1 It is recommend not to convert the generator polynomials created by 'bchpoly' into generator and parity check matrices with the BCH codes, as the underlying BCH software is faster than the generic coding software and can treat significantly longer codes. As well as using the 'encode' and 'decode' functions previously discussed, the user can directly use the low-level BCH functions 'bchenco' and 'bchdeco'. In this case the messages must be in the format of a binary matrix with K columns octave:1> n = 31; octave:2> pgs = bchpoly (n); octave:3> pg = pgs(floor (rand () * (rows (pgs) + 1)),:); # Pick a poly octave:4> k = pg(2); octave:5> t = pg(3); octave:6> msg = randint (10, k); octave:7> code = bchenco (msg, n, k); octave:8> noisy = code + [ones(10, 1), zeros(10, n-1)]; octave:9> dec = bchdeco (code, k, t);  File: comms.info, Node: Reed-Solomon Codes, Prev: BCH Codes, Up: Block Coding 4.4 Reed-Solomon Codes ====================== * Menu: * Representation of Reed-Solomon Messages:: * Creating and Decoding Messages:: * Shortened Reed-Solomon Codes::  File: comms.info, Node: Representation of Reed-Solomon Messages, Next: Creating and Decoding Messages, Up: Reed-Solomon Codes 4.4.1 Representation of Reed-Solomon Messages --------------------------------------------- The Reed-Solomon coder used in this package is based on code written by Phil Karn (http://www.ka9q.net/code/fec). This code was originally written in C and has been converted for use as an Octave oct-file. Reed-Solomon codes are based on Galois Fields of even characteristics GF(2^M). Many of the properties of Galois Fields are therefore important when considering Reed-Solomon coders. The representation of the symbols of the Reed-Solomon code differs from the other block codes, in that the other block codes use a binary representation, while the Reed-Solomon code represents each m-bit symbol by an integer. The elements of the message and codeword must be elements of the Galois Field corresponding to the Reed-Solomon code. Thus to code a message with a [7,5] Reed-Solomon code an example is octave:1> m = 3; octave:2> n = 7; octave:3> k = 5; octave:4> msg = gf (floor (2^m * rand (2, k)), m) msg = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 5 0 6 3 2 4 1 3 1 2 octave:5> code = rsenc (msg, n, k) code = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 5 0 6 3 2 3 5 4 1 3 1 2 6 3 The variable N is the codeword length of the Reed-Solomon coder, while K is the message length. It should be noted that K should be less than N and that 'N - K' should be even. The error correcting capability of the Reed-Solomon code is then '(N - K)/2' symbols. M is the number of bits per symbol, and is related to N by 'N = 2^M - 1'. For a valid Reed-Solomon coder, M should be between 3 and 16.  File: comms.info, Node: Creating and Decoding Messages, Next: Shortened Reed-Solomon Codes, Prev: Representation of Reed-Solomon Messages, Up: Reed-Solomon Codes 4.4.2 Creating and Decoding Messages ------------------------------------ The Reed-Solomon encoding function requires at least three arguments. The first MSG is the message in encodes, the second is N the codeword length and K is the message length. Therefore MSG must have K columns and the output will have N columns of symbols. The message itself is many up of elements of a Galois Field GF(2^M). Normally, The order of the Galois Field (M), is related to the codeword length by 'N = 2^M - 1'. Another important parameter when determining the behavior of the Reed-Solomon coder is the primitive polynomial of the Galois Field (see 'gf'). Thus the messages octave:1> msg0 = gf ([0, 1, 2, 3], 3); octave:2> msg1 = gf ([0, 1, 2, 3], 3, 13); will not result in the same Reed-Solomon coding. Finally, the parity of the Reed-Solomon code are generated with the use of a generator polynomial. The parity symbols are then generated by treating the message to encode as a polynomial and finding the remainder of the division of this polynomial by the generator polynomial. Therefore the generator polynomial must have as many roots as 'N - K'. Whether the parity symbols are placed before or afterwards the message will then determine which end of the message is the most-significant term of the polynomial representing the message. The parity symbols are therefore different in these two cases. The position of the parity symbols can be chosen by specifying "beginning" or "end" to 'rsenc' and 'rsdec'. By default the parity symbols are placed after the message. Valid generator polynomials can be constructed with the 'rsgenpoly' function. The roots of the generator polynomial are then defined by G = (X - A^(B*S)) * (X - A^((B+1)*S)) * ... * (X - A^((B+2*T-1)*S)). where T is '(N - K)/2', A is the primitive element of the Galois Field, B is the first consecutive root, and S is the step between roots. Generator polynomial of this form are constructed by 'rsgenpoly' and can be passed to both 'rsenc' and 'rsdec'. It is also possible to pass the B and S values directly to 'rsenc' and 'rsdec'. In the case of 'rsdec' passing B and S can make the decoding faster. Consider the example below. octave:1> m = 8; octave:2> n = 2^m - 1; octave:3> k = 223; octave:4> prim = 391; octave:5> b = 112; octave:6> s = 11; octave:7> gg = rsgenpoly (n, k, prim, b, s); octave:8> msg = gf (floor (2^m * rand (17, k)), m, prim); octave:9> code = rsenc (msg, n, k, gg); octave:10> noisy = code + [toeplitz([ones(1,17)], zeros(1,17)), zeros(17,238)]; octave:11> [dec, nerr] = rsdec (msg, n, k, b, s); octave:12> nerr' ans = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -1 octave:13> any (msg' != dec') ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 This is an interesting example in that it demonstrates many of the additional arguments of the Reed-Solomon functions. In particular this example approximates the CCSDS standard Reed-Solomon coder, lacking only the dual-basis lookup tables used in this standard. The CCSDS uses non-default values to all of the basic functions involved in the Reed-Solomon encoding, since it has a non-default primitive polynomial, generator polynomial, etc. The example creates 17 message blocks and adds between 1 and 17 error symbols to these block. As can be seen NERR gives the number of errors corrected. In the case of 17 introduced errors NERR equals -1, indicating a decoding failure. This is normal as the correction ability of this code is up to 16 error symbols. Comparing the input message and the decoding it can be seen that as expected, only the case of 17 errors has not been correctly decoded.  File: comms.info, Node: Shortened Reed-Solomon Codes, Prev: Creating and Decoding Messages, Up: Reed-Solomon Codes 4.4.3 Shortened Reed-Solomon Codes ---------------------------------- In general the codeword length of the Reed-Solomon coder is chosen so that it is related directly to the order of the Galois Field by the formula 'N = 2^M - 1'. Although, the underlying Reed-Solomon coding must operate over valid codeword length, there are sometimes reasons to assume that the codeword length will be shorter. In this case the message is padded with zeros before coding, and the zeros are stripped from the returned block. For example consider the shortened [6,4] Reed-Solomon below octave:1> m = 3; octave:2> n = 6; octave:3> k = 4; octave:4> msg = gf (floor (2^m * rand (2, k)), m) msg = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 2 5 1 5 7 1 octave:5> code = rsenc (msg, n, k) code = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 2 5 2 3 1 5 7 1 0 2  File: comms.info, Node: Convolutional Coding, Next: Modulations, Prev: Block Coding, Up: Top 5 Convolutional Coding ********************** Some initial support for convolutional codes is provided by the functions described in this chapter. Convolutional codes are different from block codes in that the sequence of preceding symbols is taken into account when computing the output symbol of the coder. * Menu: * Trellis Structure:: * Convolutional Encoding::  File: comms.info, Node: Trellis Structure, Next: Convolutional Encoding, Up: Convolutional Coding 5.1 Trellis Structure ===================== Like block codes, convolutional codes can be described by a set of generator polynomials. Each polynomial describes the combination of current and previous input symbols used to compute one output bit of the encoder. The state transitions and outputs of a convolutional encoder can also be described by a trellis diagram. This diagram describes the transitions between states and the outputs of the encoder as a function of the current state and the current input symbol. A trellis structure can be created from a set of generator polynomials, specified as octal numbers by convention, octave:1> g0 = 13; octave:2> g1 = 17; octave:3> trellis = poly2trellis (4, [g0, g1]); where G0 and G1 are the two polynomials of a rate 1/2 encoder with a constraint length of 4. The returned trellis structure contains the following fields 'numInputSymbols' The number of possible input symbols in the input sequence. 'numOutputSymbols' The number of possible output symbols in the encoded sequence. 'numStates' The number of possible states that the encoder can take. 'nextStates' The state transition table for the encoder. Each row contains the (zero-based) indices of the states reachable from the state represented by that row for each possible input symbol. 'outputs' The output table for the encoder. Each row contains the (octal-encoded) output symbols produced by the encoder in the state represented by that row for each possible input symbol. To check if a variable references a structure that is a valid trellis describing a convolutional encoder, use the 'istrellis' function.  File: comms.info, Node: Convolutional Encoding, Prev: Trellis Structure, Up: Convolutional Coding 5.2 Convolutional Encoding ========================== The convolutional encoding function takes the message to be encoded and a trellis describing the encoder. The message must be a binary vector containing an even number of symbols. For example, using the encoder from the previous section, octave:1> trellis = poly2trellis (4, [13, 17]); octave:2> msg = [1 1 0 1 1 0 0 0]; octave:3> out = convenc (msg, trellis) out = 1 1 1 0 1 0 1 1 0 1 1 0 0 0 1 1 The initial state of the encoder can also be passed in to 'convenc', and the ending state can be read with an optional output argument. Encoding a different vector with a different initial state using the same encoder, octave:4> msg = [0 1 1 0 1 0 1 1]; octave:5> [out, state] = convenc (msg, trellis, [], 4) out = 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 state = 6 returns both the encoded array and the final state of the convolutional encoder. This can be used to encode data in blocks, for example, saving and restoring the internal state of the encoder for each subsequent input block.  File: comms.info, Node: Modulations, Next: Special Filters, Prev: Convolutional Coding, Up: Top 6 Modulations ************* To be written. Currently have functions amodce, ademodce, apkconst, demodmap, modmap, qaskdeco, qaskenco, genqammod, pamdemod, pammod, pskdemod and pskmod.  File: comms.info, Node: Special Filters, Next: Galois Fields, Prev: Modulations, Up: Top 7 Special Filters ***************** To be written.  File: comms.info, Node: Galois Fields, Next: Function Reference, Prev: Special Filters, Up: Top 8 Galois Fields *************** * Menu: * Galois Field Basics:: * Manipulating Galois Fields::  File: comms.info, Node: Galois Field Basics, Next: Manipulating Galois Fields, Up: Galois Fields 8.1 Galois Field Basics ======================= A Galois Field is a finite algebraic field. This package implements a Galois Field type in Octave having 2^M members where M is an integer between 1 and 16. Such fields are denoted as GF(2^M) and are used in error correcting codes in communications systems. Galois Fields having odd numbers of elements are not implemented. The _primitive element_ of a Galois Field has the property that all elements of the Galois Field can be represented as a power of this element. The _primitive polynomial_ is the minimum polynomial of some primitive element in GF(2^M) and is irreducible and of order M. This means that the primitive element is a root of the primitive polynomial. The elements of the Galois Field GF(2^M) are represented as the values 0 to 2^M -1 by Octave. The first two elements represent the zero and unity values of the Galois Field and are unique in all fields. The element represented by 2 is the primitive element of the field and all elements can be represented as combinations of the primitive element and unity as follows Integer Binary Element of GF(2^M) 0 000 '0' 1 001 '1' 2 010 'A' 3 011 'A + 1' 4 100 'A^2' 5 101 'A^2 + 1' 6 110 'A^2 + A' 7 111 'A^2 + A + 1' It should be noted that there is often more than a single primitive polynomial of GF(2^M). Each Galois Field over a different primitive polynomial represents a different realization of the Field. The representations above however rest valid. * Menu: * Creating Galois Fields:: * Primitive Polynomials:: * Accessing Internal Fields:: * Function Overloading:: * Known Problems::  File: comms.info, Node: Creating Galois Fields, Next: Primitive Polynomials, Up: Galois Field Basics 8.1.1 Creating Galois Fields ---------------------------- To work with a Galois Field GF(2^M) in Octave, you must first create a variable that Octave recognizes as a Galois Field. This is done with the function 'gf (A, M)' as follows. octave:1> a = [0:7]; octave:2> b = gf (a, 4) b = GF(2^4) array. Primitive Polynomial = D^4+D+1 (decimal 19) Array elements = 0 1 2 3 4 5 6 7 This creates an array B with 8 elements that Octave recognizes as a Galois Field. The field is created with the default primitive polynomial for the field GF(2^4). It can be verified that a variable is in fact a Galois Field with the functions 'isgalois' or 'whos'. octave:3> isgalois (a) ans = 0 octave:4> isgalois (b) ans = 1 octave:5> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x8 24 double b 1x8 32 galois Total is 16 elements using 56 bytes It is also possible to create a Galois Field with an arbitrary primitive polynomial. However, if the polynomial is not a primitive polynomial of the field, and error message is returned. For instance. octave:1> a = [0:7]; octave:2> b = gf (a, 4, 25) b = GF(2^4) array. Primitive Polynomial = D^4+D^3+1 (decimal 25) Array elements = 0 1 2 3 4 5 6 7 octave:3> c = gf (a, 4, 21) error: gf: primitive polynomial (21) of Galois Field must be irreducible The function 'gftable' is included for compatibility with MATLAB. In MATLAB this function is used to create the lookup tables used to accelerate the computations over the Galois Field and store them to a file. However Octave stores these parameters for all of the fields currently in use and so this function is not required, although it is silently accepted.  File: comms.info, Node: Primitive Polynomials, Next: Accessing Internal Fields, Prev: Creating Galois Fields, Up: Galois Field Basics 8.1.2 Primitive Polynomials --------------------------- The function 'gf (A, M)' creates a Galois Field using the default primitive polynomial. However there exists many possible primitive polynomials for most Galois Fields. Two functions exist for identifying primitive polynomials, 'isprimitive' and 'primpoly'. 'primpoly (M, OPT)' is used to identify the primitive polynomials of the fields GF(2^M). For example octave:1> primpoly (4) Primitive polynomial(s) = D^4+D+1 ans = 19 identifies the default primitive polynomials of the field GF(2^M), which is the same as 'primpoly (4, "min")'. All of the primitive polynomials of a field can be identified with the function 'primpoly (M, "all")'. For example octave:1> primpoly (4, "all") Primitive polynomial(s) = D^4+D+1 D^4+D^3+1 ans = 19 25 while 'primpoly (M, "max")' returns the maximum primitive polynomial of the field, which for the case above is 25. The function 'primpoly' can also be used to identify the primitive polynomials having only a certain number of non-zero terms. For instance octave:1> primpoly (5, 3) Primitive polynomial(s) = D^5+D^2+1 D^5+D^3+1 ans = 37 41 identifies the polynomials with only three terms that can be used as primitive polynomials of GF(2^5). If no primitive polynomials existing having the requested number of terms then 'primpoly' returns an empty vector. That is octave:1> primpoly (5, 2) warning: primpoly: No primitive polynomial satisfies the given constraints ans = [](1x0) As can be seen above, 'primpoly' displays the polynomial forms the the polynomials that it finds. This output can be suppressed with the "nodisplay" option, while the returned value is left unchanged. octave:1> primpoly (4, "all", "nodisplay") ans = 19 25 'isprimitive (A)' identifies whether the elements of A can be used as primitive polynomials of the Galois Fields GF(2^M). Consider as an example the fields GF(2^4). The primitive polynomials of these fields must have an order m and so their integer representation must be between 16 and 31. Therefore 'isprimitive' can be used in a similar manner to 'primpoly' as follows octave:1> find (isprimitive (16:31)) + 15 ans = 19 25 which finds all of the primitive polynomials of GF(2^4).  File: comms.info, Node: Accessing Internal Fields, Next: Function Overloading, Prev: Primitive Polynomials, Up: Galois Field Basics 8.1.3 Accessing Internal Fields ------------------------------- Once a variable has been defined as a Galois Field, the parameters of the field of this structure can be obtained by adding a suffix to the variable. Valid suffixes are '.m', '.prim_poly' and '.x', which return the order of the Galois Field, its primitive polynomial and the data the variable contains respectively. For instance octave:1> a = [0:7]; octave:2> b = gf (a, 4); octave:3> b.m ans = 4 octave:4> b.prim_poly ans = 19 octave:5> c = b.x; octave:6> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x8 24 double b 1x8 32 galois c 1x8 64 double Total is 24 elements using 120 bytes Please note that it is explicitly forbidden to modify the Galois field by accessing these variables. For instance octave:1> a = gf ([0:7], 3); octave:2> a.prim_poly = 13; is explicitly forbidden. The result of this will be to replace the Galois array A with a structure A with a single element called '.prim_poly'. To modify the order or primitive polynomial of a field, a new field must be created and the data copied. That is octave:1> a = gf ([0:7], 3); octave:2> a = gf (a.x, a.m, 13);  File: comms.info, Node: Function Overloading, Next: Known Problems, Prev: Accessing Internal Fields, Up: Galois Field Basics 8.1.4 Function Overloading -------------------------- An important consideration in the use of the Galois Field package is that many of the internal functions of Octave, such as 'roots', can not accept Galois Fields as an input. This package therefore uses Octave classes to _overload_ the internal Octave functions with equivalent functions that work with Galois Fields, so that the standard function names can be used. The version of the function that is chosen is determined by the first argument of the function. This is a temporary situation until the Galois Field class constructor can be rewritten to allow the use of the 'superiorto' function to define the galois class with a higher precedence. So, considering the 'filter' function, if the first argument is a _Matrix_, then the normal version of the function is called regardless of whether the other arguments of the function are Galois vectors or not. Other Octave functions work correctly with Galois Fields and so overloaded versions are not necessary. This include such functions as 'size' and 'polyval'. It is also useful to use the '.x' option discussed in the previous section, to extract the raw data of the Galois field for use with some functions. An example is octave:1> a = minpol (gf (14, 5)); octave:2> b = de2bi (a.x, [], "left-msb"); converts the polynomial form of the minimum polynomial of 14 in GF(2^5) into an integer. Finally help for the Galois specific versions of the functions must explicitly call the correct function as octave:1> help @galois/conv  File: comms.info, Node: Known Problems, Prev: Function Overloading, Up: Galois Field Basics 8.1.5 Known Problems -------------------- Please review the following list of known problems with the Galois type before reporting a bug against this package. Saving and loading Galois variables Saving a Galois variable to a file is as simple as octave:1> a = gf (...); octave:2> save a.mat a where A is any Galois variable. Galois variables can be saved in the Octave binary and ASCII formats, as well as the HDF5 format. To load a Galois variable from a file, the Galois type must already be registered to the Octave interpreter prior to the call to 'load'. If no Galois variables have been created yet, you will have to do something like octave:1> dummy = gf (1); octave:2> load a.mat Logarithm of zero does not return NaN The logarithm of zero in a Galois field is not defined. However, to avoid segmentation faults in later calculations the logarithm of zero is defined as '2^M - 1', whose value is not the logarithm of any other value in the Galois field. A warning is also shown to tell the user about the problem. For example octave:1> m = 3; octave:2> a = log (gf ([0:2^m-1], m)) warning: log of zero undefined in Galois field a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 7 0 1 3 2 6 4 5 To fix this problem would require a major rewrite of all code, adding an exception for the case of NaN to all basic operators. These exceptions will certainly slow the code down. Speed The code was written piecemeal with no attention to optimization. Some operations may be slower than they could be. Contributions are welcome.  File: comms.info, Node: Manipulating Galois Fields, Prev: Galois Field Basics, Up: Galois Fields 8.2 Manipulating Galois Fields ============================== * Menu: * Expressions manipulation and assignment:: * Unary operations:: * Arithmetic operations:: * Comparison operations:: * Polynomial manipulations:: * Linear Algebra:: * Signal Processing::  File: comms.info, Node: Expressions manipulation and assignment, Next: Unary operations, Up: Manipulating Galois Fields 8.2.1 Expressions, manipulation and assignment ---------------------------------------------- Galois variables can be treated in similar manner to other variables within Octave. For instance Galois fields can be accessed using index expressions in a similar manner to all other Octave matrices. For example octave:1> a = gf ([[0:7]; [7:-1:0]], 3) a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0 octave:2> b = a(1,:) b = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 1 2 3 4 5 6 7 Galois arrays can equally use indexed assignments. That is, the data in the array can be partially replaced, on the condition that the two fields are identical. An example is octave:1> a = gf (ones (2, 8), 3); octave:2> b = gf (zeros (1, 8), 3); octave:3> a(1,:) = b a = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 Implicit conversions between normal matrices and Galois arrays are possible. For instance data can be directly copied from a Galois array to a real matrix as follows. octave:1> a = gf (ones (2, 8), 3); octave:2> b = zeros (2, 8); octave:3> b(2,:) = a(2,:) b = 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 The inverse is equally possible, with the proviso that the data in the matrix is valid in the Galois field. For instance octave:1> a = gf ([0:7], 3); octave:2> a(1) = 1; is valid, while octave:1> a = gf ([0:7], 3); octave:2> a(1) = 8; is not, since 8 is not an element of GF(2^3). This is a basic rule of manipulating Galois arrays. That is matrices and scalars can be used in conjunction with a Galois array as long as they contain valid data within the Galois field. In this case they will be assumed to be of the same field. Galois arrays can also be concatenated with real matrices or with other Galois arrays in the same field. For example octave:1> a = [gf([0:7], 3); gf([7:-1:0], 3)]; octave:2> b = [a, a]; octave:3> c = [a, eye(2)]; octave:3> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 2x8 64 galois b 2x16 128 galois c 2x10 80 galois Total is 68 elements using 272 bytes Other basic manipulations of Galois arrays are 'isempty' Returns true if the Galois array is empty. 'size' Returns the number of rows and columns in the Galois array. 'length' Returns the length of a Galois vector, or the maximum of rows or columns of Galois arrays. 'find' Find the indexes of the non-zero elements of a Galois array. 'diag' Create a diagonal Galois array from a Galois vector, or extract a diagonal from a Galois array. 'reshape' Change the shape of the Galois array.  File: comms.info, Node: Unary operations, Next: Arithmetic operations, Prev: Expressions manipulation and assignment, Up: Manipulating Galois Fields 8.2.2 Unary operations ---------------------- The same unary operators that are available for normal Octave matrices are also available for Galois arrays. These operations are '+X' Unary plus. This operator has no effect on the operand. '-X' Unary minus. Note that in a Galois Field this operator also has no effect on the operand. '!X' Returns true for zero elements of Galois Array. 'X'' Complex conjugate transpose. As the Galois Field only contains integer values, this is equivalent to the transpose operator. 'X.'' Transpose of the Galois array.  File: comms.info, Node: Arithmetic operations, Next: Comparison operations, Prev: Unary operations, Up: Manipulating Galois Fields 8.2.3 Arithmetic operations --------------------------- The available arithmetic operations on Galois arrays are the same as on other Octave matrices. It should be noted that both operands must be in the same Galois Field. If one operand is a Galois array and the second is a matrix or scalar, then the second operand is silently converted to the same Galois Field. The element(s) of these matrix or scalar must however be valid members of the Galois field. Thus octave:1> a = gf ([0:7], 3); octave:2> b = a + [0:7]; is valid, while octave:1> a = gf ([0:7], 3); octave:2> b = a + [1:8]; is not, since 8 is not a valid element of GF(2^3). The available arithmetic operators are 'X + Y' Addition. If both operands are Galois arrays or matrices, the number of rows and columns must both agree. If one operand is a is a Galois array with a single element or a scalar, its value is added to all the elements of the other operand. The '+' operator on a Galois Field is equivalent to an exclusive-or on normal integers. 'X .+ Y' Element by element addition. This operator is equivalent to '+'. 'X - Y' As both '+' and '-' in a Galois Field are equivalent to an exclusive-or for normal integers, '-' is equivalent to the '+' operator 'X .- Y' Element by element subtraction. This operator is equivalent to '-'. 'X * Y' Matrix multiplication. The number of columns of X must agree with the number of rows of Y. 'X .* Y' Element by element multiplication. If both operands are matrices, the number of rows and columns must both agree. 'X / Y' Right division. This is conceptually equivalent to the expression (inverse (y') * x')' but it is computed without forming the inverse of Y'. If the matrix is singular then an error occurs. If the matrix is under-determined, then a particular solution is found (but not minimum norm). If the solution is over-determined, then an attempt is made to find a solution, but this is not guaranteed to work. 'X ./ Y' Element by element right division. 'X \ Y' Left division. This is conceptually equivalent to the expression inverse (x) * y but it is computed without forming the inverse of X. If the matrix is singular then an error occurs. If the matrix is under-determined, then a particular solution is found (but not minimum norm). If the solution is over-determined, then an attempt is made to find a solution, but this is not guaranteed to work. 'X .\ Y' Element by element left division. Each element of Y is divided by each corresponding element of X. 'X ^ Y' 'X ** Y' Power operator. If X and Y are both scalars, this operator returns X raised to the power Y. Otherwise X must be a square matrix raised to an integer power. 'X .^ Y' 'X .** Y' Element by element power operator. If both operands are matrices, the number of rows and columns must both agree.  File: comms.info, Node: Comparison operations, Next: Polynomial manipulations, Prev: Arithmetic operations, Up: Manipulating Galois Fields 8.2.4 Comparison operations --------------------------- Galois variables can be tested for equality in the usual manner. That is octave:1> a = gf ([0:7], 3); octave:2> a == ones (1, 8) ans = 0 1 0 0 0 0 0 0 octave:3> a != zeros (1, 8) ans = 0 1 1 1 1 1 1 1 Likewise, Galois vectors can be tested against scalar values (whether they are Galois or not). For instance octave:4> a == 1 ans = 0 1 0 0 0 0 0 0 To test if any or all of the values in a Galois array are non-zero, the functions 'any' and 'all' can be used as normally. In addition the comparison operators '>', '>=', '<' and '<=' are available. As elements of the Galois Field are modulus 2^M, all elements of the field are both greater than and less than all others at the same time. Thus these comparison operators don't make that much sense and are only included for completeness. The comparison is done relative to the integer value of the Galois Field elements.  File: comms.info, Node: Polynomial manipulations, Next: Linear Algebra, Prev: Comparison operations, Up: Manipulating Galois Fields 8.2.5 Polynomial manipulations ------------------------------ A polynomial in GF(2^M) can be expressed as a vector in GF(2^M). For instance if A is the _primitive element_, then the example octave:1> poly = gf ([2, 4, 5, 1], 3); represents the polynomial poly = A * x^3 + A^2 * x^2 + (A^2 + 1) * x + 1 Arithmetic can then be performed on these vectors. For instance to add to polynomials an example is octave:1> poly1 = gf ([2, 4, 5, 1], 3); octave:2> poly2 = gf ([1, 2], 3); octave:3> sumpoly = poly1 + [0, 0, poly2] sumpoly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 4 3 Note that POLY2 must be zero padded to the same length as poly1 to allow the addition to take place. Multiplication and division of Galois polynomials is equivalent to convolution and de-convolution of vectors of Galois elements. Thus to multiply two polynomials in GF(2^3). octave:4> mulpoly = conv (poly1, poly2) mulpoly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 0 6 0 2 Likewise the division of two polynomials uses the de-convolution function as follows octave:5> [poly, remd] = deconv (mulpoly, poly2) poly = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 5 1 remd = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 0 0 Note that the remainder of this division is zero, as we performed the inverse operation to the multiplication. To evaluate a polynomial for a certain value in GF(2^M), use the Octave function 'polyval'. octave:1> poly1 = gf ([2, 4, 5, 1], 3); ## a*x^3+a^2*x^2+(a^2+1)*x+1 octave:2> x0 = gf ([0, 1, 2], 3); octave:3> y0 = polyval (poly1, x0); y0 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 2 0 octave:4> a = gf (2, 3); ## The primitive element octave:5> y1 = a .* x0.^3 + a.^2 .* x0.^2 + (a.^2 + 1) .* x0 + 1 y1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 2 0 It is equally possible to find the roots of Galois polynomials with the 'roots' function. Using the polynomial above over GF(2^3), we can find its roots in the following manner octave:1> poly1 = gf ([2, 4, 5, 1], 3); octave:2> root1 = roots (poly1) root1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 5 5 Thus the example polynomial has 3 roots in GF(2^3) with one root of multiplicity 2. We can check this answer with the 'polyval' function as follows octave:3> check1 = polyval (poly1, root1) check1 = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 0 0 0 which as expected gives a zero vector. It should be noted that both the number of roots and their value, will depend on the chosen field. Thus for instance octave:1> poly3 = gf ([2, 4, 5, 1], 3, 13); octave:2> root3 = roots (poly3) root3 = GF(2^3) array. Primitive Polynomial = D^3+D^2+1 (decimal 13) Array elements = 5 shows that in the field GF(2^3) with a different primitive polynomial, has only one root exists. The minimum polynomial of an element of GF(2^M) is the minimum degree polynomial in GF(2), excluding the trivial zero polynomial, that has that element as a root. The fact that the minimum polynomial is in GF(2) means that its coefficients are one or zero only. The 'minpol' function can be used to find the minimum polynomial as follows octave:1> a = gf (2, 3); ## The primitive element octave:2> b = minpol (a) b = GF(2) array. Array elements = 1 0 1 1 Note that the minimum polynomial of the primitive element is the primitive polynomial. Elements of GF(2^M) sharing the same minimum polynomial form a partitioning of the field. This partitioning can be found with the 'cosets' function as follows octave:1> c = cosets (3) c = { [1,1] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 [1,2] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 2 4 6 [1,3] = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 3 5 7 } which returns a cell array containing all of the elements of the GF(2^3), partitioned into groups sharing the same minimum polynomial. The function 'cosets' can equally accept a second argument defining the primitive polynomial to use in its calculations (i.e. 'cosets (A, P)').  File: comms.info, Node: Linear Algebra, Next: Signal Processing, Prev: Polynomial manipulations, Up: Manipulating Galois Fields 8.2.6 Linear Algebra -------------------- The basic linear algebra operation of this package is the LU factorization of a Galois array. That is the Galois array A is factorized in the following way octave:2> [l, u, p] = lu (a) such that 'P * A = L * U'. The matrix P contains row permutations of A, such that L and U are strictly upper and low triangular. The Galois array A can be rectangular. All other linear algebra operations within this package are based on this LU factorization of a Galois array. An important consequence of this is that no solution can be found for singular matrices, only a particular solution will be found for under-determined systems of equation and the solution found for over-determined systems is not always correct. This is identical to the way MATLAB performs linear algebra on Galois arrays. For instance consider the under-determined linear equation octave:1> A = gf ([2, 0, 3, 3; 3, 1, 3, 1; 3, 1, 1, 0], 2); octave:2> b = [0:2]'; octave:3> x = A \ b; gives the solution 'X = [2, 0, 3, 2]'. There are in fact 4 possible solutions to this linear system; 'X = [3, 2, 2, 0]', 'X = [0, 3, 1, 1]', 'X = [2, 0, 3, 2]' and 'X = [1, 1, 0, 3]'. No particular selection criteria are applied to the chosen solution. In addition, because singular matrices cannot be solved, unless you know the matrix is not singular, you should test the determinant of the matrix prior to solving the linear system. For instance octave:1> A = gf (floor (2^m * rand (3)), 2); octave:2> b = [0:2]'; octave:3> if (det (A) != 0); x = A \ b; y = b' / A; endif; octave:4> r = rank (A); solves the linear systems 'A * X = B' and 'Y * A = B'. Note that you do not need to take into account rounding errors in the determinant, as the determinant can only take values within the Galois Field. So if the determinant equals zero, the array is singular.  File: comms.info, Node: Signal Processing, Prev: Linear Algebra, Up: Manipulating Galois Fields 8.2.7 Signal Processing with Galois Fields ------------------------------------------ Signal processing functions such as filtering, convolution, de-convolution and Fourier transforms can be performed over Galois Fields. For instance the 'filter' function can be used with Galois vectors in the same manner as usual. For instance octave:1> b = gf ([2, 0, 0, 1, 0, 2, 0, 1], 2); octave:2> a = gf ([2, 0, 1, 1], 2); octave:3> x = gf ([1, zeros(1, 20)], 2); octave:4> y = filter (b, a, x) y = GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7) Array elements = 1 0 3 0 2 3 1 0 1 3 3 1 0 1 3 3 1 0 1 3 3 gives the impulse response of the filter defined by A and B. Two equivalent ways are given to perform the convolution of two Galois vectors. Firstly the function 'conv' can be used, or alternatively the function 'convmtx' can be used. The first of these function is identical to the convolution function over real vectors, and has been described in the section about multiplying two Galois polynomials. In the case where many Galois vectors will be convolved with the same vector, the second function 'convmtx' offers an alternative method to calculate the convolution. If A is a column vector and X is a column vector of length N, then octave:1> m = 3; octave:2> a = gf (floor (2^m * rand (4, 1)), m); octave:3> b = gf (floor (2^m * rand (4, 1)), m); octave:4> c0 = conv (a, b)'; octave:5> c1 = convmtx (a, length (b)) * b; octave:6> check = all (c0 == c1) check = 1 shows the equivalence of the two functions. The de-convolution function has been previously described above. The final signal processing function available in this package are the functions to perform Fourier transforms over a Galois field. Three functions are available, 'fft', 'ifft' and 'dftmtx'. The first two functions use the third to perform their work. Given an element A of the Galois field GF(2^M), 'dftmtx' returns the '2^M - 1' square matrix used in the Fourier transforms with respect to A. The minimum polynomial of A must be primitive in GF(2^M). In the case of the 'fft' function 'dftmtx' is called with the primitive element of the Galois Field as an argument. As an example octave:1> m = 4; octave:2> n = 2^m - 1; octave:2> alph = gf (2, m); octave:3> x = gf (floor (2^m * rand (n, 1)), m); octave:4> y0 = fft (x); octave:5> y1 = dftmtx (alph) * x; octave:6> z0 = ifft (y0); octave:7> z1 = dftmtx (1/alph) * y1; octave:8> check = all (y0 == y1) & all (z0 == x) & all (z1 == x) check = 1 In all cases, the length of the vector to be transformed must be '2^M -1'. As the 'dftmtx' creates a matrix representing the Fourier transform, to limit the computational task only Fourier transforms in GF(2^M), where M is less than or equal to 8, are supported.  File: comms.info, Node: Function Reference, Prev: Galois Fields, Up: Top 9 Function Reference ******************** 9.1 Functions Alphabetically ============================ * Menu: * ademodce:: Baseband demodulator for analog signals. * amdemod:: Compute the amplitude demodulation of the signal S with a carrier * ammod:: Create the AM modulation of the signal x with carrier frequency fs. * amodce:: Baseband modulator for analog signals. * apkconst:: Plots a ASK/PSK signal constellation. * awgn:: Add white Gaussian noise to a voltage signal * bchdeco:: Decodes the coded message CODE using a BCH coder. * bchenco:: Encodes the message MSG using a [N,K] BCH coding. * bchpoly:: Calculates the generator polynomials for a BCH coder. * bi2de:: Convert bit matrix to a vector of integers * biterr:: Compares two matrices and returns the number of bit errors and the bit error rate. * bsc:: Send DATA into a binary symmetric channel with probability P of * comms:: Manual and test code for the Octave Communications toolbox. * compand:: Compresses and expanding the dynamic range of a signal using a * conv:: Convolve two Galois vectors * convenc:: Encode the binary vector MSG with the convolutional encoder * convmtx:: Create matrix to perform repeated convolutions with the same vector in a Galois Field. * cosets:: Finds the elements of GF(2^M) with primitive polynomial PRIM, that share the same minimum polynomial. * cyclgen:: Produce the parity check and generator matrix of a cyclic code. * cyclpoly:: This function returns the cyclic generator polynomials of the code [N,K]. * de2bi:: Convert a non-negative integer to bit vector * decode:: Top level block decoder. * deconv:: Deconvolve two Galois vectors * deintrlv:: Restore elements of DATA according to ELEMENTS See also: intrlv * demodmap:: Demapping of an analog signal to a digital signal. * det:: Compute the determinant of the Galois array A * dftmtx:: Form a matrix, that can be used to perform Fourier transforms in a * diag:: Return a diagonal matrix with Galois vector V on diagonal K The second argument is optional. * dpcmdeco:: Decode using differential pulse code modulation (DPCM) * dpcmenco:: PREDICTOR) * dpcmopt:: (TRAINING_SET, ORD, CB) * egolaydec:: Decode Extended Golay code * egolayenc:: Encode with Extended Golay code * egolaygen:: Extended Golay code generator matrix * encode:: Top level block encoder. * exp:: Compute the anti-logarithm for each element of X for a Galois array * eyediagram:: Plot the eye-diagram of a signal. * fft:: If X is a column vector, finds the FFT over the primitive element of the Galois Field of X. * fibodeco:: Returns the decoded Fibonacci value from the binary vectors CODE * fiboenco:: Returns the cell-array of encoded Fibonacci value from the column * fibosplitstream:: Returns the split data stream at the word boundaries Assuming the * filter:: Digital filtering of vectors in a Galois Field. * fmdemod:: Create the FM demodulation of the signal x with carrier frequency * fmmod:: Create the FM modulation of the signal x with carrier frequency fs. * gen2par:: Converts binary generator matrix GEN to the parity check matrix PAR and visa-versa. * genqamdemod:: General quadrature amplitude demodulation. * genqammod:: Modulates an information sequence of integers X in the range '[0 * gf:: Creates a Galois field array GF(2^M) from the matrix X. * gftable:: This function exists for compatibility with matlab. * gfweight:: Calculate the minimum weight or distance of a linear block code. * golombdeco:: Returns the Golomb decoded signal vector using CODE and M Compulsory m is need to be specified. * golombenco:: Returns the Golomb coded signal as cell array Also total length of * hammgen:: Produce the parity check and generator matrices of a Hamming code. * helscanintrlv:: NROWS-by-NCOLS See also: helscandeintrlv * huffmandeco:: Decode signal encoded by 'huffmanenco' * huffmandict:: Builds a Huffman code, given a probability list. * huffmanenco:: Returns the Huffman encoded signal using DICT. * ifft:: If X is a column vector, finds the IFFT over the primitive element of the Galois Field of X. * intrlv:: Interleaved elements of DATA according to ELEMENTS See also: * inv:: Compute the inverse of the square matrix A. * inverse:: See inv * isequal:: Return true if all of X1, X2, ... are equal See also: * isgalois:: Return 1 if the value of the expression EXPR is a Galois Field. * isprimitive:: Returns 1 is the polynomial represented by A is a primitive polynomial of GF(2). * istrellis:: Return true if T is a valid trellis structure * lloyds:: Optimize the quantization table and codes to reduce distortion. * log:: Compute the natural logarithm for each element of X for a Galois * lu:: Compute the LU decomposition of A in a Galois Field. * lz77deco:: Lempel-Ziv 77 source algorithm decoding implementation. * lz77enco:: Lempel-Ziv 77 source algorithm implementation. * matdeintrlv:: Restore elements of DATA with a temporary matrix of size * matintrlv:: Interleaved elements of DATA with a temporary matrix of size * minpol:: Finds the minimum polynomial for elements of a Galois Field. * modmap:: Mapping of a digital signal to an analog signal. * oct2dec:: Convert octal to decimal values * pamdemod:: Demodulates a pulse amplitude modulated signal X into an * pammod:: Modulates an information sequence of integers X in the range '[0 * poly2trellis:: Convert convolutional code generator polynomials into trellis form * primpoly:: Finds the primitive polynomials in GF(2^M). * prod:: Product of elements along dimension DIM of Galois array. * pskdemod:: Demodulates a complex-baseband phase shift keying modulated signal * pskmod:: Modulates an information sequence of integers X in the range '[0 * qamdemod:: Create the QAM demodulation of x with a size of alphabet m See * qammod:: Create the QAM modulation of x with a size of alphabet m See also: * qaskdeco:: Demaps an analog signal using a square QASK constellation. * qaskenco:: Map a digital signal using a square QASK constellation. * qfunc:: Compute the Q function See also: erfc, erf * qfuncinv:: Compute the inverse Q function See also: erfc, erf * quantiz:: Quantization of an arbitrary signal relative to a partitioning * randdeintrlv:: Restore elements of DATA with a random permutation See also: * randerr:: Generate a matrix of random bit errors. * randint:: Generate a matrix of random binary numbers. * randintrlv:: Interleaves elements of DATA with a random permutation See also: * randsrc:: Generate a matrix of random symbols. * rank:: Compute the rank of the Galois array A by counting the independent * reedmullerdec:: Decode the received code word VV using the RM-generator matrix G, of order R, M, returning the code-word C. * reedmullerenc:: Definition type construction of Reed-Muller code, of order R, length 2^M. * reedmullergen:: Definition type construction of Reed-Muller code, of order R, length 2^M. * reshape:: Return a matrix with M rows and N columns whose elements are taken from the Galois array A. * ricedeco:: Returns the Rice decoded signal vector using CODE and K Compulsory * riceenco:: Returns the Rice encoded signal using K or optimal K Default optimal K is chosen between 0-7. * rledeco:: Returns decoded run-length MESSAGE. * rleenco:: Returns run-length encoded MESSAGE. * roots:: For a vector V with N components, return the roots of the * rsdec:: Decodes the message contained in CODE using a [N,K] Reed-Solomon code. * rsdecof:: Decodes an ASCII file using a Reed-Solomon coder. * rsenc:: Encodes the message MSG using a [N,K] Reed-Solomon coding. * rsencof:: Encodes an ASCII file using a Reed-Solomon coder. * rsgenpoly:: Creates a generator polynomial for a Reed-Solomon coding with message length of K and codelength of N. * scatterplot:: Display the scatter plot of a signal. * shannonfanodeco:: Returns the original signal that was Shannon-Fano encoded. * shannonfanodict:: Returns the code dictionary for source using Shannon-Fano algorithm * shannonfanoenco:: Returns the Shannon-Fano encoded signal using DICT This function * sqrt:: Compute the square root of X, element by element, in a Galois Field * sum:: Sum of elements along dimension DIM of Galois array. * sumsq:: Sum of squares of elements along dimension DIM of Galois array If * symerr:: Compares two matrices and returns the number of symbol errors and the symbol error rate. * syndtable:: Create the syndrome decoding table from the parity check matrix H. * systematize:: Given G, extract P parity check matrix. * vec2mat:: Converts the vector V into a C column matrix with row priority * wgn:: Returns a M-by-N matrix Y of white Gaussian noise.  File: comms.info, Node: ademodce, Next: amdemod, Up: Function Reference 9.1.1 ademodce -------------- -- Function File: Y = ademodce (X, FS, "amdsb-tc", offset) -- Function File: Y = ademodce (X, FS, "amdsb-tc/costas", offset) -- Function File: Y = ademodce (X, FS, "amdsb-sc") -- Function File: Y = ademodce (X, FS, "amdsb-sc/costas") -- Function File: Y = ademodce (X, FS, "amssb") -- Function File: Y = ademodce (X, FS, "qam") -- Function File: Y = ademodce (X, FS, "qam/cmplx") -- Function File: Y = ademodce (X, FS, "fm", DEV) -- Function File: Y = ademodce (X, FS, "pm", DEV) -- Function File: Y = ademodce (X, [FS, IPHS], ...) -- Function File: Y = ademodce (..., NUM, DEN) Baseband demodulator for analog signals. The input signal is specified by X, its sampling frequency by FS and the type of modulation by the third argument, TYP. The default values of FS is 1 and TYP is "amdsb-tc" If the argument FS is a two element vector, the first element represents the sampling rate and the second the initial phase The different types of demodulations that are available are "am" "amdsb-tc" Double-sideband with carrier "amdsb-tc/costas" Double-sideband with carrier and Costas phase locked loop "amdsb-sc" Double-sideband with suppressed carrier "amssb" Single-sideband with frequency domain Hilbert filtering "qam" Quadrature amplitude demodulation. In-phase in odd-columns and quadrature in even-columns "qam/cmplx" Quadrature amplitude demodulation with complex return value "fm" Frequency demodulation "pm" Phase demodulation Additional arguments are available for the demodulations "amdsb-tc", "fm", "pm". These arguments are 'offset' The offset in the input signal for the transmitted carrier 'dev' The deviation of the phase and frequency modulation It is possible to specify a low-pass filter, by the numerator NUM and denominator DEN that will be applied to the returned vector See also: ademodce, dmodce  File: comms.info, Node: amdemod, Next: ammod, Prev: ademodce, Up: Function Reference 9.1.2 amdemod ------------- -- Function File: M = amdemod (S, FC, FS) Compute the amplitude demodulation of the signal S with a carrier frequency of FC and a sample frequency of FS See also: ammod  File: comms.info, Node: ammod, Next: amodce, Prev: amdemod, Up: Function Reference 9.1.3 ammod ----------- -- Function File: ammod (X, FC, FS) Create the AM modulation of the signal x with carrier frequency fs. Where x is sample at frequency fs See also: amdemod, fmmod, fmdemod  File: comms.info, Node: amodce, Next: apkconst, Prev: ammod, Up: Function Reference 9.1.4 amodce ------------ -- Function File: Y = amodce (X, FS, "amdsb-tc", offset) -- Function File: Y = amodce (X, FS, "amdsb-sc") -- Function File: Y = amodce (X, FS, "amssb") -- Function File: Y = amodce (X, FS, "amssb/time", NUM, DEN) -- Function File: Y = amodce (X, FS, "qam") -- Function File: Y = amodce (X, FS, "fm", DEV) -- Function File: Y = amodce (X, FS, "pm", DEV) -- Function File: Y = amodce (X, [FS, IPHS], ...) Baseband modulator for analog signals. The input signal is specified by X, its sampling frequency by FS and the type of modulation by the third argument, TYP. The default values of FS is 1 and TYP is "amdsb-tc" If the argument FS is a two element vector, the first element represents the sampling rate and the second the initial phase The different types of modulations that are available are "am" "amdsb-tc" Double-sideband with carrier "amdsb-sc" Double-sideband with suppressed carrier "amssb" Single-sideband with frequency domain Hilbert filtering "amssb/time" Single-sideband with time domain filtering. Hilbert filter is used by default, but the filter can be specified "qam" Quadrature amplitude modulation "fm" Frequency modulation "pm" Phase modulation Additional arguments are available for the modulations "amdsb-tc", "fm", "pm" and "amssb/time". These arguments are 'offset' The offset in the input signal for the transmitted carrier 'dev' The deviation of the phase and frequency modulation 'num' 'den' The numerator and denominator of the filter transfer function for the time domain filtering of the SSB modulation See also: ademodce, dmodce  File: comms.info, Node: apkconst, Next: awgn, Prev: amodce, Up: Function Reference 9.1.5 apkconst -------------- -- Function File: apkconst (NSIG) -- Function File: apkconst (NSIG, AMP) -- Function File: apkconst (NSIG, AMP, PHS) -- Function File: apkconst (..., "n") -- Function File: apkconst (..., STR) -- Function File: Y = apkconst (...) Plots a ASK/PSK signal constellation. Argument NSIG is a real vector whose length determines the number of ASK radii in the constellation The values of vector NSIG determine the number of points in each ASK radii By default the radii of each ASK modulated level is given by the index of NSIG. The amplitudes can be defined explicitly in the variable AMP, which is a vector of the same length as NSIG By default the first point in each ASK radii has zero phase, and following points are coding in an anti-clockwise manner. If PHS is defined then it is a vector of the same length as NSIG defining the initial phase in each ASK radii In addition 'apkconst' takes two string arguments "n" and STR If the string "n" is included in the arguments, then a number is printed next to each constellation point giving the symbol value that would be mapped to this point by the 'modmap' function. The argument STR is a plot style string (example "r+") and determines the default gnuplot point style to use for plot points in the constellation If 'apkconst' is called with a return argument, then no plot is created. However the return value is a vector giving the in-phase and quadrature values of the symbols in the constellation See also: dmod, ddemod, modmap, demodmap  File: comms.info, Node: awgn, Next: bchdeco, Prev: apkconst, Up: Function Reference 9.1.6 awgn ---------- -- Function File: Y = awgn (X, SNR) -- Function File: Y = awgn (X, SNR, PWR) -- Function File: Y = awgn (X, SNR, PWR, SEED) -- Function File: Y = awgn (..., TYPE) Add white Gaussian noise to a voltage signal The input X is assumed to be a real or complex voltage signal. The returned value Y will be the same form and size as X but with Gaussian noise added. Unless the power is specified in PWR, the signal power is assumed to be 0dBW, and the noise of SNR dB will be added with respect to this. If PWR is a numeric value then the signal X is assumed to be PWR dBW, otherwise if PWR is "measured", then the power in the signal will be measured and the noise added relative to this measured power If SEED is specified, then the random number generator seed is initialized with this value By default the SNR and PWR are assumed to be in dB and dBW respectively. This default behavior can be chosen with TYPE set to "dB". In the case where TYPE is set to "linear", PWR is assumed to be in Watts and SNR is a ratio See also: randn, wgn  File: comms.info, Node: bchdeco, Next: bchenco, Prev: awgn, Up: Function Reference 9.1.7 bchdeco ------------- -- Loadable Function: MSG = bchdeco (CODE, K, T) -- Loadable Function: MSG = bchdeco (CODE, K, T, PRIM) -- Loadable Function: MSG = bchdeco (..., PARPOS) -- Loadable Function: [MSG, ERR] = bchdeco (...) -- Loadable Function: [MSG, ERR, CCODE] = bchdeco (...) Decodes the coded message CODE using a BCH coder. The message length of the coder is defined in variable K, and the error correction capability of the code is defined in T. The variable CODE is a binary array with N columns and an arbitrary number of rows. Each row of CODE represents a single symbol to be decoded by the BCH coder. The decoded message is returned in the binary array MSG containing K columns and the same number of rows as CODE. The use of 'bchdeco' can be seen in the following short example. m = 3; n = 2^m -1; k = 4; t = 1; msg = randint (10, k); code = bchenco (msg, n, k); noisy = mod (randerr (10,n) + code, 2); [dec, err] = bchdeco (msg, k, t); Valid codes can be found using 'bchpoly'. In general the codeword length N should be of the form '2^M-1', where m is an integer. However, shortened BCH codes can be used such that if '[2^M-1,K]' is a valid code '[2^M-1-X,K-X]' is also a valid code using the same generator polynomial. By default the BCH coding is based on the properties of the Galois Field GF(2^M). The primitive polynomial used in the Galois can be overridden by a primitive polynomial in PRIM. Suitable primitive polynomials can be constructed with 'primpoly'. The form of PRIM maybe be either a integer representation of the primitive polynomial as given by 'primpoly', or a binary representation that might be constructed like m = 3; prim = de2bi (primpoly (m)); By default the parity symbols are assumed to be placed at the beginning of the coded message. The variable PARPOS controls this positioning and can take the values '"beginning\"' or '\"end\"'. See also: bchpoly, bchenco, decode, primpoly  File: comms.info, Node: bchenco, Next: bchpoly, Prev: bchdeco, Up: Function Reference 9.1.8 bchenco ------------- -- Loadable Function: CODE = bchenco (MSG, N, K) -- Loadable Function: CODE = bchenco (MSG, N, K, G) -- Loadable Function: CODE = bchenco (..., PARPOS) Encodes the message MSG using a [N,K] BCH coding. The variable MSG is a binary array with K columns and an arbitrary number of rows. Each row of MSG represents a single symbol to be coded by the BCH coder. The coded message is returned in the binary array CODE containing N columns and the same number of rows as MSG. The use of 'bchenco' can be seen in the following short example. m = 3; n = 2^m -1; k = 4; msg = randint (10,k); code = bchenco (msg, n, k); Valid codes can be found using 'bchpoly'. In general the codeword length N should be of the form '2^M-1', where m is an integer. However, shortened BCH codes can be used such that if '[2^M-1,K]' is a valid code '[2^M-1-X,K-X]' is also a valid code using the same generator polynomial. By default the generator polynomial used in the BCH coding is based on the properties of the Galois Field GF(2^M). This default generator polynomial can be overridden by a polynomial in G. Suitable generator polynomials can be constructed with 'bchpoly'. By default the parity symbols are placed at the beginning of the coded message. The variable PARPOS controls this positioning and can take the values '"beginning\"' or '\"end\"'. See also: bchpoly, bchdeco, encode  File: comms.info, Node: bchpoly, Next: bi2de, Prev: bchenco, Up: Function Reference 9.1.9 bchpoly ------------- -- Function File: P = bchpoly () -- Function File: P = bchpoly (N) -- Function File: P = bchpoly (N, K) -- Function File: P = bchpoly (PRIM, K) -- Function File: P = bchpoly (N, K, PRIM) -- Function File: P = bchpoly (..., PROBE) -- Function File: [P, F] = bchpoly (...) -- Function File: [P, F, C] = bchpoly (...) -- Function File: [P, F, C, PAR] = bchpoly (...) -- Function File: [P, F, C, PAR, T] = bchpoly (...) Calculates the generator polynomials for a BCH coder. Called with no input arguments 'bchpoly' returns a list of all of the valid BCH codes for the codeword length 7, 15, 31, 63, 127, 255 and 511. A three column matrix is returned with each row representing a separate valid BCH code. The first column is the codeword length, the second the message length and the third the error correction capability of the code Called with a single input argument, 'bchpoly' returns the valid BCH codes for the specified codeword length N. The output format is the same as above When called with two or more arguments, 'bchpoly' calculates the generator polynomial of a particular BCH code. The generator polynomial is returned in P as a vector representation of a polynomial in GF(2). The terms of the polynomial are listed least-significant term first The desired BCH code can be specified by its codeword length N and its message length K. Alternatively, the primitive polynomial over which to calculate the polynomial can be specified as PRIM If a vector representation of the primitive polynomial is given, then PRIM can be specified as the first argument of two arguments, or as the third argument. However, if an integer representation of the primitive polynomial is used, then the primitive polynomial must be specified as the third argument When called with two or more arguments, 'bchpoly' can also return the factors F of the generator polynomial P, the cyclotomic coset for the Galois field over which the BCH code is calculated, the parity check matrix PAR and the error correction capability T. It should be noted that the parity check matrix is calculated with 'cyclgen' and limitations in this function means that the parity check matrix is only available for codeword length up to 63. For codeword length longer than this PAR returns an empty matrix With a string argument PROBE defined, the action of 'bchpoly' is to calculate the error correcting capability of the BCH code defined by N, K and PRIM and return it in P. This is similar to a call to 'bchpoly' with zero or one argument, except that only a single code is checked. Any string value for PROBE will force this action In general the codeword length N can be expressed as '2^M-1', where M is an integer. However, if [N,K] is a valid BCH code, then a shortened BCH code of the form [N-X,K-X] can be created with the same generator polynomial See also: cyclpoly, encode, decode, cosets  File: comms.info, Node: bi2de, Next: biterr, Prev: bchpoly, Up: Function Reference 9.1.10 bi2de ------------ -- Function File: D = bi2de (B) -- Function File: D = bi2de (B, F) -- Function File: D = bi2de (B, P) -- Function File: D = bi2de (B, P, F) Convert bit matrix to a vector of integers Each row of the matrix B is treated as a single integer represented in binary form. The elements of B, must therefore be '0' or '1' If P is defined then it is treated as the base of the decomposition and the elements of B must then lie between '0' and 'p-1' The variable F defines whether the first or last element of B is considered to be the most-significant. Valid values of F are "right-msb" or "left-msb". By default F is "right-msb" See also: de2bi  File: comms.info, Node: biterr, Next: bsc, Prev: bi2de, Up: Function Reference 9.1.11 biterr ------------- -- Function File: [NUM, RATE] = biterr (A, B) -- Function File: [NUM, RATE] = biterr (..., K) -- Function File: [NUM, RATE] = biterr (..., FLAG) -- Function File: [NUM, RATE IND] = biterr (...) Compares two matrices and returns the number of bit errors and the bit error rate. The binary representations of the variables A and B are treated and A and B can be either: Both matrices In this case both matrices must be the same size and then by default the return values NUM and RATE are the overall number of bit errors and the overall bit error rate One column vector In this case the column vector is used for bit error comparison column-wise with the matrix. The returned values NUM and RATE are then row vectors containing the number of bit errors and the bit error rate for each of the column-wise comparisons. The number of rows in the matrix must be the same as the length of the column vector One row vector In this case the row vector is used for bit error comparison row-wise with the matrix. The returned values NUM and RATE are then column vectors containing the number of bit errors and the bit error rate for each of the row-wise comparisons. The number of columns in the matrix must be the same as the length of the row vector This behavior can be overridden with the variable FLAG. FLAG can take the value "column-wise", "row-wise" or "overall". A column-wise comparison is not possible with a row vector and visa-versa By default the number of bits in each symbol is assumed to be give by the number required to represent the maximum value of A and B The number of bits to represent a symbol can be overridden by the variable K  File: comms.info, Node: bsc, Next: comms, Prev: biterr, Up: Function Reference 9.1.12 bsc ---------- -- Function File: Y = bsc (DATA, P) Send DATA into a binary symmetric channel with probability P of error one each symbol  File: comms.info, Node: comms, Next: compand, Prev: bsc, Up: Function Reference 9.1.13 comms ------------ -- Function File: comms ("help") -- Function File: comms ("info") -- Function File: comms ("info", MOD) -- Function File: comms ("test") -- Function File: comms ("test", MOD) Manual and test code for the Octave Communications toolbox. There are 5 possible ways to call this function 'comms ("help")' Display this help message. Called with no arguments, this function also displays this help message 'comms ("info")' Open the Communications toolbox manual 'comms ("info", MOD)' Open the Communications toolbox manual at the section specified by MOD 'comms ("test")' Run all of the test code for the Communications toolbox 'comms ("test", MOD)' Run only the test code for the Communications toolbox in the module MOD Valid values for the variable MOD are "all" All of the toolbox "random" The random signal generation and analysis package "source" The source coding functions of the package "block" The block coding functions "convol" The convolution coding package "modulation" The modulation package "special" The special filter functions "galois" The Galois fields package Please note that this function file should be used as an example of the use of this toolbox  File: comms.info, Node: compand, Next: conv, Prev: comms, Up: Function Reference 9.1.14 compand -------------- -- Function File: Y = compand (X, MU, V, "mu/compressor") -- Function File: Y = compand (X, MU, V, "mu/expander") -- Function File: Y = compand (X, MU, V, "A/compressor") -- Function File: Y = compand (X, MU, V, "A/expander") Compresses and expanding the dynamic range of a signal using a mu-law or or A-law algorithm The mu-law compressor/expander for reducing the dynamic range, is used if the fourth argument of 'compand' starts with "mu/". Whereas the A-law compressor/expander is used if 'compand' starts with "A/" The mu-law algorithm uses the formulation V log (1 + \mu/V |x|) y = -------------------- sgn(x) log (1 + \mu) while the A-law algorithm used the formulation / A / (1 + log A) x, 0 <= |x| <= V/A | y = < V ( 1 + log (A/V |x|) ) | ----------------------- sgn(x), V/A < |x| <= V \ 1 + log A Neither converts from or to audio file ulaw format. Use mu2lin or lin2mu instead See also: m2ulin, lin2mu  File: comms.info, Node: conv, Next: convenc, Prev: compand, Up: Function Reference 9.1.15 conv ----------- -- Function File: conv (A, B) Convolve two Galois vectors 'y = conv (a, b)' returns a vector of length equal to 'length (a) + length (b) - 1' If A and B are polynomial coefficient vectors, 'conv' returns the coefficients of the product polynomial See also: deconv  File: comms.info, Node: convenc, Next: convmtx, Prev: conv, Up: Function Reference 9.1.16 convenc -------------- -- Function File: Y = convenc (MSG, T) -- Function File: Y = convenc (MSG, T, PUNCT) -- Function File: Y = convenc (MSG, T, PUNCT, S0) -- Function File: [Y, STATE_END] = convenc (...) Encode the binary vector MSG with the convolutional encoder described by the trellis structure T The rate k/n convolutional encoder encodes k bits at a time from the input vector and produces n bits at a time into the output vector. The input MSG must have a length that is a multiple of k If the initial state S0 is specified, it indicates the internal state of the encoder when the first k input bits are fed in. The default value of S0 is 0 The optional output argument STATE_END indicates the internal state of the encoder after the last bits are encoded. This allows the state of the encoder to be saved and applied to the next call to 'convenc' to process data in blocks See also: poly2trellis  File: comms.info, Node: convmtx, Next: cosets, Prev: convenc, Up: Function Reference 9.1.17 convmtx -------------- -- Function File: convmtx (A, N) Create matrix to perform repeated convolutions with the same vector in a Galois Field. If A is a column vector and X is a column vector of length N, in a Galois Field then 'convmtx (A, N) * X' gives the convolution of of A and X and is the same as 'conv (A, X)'. The difference is if many vectors are to be convolved with the same vector, then this technique is possibly faster Similarly, if A is a row vector and X is a row vector of length N, then 'X * convmtx (A, N)' is the same as 'conv (X, A)' See also: conv  File: comms.info, Node: cosets, Next: cyclgen, Prev: convmtx, Up: Function Reference 9.1.18 cosets ------------- -- Function File: cosets (M, PRIM) Finds the elements of GF(2^M) with primitive polynomial PRIM, that share the same minimum polynomial. Returns a cell array of the partitioning of GF(2^M)  File: comms.info, Node: cyclgen, Next: cyclpoly, Prev: cosets, Up: Function Reference 9.1.19 cyclgen -------------- -- Loadable Function: H = cyclgen (N, P) -- Loadable Function: H = cyclgen (N, P, TYP) -- Loadable Function: [H, G] = cyclgen (...) -- Loadable Function: [H, G, K] = cyclgen (...) Produce the parity check and generator matrix of a cyclic code. The parity check matrix is returned as a M by N matrix, representing the [N,K] cyclic code. M is the order of the generator polynomial P and the message length K is given by 'N - M'. The generator polynomial can either be a vector of ones and zeros, and length M representing, P(1) + P(2) * x + P(3) * x^2 + ... + P(M) * x^(m-1) The terms of the polynomial are stored least-significant term first. Alternatively, P can be an integer representation of the same polynomial. The form of the parity check matrix is determined by TYP. If TYP is 'system', a systematic parity check matrix is produced. If TYP is 'nosys' and non-systematic parity check matrix is produced. If requested 'cyclgen' also returns the K by N generator matrix G. See also: hammgen, gen2par, cyclpoly  File: comms.info, Node: cyclpoly, Next: de2bi, Prev: cyclgen, Up: Function Reference 9.1.20 cyclpoly --------------- -- Loadable Function: Y = cyclpoly (N, K) -- Loadable Function: Y = cyclpoly (N, K, OPT) -- Loadable Function: Y = cyclpoly (N, K, OPT, REP) This function returns the cyclic generator polynomials of the code [N,K]. By default the polynomial with the smallest weight is returned. However this behavior can be overridden with the OPT flag. Valid values of OPT are: '"all\"' Returns all of the polynomials of the code [N,K] '\"min\"' Returns the polynomial of minimum weight of the code [N,K] '\"max\"' Returns the polynomial of the maximum weight of the code [N,K] L Returns the polynomials having exactly the weight L The polynomials are returns as row-vectors in the variable Y. Each row of Y represents a polynomial with the least-significant term first. The polynomials can be returned with an integer representation if REP is '\"integer\"'. The default behavior is given if REP is '\"polynomial\"'. See also: gf, isprimitive  File: comms.info, Node: de2bi, Next: decode, Prev: cyclpoly, Up: Function Reference 9.1.21 de2bi ------------ -- Function File: B = de2bi (D) -- Function File: B = de2bi (D, N) -- Function File: B = de2bi (D, N, P) -- Function File: B = de2bi (D, N, P, F) Convert a non-negative integer to bit vector The variable D must be a vector of non-negative integers. 'de2bi' then returns a matrix where each row represents the binary representation of elements of D. If N is defined then the returned matrix will have N columns. This number of columns can be either larger than the minimum needed and zeros will be added to the msb of the binary representation or smaller than the minimum in which case the least-significant part of the element is returned If P is defined then it is used as the base for the decomposition of the returned values. That is the elements of the returned value are between '0' and 'p-1' The variable F defines whether the first or last element of B is considered to be the most-significant. Valid values of F are "right-msb" or "left-msb". By default F is "right-msb" See also: bi2de  File: comms.info, Node: decode, Next: deconv, Prev: de2bi, Up: Function Reference 9.1.22 decode ------------- -- Function File: MSG = decode (CODE, N, K) -- Function File: MSG = decode (CODE, N, K, TYP) -- Function File: MSG = decode (CODE, N, K, TYP, OPT1) -- Function File: MSG = decode (CODE, N, K, TYP, OPT1, OPT2) -- Function File: [MSG, ERR] = decode (...) -- Function File: [MSG, ERR, CCODE] = decode (...) -- Function File: [MSG, ERR, CCODE, CERR] = decode (...) Top level block decoder. This function makes use of the lower level functions such as 'cyclpoly', 'cyclgen', 'hammgen', and 'bchenco'. The coded message to decode is pass in CODE, the codeword length is N and the message length is K. This function is used to decode messages using either: A [n,k] linear block code defined by a generator matrix A [n,k] cyclic code defined by a generator polynomial A [n,k] Hamming code defined by a primitive polynomial A [n,k] BCH code code defined by a generator polynomial The type of coding to use is defined by the variable TYP. This variable is a string taking one of the values '"linear"' '"linear/binary"' A linear block code is assumed with the message MSG being in a binary format. In this case the argument OPT1 is the generator matrix, and is required. Additionally, OPT2 containing the syndrome lookup table (see 'syndtable') can also be passed '"cyclic"' '"cyclic/binary"' A cyclic code is assumed with the message MSG being in a binary format. The generator polynomial to use can be defined in OPT1 The default generator polynomial to use will be 'cyclpoly (N, K)'. Additionally, OPT2 containing the syndrome lookup table (see 'syndtable') can also be passed '"hamming"' '"hamming/binary"' A Hamming code is assumed with the message MSG being in a binary format. In this case N must be of an integer of the form '2^M-1', where M is an integer. In addition K must be 'N-M'. The primitive polynomial to use can be defined in OPT1. The default primitive polynomial to use is the same as defined by 'hammgen'. The variable OPT2 should not be defined '"bch"' '"bch/binary"' A BCH code is assumed with the message MSG being in a binary format. The primitive polynomial to use can be defined in OPT2 The error correction capability of the code can also be defined in OPT1. Use the empty matrix [] to let the error correction capability take the default value In addition the argument "binary" above can be replaced with "decimal", in which case the message is assumed to be a decimal vector, with each value representing a symbol to be coded. The binary format can be in two forms 'An X-by-N matrix' Each row of this matrix represents a symbol to be decoded 'A vector with length divisible by N' The coded symbols are created from groups of N elements of this vector The decoded message is return in MSG. The number of errors encountered is returned in ERR. If the coded message format is "decimal" or a "binary" matrix, then ERR is a column vector having a length equal to the number of decoded symbols. If CODE is a "binary" vector, then ERR is the same length as MSG and indicated the number of errors in each symbol. If the value ERR is positive it indicates the number of errors corrected in the corresponding symbol. A negative value indicates an uncorrectable error. The corrected code is returned in CCODE in a similar format to the coded message MSG. The variable CERR contains similar data to ERR for CCODE It should be noted that all internal calculations are performed in the binary format. Therefore for large values of N, it is preferable to use the binary format to pass the messages to avoid possible rounding errors. Additionally, if repeated calls to 'decode' will be performed, it is often faster to create a generator matrix externally with the functions 'hammgen' or 'cyclgen', rather than let 'decode' recalculate this matrix at each iteration. In this case TYP should be "linear". The exception to this case is BCH codes, where the required syndrome table is too large. The BCH decoder, decodes directly from the polynomial never explicitly forming the syndrome table See also: encode, cyclgen, cyclpoly, hammgen, bchdeco, bchpoly, syndtable  File: comms.info, Node: deconv, Next: deintrlv, Prev: decode, Up: Function Reference 9.1.23 deconv ------------- -- Function File: deconv (Y, A) Deconvolve two Galois vectors '[b, r] = deconv (y, a)' solves for B and R such that 'y = conv (a, b) + r' If Y and A are polynomial coefficient vectors, B will contain the coefficients of the polynomial quotient and R will be a remainder polynomial of lowest order See also: conv  File: comms.info, Node: deintrlv, Next: demodmap, Prev: deconv, Up: Function Reference 9.1.24 deintrlv --------------- -- Function File: DEINTRLVD = deintrlv (DATA, ELEMENTS) Restore elements of DATA according to ELEMENTS See also: intrlv  File: comms.info, Node: demodmap, Next: det, Prev: deintrlv, Up: Function Reference 9.1.25 demodmap --------------- -- Function File: z = demodmap (Y, FD, FS, "ask", M) -- Function File: z = demodmap (Y, FD, FS, "fsk", M, TONE) -- Function File: z = demodmap (Y, FD, FS, "msk") -- Function File: z = demodmap (Y, FD, FS, "psk", M) -- Function File: z = demodmap (Y, FD, FS, "qask", M) -- Function File: z = demodmap (Y, FD, FS, "qask/cir", NSIG, AMP, PHS) -- Function File: z = demodmap (Y, FD, FS, "qask/arb", INPHASE, QUADR) -- Function File: z = demodmap (Y, FD, FS, "qask/arb", MAP) -- Function File: z = demodmap (Y, [FD, OFF], ...) Demapping of an analog signal to a digital signal. The function 'demodmap' must have at least three input arguments and one output argument. Argument Y is a complex variable representing the analog signal to be demapped. The variables FD and FS are the sampling rate of the of digital signal and the sampling rate of the analog signal respectively. It is required that 'FS/FD' is an integer The available mapping of the digital signal are "ask" Amplitude shift keying "fsk" Frequency shift keying "msk" Minimum shift keying "psk" Phase shift keying "qask" "qsk" "qam" Quadrature amplitude shift keying In addition the "qask", "qsk" and "qam" method can be modified with the flags "/cir" or "/arb". That is "qask/cir" and "qask/arb", etc are valid methods and give circular- and arbitrary-qask mappings respectively. Also the method "fsk" and "msk" can be modified with the flag "/max", in which case Y is assumed to be a matrix with M columns, representing the symbol correlations The variable M is the order of the modulation to use. By default this is 2, and in general should be specified For "qask/cir", the additional arguments are the same as for 'apkconst', and you are referred to 'apkconst' for the definitions of the additional variables For "qask/arb", the additional arguments INPHASE and QUADR give the in-phase and quadrature components of the mapping, in a similar mapping to the outputs of 'qaskenco' with one argument. Similar MAP represents the in-phase and quadrature components of the mapping as the real and imaginary parts of the variable MAP See also: modmap, ddemodce, ademodce, apkconst, qaskenco  File: comms.info, Node: det, Next: dftmtx, Prev: demodmap, Up: Function Reference 9.1.26 det ---------- -- Loadable Function: D = det (A) Compute the determinant of the Galois array A  File: comms.info, Node: dftmtx, Next: diag, Prev: det, Up: Function Reference 9.1.27 dftmtx ------------- -- Function File: D = dftmtx (A) Form a matrix, that can be used to perform Fourier transforms in a Galois Field Given that A is an element of the Galois Field GF(2^m), and that the minimum value for K for which 'A ^ K' is equal to one is '2^m - 1', then this function produces a K-by-K matrix representing the discrete Fourier transform over a Galois Field with respect to A. The Fourier transform of a column vector is then given by 'dftmtx (A) * X' The inverse Fourier transform is given by 'dftmtx (1 / A)'  File: comms.info, Node: diag, Next: dpcmdeco, Prev: dftmtx, Up: Function Reference 9.1.28 diag ----------- -- Loadable Function: diag (V, K) Return a diagonal matrix with Galois vector V on diagonal K The second argument is optional. If it is positive, the vector is placed on the K-th super-diagonal. If it is negative, it is placed on the -K-th sub-diagonal. The default value of K is 0, and the vector is placed on the main diagonal. For example, diag (gf ([1, 2, 3], 2), 1) ans = GF(2^2) array. Primitive Polynomial = D^2+D+1 (decimal 7) Array elements = 0 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0  File: comms.info, Node: dpcmdeco, Next: dpcmenco, Prev: diag, Up: Function Reference 9.1.29 dpcmdeco --------------- -- Function File: SIG = dpcmdeco (INDX, CODEBOOK, PREDICTOR) Decode using differential pulse code modulation (DPCM) 'sig = dpcmdeco (indx, codebook, predictor)' Decode the signal coded by DPCM Use the prediction model and the coded prediction error given by a codebook and the index of each sample in this codebook See also: dpcmenco, dpcmopt  File: comms.info, Node: dpcmenco, Next: dpcmopt, Prev: dpcmdeco, Up: Function Reference 9.1.30 dpcmenco --------------- -- Function File: QIDX = dpcmenco (SIG, CODEBOOK, PARTITION, PREDICTOR) -- Function File: [QIDX, Q] = dpcmenco (SIG, CODEBOOK, PARTITION, PREDICTOR) -- Function File: [QIDX, Q, D] = dpcmenco (...) Encode using differential pulse code modulation (DPCM) 'qidx = dpcmenco (sig, codebook, partition, predictor)' Determine position of the prediction error in a strictly monotonic table (partition) The predictor vector describes a m-th order prediction for the output according to the following equation y(k) = p(1)sig(k-1) + p(2)sig(k-2) + ... + p(m-1)sig(k-m+1) + p(m)sig(k-m) , where the predictor vector is given by predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)] '[qidx, q] = dpcmenco (sig, codebook, partition, predictor)' Also return the quantized values '[qidx, q, d] = dpcmenco (...)' Also compute distortion: mean squared distance of original sig from the corresponding quantized values See also: dpcmdeco, dpcmopt, quantiz  File: comms.info, Node: dpcmopt, Next: egolaydec, Prev: dpcmenco, Up: Function Reference 9.1.31 dpcmopt -------------- -- Function File: PREDICTOR = dpcmopt (TRAINING_SET, ORD) -- Function File: [PREDICTOR, PARTITION, CODEBOOK] = dpcmopt (TRAINING_SET, ORD, CB) Optimize the DPCM parameters and codebook It uses the Levinson-Durbin algorithm to find the all-pole IIR filter using the autocorrelation sequence. After the best predictor is found, it uses the Lloyds algorithm to find the best codebook and partition for the interval 'predictor = dpcmopt (training_set, ord)' Optimize the DPCM parameters using the Levinson-Durbin algorithm The predictor vector describes a m-th order prediction for the output according to the following equation y(k) = p(1)sig(k-1) + p(2)sig(k-2) + ... + p(m-1)sig(k-m+1) + p(m)sig(k-m) where the predictor vector is given by predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)] training_set is the training data used to find the best predictor ord is the order of the desired prediction model '[predictor, partition, codebook] = dpcmopt (training_set,ord,cb)' Optimize the DPCM parameters and also uses the Lloyds algorithm to find the best codebook and partition for the given training signal cb might be the initial codebook used by Lloyds algorithm or the length of the desired codebook See also: dpcmenco, dpcmdeco, levinson, lloyds  File: comms.info, Node: egolaydec, Next: egolayenc, Prev: dpcmopt, Up: Function Reference 9.1.32 egolaydec ---------------- -- Function File: [C, ERR] = egolaydec (R) Decode Extended Golay code Given R, the received Extended Golay code, this function tries to decode it using the Extended Golay code parity check matrix Extended Golay code (24,12) which can correct up to 3 errors The received code R, needs to be of length Nx24, for encoding. We can decode several codes at once, if they are stacked as a matrix of 24 columns, each code in a separate row The generator used in here is same as obtained from the function 'egolaygen' The function returns C, the error-corrected code word from the received word. If decoding failed, ERR value is 1, otherwise it is 0 Extended Golay code (24,12) which can correct up to 3 errors. Decoding algorithm follows from Lin & Costello Ref: Lin & Costello, pg 128, Ch4, "Error Control Coding", 2nd ed, Pearson msg = rand (10, 12) > 0.5; c1 = egolayenc (msg); c1(:,1) = mod (c1(:,1) + 1, 2) c2 = egolaydec (c1) See also: egolaygen, egolayenc  File: comms.info, Node: egolayenc, Next: egolaygen, Prev: egolaydec, Up: Function Reference 9.1.33 egolayenc ---------------- -- Function File: C = egolayenc (M) Encode with Extended Golay code The message M, needs to be of size Nx12, for encoding We can encode several messages, into codes at once, if they are stacked in the order suggested The generator used in here is same as obtained from the function 'egolaygen'. Extended Golay code (24,12) which can correct up to 3 errors msg = rand (10, 12) > 0.5; c = egolayenc (msg) See also: egolaygen, egolaydec  File: comms.info, Node: egolaygen, Next: encode, Prev: egolayenc, Up: Function Reference 9.1.34 egolaygen ---------------- -- Function File: [G, P] = egolaygen () Extended Golay code generator matrix Returns G, the Extended Golay code (24,12) generator matrix, which can correct up to 3 errors. P is the parity check matrix, for this code See also: egolaydec, egolayenc  File: comms.info, Node: encode, Next: exp, Prev: egolaygen, Up: Function Reference 9.1.35 encode ------------- -- Function File: CODE = encode (MSG, N, K) -- Function File: CODE = encode (MSG, N, K, TYP) -- Function File: CODE = encode (MSG, N, K, TYP, OPT) -- Function File: [CODE, ADDED] = encode (...) Top level block encoder. This function makes use of the lower level functions such as 'cyclpoly', 'cyclgen', 'hammgen', and 'bchenco'. The message to code is pass in MSG, the codeword length is N and the message length is K. This function is used to encode messages using either: A [n,k] linear block code defined by a generator matrix A [n,k] cyclic code defined by a generator polynomial A [n,k] Hamming code defined by a primitive polynomial A [n,k] BCH code code defined by a generator polynomial The type of coding to use is defined by the variable TYP. This variable is a string taking one of the values '"linear"' '"linear/binary"' A linear block code is assumed with the coded message CODE being in a binary format. In this case the argument OPT is the generator matrix, and is required '"cyclic"' '"cyclic/binary"' A cyclic code is assumed with the coded message CODE being in a binary format. The generator polynomial to use can be defined in OPT The default generator polynomial to use will be 'cyclpoly (N, K)' '"hamming"' '"hamming/binary"' A Hamming code is assumed with the coded message CODE being in a binary format. In this case N must be of an integer of the form '2^M-1', where M is an integer. In addition K must be 'N-M'. The primitive polynomial to use can be defined in OPT. The default primitive polynomial to use is the same as defined by 'hammgen' '"bch"' '"bch/binary"' A BCH code is assumed with the coded message CODE being in a binary format. The generator polynomial to use can be defined in OPT The default generator polynomial to use will be 'bchpoly (N, K)' In addition the argument "binary" above can be replaced with "decimal", in which case the message is assumed to be a decimal vector, with each value representing a symbol to be coded. The binary format can be in two forms 'An X-by-K matrix' Each row of this matrix represents a symbol to be coded 'A vector' The symbols are created from groups of K elements of this vector If the vector length is not divisible by K, then zeros are added and the number of zeros added is returned in ADDED It should be noted that all internal calculations are performed in the binary format. Therefore for large values of N, it is preferable to use the binary format to pass the messages to avoid possible rounding errors. Additionally, if repeated calls to 'encode' will be performed, it is often faster to create a generator matrix externally with the functions 'hammgen' or 'cyclgen', rather than let 'encode' recalculate this matrix at each iteration. In this case TYP should be "linear". The exception to this case is BCH codes, whose encoder is implemented directly from the polynomial and is significantly faster See also: decode, cyclgen, cyclpoly, hammgen, bchenco, bchpoly  File: comms.info, Node: exp, Next: eyediagram, Prev: encode, Up: Function Reference 9.1.36 exp ---------- -- Loadable Function: exp (X) Compute the anti-logarithm for each element of X for a Galois array  File: comms.info, Node: eyediagram, Next: fft, Prev: exp, Up: Function Reference 9.1.37 eyediagram ----------------- -- Function File: eyediagram (X, N) -- Function File: eyediagram (X, N, PER) -- Function File: eyediagram (X, N, PER, OFF) -- Function File: eyediagram (X, N, PER, OFF, STR) -- Function File: eyediagram (X, N, PER, OFF, STR, H) -- Function File: H = eyediagram (...) Plot the eye-diagram of a signal. The signal X can be either in one of three forms A real vector In this case the signal is assumed to be real and represented by the vector X. A single eye-diagram representing this signal is plotted A complex vector In this case the in-phase and quadrature components of the signal are plotted separately A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal Each line of the eye-diagram has N elements and the period is assumed to be given by PER. The time axis is then [-PER/2 PER/2] By default PER is 1 By default the signal is assumed to start at -PER/2. This can be overridden by the OFF variable, which gives the number of samples to delay the signal The string STR is a plot style string (example "r+"), and by default is the default gnuplot line style The figure handle to use can be defined by H. If H is not given, then the next available figure handle is used. The figure handle used in returned on HOUT See also: scatterplot  File: comms.info, Node: fft, Next: fibodeco, Prev: eyediagram, Up: Function Reference 9.1.38 fft ---------- -- Function File: fft (X) If X is a column vector, finds the FFT over the primitive element of the Galois Field of X. If X is in the Galois Field GF(2^M), then X must have '2^M - 1' elements  File: comms.info, Node: fibodeco, Next: fiboenco, Prev: fft, Up: Function Reference 9.1.39 fibodeco --------------- -- Function File: fibodeco (CODE) Returns the decoded Fibonacci value from the binary vectors CODE Universal codes like Fibonacci codes have a useful synchronization property, only for 255 maximum value we have designed these routines. We assume user has partitioned the code into several unique segments based on the suffix property of unique strings "11" and we just decode the parts. Partitioning the stream is as simple as identifying the "11" pairs that occur, at the terminating ends. This system implements the standard binary Fibonacci codes, which means that row vectors can only contain 0 or 1. Ref: fibodeco ({[0 1 0 0 1 1]}) => 10 fibodeco ({[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]}) => [1, 2, 3, 4] See also: fiboenco  File: comms.info, Node: fiboenco, Next: fibosplitstream, Prev: fibodeco, Up: Function Reference 9.1.40 fiboenco --------------- -- Function File: fiboenco (NUM) Returns the cell-array of encoded Fibonacci value from the column vectors NUM Universal codes like Fibonacci codes have a useful synchronization property, only for 255 maximum value we have designed these routines. We assume user has partitioned the code into several unique segments based on the suffix property of unique elements [1 1] and we just decode the parts. Partitioning the stream is as simple as identifying the [1 1] pairs that occur, at the terminating ends. This system implements the standard binary Fibonacci codes, which means that row vectors can only contain 0 or 1. Ref: http://en.wikipedia.org/wiki/Fibonacci_coding Ugly O(k.N^2) encoder.Ref: Wikipedia article accessed March, 2006 , UCI Data Compression Book, , (accessed October 2006) fiboenco (10) => {[ 0 1 0 0 1 1]} fiboenco (1:4) => {[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]} See also: fibodeco  File: comms.info, Node: fibosplitstream, Next: filter, Prev: fiboenco, Up: Function Reference 9.1.41 fibosplitstream ---------------------- -- Function File: fibosplitstream (CODE) Returns the split data stream at the word boundaries Assuming the stream was originally encoded using 'fiboenco' and this routine splits the stream at the points where "11" occur together & gives us the code-words which can later be decoded from the 'fibodeco' This however doesn't mean that we intend to verify if all the codewords are correct, and in fact the last symbol in the return list can or can not be a valid codeword A example use of 'fibosplitstream' would be fibodeco (fibosplitstream ([fiboenco(randint (1, 100, [0, 255])){:}])) fibodeco (fibosplitstream ([fiboenco(1:10){:}])) See also: fiboenco, fibodeco  File: comms.info, Node: filter, Next: fmdemod, Prev: fibosplitstream, Up: Function Reference 9.1.42 filter ------------- -- Loadable Function: y = filter (B, A, X) -- Loadable Function: [Y, SF] = filter (B, A, X, SI) Digital filtering of vectors in a Galois Field. Returns the solution to the following linear, time-invariant difference equation over a Galois Field: N M SUM a(k+1) y(n-k) = SUM b(k+1) x(n-k) for 1<=n<=length(x) k=0 k=0 where N=length(a)-1 and M=length(b)-1 An equivalent form of this equation is: N M y(n) = - SUM c(k+1) y(n-k) + SUM d(k+1) x(n-k) for 1<=n<=length(x) k=1 k=0 where c = a/a(1) and d = b/a(1) If the fourth argument SI is provided, it is taken as the initial state of the system and the final state is returned as SF. The state vector is a column vector whose length is equal to the length of the longest coefficient vector minus one If SI is not supplied, the initial state vector is set to all zeros  File: comms.info, Node: fmdemod, Next: fmmod, Prev: filter, Up: Function Reference 9.1.43 fmdemod -------------- -- Function File: fmdemod (X, FC, FS) Create the FM demodulation of the signal x with carrier frequency fs Where x is sample at frequency fs See also: ammod, amdemod, fmmod  File: comms.info, Node: fmmod, Next: gen2par, Prev: fmdemod, Up: Function Reference 9.1.44 fmmod ------------ -- Function File: fmmod (X, FC, FS) Create the FM modulation of the signal x with carrier frequency fs. Where x is sample at frequency fs See also: ammod, fmdemod, amdemod  File: comms.info, Node: gen2par, Next: genqamdemod, Prev: fmmod, Up: Function Reference 9.1.45 gen2par -------------- -- Function File: PAR = gen2par (GEN) -- Function File: GEN = gen2par (PAR) Converts binary generator matrix GEN to the parity check matrix PAR and visa-versa. The input matrix must be in standard form That is a generator matrix must be k-by-n and in the form [eye(k) P] or [P eye(k)], and the parity matrix must be (n-k)-by-n and of the form [eye(n-k) P'] or [P' eye(n-k)] See also: cyclgen, hammgen  File: comms.info, Node: genqamdemod, Next: genqammod, Prev: gen2par, Up: Function Reference 9.1.46 genqamdemod ------------------ -- Loadable Function: Y = genqamdemod (X, C) General quadrature amplitude demodulation. The complex envelope quadrature amplitude modulated signal X is demodulated using a constellation mapping specified by the 1D vector C.  File: comms.info, Node: genqammod, Next: gf, Prev: genqamdemod, Up: Function Reference 9.1.47 genqammod ---------------- -- Function File: Y = genqammod (X, C) Modulates an information sequence of integers X in the range '[0 ... M-1]' onto a quadrature amplitude modulated signal Y, where 'M = length (c) - 1' and C is a 1D vector specifying the signal constellation mapping to be used. An example of combined 4PAM-4PSK is d = randint (1, 1e4, 8); c = [1+j -1+j -1-j 1-j 1+sqrt(3) j*(1+sqrt(3)) -1-sqrt(3) -j*(1+sqrt(3))]; y = genqammod (d, c); z = awgn (y, 20); plot (z, "rx") See also: genqamdemod  File: comms.info, Node: gf, Next: gftable, Prev: genqammod, Up: Function Reference 9.1.48 gf --------- -- Loadable Function: Y = gf (X) -- Loadable Function: Y = gf (X, M) -- Loadable Function: Y = gf (X, M, PRIMPOLY) Creates a Galois field array GF(2^M) from the matrix X. The Galois field has 2^M elements, where M must be between 1 and 16. The elements of X must be between 0 and 2^M - 1. If M is undefined it defaults to the value 1. The primitive polynomial to use in the creation of Galois field can be specified with the PRIMPOLY variable. If this is undefined a default primitive polynomial is used. It should be noted that the primitive polynomial must be of the degree M and it must be irreducible. The output of this function is recognized as a Galois field by Octave and other matrices will be converted to the same Galois field when used in an arithmetic operation with a Galois field. See also: isprimitive, primpoly  File: comms.info, Node: gftable, Next: gfweight, Prev: gf, Up: Function Reference 9.1.49 gftable -------------- -- Function File: gftable (M, PRIMPOLY) This function exists for compatibility with matlab. As the Octave Galois fields store a copy of the lookup tables for every field in use internally, there is no need to use this function See also: gf  File: comms.info, Node: gfweight, Next: golombdeco, Prev: gftable, Up: Function Reference 9.1.50 gfweight --------------- -- Function File: W = gfweight (GEN) -- Function File: W = gfweight (GEN, "gen") -- Function File: W = gfweight (PAR, "par") -- Function File: W = gfweight (P, n) Calculate the minimum weight or distance of a linear block code. The code can be either defined by its generator or parity check matrix, or its generator polynomial. By default if the first argument is a matrix, it is assumed to be the generator matrix of the code. The type of the matrix can be defined by a flag "gen" for the generator matrix or "par" for the parity check matrix If the first argument is a vector, it is assumed that it defines the generator polynomial of the code. In this case a second argument is required that defines the codeword length See also: hammgen, cyclpoly, bchpoly  File: comms.info, Node: golombdeco, Next: golombenco, Prev: gfweight, Up: Function Reference 9.1.51 golombdeco ----------------- -- Function File: golombdeco (CODE, M) Returns the Golomb decoded signal vector using CODE and M Compulsory m is need to be specified. A restrictions is that a signal set must strictly be non-negative. The value of code is a cell array of row-vectors which have the encoded Golomb value for a single sample. The Golomb algorithm is used to encode the "code" and only that can be meaningfully decoded. CODE is assumed to have been of format generated by the function 'golombenco'. Also the parameter M need to be a non-zero number, unless which it makes divide-by-zero errors This function works backward the Golomb algorithm see 'golombenco' for more details on that Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info Theory An example of the use of 'golombdeco' is golombdeco (golombenco (1:4, 2), 2) => [1 2 3 4] See also: golombenco  File: comms.info, Node: golombenco, Next: hammgen, Prev: golombdeco, Up: Function Reference 9.1.52 golombenco ----------------- -- Function File: golombenco (SIG, M) Returns the Golomb coded signal as cell array Also total length of output code in bits can be obtained This function uses a M need to be supplied for encoding signal vector into a Golomb coded vector. A restrictions is that a signal set must strictly be non-negative. Also the parameter M need to be a non-zero number, unless which it makes divide-by-zero errors The Golomb algorithm [1], is used to encode the data into unary coded quotient part which is represented as a set of 1's separated from the K-part (binary) using a zero. This scheme doesn't need any kind of dictionaries, it is a parameterized prefix codes Implementation is close to O(N^2), but this implementation *may be* sluggish, though correct. Details of the scheme are, to encode the remainder(r of number N) using the floor(log2(m)) bits when rem is in range 0:(2^ceil(log2(m)) - N), and encode it as r+(2^ceil(log2(m)) - N), using total of 2^ceil(log2(m)) bits in other instance it doesn't belong to case 1. Quotient is coded simply just using the unary code. Also according to [2] Golomb codes are optimal for sequences using the Bernoulli probability model: P(n)=p^n-1.q & p+q=1, and when M=[1/log2(p)], or P=2^(1/M) Reference: 1. Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info' Theory. 2. Khalid Sayood, Data Compression, 3rd Edition An example of the use of 'golombenco' is golombenco (1:4, 2) => {[0 1], [1 0 0], [1 0 1], [1 1 0 0]} golombenco (1:10, 2) => {[0 1], [1 0 0], [1 0 1], [1 1 0 0], [1 1 0 1], [1 1 1 0 0], [1 1 1 0 1], [1 1 1 1 0 0], [1 1 1 1 0 1], [1 1 1 1 1 0 0]} See also: golombdeco  File: comms.info, Node: hammgen, Next: helscanintrlv, Prev: golombenco, Up: Function Reference 9.1.53 hammgen -------------- -- Function File: H = hammgen (M) -- Function File: H = hammgen (M, P) -- Function File: [H, G] = hammgen (...) -- Function File: [H, G, N, K] = hammgen (...) Produce the parity check and generator matrices of a Hamming code. The variable M defines the [N,K] Hamming code where 'N = 2 ^ M - 1' and 'K = N - M' M must be between 3 and 16 The parity check matrix is generated relative to the primitive polynomial of GF(2^M). If P is specified the default primitive polynomial of GF(2^M) is overridden. P must be a valid primitive polynomial of the correct order for GF(2^M) The parity check matrix is returned in the M by N matrix H, and if requested the generator matrix is returned in the K by N matrix G See also: gen2par  File: comms.info, Node: helscanintrlv, Next: huffmandeco, Prev: hammgen, Up: Function Reference 9.1.54 helscanintrlv -------------------- -- Function File: OUTDATA = helscanintrlv (DATA, NROWS, NCOLS, NSHIFT) NROWS-by-NCOLS See also: helscandeintrlv  File: comms.info, Node: huffmandeco, Next: huffmandict, Prev: helscanintrlv, Up: Function Reference 9.1.55 huffmandeco ------------------ -- Function File: SIG = huffmandeco (HCODE, DICT) Decode signal encoded by 'huffmanenco' This function uses a dict built from the 'huffmandict' and uses it to decode a signal list into a Huffman list. A restriction is that HCODE is expected to be a binary code The returned SIG set that strictly belongs in the range '[1,N]' with 'N = length (DICT)'. Also DICT can only be from the 'huffmandict' routine. Whenever decoding fails, those signal values a re indicated by '-1', and we successively try to restart decoding from the next bit that hasn't failed in decoding, ad-infinitum. An example of the use of 'huffmandeco' is: hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]); hcode = huffmanenco (1:4, hd); back = huffmandeco (hcode, hd) => [1 2 3 4] See also: huffmandict, huffmanenco  File: comms.info, Node: huffmandict, Next: huffmanenco, Prev: huffmandeco, Up: Function Reference 9.1.56 huffmandict ------------------ -- Function File: huffmandict (SYMB, PROB) -- Function File: huffmandict (SYMB, PROB, TOGGLE) -- Function File: huffmandict (SYMB, PROB, TOGGLE, MINVAR) Builds a Huffman code, given a probability list. The Huffman codes per symbol are output as a list of strings-per-source symbol. A zero probability symbol is NOT assigned any codeword as this symbol doesn't occur in practice anyway TOGGLE is an optional argument with values 1 or 0, that starts building a code based on 1s or 0s, defaulting to 0. Also MINVAR is a boolean value that is useful in choosing if you want to optimize buffer for transmission in the applications of Huffman coding, however it doesn't affect the type or average codeword length of the generated code. An example of the use of 'huffmandict' is huffmandict (symbols, [0.5 0.25 0.15 0.1], 1) => {[0], [1 0], [1 1 1], [1 1 0]} huffmandict (symbols, 0.25 * ones (1,4), 1) => {[1 1], [1 0], [0 1], [0 0]} prob = [0.5 0 0.25 0.15 0.1]; dict = huffmandict (1:5, prob, 1); entropy (prob) => 2.3219 laverage (dict, prob) => 1.8500 x = [0.2 0.4 0.2 0.1 0.1]; huffmandict (1, x, 0, true) => {[1 0], [0 0], [1 1], [0 1 0], [0 1 1]} huffmandict (1, x) => {[0 1], [1], [0 0 1], [0 0 0 0], [0 0 0 1]} Reference: Dr.Rao's course EE5351 Digital Video Coding, at UT-Arlington See also: huffmandeco, huffmanenco  File: comms.info, Node: huffmanenco, Next: ifft, Prev: huffmandict, Up: Function Reference 9.1.57 huffmanenco ------------------ -- Function File: huffmanenco (SIG, DICT) Returns the Huffman encoded signal using DICT. This function uses a DICT built from the 'huffmandict' and uses it to encode a signal list into a Huffman list. A restrictions is that a signal set must strictly belong in the range '[1,N]' with 'N = length (dict)' Also DICT can only be from the 'huffmandict' routine An example of the use of 'huffmanenco' is hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]); huffmanenco (1:4, hd) => [1 0 1 0 0 0 0 0 1] See also: huffmandict, huffmandeco  File: comms.info, Node: ifft, Next: intrlv, Prev: huffmanenco, Up: Function Reference 9.1.58 ifft ----------- -- Function File: ifft (X) If X is a column vector, finds the IFFT over the primitive element of the Galois Field of X. If X is in the Galois Field GF(2^M), then X must have '2^M - 1' elements See also: ifft  File: comms.info, Node: intrlv, Next: inv, Prev: ifft, Up: Function Reference 9.1.59 intrlv ------------- -- Function File: INTRLVD = intrlv (DATA, ELEMENTS) Interleaved elements of DATA according to ELEMENTS See also: deintrlv  File: comms.info, Node: inv, Next: inverse, Prev: intrlv, Up: Function Reference 9.1.60 inv ---------- -- Loadable Function: [X, RCOND] = inv (A) Compute the inverse of the square matrix A. Return an estimate of the reciprocal condition number if requested, otherwise warn of an ill-conditioned matrix if the reciprocal condition number is small  File: comms.info, Node: inverse, Next: isequal, Prev: inv, Up: Function Reference 9.1.61 inverse -------------- -- Loadable Function: [X, RCOND] = inverse (A) See inv  File: comms.info, Node: isequal, Next: isgalois, Prev: inverse, Up: Function Reference 9.1.62 isequal -------------- -- Function File: isequal (X1, X2, ...) Return true if all of X1, X2, ... are equal See also: isequalwithequalnans  File: comms.info, Node: isgalois, Next: isprimitive, Prev: isequal, Up: Function Reference 9.1.63 isgalois --------------- -- Loadable Function: isgalois (EXPR) Return 1 if the value of the expression EXPR is a Galois Field.  File: comms.info, Node: isprimitive, Next: istrellis, Prev: isgalois, Up: Function Reference 9.1.64 isprimitive ------------------ -- Loadable Function: Y = isprimitive (A) Returns 1 is the polynomial represented by A is a primitive polynomial of GF(2). Otherwise it returns zero. See also: gf, primpoly  File: comms.info, Node: istrellis, Next: lloyds, Prev: isprimitive, Up: Function Reference 9.1.65 istrellis ---------------- -- Function File: istrellis (T) -- Function File: [STATUS, TEXT] = istrellis (T) Return true if T is a valid trellis structure If called with two output arguments, TEXT contains a string indicating a reason if STATUS is false or an empty string if STATUS is true See also: poly2trellis, struct  File: comms.info, Node: lloyds, Next: log, Prev: istrellis, Up: Function Reference 9.1.66 lloyds ------------- -- Function File: [TABLE, CODES] = lloyds (SIG, INIT_CODES) -- Function File: [TABLE, CODES] = lloyds (SIG, LEN) -- Function File: [TABLE, CODES] = lloyds (SIG, ..., TOL) -- Function File: [TABLE, CODES] = lloyds (SIG, ..., TOL, TYPE) -- Function File: [TABLE, CODES, DIST] = lloyds (...) -- Function File: [TABLE, CODES, DIST, RELDIST] = lloyds (...) Optimize the quantization table and codes to reduce distortion. This is based on the article by Lloyd S. Lloyd _Least squared quantization in PCM_, IEEE Trans Inform Theory, Mar 1982, no 2, p129-137 which describes an iterative technique to reduce the quantization error by making the intervals of the table such that each interval has the same area under the PDF of the training signal SIG. The initial codes to try can either be given in the vector INIT_CODES or as scalar LEN. In the case of a scalar the initial codes will be an equi-spaced vector of length LEN between the minimum and maximum value of the training signal The stopping criteria of the iterative algorithm is given by abs(DIST(n) - DIST(n-1)) < max(TOL, abs(EPS*max(SIG)) By default TOL is 1.e-7. The final input argument determines how the updated table is created. By default the centroid of the values of the training signal that fall within the interval described by CODES are used to update TABLE. If TYPE is any other string than "centroid", this behavior is overridden and TABLE is updated as follows TABLE = (CODE(2:length(CODE)) + CODE(1:length(CODE-1))) / 2 The optimized values are returned as TABLE and CODE. In addition the distortion of the optimized codes representing the training signal is returned as DIST. The relative distortion in the final iteration is also returned as RELDIST See also: quantiz  File: comms.info, Node: log, Next: lu, Prev: lloyds, Up: Function Reference 9.1.67 log ---------- -- Loadable Function: log (X) Compute the natural logarithm for each element of X for a Galois array  File: comms.info, Node: lu, Next: lz77deco, Prev: log, Up: Function Reference 9.1.68 lu --------- -- Loadable Function: [L, U, P] = lu (A) Compute the LU decomposition of A in a Galois Field. The result is returned in a permuted form, according to the optional return value P. For example, given the matrix 'a = gf ([1, 2; 3, 4], 3)', [l, u, p] = lu (a) returns l = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 0 6 1 u = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 3 4 0 7 p = Permutation Matrix 0 1 1 0 Such that 'P * A = L * U'. If the argument P is not included then the permutations are applied to L so that 'A = L * U'. L is then a pseudo- lower triangular matrix. The matrix A can be rectangular  File: comms.info, Node: lz77deco, Next: lz77enco, Prev: lu, Up: Function Reference 9.1.69 lz77deco --------------- -- Function File: M = lz77deco (C, ALPH, LA, N) Lempel-Ziv 77 source algorithm decoding implementation. Where M message decoded (1xN) C encoded message (Mx3) ALPH size of alphabet LA lookahead buffer size N sliding window buffer size See also: lz77enco  File: comms.info, Node: lz77enco, Next: matdeintrlv, Prev: lz77deco, Up: Function Reference 9.1.70 lz77enco --------------- -- Function File: C = lz77enco (M, ALPH, LA, N) Lempel-Ziv 77 source algorithm implementation. Where C encoded message (Mx3) ALPH size of alphabet LA lookahead buffer size N sliding window buffer size See also: lz77deco  File: comms.info, Node: matdeintrlv, Next: matintrlv, Prev: lz77enco, Up: Function Reference 9.1.71 matdeintrlv ------------------ -- Function File: INTRLVD = matdeintrlv (DATA, NROWS, NCOLS) Restore elements of DATA with a temporary matrix of size NROWS-by-NCOLS See also: matintrlv  File: comms.info, Node: matintrlv, Next: minpol, Prev: matdeintrlv, Up: Function Reference 9.1.72 matintrlv ---------------- -- Function File: INTRLVD = matintrlv (DATA, NROWS, NCOLS) Interleaved elements of DATA with a temporary matrix of size NROWS-by-NCOLS See also: matdeintrlv  File: comms.info, Node: minpol, Next: modmap, Prev: matintrlv, Up: Function Reference 9.1.73 minpol ------------- -- Function File: minpol (V) Finds the minimum polynomial for elements of a Galois Field. For a vector V with N components, representing N values in a Galois Field GF(2^M), return the minimum polynomial in GF(2) representing those values  File: comms.info, Node: modmap, Next: oct2dec, Prev: minpol, Up: Function Reference 9.1.74 modmap ------------- -- Function File: modmap (METHOD, ...) -- Function File: y = modmap (X, FD, FS, "ask", M) -- Function File: y = modmap (X, FD, FS, "fsk", M, TONE) -- Function File: y = modmap (X, FD, FS, "msk") -- Function File: y = modmap (X, FD, FS, "psk", M) -- Function File: y = modmap (X, FD, FS, "qask", M) -- Function File: y = modmap (X, FD, FS, "qask/cir", NSIG, AMP, PHS) -- Function File: y = modmap (X, FD, FS, "qask/arb", INPHASE, QUADR) -- Function File: y = modmap (X, FD, FS, "qask/arb", MAP) Mapping of a digital signal to an analog signal. With no output arguments 'modmap' plots the constellation of the mapping. In this case the first argument must be the string METHOD defining one of "ask", "fsk", "msk", "qask", "qask/cir" or "qask/arb". The arguments following the string METHOD are generally the same as those after the corresponding string in the function call without output arguments The exception is 'modmap ("msk", FD)' With an output argument, Y is the complex mapped analog signal. In this case the arguments X, FD and FS are required. The variable X is the digital signal to be mapped, FD is the sampling rate of the of digital signal and the FS is the sampling rate of the analog signal. It is required that 'FS/FD' is an integer The available mapping of the digital signal are "ask" Amplitude shift keying "fsk" Frequency shift keying "msk" Minimum shift keying "psk" Phase shift keying "qask" "qsk" "qam" Quadrature amplitude shift keying In addition the "qask", "qsk" and "qam" method can be modified with the flags "/cir" or "/arb". That is "qask/cir" and "qask/arb", etc are valid methods and give circular- and arbitrary-qask mappings respectively The additional argument M is the order of the modulation to use M must be larger than the largest element of X. The variable TONE is the FSK tone to use in the modulation For "qask/cir", the additional arguments are the same as for 'apkconst', and you are referred to 'apkconst' for the definitions of the additional variables For "qask/arb", the additional arguments INPHASE and QUADR give the in-phase and quadrature components of the mapping, in a similar mapping to the outputs of 'qaskenco' with one argument. Similar MAP represents the in-phase and quadrature components of the mapping as the real and imaginary parts of the variable MAP See also: demodmap, dmodce, amodce, apkconst, qaskenco  File: comms.info, Node: oct2dec, Next: pamdemod, Prev: modmap, Up: Function Reference 9.1.75 oct2dec -------------- -- Function File: D = oct2dec (C) Convert octal to decimal values Each element of the octal matrix C is converted to a decimal value See also: base2dec, bin2dec, dec2bin  File: comms.info, Node: pamdemod, Next: pammod, Prev: oct2dec, Up: Function Reference 9.1.76 pamdemod --------------- -- Function File: Y = pamdemod (X, M) -- Function File: Y = pamdemod (X, M, PHI) -- Function File: Y = pamdemod (X, M, PHI, TYPE) Demodulates a pulse amplitude modulated signal X into an information sequence of integers in the range '[0 ... M-1]' PHI controls the initial phase and TYPE controls the constellation mapping. If TYPE is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding An example of Gray-encoded 8-PAM is d = randint (1, 1e4, 8); y = pammod (d, 8, 0, "gray"); z = awgn (y, 20); d_est = pamdemod (z, 8, 0, "gray"); plot (z, "rx") biterr (d, d_est) See also: pammod  File: comms.info, Node: pammod, Next: poly2trellis, Prev: pamdemod, Up: Function Reference 9.1.77 pammod ------------- -- Function File: Y = pammod (X, M) -- Function File: Y = pammod (X, M, PHI) -- Function File: Y = pammod (X, M, PHI, TYPE) Modulates an information sequence of integers X in the range '[0 ... M-1]' onto a pulse amplitude modulated signal Y PHI controls the initial phase and TYPE controls the constellation mapping. If TYPE is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding An example of Gray-encoded 8-PAM is d = randint (1, 1e4, 8); y = pammod (d, 8, 0, "gray"); z = awgn (y, 20); plot (z, "rx") See also: pamdemod  File: comms.info, Node: poly2trellis, Next: primpoly, Prev: pammod, Up: Function Reference 9.1.78 poly2trellis ------------------- -- Function File: T = poly2trellis (M, G) Convert convolutional code generator polynomials into trellis form The arguments M and G together describe a rate k/n feedforward convolutional encoder. The output T is a trellis structure describing the same encoder with the fields listed below The vector M is a k-by-1 array containing the lengths of each of the shift registers for the k input bits to the encoder The matrix G is a k-by-n octal-value matrix describing the generation of each of the n outputs from each of the k inputs. For a particular entry of G, the least-significant bit corresponds to the most-delayed input bit in the kth shift-register The returned trellis structure contains the following fields: 'numInputSymbols' The number of k-bit input symbols possible, i.e. 2^k 'numOutputSymbols' The number of n-bit output symbols possible, i.e. 2^n 'numStates' The number of states in the trellis 'nextStates' The state transition table for the trellis. The ith row contains the indices of the states reachable from the (i-1)th state for each possible input symbol 'outputs' A table of octal-encoded output values for the trellis. The ith row contains values representing the output symbols produced in the (i-1)th state for each possible input symbol Input symbols, output symbols, and encoder states are all interpreted with the lowest indices being the most significant bits References: [1] S. Lin and D. J. Costello, "Convolutional codes," in 'Error Control Coding', 2nd ed. Upper Saddle River, NJ: Pearson, 2004, ch. 11, pp. 453-513 See also: istrellis  File: comms.info, Node: primpoly, Next: prod, Prev: poly2trellis, Up: Function Reference 9.1.79 primpoly --------------- -- Loadable Function: Y = primpoly (M) -- Loadable Function: Y = primpoly (M, OPT) -- Loadable Function: Y = primpoly (..., "nodisplay\") Finds the primitive polynomials in GF(2^M). The first form of this function returns the default primitive polynomial of GF(2^M). This is the minimum primitive polynomial of the field. The polynomial representation is printed and an integer representation of the polynomial is returned The call 'primpoly (M, OPT)' returns one or more primitive polynomials. The output of the function is dependent of the value of OPT. Valid values of OPT are: '\"all\"' Returns all of the primitive polynomials of GF(2^M) '\"min\"' Returns the minimum primitive polynomial of GF(2^M) '\"max\"' Returns the maximum primitive polynomial of GF(2^M) K Returns the primitive polynomials having exactly K non-zero terms The call 'primpoly (..., \"nodisplay\")' disables the output of the polynomial forms of the primitives. The return value is not affected. See also: gf, isprimitive  File: comms.info, Node: prod, Next: pskdemod, Prev: primpoly, Up: Function Reference 9.1.80 prod ----------- -- Loadable Function: prod (X, DIM) Product of elements along dimension DIM of Galois array. If DIM is omitted, it defaults to 1 (column-wise products)  File: comms.info, Node: pskdemod, Next: pskmod, Prev: prod, Up: Function Reference 9.1.81 pskdemod --------------- -- Function File: Y = pamdemod (X, M) -- Function File: Y = pamdemod (X, M, PHI) -- Function File: Y = pamdemod (X, M, PHI, TYPE) Demodulates a complex-baseband phase shift keying modulated signal into an information sequence of integers in the range '[0 ... M-1]'. PHI controls the initial phase and TYPE controls the constellation mapping. If TYPE is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding. An example of Gray-encoded 8-PSK is d = randint (1, 1e3, 8); y = pskmod (d, 8, 0, "gray"); z = awgn (y, 20); d_est = pskdemod (z, 8, 0, "gray"); plot (z, "rx") biterr (d, d_est) See also: pskmod  File: comms.info, Node: pskmod, Next: qamdemod, Prev: pskdemod, Up: Function Reference 9.1.82 pskmod ------------- -- Function File: Y = pskmod (X, M) -- Function File: Y = pskmod (X, M, PHI) -- Function File: Y = pskmod (X, M, PHI, TYPE) Modulates an information sequence of integers X in the range '[0 ... M-1]' onto a complex baseband phase shift keying modulated signal Y. PHI controls the initial phase and TYPE controls the constellation mapping. If TYPE is set to "Bin" will result in binary encoding, in contrast, if set to "Gray" will give Gray encoding. An example of Gray-encoded QPSK is d = randint (1, 5e3, 4); y = pskmod (d, 4, 0, "gray"); z = awgn (y, 30); plot (z, "rx") See also: pskdemod  File: comms.info, Node: qamdemod, Next: qammod, Prev: pskmod, Up: Function Reference 9.1.83 qamdemod --------------- -- Function File: qamdemod (X, M) Create the QAM demodulation of x with a size of alphabet m See also: qammod, pskmod, pskdemod  File: comms.info, Node: qammod, Next: qaskdeco, Prev: qamdemod, Up: Function Reference 9.1.84 qammod ------------- -- Function File: qammod (X, M) Create the QAM modulation of x with a size of alphabet m See also: qamdemod, pskmod, pskdemod  File: comms.info, Node: qaskdeco, Next: qaskenco, Prev: qammod, Up: Function Reference 9.1.85 qaskdeco --------------- -- Function File: MSG = qaskdeco (C, M) -- Function File: MSG = qaskdeco (INPHASE, QUADR, M) -- Function File: MSG = qaskdeco (..., MNMX) Demaps an analog signal using a square QASK constellation. The input signal maybe either a complex variable C, or as two real variables INPHASE and QUADR representing the in-phase and quadrature components of the signal The argument M must be a positive integer power of 2. By default the same constellation as created in 'qaskenco' is used by 'qaskdeco' If is possible to change the values of the minimum and maximum of the in-phase and quadrature components of the constellation to account for linear changes in the signal values in the received signal. The variable MNMX is a 2-by-2 matrix of the following form | min in-phase , max in-phase | | min quadrature , max quadrature | If 'sqrt (M)' is an integer, then 'qaskenco' uses a Gray mapping. Otherwise, an attempt is made to create a nearly square mapping with a minimum Hamming distance between adjacent constellation points See also: qaskenco  File: comms.info, Node: qaskenco, Next: qfunc, Prev: qaskdeco, Up: Function Reference 9.1.86 qaskenco --------------- -- Function File: qaskenco (M) -- Function File: qaskenco (MSG, M) -- Function File: Y = qaskenco (...) -- Function File: [INPHASE, QUADR] = qaskenco (...) Map a digital signal using a square QASK constellation. The argument M must be a positive integer power of 2. With two input arguments the variable MSG represents the message to be encoded. The values of MSG must be between 0 and 'M-1'. In all cases 'qaskenco (M)' is equivalent to 'qaskenco (1:M, M)' Three types of outputs can be created depending on the number of output arguments. That is No output arguments In this case 'qaskenco' plots the constellation. Only the points in MSG are plotted, which in the case of a single input argument is all constellation points A single output argument The returned variable is a complex variable representing the in-phase and quadrature components of the mapped message MSG. With, a single input argument this effectively gives the mapping from symbols to constellation points Two output arguments This is the same as one output argument, expect that the in-phase and quadrature components are returned explicitly. That is c = qaskenco (msg, m); [a, b] = qaskenco (msg, m); all (c == a + 1i*b) => 1 If 'sqrt (M)' is an integer, then 'qaskenco' uses a Gray mapping. Otherwise, an attempt is made to create a nearly square mapping with a minimum Hamming distance between adjacent constellation points See also: qaskdeco  File: comms.info, Node: qfunc, Next: qfuncinv, Prev: qaskenco, Up: Function Reference 9.1.87 qfunc ------------ -- Function File: Y = qfunc (X) Compute the Q function See also: erfc, erf  File: comms.info, Node: qfuncinv, Next: quantiz, Prev: qfunc, Up: Function Reference 9.1.88 qfuncinv --------------- -- Function File: Y = qfuncinv (X) Compute the inverse Q function See also: erfc, erf  File: comms.info, Node: quantiz, Next: randdeintrlv, Prev: qfuncinv, Up: Function Reference 9.1.89 quantiz -------------- -- Function File: QIDX = quantiz (X, TABLE) -- Function File: [QIDX, Q] = quantiz (X, TABLE, CODES) -- Function File: [ QIDX, Q, D] = quantiz (...) Quantization of an arbitrary signal relative to a partitioning 'qidx = quantiz (x, table)' Determine position of x in strictly monotonic table. The first interval, using index 0, corresponds to x <= table(1) Subsequent intervals are table(i-1) < x <= table(i) '[qidx, q] = quantiz (x, table, codes)' Associate each interval of the table with a code. Use codes(1) for x <= table(1) and codes(n+1) for table(n) < x <= table(n+1) '[qidx, q, d] = quantiz (...)' Compute distortion as mean squared distance of x from the corresponding quantization values  File: comms.info, Node: randdeintrlv, Next: randerr, Prev: quantiz, Up: Function Reference 9.1.90 randdeintrlv ------------------- -- Function File: INTRLVD = randdeintrlv (DATA, STATE) Restore elements of DATA with a random permutation See also: randintrlv, intrlv, deintrlv  File: comms.info, Node: randerr, Next: randint, Prev: randdeintrlv, Up: Function Reference 9.1.91 randerr -------------- -- Function File: B = randerr (N) -- Function File: B = randerr (N, M) -- Function File: B = randerr (N, M, ERR) -- Function File: B = randerr (N, M, ERR, SEED) Generate a matrix of random bit errors. The size of the matrix is N rows by M columns. By default M is equal to N Bit errors in the matrix are indicated by a 1 The variable ERR determines the number of errors per row. By default the return matrix B has exactly one bit error per row If ERR is a scalar, there each row of B has exactly this number of errors per row. If ERR is a vector then each row has a number of errors that is in this vector. Each number of errors has an equal probability. If ERR is a matrix with two rows, then the first row determines the number of errors and the second their probabilities The variable SEED allows the random number generator to be seeded with a fixed value. The initial seed will be restored when returning  File: comms.info, Node: randint, Next: randintrlv, Prev: randerr, Up: Function Reference 9.1.92 randint -------------- -- Function File: B = randint (N) -- Function File: B = randint (N, M) -- Function File: B = randint (N, M, RANGE) -- Function File: B = randint (N, M, RANGE, SEED) Generate a matrix of random binary numbers. The size of the matrix is N rows by M columns. By default M is equal to N The range in which the integers are generated will is determined by the variable RANGE. If RANGE is an integer, the value will lie in the range [0,RANGE-1], or [RANGE+1,0] if RANGE is negative. If RANGE contains two elements the integers will lie within these two elements, inclusive. By default RANGE is assumed to be [0:1] The variable SEED allows the random number generator to be seeded with a fixed value. The initial seed will be restored when returning  File: comms.info, Node: randintrlv, Next: randsrc, Prev: randint, Up: Function Reference 9.1.93 randintrlv ----------------- -- Function File: INTRLVD = randintrlv (DATA, STATE) Interleaves elements of DATA with a random permutation See also: intrlv, deintrlv  File: comms.info, Node: randsrc, Next: rank, Prev: randintrlv, Up: Function Reference 9.1.94 randsrc -------------- -- Function File: B = randsrc (N) -- Function File: B = randsrc (N, M) -- Function File: B = randsrc (N, M, ALPHABET) -- Function File: B = randsrc (N, M, ALPHABET, SEED) Generate a matrix of random symbols. The size of the matrix is N rows by M columns. By default M is equal to N The variable ALPHABET can be either a row vector or a matrix with two rows. When ALPHABET is a row vector the symbols returned in B are chosen with equal probability from ALPHABET. When ALPHABET has two rows, the second row determines the probability with which each of the symbols is chosen. The sum of the probabilities must equal 1. By default ALPHABET is [-1 1] The variable SEED allows the random number generator to be seeded with a fixed value. The initial seed will be restored when returning  File: comms.info, Node: rank, Next: reedmullerdec, Prev: randsrc, Up: Function Reference 9.1.95 rank ----------- -- Loadable Function: D = rank (A) Compute the rank of the Galois array A by counting the independent rows and columns  File: comms.info, Node: reedmullerdec, Next: reedmullerenc, Prev: rank, Up: Function Reference 9.1.96 reedmullerdec -------------------- -- Function File: reedmullerdec (VV, G, R, M) Decode the received code word VV using the RM-generator matrix G, of order R, M, returning the code-word C. We use the standard majority logic vote method due to Irving S. Reed. The received word has to be a matrix of column size equal to to code-word size (i.e 2^m). Each row is treated as a separate received word The second return value is the message M got from C G is obtained from definition type construction of Reed-Muller code, of order R, length 2^M. Use the function reedmullergen, for the generator matrix for the (R,M) order RM code Faster code constructions (also easier) exist, but since finding permutation order of the basis vectors, is important, we stick with the standard definitions. To use decoder function reedmullerdec, you need to use this specific generator function see: Lin & Costello, Ch.4, "Error Control Coding", 2nd Ed, Pearson g = reedmullergen (2, 4); msg = rand (1, 11) > 0.5; c = mod (msg * g, 2); [dec_c, dec_m] = reedmullerdec (c, g, 2, 4) See also: reedmullergen, reedmullerenc  File: comms.info, Node: reedmullerenc, Next: reedmullergen, Prev: reedmullerdec, Up: Function Reference 9.1.97 reedmullerenc -------------------- -- Function File: reedmullerenc (MSG, R, M) Definition type construction of Reed-Muller code, of order R, length 2^M. This function returns the generator matrix for the said order RM code Encodes the given message word/block, of column size k, corresponding to the RM(R,M), and outputs a code matrix C, on each row with corresponding codeword The second return value is the G, which is generator matrix used for this code msg = rand (10, 11) > 0.5; [c, g] = reedmullerenc (msg, 2, 4); See also: reedmullerdec, reedmullergen  File: comms.info, Node: reedmullergen, Next: reshape, Prev: reedmullerenc, Up: Function Reference 9.1.98 reedmullergen -------------------- -- Function File: reedmullergen (R, M) Definition type construction of Reed-Muller code, of order R, length 2^M. This function returns the generator matrix for the said order RM code RM(r,m) codes are characterized by codewords, 'sum ( (m,0) + (m,1) + ... + (m,r)' Each of the codeword is got through spanning the space, using the finite set of m-basis codewords Each codeword is 2^M elements long see: Lin & Costello, "Error Control Coding", 2nd Ed Faster code constructions (also easier) exist, but since finding permutation order of the basis vectors, is important, we stick with the standard definitions. To use decoder function reedmullerdec, you need to use this specific generator function g = reedmullergen (2, 4); See also: reedmullerdec, reedmullerenc  File: comms.info, Node: reshape, Next: ricedeco, Prev: reedmullergen, Up: Function Reference 9.1.99 reshape -------------- -- Loadable Function: reshape (A, M, N) Return a matrix with M rows and N columns whose elements are taken from the Galois array A. To decide how to order the elements, Octave pretends that the elements of a matrix are stored in column-major order (like Fortran arrays are stored) For example, reshape (gf ([1, 2, 3, 4], 3), 2, 2) ans = GF(2^3) array. Primitive Polynomial = D^3+D+1 (decimal 11) Array elements = 1 3 2 4 The 'reshape' function is equivalent to retval = gf (zeros (m, n), a.m, a.prim_poly); retval(:) = a; but it is somewhat less cryptic to use 'reshape' instead of the colon operator. Note that the total number of elements in the original matrix must match the total number of elements in the new matrix See also: :  File: comms.info, Node: ricedeco, Next: riceenco, Prev: reshape, Up: Function Reference 9.1.100 ricedeco ---------------- -- Function File: ricedeco (CODE, K) Returns the Rice decoded signal vector using CODE and K Compulsory K is need to be specified A restrictions is that a signal set must strictly be non-negative The value of code is a cell array of row-vectors which have the encoded rice value for a single sample. The Rice algorithm is used to encode the "code" and only that can be meaningfully decoded. CODE is assumed to have been of format generated by the function 'riceenco' Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info Theory An example of the use of 'ricedeco' is ricedeco (riceenco (1:4, 2), 2) => [1 2 3 4] See also: riceenco  File: comms.info, Node: riceenco, Next: rledeco, Prev: ricedeco, Up: Function Reference 9.1.101 riceenco ---------------- -- Function File: riceenco (SIG, K) Returns the Rice encoded signal using K or optimal K Default optimal K is chosen between 0-7. Currently no other way to increase the range except to specify explicitly. Also returns K parameter used (in case it were to be chosen optimally) and LTOT the total length of output code in bits This function uses a K if supplied or by default chooses the optimal K for encoding signal vector into a rice coded vector A restrictions is that a signal set must strictly be non-negative The Rice algorithm is used to encode the data into unary coded quotient part which is represented as a set of 1's separated from the K-part (binary) using a zero. This scheme doesn't need any kind of dictionaries and its close to O(N), but this implementation *may be* sluggish, though correct Reference: Solomon Golomb, Run length Encodings, 1966 IEEE Trans Info' Theory An example of the use of 'riceenco' is riceenco (1:4) => {[0 1], [1 0 0], [1 0 1], [1 1 0 0]} riceenco (1:10, 2) => {[0 0 1], [0 1 0], [0 1 1], [1 0 0 0], [1 0 0 1], [1 0 1 0], [1 0 1 1], [1 1 0 0 0], [1 1 0 0 1], [1 1 0 1 0]} See also: ricedeco  File: comms.info, Node: rledeco, Next: rleenco, Prev: riceenco, Up: Function Reference 9.1.102 rledeco --------------- -- Function File: rledeco (MESSAGE) Returns decoded run-length MESSAGE. The RLE encoded MESSAGE has to be in the form of a row-vector. The message format (encoded RLE) is like repetition [factor, value]+ An example use of 'rledeco' is message = [1 5 2 4 3 1]; rledeco (message) => [5 4 4 1 1 1] See also: rledeco  File: comms.info, Node: rleenco, Next: roots, Prev: rledeco, Up: Function Reference 9.1.103 rleenco --------------- -- Function File: rleenco (MESSAGE) Returns run-length encoded MESSAGE. The RLE form is built from MESSAGE. The original MESSAGE has to be in the form of a row-vector. The encoded MESSAGE format (encoded RLE) is like [repetition factor]+, values An example use of 'rleenco' is message = [5 4 4 1 1 1] rleenco (message) => [1 5 2 4 3 1]; See also: rleenco  File: comms.info, Node: roots, Next: rsdec, Prev: rleenco, Up: Function Reference 9.1.104 roots ------------- -- Function File: roots (V) For a vector V with N components, return the roots of the polynomial over a Galois Field v(1) * z^(N-1) + ... + v(N-1) * z + v(N) The number of roots returned and their value will be determined by the order and primitive polynomial of the Galois Field  File: comms.info, Node: rsdec, Next: rsdecof, Prev: roots, Up: Function Reference 9.1.105 rsdec ------------- -- Loadable Function: MSG = rsdec (CODE, N, K) -- Loadable Function: MSG = rsdec (CODE, N, K, G) -- Loadable Function: MSG = rsdec (CODE, N, K, FCR, PRIM) -- Loadable Function: MSG = rsdec (..., PARPOS) -- Loadable Function: [MSG, NERR] = rsdec (...) -- Loadable Function: [MSG, NERR, CCODE] = rsdec (...) Decodes the message contained in CODE using a [N,K] Reed-Solomon code. The variable CODE must be a Galois array with N columns and an arbitrary number of rows. Each row of CODE represents a single block to be decoded by the Reed-Solomon coder. The decoded message is returned in the variable MSG containing K columns and the same number of rows as CODE. If N does not equal '2^M-1', where m is an integer, then a shorten Reed-Solomon decoding is used where zeros are added to the start of each row to obtain an allowable codeword length. The returned MSG has these prepending zeros stripped. By default the generator polynomial used in the Reed-Solomon coding is based on the properties of the Galois Field in which MSG is given. This default generator polynomial can be overridden by a polynomial in G. Suitable generator polynomials can be constructed with 'rsgenpoly'. FCR is an integer value, and it is taken to be the first consecutive root of the generator polynomial. The variable PRIM is then the primitive element used to construct the generator polynomial. By default FCR and PRIM are both 1. It is significantly faster to specify the generator polynomial in terms of FCR and PRIM, since G is converted to this form in any case. By default the parity symbols are placed at the end of the coded message. The variable PARPOS controls this positioning and can take the values '"beginning\"' or '\"end\"'. If the parity symbols are at the end, the message is treated with the most-significant symbol first, otherwise the message is treated with the least-significant symbol first. See also: gf, rsenc, rsgenpoly  File: comms.info, Node: rsdecof, Next: rsenc, Prev: rsdec, Up: Function Reference 9.1.106 rsdecof --------------- -- Function File: rsdecof (IN, OUT) -- Function File: rsdecof (IN, OUT, T) Decodes an ASCII file using a Reed-Solomon coder. The input file is defined by IN and the result is written to the output file OUT The type of coding to use is determined by whether the input file is 7- or 8-bit. If the input file is 7-bit, the default coding is [127,117] while the default coding for an 8-bit file is a [255, 235]. This allows for 5 or 10 error characters in 127 or 255 symbols to be corrected respectively. The number of errors that can be corrected can be overridden by the variable T If the file is not an integer multiple of the message size (127 or 255) in length, then the file is padded with the EOT (ASCII character 4) character before decoding See also: rsencof  File: comms.info, Node: rsenc, Next: rsencof, Prev: rsdecof, Up: Function Reference 9.1.107 rsenc ------------- -- Loadable Function: CODE = rsenc (MSG, N, K) -- Loadable Function: CODE = rsenc (MSG, N, K, G) -- Loadable Function: CODE = rsenc (MSG, N, K, FCR, PRIM) -- Loadable Function: CODE = rsenc (..., PARPOS) Encodes the message MSG using a [N,K] Reed-Solomon coding. The variable MSG is a Galois array with K columns and an arbitrary number of rows. Each row of MSG represents a single block to be coded by the Reed-Solomon coder. The coded message is returned in the Galois array CODE containing N columns and the same number of rows as MSG. The use of 'rsenc' can be seen in the following short example. m = 3; n = 2^m -1; k = 3; msg = gf ([1 2 3; 4 5 6], m); code = rsenc (msg, n, k); If N does not equal '2^M-1', where m is an integer, then a shorten Reed-Solomon coding is used where zeros are added to the start of each row to obtain an allowable codeword length. The returned CODE has these prepending zeros stripped. By default the generator polynomial used in the Reed-Solomon coding is based on the properties of the Galois Field in which MSG is given. This default generator polynomial can be overridden by a polynomial in G. Suitable generator polynomials can be constructed with 'rsgenpoly'. FCR is an integer value, and it is taken to be the first consecutive root of the generator polynomial. The variable PRIM is then the primitive element used to construct the generator polynomial, such that G = (X - A^B) * (X - A^(B+PRIM)) * ... * (X - A^(B+2*T*PRIM-1)). where B is equal to 'FCR * PRIM'. By default FCR and PRIM are both 1. By default the parity symbols are placed at the end of the coded message. The variable PARPOS controls this positioning and can take the values '"beginning\"' or '\"end\"'. See also: gf, rsdec, rsgenpoly  File: comms.info, Node: rsencof, Next: rsgenpoly, Prev: rsenc, Up: Function Reference 9.1.108 rsencof --------------- -- Function File: rsencof (IN, OUT) -- Function File: rsencof (IN, OUT, T) -- Function File: rsencof (..., PAD) Encodes an ASCII file using a Reed-Solomon coder. The input file is defined by IN and the result is written to the output file OUT The type of coding to use is determined by whether the input file is 7- or 8-bit. If the input file is 7-bit, the default coding is [127,117] while the default coding for an 8-bit file is a [255, 235]. This allows for 5 or 10 error characters in 127 or 255 symbols to be corrected respectively. The number of errors that can be corrected can be overridden by the variable T If the file is not an integer multiple of the message size (127 or 255) in length, then the file is padded with the EOT (ASCII character 4) characters before coding. Whether these characters are written to the output is defined by the PAD variable. Valid values for PAD are "pad" (the default) and "nopad", which write or not the padding respectively See also: rsdecof  File: comms.info, Node: rsgenpoly, Next: scatterplot, Prev: rsencof, Up: Function Reference 9.1.109 rsgenpoly ----------------- -- Function File: G = rsgenpoly (N, K) -- Function File: G = rsgenpoly (N, K, P) -- Function File: G = rsgenpoly (N, K, P, B, S) -- Function File: G = rsgenpoly (N, K, P, B) -- Function File: [G, T] = rsgenpoly (...) Creates a generator polynomial for a Reed-Solomon coding with message length of K and codelength of N. N must be greater than K and their difference must be even. The generator polynomial is returned on G as a polynomial over the Galois Field GF(2^M) where N is equal to '2^M-1'. If M is not integer the next highest integer value is used and a generator for a shorten Reed-Solomon code is returned The elements of G represent the coefficients of the polynomial in descending order. If the length of G is lg, then the generator polynomial is given by G(0) * x^(lg-1) + G(1) * x^(lg-2) + ... + G(lg-1) * x + G(lg) If P is defined then it is used as the primitive polynomial of the Galois Field GF(2^M). The default primitive polynomial will be used if P is equal to [] The variables B and S determine the form of the generator polynomial in the following manner G = (X - A^(B*S)) * (X - A^((B+1)*S)) * ... * (X - A^((B+2*T-1)*S)) where T is '(N-K)/2', and A is the primitive element of the Galois Field. Therefore B is the first consecutive root of the generator polynomial and S is the primitive element to generate the polynomial roots If requested the variable T, which gives the error correction capability of the Reed-Solomon code See also: gf, rsenc, rsdec  File: comms.info, Node: scatterplot, Next: shannonfanodeco, Prev: rsgenpoly, Up: Function Reference 9.1.110 scatterplot ------------------- -- Function File: scatterplot (X) -- Function File: scatterplot (X, N) -- Function File: scatterplot (X, N, OFF) -- Function File: scatterplot (X, N, OFF, STR) -- Function File: scatterplot (X, N, OFF, STR, H) -- Function File: H = scatterplot (...) Display the scatter plot of a signal. The signal X can be either in one of three forms A real vector In this case the signal is assumed to be real and represented by the vector X. The scatterplot is plotted along the x axis only A complex vector In this case the in-phase and quadrature components of the signal are plotted separately on the x and y axes respectively A matrix with two columns In this case the first column represents the in-phase and the second the quadrature components of a complex signal and are plotted on the x and y axes respectively Each point of the scatter plot is assumed to be separated by N elements in the signal. The first element of the signal to plot is determined by OFF. By default N is 1 and OFF is 0 The string STR is a plot style string (example "r+"), and by default is the default gnuplot point style The figure handle to use can be defined by H. If H is not given, then the next available figure handle is used. The figure handle used in returned on HOUT See also: eyediagram  File: comms.info, Node: shannonfanodeco, Next: shannonfanodict, Prev: scatterplot, Up: Function Reference 9.1.111 shannonfanodeco ----------------------- -- Function File: shannonfanodeco (HCODE, DICT) Returns the original signal that was Shannon-Fano encoded. The signal was encoded using 'shannonfanoenco'. This function uses a dict built from the 'shannonfanodict' and uses it to decode a signal list into a Shannon-Fano list. Restrictions include hcode is expected to be a binary code; returned signal set that strictly belongs in the 'range [1,N]', with 'N = length (dict)'. Also dict can only be from the 'shannonfanodict (...)' routine. Whenever decoding fails, those signal values are indicated by -1, and we successively try to restart decoding from the next bit that hasn't failed in decoding, ad-infinitum An example use of 'shannonfanodeco' is hd = shannonfanodict (1:4, [0.5 0.25 0.15 0.10]); hcode = shannonfanoenco (1:4, hd) => hcode = [0 1 0 1 1 0 1 1 1 0] shannonfanodeco (hcode, hd) => [1 2 3 4] See also: shannonfanoenco, shannonfanodict  File: comms.info, Node: shannonfanodict, Next: shannonfanoenco, Prev: shannonfanodeco, Up: Function Reference 9.1.112 shannonfanodict ----------------------- -- Function File: shannonfanodict (SYMBOLS, SYMBOL_PROBABILITES) Returns the code dictionary for source using Shannon-Fano algorithm Dictionary is built from SYMBOL_PROBABILITIES using the Shannon-Fano scheme. Output is a dictionary cell-array, which are codewords, and correspond to the order of input probability cw = shannonfanodict (1:4, [0.5 0.25 0.15 0.1]); assert (redundancy (cw, [0.5 0.25 0.15 0.1]), 0.25841, 0.001) shannonfanodict (1:5, [0.35 0.17 0.17 0.16 0.15]) shannonfanodict (1:8, [8 7 6 5 5 4 3 2] / 40) See also: shannonfanoenc, shannonfanodec  File: comms.info, Node: shannonfanoenco, Next: sqrt, Prev: shannonfanodict, Up: Function Reference 9.1.113 shannonfanoenco ----------------------- -- Function File: shannonfanoenco (HCODE, DICT) Returns the Shannon-Fano encoded signal using DICT This function uses a DICT built from the 'shannonfanodict' and uses it to encode a signal list into a Shannon-Fano code Restrictions include a signal set that strictly belongs in the 'range [1,N]' with 'N = length (dict)'. Also dict can only be from the 'shannonfanodict' routine An example use of 'shannonfanoenco' is hd = shannonfanodict (1:4, [0.5 0.25 0.15 0.10]); shannonfanoenco (1:4, hd) => [0 1 0 1 1 0 1 1 1 0] See also: shannonfanodeco, shannonfanodict  File: comms.info, Node: sqrt, Next: sum, Prev: shannonfanoenco, Up: Function Reference 9.1.114 sqrt ------------ -- Loadable Function: sqrt (X) Compute the square root of X, element by element, in a Galois Field See also: exp  File: comms.info, Node: sum, Next: sumsq, Prev: sqrt, Up: Function Reference 9.1.115 sum ----------- -- Loadable Function: sum (X, DIM) Sum of elements along dimension DIM of Galois array. If DIM is omitted, it defaults to 1 (column-wise sum)  File: comms.info, Node: sumsq, Next: symerr, Prev: sum, Up: Function Reference 9.1.116 sumsq ------------- -- Loadable Function: sumsq (X, DIM) Sum of squares of elements along dimension DIM of Galois array If DIM is omitted, it defaults to 1 (column-wise sum of squares) This function is equivalent to computing gsum (x .* conj (x), dim) but it uses less memory  File: comms.info, Node: symerr, Next: syndtable, Prev: sumsq, Up: Function Reference 9.1.117 symerr -------------- -- Function File: [NUM, RATE] = symerr (A, B) -- Function File: [NUM, RATE] = symerr (..., FLAG) -- Function File: [NUM, RATE IND] = symerr (...) Compares two matrices and returns the number of symbol errors and the symbol error rate. The variables A and B can be either: Both matrices In this case both matrices must be the same size and then by default the return values NUM and RATE are the overall number of symbol errors and the overall symbol error rate One column vector In this case the column vector is used for symbol error comparison column-wise with the matrix. The returned values NUM and RATE are then row vectors containing the number of symbol errors and the symbol error rate for each of the column-wise comparisons. The number of rows in the matrix must be the same as the length of the column vector One row vector In this case the row vector is used for symbol error comparison row-wise with the matrix. The returned values NUM and RATE are then column vectors containing the number of symbol errors and the symbol error rate for each of the row-wise comparisons. The number of columns in the matrix must be the same as the length of the row vector This behavior can be overridden with the variable FLAG. FLAG can take the value "column-wise", "row-wise" or "overall". A column-wise comparison is not possible with a row vector and visa-versa  File: comms.info, Node: syndtable, Next: systematize, Prev: symerr, Up: Function Reference 9.1.118 syndtable ----------------- -- Loadable Function: T = syndtable (H) Create the syndrome decoding table from the parity check matrix H. Each row of the returned matrix T represents the error vector in a received symbol for a certain syndrome. The row selected is determined by a conversion of the syndrome to an integer representation, and using this to reference each row of T. See also: hammgen, cyclgen  File: comms.info, Node: systematize, Next: vec2mat, Prev: syndtable, Up: Function Reference 9.1.119 systematize ------------------- -- Function File: systematize (G) Given G, extract P parity check matrix. Assume row-operations in GF(2) G is of size KxN, when decomposed through row-operations into a I of size KxK identity matrix, and a parity check matrix P of size Kx(N-K) Most arbitrary code with a given generator matrix G, can be converted into its systematic form using this function This function returns 2 values, first is default being GX the systematic version of the G matrix, and then the parity check matrix P g = [1 1 1 1; 1 1 0 1; 1 0 0 1]; [gx, p] = systematize (g); => gx = [1 0 0 1; 0 1 0 0; 0 0 1 0]; => p = [1 0 0]; See also: bchpoly, biterr  File: comms.info, Node: vec2mat, Next: wgn, Prev: systematize, Up: Function Reference 9.1.120 vec2mat --------------- -- Function File: M = vec2mat (V, C) -- Function File: M = vec2mat (V, C, D) -- Function File: [M, ADD] = vec2mat (...) Converts the vector V into a C column matrix with row priority arrangement and with the final column padded with the value D to the correct length. By default D is 0. The amount of padding added to the matrix is returned in ADD  File: comms.info, Node: wgn, Prev: vec2mat, Up: Function Reference 9.1.121 wgn ----------- -- Function File: Y = wgn (M, N, P) -- Function File: Y = wgn (M, N, P, IMP) -- Function File: Y = wgn (M, N, P, IMP, SEED) -- Function File: Y = wgn (..., TYPE) -- Function File: Y = wgn (..., OUTPUT) Returns a M-by-N matrix Y of white Gaussian noise. P specifies the power of the output noise, which is assumed to be referenced to an impedance of 1 Ohm, unless IMP explicitly defines the impedance If SEED is defined then the randn function is seeded with this value The arguments TYPE and OUTPUT must follow the above numerical arguments, but can be specified in any order. TYPE specifies the units of P, and can be "dB", "dBW", "dBm" or "linear". "dB" is in fact the same as "dBW" and is keep as a misnomer of Matlab. The units of "linear" are in Watts The OUTPUT variable should be either "real" or "complex". If the output is complex then the power P is divided equally between the real and imaginary parts See also: randn, awgn  Tag Table: Node: Top71 Node: Introduction376 Node: Random Signals911 Node: Signal Creation1584 Node: Signal Analysis9779 Node: Source Coding13793 Node: Quantization14016 Node: PCM Coding16263 Node: Arithmetic Coding16614 Node: Dynamic Range Compression16864 Node: Block Coding18070 Node: Data Formats18625 Node: Binary Block Codes20818 Node: BCH Codes26397 Node: Reed-Solomon Codes29071 Node: Representation of Reed-Solomon Messages29324 Node: Creating and Decoding Messages31248 Node: Shortened Reed-Solomon Codes35256 Node: Convolutional Coding36418 Node: Trellis Structure36889 Node: Convolutional Encoding38692 Node: Modulations39962 Node: Special Filters40255 Node: Galois Fields40404 Node: Galois Field Basics40605 Node: Creating Galois Fields42724 Node: Primitive Polynomials44851 Node: Accessing Internal Fields47394 Node: Function Overloading49024 Node: Known Problems50731 Node: Manipulating Galois Fields52625 Node: Expressions manipulation and assignment52988 Node: Unary operations56380 Node: Arithmetic operations57134 Node: Comparison operations60330 Node: Polynomial manipulations61527 Node: Linear Algebra66602 Node: Signal Processing68658 Node: Function Reference71708 Node: ademodce80516 Node: amdemod82690 Node: ammod82992 Node: amodce83291 Node: apkconst85220 Node: awgn86958 Node: bchdeco88193 Node: bchenco90430 Node: bchpoly92057 Node: bi2de95278 Node: biterr96091 Node: bsc98085 Node: comms98328 Node: compand99871 Node: conv101140 Node: convenc101547 Node: convmtx102629 Node: cosets103365 Node: cyclgen103694 Node: cyclpoly104931 Node: de2bi106102 Node: decode107306 Node: deconv112022 Node: deintrlv112489 Node: demodmap112743 Node: det115241 Node: dftmtx115440 Node: diag116115 Node: dpcmdeco116865 Node: dpcmenco117382 Node: dpcmopt118587 Node: egolaydec120166 Node: egolayenc121390 Node: egolaygen122025 Node: encode122433 Node: exp125923 Node: eyediagram126142 Node: fft127761 Node: fibodeco128087 Node: fiboenco129097 Node: fibosplitstream130360 Node: filter131239 Node: fmdemod132414 Node: fmmod132725 Node: gen2par133027 Node: genqamdemod133590 Node: genqammod133970 Node: gf134663 Node: gftable135679 Node: gfweight136064 Node: golombdeco137016 Node: golombenco138106 Node: hammgen140082 Node: helscanintrlv140999 Node: huffmandeco141264 Node: huffmandict142303 Node: huffmanenco144016 Node: ifft144753 Node: intrlv145098 Node: inv145346 Node: inverse145718 Node: isequal145900 Node: isgalois146152 Node: isprimitive146392 Node: istrellis146723 Node: lloyds147181 Node: log149198 Node: lu149417 Node: lz77deco150427 Node: lz77enco150892 Node: matdeintrlv151318 Node: matintrlv151622 Node: minpol151924 Node: modmap152308 Node: oct2dec155057 Node: pamdemod155371 Node: pammod156227 Node: poly2trellis157006 Node: primpoly158944 Node: prod160216 Node: pskdemod160498 Node: pskmod161373 Node: qamdemod162171 Node: qammod162436 Node: qaskdeco162697 Node: qaskenco164012 Node: qfunc165805 Node: qfuncinv166007 Node: quantiz166225 Node: randdeintrlv167163 Node: randerr167459 Node: randint168578 Node: randintrlv169512 Node: randsrc169792 Node: rank170769 Node: reedmullerdec171021 Node: reedmullerenc172356 Node: reedmullergen173100 Node: reshape174093 Node: ricedeco175110 Node: riceenco175972 Node: rledeco177406 Node: rleenco177911 Node: roots178461 Node: rsdec178894 Node: rsdecof181089 Node: rsenc182045 Node: rsencof184094 Node: rsgenpoly185294 Node: scatterplot187054 Node: shannonfanodeco188633 Node: shannonfanodict189825 Node: shannonfanoenco190624 Node: sqrt191415 Node: sum191661 Node: sumsq191925 Node: symerr192329 Node: syndtable194024 Node: systematize194570 Node: vec2mat195446 Node: wgn195947  End Tag Table communications-1.2.1/doc/PaxHeaders.3802/images.mk0000644000000000000000000000013112510010473016547 xustar0030 mtime=1428164923.998508931 29 atime=1428164924.00250884 30 ctime=1428164983.712815029 communications-1.2.1/doc/images.mk0000644000000000000000000000246112510010473017100 0ustar00rootroot00000000000000IMAGES = awgn.eps eyediagram.eps scatterplot.eps awgn.pdf eyediagram.pdf scatterplot.pdf awgn.png eyediagram.png scatterplot.png IMAGES_EPS = awgn.eps eyediagram.eps scatterplot.eps IMAGES_PDF = awgn.pdf eyediagram.pdf scatterplot.pdf IMAGES_PNG = awgn.png eyediagram.png scatterplot.png awgn.eps: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('awgn', 'eps');" eyediagram.eps: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('eyediagram', 'eps');" scatterplot.eps: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('scatterplot', 'eps');" awgn.pdf: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('awgn', 'pdf');" eyediagram.pdf: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('eyediagram', 'pdf');" scatterplot.pdf: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('scatterplot', 'pdf');" awgn.png: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('awgn', 'png');" eyediagram.png: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('eyediagram', 'png');" scatterplot.png: commsimages.m $(OCTAVE) --path=$(CURDIR)/../inst -f -q -H --eval "commsimages ('scatterplot', 'png');" communications-1.2.1/PaxHeaders.3802/DESCRIPTION0000644000000000000000000000013212510010473015713 xustar0030 mtime=1428164923.850512296 30 atime=1428164923.850512296 30 ctime=1428164983.712815029 communications-1.2.1/DESCRIPTION0000644000000000000000000000056412510010473016245 0ustar00rootroot00000000000000Name: Communications Version: 1.2.1 Date: 2015-04-04 Author: various authors Maintainer: Mike Miller Title: Communications Description: Digital Communications, Error Correcting Codes (Channel Code), Source Code functions, Modulation and Galois Fields Depends: octave (>= 3.4), signal (>= 1.1.3) Autoload: no License: GPLv3+ Url: http://octave.sf.net communications-1.2.1/PaxHeaders.3802/INDEX0000644000000000000000000000013212510010473014777 xustar0030 mtime=1428164923.850512296 30 atime=1428164924.094506728 30 ctime=1428164983.712815029 communications-1.2.1/INDEX0000644000000000000000000000410212510010473015321 0ustar00rootroot00000000000000communications >> Communications Random Signals awgn biterr eyediagram randerr randint randsrc scatterplot symerr wgn bsc Source Coding arithenco arithdeco compand dpcmdeco dpcmenco dpcmopt huffmandeco huffmandict huffmanenco lloyds lz77deco lz77enco quantiz shannonfanodict shannonfanoenco shannonfanodeco rleenco rledeco riceenco ricedeco fiboenco fibodeco fibosplitstream golombenco golombdeco Block Interleavers intrlv algintrlv helscanintrlv matintrlv randintrlv deintrlv matdeintrlv randdeintrlv Block Coding bchdeco bchenco bchpoly convenc cyclgen cyclpoly decode encode egolaydec egolayenc egolaygen gen2par hammgen reedmullerdec reedmullerenc reedmullergen rsgenpoly rsdec rsdecof rsenc rsencof systematize syndtable vitdec Modulations ademod ademodce amod amodce ammod amdemod apkconst ddemod ddemodce demodmap dmod dmodce fmmod fmdemod genqammod genqamdemod modmap pamdemod pammod pskdemod pskmod qaskdeco qaskenco qammod qamdemod Special Filters hank2sys hilbiir rcosflt rcosiir rcosine rcosfir Galois Fields of Even Characteristic + - = Addition and subtraction in a Galois Field. * / \ = Matrix multiplication and division of Galois arrays. .* ./ .\ = Element by element multiplication and division of Galois arrays. ** ^ = Matrix exponentiation of Galois arrays. .** .^ = Element by element matrix exponentiation of Galois arrays. ' .' = Matrix transpose of Galois arrays. == ~= != > >= < <= = Logical operators on Galois arrays. all any cosets conv convmtx deconv det dftmtx diag exp gf fft filter gftable gfweight ifft inv inverse isequal log lu prod sqrt rank reshape roots sum sumsq isempty isgalois isprimitive length minpol polyval primpoly size Galois Fields of Odd Characteristic gfadd gfconv gfcosets gfdeconv gfdiv gffilter gflineq gfminpol gfmul gfpretty gfprimck gfprimdf gfprimfd gfrank gfrepcov gfroots gfsub gftrunc gftuple Utility Functions comms bi2de de2bi oct2dec istrellis poly2trellis vec2mat qfunc qfuncinv communications-1.2.1/PaxHeaders.3802/COPYING0000644000000000000000000000013212510010473015240 xustar0030 mtime=1428164923.850512296 30 atime=1428164923.850512296 30 ctime=1428164983.712815029 communications-1.2.1/COPYING0000644000000000000000000010451312510010473015571 0ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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. This program 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 this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . communications-1.2.1/PaxHeaders.3802/NEWS0000644000000000000000000000013212510010473014704 xustar0030 mtime=1428164923.850512296 30 atime=1428164923.850512296 30 ctime=1428164983.712815029 communications-1.2.1/NEWS0000644000000000000000000000330312510010473015230 0ustar00rootroot00000000000000Summary of important user-visible changes for communications 1.2.1: ------------------------------------------------------------------ ** The communications package is now compatible with Octave 4.0.0. Summary of important user-visible changes for communications 1.2.0: ------------------------------------------------------------------ ** The following functions are new: dpcmdeco istrellis dpcmenco poly2trellis dpcmopt ** The function `convenc' has been completely rewritten to be compatible with Matlab. ** The plotting functions `eyediagram' and `scatterplot' have improved Matlab compatibility. ** Fixed a bug in `egolaydec' which gave an error when there were more than the three allowed erroneous bits, rather than setting the error flag. ** Fixed a bug in `oct2dec' to handle large numbers properly. ** Fixed a bug in `quantiz' which gave incorrect results when the lookup table has one element. Summary of important user-visible changes for communications 1.1.1: ------------------------------------------------------------------ ** The function `marcumq' has been moved to the signal package ** communications is no longer dependent on the image package ** The following functions are new: convenc ** The following functions have improved Matlab compatibility and tests: bi2de de2bi oct2dec ** The function `reedmullerdec' had a bug fix introduced on the previous release ** The function `huffmandeco' has been rewritten and made more efficient and should perform faster ** Fixed bug in `glu' which made it unusable ** Use of deprecated functions has been removed ** Package is no longer automatically loaded.