./PaxHeaders.12771/communications-1.2.20000644000000000000000000000013213604150040014353 xustar0030 mtime=1578160160.353401177 30 atime=1578160213.541197341 30 ctime=1578160213.541197341 communications-1.2.2/0000755000175000017500000000000013604150040014177 5ustar00nirnir00000000000000communications-1.2.2/PaxHeaders.12771/src0000644000000000000000000000013213604150125015011 xustar0030 mtime=1578160213.541197341 30 atime=1578160213.541197341 30 ctime=1578160213.541197341 communications-1.2.2/src/0000755000175000017500000000000013604150125014772 5ustar00nirnir00000000000000communications-1.2.2/src/PaxHeaders.12771/op-m-gm.cc0000644000000000000000000000007413604150022016647 xustar0030 atime=1578160160.421400916 30 ctime=1578160213.541197341 communications-1.2.2/src/op-m-gm.cc0000644000175000017500000001251213604150022016547 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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) #ifndef DEFMETHOD_DLD 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); } #else void install_m_gm_ops (octave::type_info& ti) { INSTALL_BINOP_TI (ti, op_add, octave_matrix, octave_galois, add); INSTALL_BINOP_TI (ti, op_sub, octave_matrix, octave_galois, sub); INSTALL_BINOP_TI (ti, op_mul, octave_matrix, octave_galois, mul); INSTALL_BINOP_TI (ti, op_div, octave_matrix, octave_galois, div); INSTALL_BINOP_TI (ti, op_pow, octave_matrix, octave_galois, pow); INSTALL_BINOP_TI (ti, op_ldiv, octave_matrix, octave_galois, ldiv); INSTALL_BINOP_TI (ti, op_lt, octave_matrix, octave_galois, lt); INSTALL_BINOP_TI (ti, op_le, octave_matrix, octave_galois, le); INSTALL_BINOP_TI (ti, op_eq, octave_matrix, octave_galois, eq); INSTALL_BINOP_TI (ti, op_ge, octave_matrix, octave_galois, ge); INSTALL_BINOP_TI (ti, op_gt, octave_matrix, octave_galois, gt); INSTALL_BINOP_TI (ti, op_ne, octave_matrix, octave_galois, ne); INSTALL_BINOP_TI (ti, op_el_mul, octave_matrix, octave_galois, el_mul); INSTALL_BINOP_TI (ti, op_el_div, octave_matrix, octave_galois, el_div); INSTALL_BINOP_TI (ti, op_el_pow, octave_matrix, octave_galois, el_pow); INSTALL_BINOP_TI (ti, op_el_ldiv, octave_matrix, octave_galois, el_ldiv); INSTALL_BINOP_TI (ti, op_el_and, octave_matrix, octave_galois, el_and); INSTALL_BINOP_TI (ti, op_el_or, octave_matrix, octave_galois, el_or); INSTALL_CATOP_TI (ti, octave_matrix, octave_galois, m_gm); INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_matrix, octave_galois, assign); //INSTALL_ASSIGNCONV (octave_base_value, octave_matrix, octave_galois); } #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.2/src/PaxHeaders.12771/galoisfield.h0000644000000000000000000000006213604150022017517 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/galoisfield.h0000644000175000017500000000420413604150022017421 0ustar00nirnir00000000000000//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.2/src/PaxHeaders.12771/galoisfield.cc0000644000000000000000000000007413604150022017660 xustar0030 atime=1578160160.421400916 30 ctime=1578160213.541197341 communications-1.2.2/src/galoisfield.cc0000644000175000017500000001136713604150022017567 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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.2/src/PaxHeaders.12771/configure.ac0000644000000000000000000000007413604150022017355 xustar0030 atime=1578160212.425201622 30 ctime=1578160213.541197341 communications-1.2.2/src/configure.ac0000644000175000017500000001451613604150022017263 0ustar00nirnir00000000000000AC_PREREQ([2.60]) AC_INIT([Octave-Forge communications package], [0]) AC_CONFIG_HEADERS([config.h]) # Avoid warnings for redefining AH-generated preprocessor symbols of # Octave. AH_TOP([#include "undef-ah-octave.h"]) AC_CONFIG_MACRO_DIRS([m4]) 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 # Checks for octave depreciated symbols ## Simple symbol alternatives of different Octave versions. AC_LANG(C++) save_altsyms_CXX="$CXX" save_altsyms_CXXFLAGS="$CXXFLAGS" save_altsyms_CPPFLAGS="$CPPFLAGS" save_altsyms_LDFLAGS="$LDFLAGS" save_altsyms_LIBS="$LIBS" OCTINCLUDEDIR=${OCTINCLUDEDIR:-`$MKOCTFILE -p INCFLAGS`} OCTLIBDIR=${OCTLIBDIR:-`$MKOCTFILE -p OCTLIBDIR`} CXX=`${MKOCTFILE} -p CXX` CPPFLAGS="$OCTINCLUDEDIR $CPPFLAGS" LDFLAGS="-L$OCTLIBDIR $LDFLAGS" LIBS="-loctinterp $LIBS" OF_OCTAVE_LIST_ALT_SYMS([ [dnl [gripe_nonconformant], [octave::err_nonconformant], [[octave::err_nonconformant ("a",0,0)]], [OCTAVE__ERR_NONCONFORMANT], [[#include ]], [[#include ]] ], [dnl [gripe_wrong_type_arg], [err_wrong_type_arg], [[err_wrong_type_arg ("a", "b")]], [OCTAVE__ERR_WRONG_TYPE_ARG], [[#include ]], [[#include ]] ], [dnl [gripe_square_matrix_required], [err_square_matrix_required], [[err_square_matrix_required ("a", "b")]], [DELOCTAVE__ERR_SQUARE_MATRIX_REQUIRED], [[#include ]], [[#include ]] ], [dnl [gripe_invalid_conversion], [err_invalid_conversion], [[err_invalid_conversion ("a", "b")]], [OCTAVE__ERR_INVALID_CONVERSION], [[#include ]], [[#include ]] ], [dnl [gripe_implicit_conversion], [warn_implicit_conversion], [[warn_implicit_conversion ("a", "b", "c")]], [OCTAVE__WARN_INVALID_CONVERSION], [[#include ]], [[#include ]] ], [dnl [flush_octave_stdout], [octave::flush_stdout], [[octave::flush_stdout ();]], [OCTAVE__FLUSH_STDOUT], [[]], [[]] ], [dnl [is_complex_type], [iscomplex], [[octave_value ().iscomplex ();]], [OV_ISCOMPLEX], [], [] ], [dnl [is_real_type], [isreal], [[octave_value ().isreal ();]], [OV_ISREAL], [], [] ], [dnl [is_numeric_type], [isnumeric], [[octave_value ().isnumeric ();]], [OV_ISNUMERIC], [], [] ], [dnl [is_empty], [isempty], [[octave_value ().isempty ();]], [OV_ISEMPTY], [], [] ], [dnl [oct_mach_info::float_format], [octave::mach_info::float_format], [[octave::mach_info::float_format fmt;]], [OCTAVE_MACH_INFO_FLOAT_FORMAT], [], [] ] ],[oct-alt-includes.h]) AC_CHECK_HEADERS([octave/oct.h]) AC_CHECK_HEADERS([octave/base-lu.h]) AC_CHECK_HEADERS([octave/lu.h]) AC_CHECK_HEADERS([octave/gripes.h]) AC_CHECK_HEADERS([octave/errwarn.h]) AC_CHECK_HEADERS([octave/ovl.h]) AC_CHECK_HEADERS([octave/oct-obj.h]) AC_CHECK_HEADERS([octave/ls-oct-ascii.h]) AC_CHECK_HEADERS([octave/ls-oct-text.h]) AC_CHECK_HEADERS([octave/oct-obj.h]) AC_CHECK_HEADERS([octave/interpreter.h]) CXX=$save_altsyms_CXX CXXFLAGS=$save_altsyms_CXXFLAGS CPPFLAGS=$save_altsyms_CPPFLAGS LDFLAGS=$save_altsyms_LDFLAGS LIBS=$save_altsyms_LIBS have_hdf5=no # check for HDF5 using pkg-config PKG_CHECK_MODULES([HDF5],[hdf5], [have_hdf5=yes ], [] ) if test $have_hdf5 = no; then save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" AC_CHECK_LIB(hdf5,H5Fopen, [ have_hdf5=yes AC_CHECK_HEADERS([hdf5.h]) HDF5_LIBS=-lhdf5 ], [], ) CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" fi if test $have_hdf5 = no; then AC_MSG_ERROR([hdf5 not found]) fi comm_OCT_EVAL="$OCTAVE --norc --no-history --silent --eval" 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_CFLAGS" 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 AC_DEFINE([HAVE_OCTAVE_HDF5_ID_TYPE],[1],[Define if have octave_hdf5_id]) 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_CFLAGS" 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 AC_DEFINE([HAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE],[1],[Define if have gripe_load and gripe_save]) 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_CFLAGS" 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 AC_DEFINE([HAVE_OCTAVE_BASE_VALUE_PRINT_CONST],[1],[Define if octave_base_value::print is const-qualified]) fi AC_CONFIG_FILES([Makefile]) AC_OUTPUT communications-1.2.2/src/PaxHeaders.12771/syndtable.cc0000644000000000000000000000007413604150022017363 xustar0030 atime=1578160160.421400916 30 ctime=1578160213.541197341 communications-1.2.2/src/syndtable.cc0000644000175000017500000001164213604150022017266 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifndef SIZEOF_INT #define SIZEOF_INT int(sizeof(int)) #endif #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", (int)(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.2/src/PaxHeaders.12771/gf.cc0000644000000000000000000000007413604150022015772 xustar0030 atime=1578160160.421400916 30 ctime=1578160213.541197341 communications-1.2.2/src/gf.cc0000644000175000017500000024371613604150022015706 0ustar00nirnir00000000000000// 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 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_OCTAVE_INTERPRETER_H #include #endif #include #ifdef HAVE_OCTAVE_GRIPES_H #include #define OCTAVE__ERR_SQUARE_MATRIX_REQUIRED(a) gripe_square_matrix_required(a) #endif #ifdef HAVE_OCTAVE_ERRWARN_H #include #define OCTAVE__ERR_SQUARE_MATRIX_REQUIRED(a) err_square_matrix_required(a, "") #endif #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!! #ifdef DEFMETHOD_DLD DEFMETHOD_DLD (gf, interp, args, nargout, #else DEFUN_DLD (gf, args, nargout, #endif "-*- 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 (); #ifndef DEFMETHOD_DLD 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 (); #else interp.mlock (); octave::type_info& ti = interp.get_type_info (); install_gm_gm_ops (ti); install_m_gm_ops (ti); install_gm_m_ops (ti); install_s_gm_ops (ti); install_gm_s_ops (ti); galois_type_loaded = true; #endif } 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 ())) OCTAVE__ERR_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.numel () > 0) retval = new octave_galois (r); } } else OCTAVE__ERR_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 ())) { OCTAVE__ERR_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 \ { \ OCTAVE__ERR_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 ())) { OCTAVE__ERR_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 ())) { OCTAVE__ERR_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 ())) { OCTAVE__ERR_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.numel () > b.numel () ? a.numel () : b.numel ()); b.resize (dim_vector (ab_len, 1), 0); galois retval (x.numel (), 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.numel () != 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.numel (); 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.numel () > 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.numel (); 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.numel (); 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.numel () > 1) { for (int j = 0; j < si.numel () - 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.numel ()-1, 0) = 0; if ((a(si.numel (), 0) != 0) && (retval(i, 0) != 0)) si(si.numel ()-1, 0) ^= a.alpha_to (modn (a.index_of (a(si.numel (), 0)) + a.index_of (retval(i, 0)), a.m (), a.n ())); if ((b(si.numel (), 0) != 0) && (x(i, 0) != 0)) si(si.numel ()-1, 0) ^= b.alpha_to (modn (b.index_of (b(si.numel (), 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.numel () > 0) { for (int i = 0; i < x.numel (); 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.numel () > 1) { for (int j = 0; j < si.numel () - 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.numel ()-1, 0) = 0; if ((b(si.numel (), 0) != 0) && (x(i, 0) != 0)) si(si.numel ()-1, 0) ^= b.alpha_to (modn (b.index_of (b(si.numel (), 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.numel (); 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.numel (); int b_len = b.numel (); 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 ())) { OCTAVE__ERR_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 = arg.OV_ISEMPTY(); 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 ())) { OCTAVE__ERR_WRONG_TYPE_ARG ("ginverse", arg); return retval; } galois m = ((const octave_galois&) arg.get_rep ()).galois_value (); int arg_is_empty = arg.OV_ISEMPTY (); 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) { OCTAVE__ERR_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 ())) { OCTAVE__ERR_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 = arg.OV_ISEMPTY (); 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) { OCTAVE__ERR_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 ())) { OCTAVE__ERR_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 = arg.OV_ISEMPTY (); 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 ())) { OCTAVE__ERR_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 ())) { OCTAVE__ERR_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.2/src/PaxHeaders.12771/Makefile.in0000644000000000000000000000006213604150022017131 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/Makefile.in0000644000175000017500000000234313604150022017035 0ustar00nirnir00000000000000MKOCTFILE ?= @MKOCTFILE@ OCTAVE ?= @OCTAVE@ SED ?= @SED@ HDF5_CPPFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ PKG_CPPFLAGS = -DGALOIS_DISP_PRIVATES @DEFS@ 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_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.h config.log config.status oct-alt-includes.h maintainer-clean: distclean -rm -rf autom4te.cache configure config.h.in aclocal.m4 .PHONY: all clean distclean maintainer-clean communications-1.2.2/src/PaxHeaders.12771/ov-galois.cc0000644000000000000000000000007413604150022017276 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/ov-galois.cc0000644000175000017500000004570713604150022017212 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_OCTAVE_GRIPES_H #include #endif #ifdef HAVE_OCTAVE_ERRWARN_H #include #endif #include #include #ifdef HAVE_OCTAVE_OVL_H #include #elif HAVE_OCTAVE_OCT_OBJ_H #include #endif #include #include #if defined(HAVE_OCTAVE_LS_OCT_TEXT_H) # include #else # include #endif #include "galois.h" #include "ov-galois.h" #if defined (HAVE_HDF5) # if defined (HAVE_HDF5_H) # include # endif # if defined (HAVE_OCTAVE_OCT_HDF5_TYPES_H) # include "oct-hdf5-types.h" # endif # if defined (OCTAVE_ENABLE_64) # define H5T_NATIVE_IDX H5T_NATIVE_INT64 # else # define H5T_NATIVE_IDX H5T_NATIVE_INT # endif #endif #if ! defined (X_CAST) # define X_CAST(T, E) (T) (E) #endif #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) { OCTAVE__WARN_INVALID_CONVERSION ("Octave:array-as-scalar", "real matrix", "real scalar"); retval = (double) gval (0, 0); } else OCTAVE__ERR_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) { OCTAVE__WARN_INVALID_CONVERSION ("Octave:array-as-scalar", "real matrix", "real scalar"); retval = (double) gval (0, 0); } else OCTAVE__ERR_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, OCTAVE_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.2/src/PaxHeaders.12771/primpoly.cc0000644000000000000000000000007413604150022017251 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/primpoly.cc0000644000175000017500000002034013604150022017147 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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</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='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS HDF5_LIBS HDF5_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG EGREP GREP CXXCPP 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 runstatedir 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 CXXCPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR HDF5_CFLAGS HDF5_LIBS' # 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' runstatedir='${localstatedir}/run' 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 ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -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 runstatedir 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] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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 CXXCPP C++ preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path HDF5_CFLAGS C compiler flags for HDF5, overriding pkg-config HDF5_LIBS linker flags for HDF5, overriding pkg-config 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 # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" 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_cpp conftest.$ac_ext") 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; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; 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_cpp # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 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; } && { ac_try='./conftest$ac_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 : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext 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>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_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link 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 ac_config_headers="$ac_config_headers config.h" # Avoid warnings for redefining AH-generated preprocessor symbols of # Octave. # 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 # Checks for octave depreciated symbols ## Simple symbol alternatives of different Octave versions. 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 save_altsyms_CXX="$CXX" save_altsyms_CXXFLAGS="$CXXFLAGS" save_altsyms_CPPFLAGS="$CPPFLAGS" save_altsyms_LDFLAGS="$LDFLAGS" save_altsyms_LIBS="$LIBS" OCTINCLUDEDIR=${OCTINCLUDEDIR:-`$MKOCTFILE -p INCFLAGS`} OCTLIBDIR=${OCTLIBDIR:-`$MKOCTFILE -p OCTLIBDIR`} CXX=`${MKOCTFILE} -p CXX` CPPFLAGS="$OCTINCLUDEDIR $CPPFLAGS" LDFLAGS="-L$OCTLIBDIR $LDFLAGS" LIBS="-loctinterp $LIBS" echo '/* generated by configure */' > oct-alt-includes.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking gripe_nonconformant or octave::err_nonconformant" >&5 $as_echo_n "checking gripe_nonconformant or octave::err_nonconformant... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { octave::err_nonconformant ("a",0,0) ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OCTAVE__ERR_NONCONFORMANT octave::err_nonconformant" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: octave::err_nonconformant" >&5 $as_echo "octave::err_nonconformant" >&6; } echo '#include ' >> oct-alt-includes.h else $as_echo "#define OCTAVE__ERR_NONCONFORMANT gripe_nonconformant" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: gripe_nonconformant" >&5 $as_echo " gripe_nonconformant" >&6; } echo '#include ' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking gripe_wrong_type_arg or err_wrong_type_arg" >&5 $as_echo_n "checking gripe_wrong_type_arg or err_wrong_type_arg... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { err_wrong_type_arg ("a", "b") ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OCTAVE__ERR_WRONG_TYPE_ARG err_wrong_type_arg" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: err_wrong_type_arg" >&5 $as_echo "err_wrong_type_arg" >&6; } echo '#include ' >> oct-alt-includes.h else $as_echo "#define OCTAVE__ERR_WRONG_TYPE_ARG gripe_wrong_type_arg" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: gripe_wrong_type_arg" >&5 $as_echo " gripe_wrong_type_arg" >&6; } echo '#include ' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking gripe_square_matrix_required or err_square_matrix_required" >&5 $as_echo_n "checking gripe_square_matrix_required or err_square_matrix_required... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { err_square_matrix_required ("a", "b") ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define DELOCTAVE__ERR_SQUARE_MATRIX_REQUIRED err_square_matrix_required" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: err_square_matrix_required" >&5 $as_echo "err_square_matrix_required" >&6; } echo '#include ' >> oct-alt-includes.h else $as_echo "#define DELOCTAVE__ERR_SQUARE_MATRIX_REQUIRED gripe_square_matrix_required" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: gripe_square_matrix_required" >&5 $as_echo " gripe_square_matrix_required" >&6; } echo '#include ' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking gripe_invalid_conversion or err_invalid_conversion" >&5 $as_echo_n "checking gripe_invalid_conversion or err_invalid_conversion... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { err_invalid_conversion ("a", "b") ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OCTAVE__ERR_INVALID_CONVERSION err_invalid_conversion" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: err_invalid_conversion" >&5 $as_echo "err_invalid_conversion" >&6; } echo '#include ' >> oct-alt-includes.h else $as_echo "#define OCTAVE__ERR_INVALID_CONVERSION gripe_invalid_conversion" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: gripe_invalid_conversion" >&5 $as_echo " gripe_invalid_conversion" >&6; } echo '#include ' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking gripe_implicit_conversion or warn_implicit_conversion" >&5 $as_echo_n "checking gripe_implicit_conversion or warn_implicit_conversion... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { warn_implicit_conversion ("a", "b", "c") ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OCTAVE__WARN_INVALID_CONVERSION warn_implicit_conversion" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: warn_implicit_conversion" >&5 $as_echo "warn_implicit_conversion" >&6; } echo '#include ' >> oct-alt-includes.h else $as_echo "#define OCTAVE__WARN_INVALID_CONVERSION gripe_implicit_conversion" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: gripe_implicit_conversion" >&5 $as_echo " gripe_implicit_conversion" >&6; } echo '#include ' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking flush_octave_stdout or octave::flush_stdout" >&5 $as_echo_n "checking flush_octave_stdout or octave::flush_stdout... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave::flush_stdout (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OCTAVE__FLUSH_STDOUT octave::flush_stdout" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: octave::flush_stdout" >&5 $as_echo "octave::flush_stdout" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OCTAVE__FLUSH_STDOUT flush_octave_stdout" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: flush_octave_stdout" >&5 $as_echo " flush_octave_stdout" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_complex_type or iscomplex" >&5 $as_echo_n "checking is_complex_type or iscomplex... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().iscomplex (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISCOMPLEX iscomplex" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: iscomplex" >&5 $as_echo "iscomplex" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISCOMPLEX is_complex_type" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_complex_type" >&5 $as_echo " is_complex_type" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_real_type or isreal" >&5 $as_echo_n "checking is_real_type or isreal... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().isreal (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISREAL isreal" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: isreal" >&5 $as_echo "isreal" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISREAL is_real_type" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_real_type" >&5 $as_echo " is_real_type" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_numeric_type or isnumeric" >&5 $as_echo_n "checking is_numeric_type or isnumeric... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().isnumeric (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISNUMERIC isnumeric" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: isnumeric" >&5 $as_echo "isnumeric" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISNUMERIC is_numeric_type" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_numeric_type" >&5 $as_echo " is_numeric_type" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking is_empty or isempty" >&5 $as_echo_n "checking is_empty or isempty... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave_value ().isempty (); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OV_ISEMPTY isempty" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: isempty" >&5 $as_echo "isempty" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OV_ISEMPTY is_empty" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: is_empty" >&5 $as_echo " is_empty" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking oct_mach_info::float_format or octave::mach_info::float_format" >&5 $as_echo_n "checking oct_mach_info::float_format or octave::mach_info::float_format... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { octave::mach_info::float_format fmt; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : $as_echo "#define OCTAVE_MACH_INFO_FLOAT_FORMAT octave::mach_info::float_format" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: octave::mach_info::float_format" >&5 $as_echo "octave::mach_info::float_format" >&6; } echo ' ' >> oct-alt-includes.h else $as_echo "#define OCTAVE_MACH_INFO_FLOAT_FORMAT oct_mach_info::float_format" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: oct_mach_info::float_format" >&5 $as_echo " oct_mach_info::float_format" >&6; } echo '' >> oct-alt-includes.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : 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 $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_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$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_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 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "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_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_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_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_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$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_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 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "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_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_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_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in octave/oct.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/oct.h" "ac_cv_header_octave_oct_h" "$ac_includes_default" if test "x$ac_cv_header_octave_oct_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_OCT_H 1 _ACEOF fi done for ac_header in octave/base-lu.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/base-lu.h" "ac_cv_header_octave_base_lu_h" "$ac_includes_default" if test "x$ac_cv_header_octave_base_lu_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_BASE_LU_H 1 _ACEOF fi done for ac_header in octave/lu.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/lu.h" "ac_cv_header_octave_lu_h" "$ac_includes_default" if test "x$ac_cv_header_octave_lu_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_LU_H 1 _ACEOF fi done for ac_header in octave/gripes.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/gripes.h" "ac_cv_header_octave_gripes_h" "$ac_includes_default" if test "x$ac_cv_header_octave_gripes_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_GRIPES_H 1 _ACEOF fi done for ac_header in octave/errwarn.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/errwarn.h" "ac_cv_header_octave_errwarn_h" "$ac_includes_default" if test "x$ac_cv_header_octave_errwarn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_ERRWARN_H 1 _ACEOF fi done for ac_header in octave/ovl.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/ovl.h" "ac_cv_header_octave_ovl_h" "$ac_includes_default" if test "x$ac_cv_header_octave_ovl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_OVL_H 1 _ACEOF fi done for ac_header in octave/oct-obj.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/oct-obj.h" "ac_cv_header_octave_oct_obj_h" "$ac_includes_default" if test "x$ac_cv_header_octave_oct_obj_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_OCT_OBJ_H 1 _ACEOF fi done for ac_header in octave/ls-oct-ascii.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/ls-oct-ascii.h" "ac_cv_header_octave_ls_oct_ascii_h" "$ac_includes_default" if test "x$ac_cv_header_octave_ls_oct_ascii_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_LS_OCT_ASCII_H 1 _ACEOF fi done for ac_header in octave/ls-oct-text.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/ls-oct-text.h" "ac_cv_header_octave_ls_oct_text_h" "$ac_includes_default" if test "x$ac_cv_header_octave_ls_oct_text_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_LS_OCT_TEXT_H 1 _ACEOF fi done for ac_header in octave/oct-obj.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/oct-obj.h" "ac_cv_header_octave_oct_obj_h" "$ac_includes_default" if test "x$ac_cv_header_octave_oct_obj_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_OCT_OBJ_H 1 _ACEOF fi done for ac_header in octave/interpreter.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "octave/interpreter.h" "ac_cv_header_octave_interpreter_h" "$ac_includes_default" if test "x$ac_cv_header_octave_interpreter_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OCTAVE_INTERPRETER_H 1 _ACEOF fi done CXX=$save_altsyms_CXX CXXFLAGS=$save_altsyms_CXXFLAGS CPPFLAGS=$save_altsyms_CPPFLAGS LDFLAGS=$save_altsyms_LDFLAGS LIBS=$save_altsyms_LIBS have_hdf5=no # check for HDF5 using pkg-config if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; 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_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) 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_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $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 ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; 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_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) 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_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $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 ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" 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 PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HDF5" >&5 $as_echo_n "checking for HDF5... " >&6; } if test -n "$HDF5_CFLAGS"; then pkg_cv_HDF5_CFLAGS="$HDF5_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"hdf5\""; } >&5 ($PKG_CONFIG --exists --print-errors "hdf5") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_HDF5_CFLAGS=`$PKG_CONFIG --cflags "hdf5" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$HDF5_LIBS"; then pkg_cv_HDF5_LIBS="$HDF5_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"hdf5\""; } >&5 ($PKG_CONFIG --exists --print-errors "hdf5") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_HDF5_LIBS=`$PKG_CONFIG --libs "hdf5" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then HDF5_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "hdf5" 2>&1` else HDF5_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "hdf5" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$HDF5_PKG_ERRORS" >&5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else HDF5_CFLAGS=$pkg_cv_HDF5_CFLAGS HDF5_LIBS=$pkg_cv_HDF5_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_hdf5=yes fi if test $have_hdf5 = no; then save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for H5Fopen in -lhdf5" >&5 $as_echo_n "checking for H5Fopen in -lhdf5... " >&6; } if ${ac_cv_lib_hdf5_H5Fopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lhdf5 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char H5Fopen (); int main () { return H5Fopen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_hdf5_H5Fopen=yes else ac_cv_lib_hdf5_H5Fopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hdf5_H5Fopen" >&5 $as_echo "$ac_cv_lib_hdf5_H5Fopen" >&6; } if test "x$ac_cv_lib_hdf5_H5Fopen" = xyes; then : have_hdf5=yes for ac_header in hdf5.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "hdf5.h" "ac_cv_header_hdf5_h" "$ac_includes_default" if test "x$ac_cv_header_hdf5_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_HDF5_H 1 _ACEOF fi done HDF5_LIBS=-lhdf5 fi CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" fi if test $have_hdf5 = no; then as_fn_error $? "hdf5 not found" "$LINENO" 5 fi comm_OCT_EVAL="$OCTAVE --norc --no-history --silent --eval" 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_CFLAGS" 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=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 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 $as_echo "#define HAVE_OCTAVE_HDF5_ID_TYPE 1" >>confdefs.h 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_CFLAGS" 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=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 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 $as_echo "#define HAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE 1" >>confdefs.h 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_CFLAGS" 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=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 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 $as_echo "#define HAVE_OCTAVE_BASE_VALUE_PRINT_CONST 1" >>confdefs.h 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}' DEFS=-DHAVE_CONFIG_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 case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _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 --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers 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;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --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 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "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 test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers 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" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " 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 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; 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.2/src/PaxHeaders.12771/undef-ah-octave.h0000644000000000000000000000006213604150022020203 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/undef-ah-octave.h0000644000175000017500000000070613604150022020110 0ustar00nirnir00000000000000/* To be included at the top of config.h (by autoheader). Avoid warnings for redefining AH-generated preprocessor symbols of Octave. */ #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_URL #undef PACKAGE_URL #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif communications-1.2.2/src/PaxHeaders.12771/base-lu.h0000644000000000000000000000006213604150022016565 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/base-lu.h0000644000175000017500000000334713604150022016476 0ustar00nirnir00000000000000/* Copyright (C) 1996-2015 John W. Eaton Copyright (C) 2009 VZLU Prague This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see . */ #if !defined (octave_base_lu_h) #define octave_base_lu_h 1 #include "MArray.h" #include "dColVector.h" #include "PermMatrix.h" template class base_lu { public: typedef typename lu_type::element_type lu_elt_type; base_lu (void) : a_fact (), l_fact (), ipvt () { } base_lu (const base_lu& a) : a_fact (a.a_fact), l_fact (a.l_fact), ipvt (a.ipvt) { } base_lu (const lu_type& l, const lu_type& u, const PermMatrix& p); base_lu& operator = (const base_lu& a) { if (this != &a) { a_fact = a.a_fact; l_fact = a.l_fact; ipvt = a.ipvt; } return *this; } virtual ~base_lu (void) { } bool packed (void) const; void unpack (void); lu_type L (void) const; lu_type U (void) const; lu_type Y (void) const; PermMatrix P (void) const; ColumnVector P_vec (void) const; bool regular (void) const; protected: Array getp (void) const; lu_type a_fact; lu_type l_fact; Array ipvt; }; #endif communications-1.2.2/src/PaxHeaders.12771/m40000644000000000000000000000013213604150040015325 xustar0030 mtime=1578160160.361401146 30 atime=1578160213.541197341 30 ctime=1578160213.541197341 communications-1.2.2/src/m4/0000755000175000017500000000000013604150040015306 5ustar00nirnir00000000000000communications-1.2.2/src/m4/PaxHeaders.12771/octave-forge.m40000644000000000000000000000007413604150022020232 xustar0030 atime=1578160212.669200687 30 ctime=1578160213.541197341 communications-1.2.2/src/m4/octave-forge.m40000644000175000017500000000576013604150022020141 0ustar00nirnir00000000000000# Copyright (C) 2017-2018 Olaf Till # Modifications to print what is searching for by JohnD # # 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 . # arguments of OF_OCTAVE_ALT_SYMS (see also description of # OF_OCTAVE_LIST_ALT_SYMS below): # # $1: symbol version 1 # $2: symbol version 2 # $3: test for symbol version 2 # $4: macro name to access alternative symbols # $5: include directives for symbol version 1 # $6: include directives for symbol version 2 # (a list of lists of args 1--6 is $1 of OF_OCTAVE_LIST_ALT_SYMS) # $7: name of generated include file with alternatives of Octave headers # (arg7 is $2 of OF_OCTAVE_LIST_ALT_SYMS) AC_DEFUN([OF_OCTAVE_ALT_SYMS], [ AC_MSG_CHECKING([$1 or $2]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include ] $6], [$3])], [AC_DEFINE($4, [[$2]], [macro for alternative Octave symbols]) AC_MSG_RESULT([$2]) echo '$6' >> $7], [AC_DEFINE($4, [[$1]], [macro for alternative Octave symbols]) AC_MSG_RESULT([$1]) echo '$5' >> $7] ) ]) # OF_OCTAVE_LIST_ALT_SYMS is called in the following way: # # OF_OCTAVE_LIST_ALT_SYMS([ # [dnl # [old_octave_symbol], # [new_octave_symbol], # [[compilation test] # [for new_octave_symbol]], # [NAME_OF_GENERATED_MACRO____WILL_EXPAND_TO_OLD_OR_NEW_SYMBOL], # [[include directives] # [except #include ] # [necessary to compile with old_octave_symbol]], # [[include directives] # [except #include ] # [nessary to compile with new_octave_symbol] # [and to compile the test]] # ], # # ... further such lists as the above # # ], # # [name-of-header-file-for-alternative-octave-iclude-directives.h]) # # # This file should be put into src/m4/, and the line # # AC_CONFIG_MACRO_DIRS([m4]) # # should be put into src/configure.ac. The package should use # autoheader to generate config.h.in (src/bootstrap should contain the # lines 'aclocal', 'autoconf', and 'autoheader -f'). Package code # should include config.h and use the generated macros to access the # alternative symbols of Octave. An example of a call to # OF_OCTAVE_LIST_ALT_SYMS in src/configure.ac is available together # with this file. AC_DEFUN([OF_OCTAVE_LIST_ALT_SYMS], [ echo '/* generated by configure */' > $2 m4_foreach([it], [$1], [m4_apply([OF_OCTAVE_ALT_SYMS], [it, $2])]) AH_BOTTOM([#include "$2"]) ]) communications-1.2.2/src/PaxHeaders.12771/config.h.in0000644000000000000000000000013213604150125017111 xustar0030 mtime=1578160213.541197341 30 atime=1578160213.541197341 30 ctime=1578160213.541197341 communications-1.2.2/src/config.h.in0000644000175000017500000000670513604150125017025 0ustar00nirnir00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ #include "undef-ah-octave.h" /* macro for alternative Octave symbols */ #undef DELOCTAVE__ERR_SQUARE_MATRIX_REQUIRED /* Define to 1 if you have the header file. */ #undef HAVE_HDF5_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_BASE_LU_H /* Define if have gripe_load and gripe_save */ #undef HAVE_OCTAVE_BASE_VALUE_GRIPE_LOAD_SAVE /* Define if octave_base_value::print is const-qualified */ #undef HAVE_OCTAVE_BASE_VALUE_PRINT_CONST /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_ERRWARN_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_GRIPES_H /* Define if have octave_hdf5_id */ #undef HAVE_OCTAVE_HDF5_ID_TYPE /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_INTERPRETER_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_LS_OCT_ASCII_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_LS_OCT_TEXT_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_LU_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_OCT_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_OCT_OBJ_H /* Define to 1 if you have the header file. */ #undef HAVE_OCTAVE_OVL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* macro for alternative Octave symbols */ #undef OCTAVE_MACH_INFO_FLOAT_FORMAT /* macro for alternative Octave symbols */ #undef OCTAVE__ERR_INVALID_CONVERSION /* macro for alternative Octave symbols */ #undef OCTAVE__ERR_NONCONFORMANT /* macro for alternative Octave symbols */ #undef OCTAVE__ERR_WRONG_TYPE_ARG /* macro for alternative Octave symbols */ #undef OCTAVE__FLUSH_STDOUT /* macro for alternative Octave symbols */ #undef OCTAVE__WARN_INVALID_CONVERSION /* macro for alternative Octave symbols */ #undef OV_ISCOMPLEX /* macro for alternative Octave symbols */ #undef OV_ISEMPTY /* macro for alternative Octave symbols */ #undef OV_ISNUMERIC /* macro for alternative Octave symbols */ #undef OV_ISREAL /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS #include "oct-alt-includes.h" communications-1.2.2/src/PaxHeaders.12771/galois.cc0000644000000000000000000000007413604150022016654 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/galois.cc0000644000175000017500000010416713604150022016564 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_OCTAVE_GRIPES_H #include #endif #ifdef HAVE_OCTAVE_ERRWARN_H #include #endif #include #include "galois.h" #include "galoisfield.h" #include "galois-def.h" #ifdef HAVE_OCTAVE_BASE_LU_H # include #else # include "base-lu.cc" #endif 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) { OCTAVE__ERR_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) { OCTAVE__ERR_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) { OCTAVE__ERR_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) { OCTAVE__ERR_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) { OCTAVE__ERR_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.numel ()-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.numel (); 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 (); OCTAVE__ERR_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 (); OCTAVE__ERR_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.2/src/PaxHeaders.12771/op-gm-gm.cc0000644000000000000000000000007413604150022017016 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/op-gm-gm.cc0000644000175000017500000001365113604150022016723 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_OCTAVE_OVL_H #include #elif HAVE_OCTAVE_OCT_OBJ_H #include #endif #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) #ifndef DEFMETHOD_DLD 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); } #else void install_gm_gm_ops (octave::type_info& ti) { INSTALL_UNOP_TI (ti, op_not, octave_galois, not); INSTALL_UNOP_TI (ti, op_uminus, octave_galois, uminus); INSTALL_UNOP_TI (ti, op_uplus, octave_galois, uplus); INSTALL_UNOP_TI (ti, op_transpose, octave_galois, transpose); INSTALL_UNOP_TI (ti, op_hermitian, octave_galois, transpose); INSTALL_BINOP_TI (ti, op_add, octave_galois, octave_galois, add); INSTALL_BINOP_TI (ti, op_sub, octave_galois, octave_galois, sub); INSTALL_BINOP_TI (ti, op_mul, octave_galois, octave_galois, mul); INSTALL_BINOP_TI (ti, op_div, octave_galois, octave_galois, div); INSTALL_BINOP_TI (ti, op_pow, octave_galois, octave_galois, pow); INSTALL_BINOP_TI (ti, op_ldiv, octave_galois, octave_galois, ldiv); INSTALL_BINOP_TI (ti, op_lt, octave_galois, octave_galois, lt); INSTALL_BINOP_TI (ti, op_le, octave_galois, octave_galois, le); INSTALL_BINOP_TI (ti, op_eq, octave_galois, octave_galois, eq); INSTALL_BINOP_TI (ti, op_ge, octave_galois, octave_galois, ge); INSTALL_BINOP_TI (ti, op_gt, octave_galois, octave_galois, gt); INSTALL_BINOP_TI (ti, op_ne, octave_galois, octave_galois, ne); INSTALL_BINOP_TI (ti, op_el_mul, octave_galois, octave_galois, el_mul); INSTALL_BINOP_TI (ti, op_el_div, octave_galois, octave_galois, el_div); INSTALL_BINOP_TI (ti, op_el_pow, octave_galois, octave_galois, el_pow); INSTALL_BINOP_TI (ti, op_el_ldiv, octave_galois, octave_galois, el_ldiv); INSTALL_BINOP_TI (ti, op_el_and, octave_galois, octave_galois, el_and); INSTALL_BINOP_TI (ti, op_el_or, octave_galois, octave_galois, el_or); INSTALL_CATOP_TI (ti, octave_galois, octave_galois, gm_gm); INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_galois, octave_galois, assign); } #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.2/src/PaxHeaders.12771/galois-def.cc0000644000000000000000000000007413604150022017410 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/galois-def.cc0000644000175000017500000000614513604150022017315 0ustar00nirnir00000000000000//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.2/src/PaxHeaders.12771/bootstrap0000644000000000000000000000007413604150022017027 xustar0030 atime=1578160212.353201899 30 ctime=1578160213.541197341 communications-1.2.2/src/bootstrap0000755000175000017500000000033713604150022016734 0ustar00nirnir00000000000000#!/bin/bash ## Octave-Forge: package bootstrap script ## Run this to generate the configure script set -e # halt if unhandled error aclocal autoconf # generate configure script autoheader -f rm -rf autom4te.cache communications-1.2.2/src/PaxHeaders.12771/__gfweight__.cc0000644000000000000000000000007413604150022017776 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/__gfweight__.cc0000644000175000017500000000476513604150022017711 0ustar00nirnir00000000000000//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 #ifdef HAVE_CONFIG_H #include "config.h" #endif 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"; OCTAVE__FLUSH_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.2/src/PaxHeaders.12771/cyclpoly.cc0000644000000000000000000000007413604150022017234 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/cyclpoly.cc0000644000175000017500000001741013604150022017136 0ustar00nirnir00000000000000//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 #ifdef HAVE_CONFIG_H #include "config.h" #endif 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.numel (); 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 #ifdef HAVE_CONFIG_H #include "config.h" #endif 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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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.2/src/PaxHeaders.12771/cyclgen.cc0000644000000000000000000000007413604150022017022 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/cyclgen.cc0000644000175000017500000001657413604150022016736 0ustar00nirnir00000000000000//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 #ifdef HAVE_CONFIG_H #include "config.h" #endif // 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.numel (); 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.2/src/PaxHeaders.12771/galois.h0000644000000000000000000000006213604150022016513 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/galois.h0000644000175000017500000001346113604150022016422 0ustar00nirnir00000000000000//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 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_OCTAVE_BASE_LU_H # include #else # include "base-lu.h" #endif #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; }; #ifndef DEFMETHOD_DLD 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); #else void install_gm_gm_ops (octave::type_info& ti); void install_gm_m_ops (octave::type_info& ti); void install_m_gm_ops (octave::type_info& ti); void install_gm_s_ops (octave::type_info& ti); void install_s_gm_ops (octave::type_info& ti); void install_fil_gm_ops (octave::type_info& ti); #endif 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.2/src/PaxHeaders.12771/galois-ops.h0000644000000000000000000000006213604150022017312 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/galois-ops.h0000644000175000017500000001153513604150022017221 0ustar00nirnir00000000000000//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 #if ! defined (CAST_BINOP_ARGS) # define CAST_BINOP_ARGS(t1, t2) \ t1 v1 = dynamic_cast (a1); \ t2 v2 = dynamic_cast (a2) #endif #if ! defined (CAST_UNOP_ARG) # define CAST_UNOP_ARG(t) \ t v = dynamic_cast (a) #endif #if ! defined (BINOPDECL) # define BINOPDECL(name, a1, a2) \ static octave_value \ CONCAT2(oct_binop_, name) (const octave_base_value& a1, \ const octave_base_value& a2) #endif #if ! defined (CATOPDECL) # define CATOPDECL(name, a1, a2) \ static octave_value \ CONCAT2(oct_catop_, name) (octave_base_value& a1, \ const octave_base_value& a2, \ const Array& ra_idx) #endif // 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.2/src/PaxHeaders.12771/genqamdemod.cc0000644000000000000000000000007413604150022017657 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/genqamdemod.cc0000644000175000017500000000657313604150022017571 0ustar00nirnir00000000000000//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 // . #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #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 = args(0).OV_ISEMPTY(); 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).OV_ISREAL () && args(1).OV_ISREAL ()) { // 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).OV_ISCOMPLEX () || args(1).OV_ISCOMPLEX ()) { // 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.2/src/PaxHeaders.12771/base-lu.cc0000644000000000000000000000007413604150022016726 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/base-lu.cc0000644000175000017500000001003613604150022016625 0ustar00nirnir00000000000000/* Copyright (C) 1996-2015 John W. Eaton Copyright (C) 2009 VZLU Prague This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "base-lu.h" template base_lu::base_lu (const lu_type& l, const lu_type& u, const PermMatrix& p) : a_fact (u), l_fact (l), ipvt (p.transpose ().col_perm_vec ()) { if (l.columns () != u.rows ()) (*current_liboctave_error_handler) ("lu: dimension mismatch"); } template bool base_lu :: packed (void) const { return l_fact.dims () == dim_vector (); } template void base_lu :: unpack (void) { if (packed ()) { l_fact = L (); a_fact = U (); // FIXME: sub-optimal ipvt = getp (); } } template lu_type base_lu :: L (void) const { if (packed ()) { octave_idx_type a_nr = a_fact.rows (); octave_idx_type a_nc = a_fact.cols (); octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc); lu_type l (a_nr, mn, lu_elt_type (0.0)); for (octave_idx_type i = 0; i < a_nr; i++) { if (i < a_nc) l.xelem (i, i) = 1.0; for (octave_idx_type j = 0; j < (i < a_nc ? i : a_nc); j++) l.xelem (i, j) = a_fact.xelem (i, j); } return l; } else return l_fact; } template lu_type base_lu :: U (void) const { if (packed ()) { octave_idx_type a_nr = a_fact.rows (); octave_idx_type a_nc = a_fact.cols (); octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc); lu_type u (mn, a_nc, lu_elt_type (0.0)); for (octave_idx_type i = 0; i < mn; i++) { for (octave_idx_type j = i; j < a_nc; j++) u.xelem (i, j) = a_fact.xelem (i, j); } return u; } else return a_fact; } template lu_type base_lu :: Y (void) const { if (! packed ()) (*current_liboctave_error_handler) ("lu: Y () not implemented for unpacked form"); return a_fact; } template Array base_lu :: getp (void) const { if (packed ()) { octave_idx_type a_nr = a_fact.rows (); Array pvt (dim_vector (a_nr, 1)); for (octave_idx_type i = 0; i < a_nr; i++) pvt.xelem (i) = i; for (octave_idx_type i = 0; i < ipvt.numel (); i++) { octave_idx_type k = ipvt.xelem (i); if (k != i) { octave_idx_type tmp = pvt.xelem (k); pvt.xelem (k) = pvt.xelem (i); pvt.xelem (i) = tmp; } } return pvt; } else return ipvt; } template PermMatrix base_lu :: P (void) const { return PermMatrix (getp (), false); } template ColumnVector base_lu :: P_vec (void) const { octave_idx_type a_nr = a_fact.rows (); ColumnVector p (a_nr); Array pvt = getp (); for (octave_idx_type i = 0; i < a_nr; i++) p.xelem (i) = static_cast (pvt.xelem (i) + 1); return p; } template bool base_lu::regular (void) const { bool retval = true; octave_idx_type k = std::min (a_fact.rows (), a_fact.columns ()); for (octave_idx_type i = 0; i < k; i++) { if (a_fact(i, i) == lu_elt_type ()) { retval = false; break; } } return retval; } communications-1.2.2/src/PaxHeaders.12771/op-s-gm.cc0000644000000000000000000000007413604150022016655 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/op-s-gm.cc0000644000175000017500000001276513604150022016567 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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)); } #ifndef DEFMETHOD_DLD 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); } #else void install_s_gm_ops (octave::type_info& ti) { INSTALL_BINOP_TI (ti, op_add, octave_scalar, octave_galois, add); INSTALL_BINOP_TI (ti, op_sub, octave_scalar, octave_galois, sub); INSTALL_BINOP_TI (ti, op_mul, octave_scalar, octave_galois, mul); INSTALL_BINOP_TI (ti, op_div, octave_scalar, octave_galois, div); INSTALL_BINOP_TI (ti, op_pow, octave_scalar, octave_galois, pow); INSTALL_BINOP_TI (ti, op_ldiv, octave_scalar, octave_galois, ldiv); INSTALL_BINOP_TI (ti, op_lt, octave_scalar, octave_galois, lt); INSTALL_BINOP_TI (ti, op_le, octave_scalar, octave_galois, le); INSTALL_BINOP_TI (ti, op_eq, octave_scalar, octave_galois, eq); INSTALL_BINOP_TI (ti, op_ge, octave_scalar, octave_galois, ge); INSTALL_BINOP_TI (ti, op_gt, octave_scalar, octave_galois, gt); INSTALL_BINOP_TI (ti, op_ne, octave_scalar, octave_galois, ne); INSTALL_BINOP_TI (ti, op_el_mul, octave_scalar, octave_galois, el_mul); INSTALL_BINOP_TI (ti, op_el_div, octave_scalar, octave_galois, el_div); INSTALL_BINOP_TI (ti, op_el_pow, octave_scalar, octave_galois, el_pow); INSTALL_BINOP_TI (ti, op_el_ldiv, octave_scalar, octave_galois, el_ldiv); INSTALL_BINOP_TI (ti, op_el_and, octave_scalar, octave_galois, el_and); INSTALL_BINOP_TI (ti, op_el_or, octave_scalar, octave_galois, el_or); INSTALL_CATOP_TI (ti, octave_scalar, octave_galois, s_gm); INSTALL_ASSIGNCONV_TI (ti, octave_scalar, octave_galois, octave_galois); } #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.2/src/PaxHeaders.12771/op-gm-s.cc0000644000000000000000000000007413604150022016655 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/op-gm-s.cc0000644000175000017500000001266113604150022016562 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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 (); } #ifndef DEFMETHOD_DLD 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); } #else void install_gm_s_ops (octave::type_info& ti) { INSTALL_BINOP_TI (ti, op_add, octave_galois, octave_scalar, add); INSTALL_BINOP_TI (ti, op_sub, octave_galois, octave_scalar, sub); INSTALL_BINOP_TI (ti, op_mul, octave_galois, octave_scalar, mul); INSTALL_BINOP_TI (ti, op_div, octave_galois, octave_scalar, div); INSTALL_BINOP_TI (ti, op_pow, octave_galois, octave_scalar, pow); INSTALL_BINOP_TI (ti, op_ldiv, octave_galois, octave_scalar, ldiv); INSTALL_BINOP_TI (ti, op_lt, octave_galois, octave_scalar, lt); INSTALL_BINOP_TI (ti, op_le, octave_galois, octave_scalar, le); INSTALL_BINOP_TI (ti, op_eq, octave_galois, octave_scalar, eq); INSTALL_BINOP_TI (ti, op_ge, octave_galois, octave_scalar, ge); INSTALL_BINOP_TI (ti, op_gt, octave_galois, octave_scalar, gt); INSTALL_BINOP_TI (ti, op_ne, octave_galois, octave_scalar, ne); INSTALL_BINOP_TI (ti, op_el_mul, octave_galois, octave_scalar, el_mul); INSTALL_BINOP_TI (ti, op_el_div, octave_galois, octave_scalar, el_div); INSTALL_BINOP_TI (ti, op_el_pow, octave_galois, octave_scalar, el_pow); INSTALL_BINOP_TI (ti, op_el_ldiv, octave_galois, octave_scalar, el_ldiv); INSTALL_BINOP_TI (ti, op_el_and, octave_galois, octave_scalar, el_and); INSTALL_BINOP_TI (ti, op_el_or, octave_galois, octave_scalar, el_or); INSTALL_CATOP_TI (ti, octave_galois, octave_scalar, gm_s); INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_galois, octave_scalar, assign); } #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.2/src/PaxHeaders.12771/aclocal.m40000644000000000000000000000013213604150124016725 xustar0030 mtime=1578160212.957199581 30 atime=1578160213.089199074 30 ctime=1578160213.541197341 communications-1.2.2/src/aclocal.m40000644000175000017500000002530513604150124016636 0ustar00nirnir00000000000000# generated automatically by aclocal 1.16.1 -*- Autoconf -*- # Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR m4_include([m4/octave-forge.m4]) communications-1.2.2/src/PaxHeaders.12771/op-gm-m.cc0000644000000000000000000000007413604150022016647 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.541197341 communications-1.2.2/src/op-gm-m.cc0000644000175000017500000001252013604150022016546 0ustar00nirnir00000000000000//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) #ifdef HAVE_CONFIG_H #include "config.h" #endif #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 (); } #ifndef DEFMETHOD_DLD 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); } #else void install_gm_m_ops (octave::type_info& ti) { INSTALL_BINOP_TI (ti, op_add, octave_galois, octave_matrix, add); INSTALL_BINOP_TI (ti, op_sub, octave_galois, octave_matrix, sub); INSTALL_BINOP_TI (ti, op_mul, octave_galois, octave_matrix, mul); INSTALL_BINOP_TI (ti, op_div, octave_galois, octave_matrix, div); INSTALL_BINOP_TI (ti, op_pow, octave_galois, octave_matrix, pow); INSTALL_BINOP_TI (ti, op_ldiv, octave_galois, octave_matrix, ldiv); INSTALL_BINOP_TI (ti, op_lt, octave_galois, octave_matrix, lt); INSTALL_BINOP_TI (ti, op_le, octave_galois, octave_matrix, le); INSTALL_BINOP_TI (ti, op_eq, octave_galois, octave_matrix, eq); INSTALL_BINOP_TI (ti, op_ge, octave_galois, octave_matrix, ge); INSTALL_BINOP_TI (ti, op_gt, octave_galois, octave_matrix, gt); INSTALL_BINOP_TI (ti, op_ne, octave_galois, octave_matrix, ne); INSTALL_BINOP_TI (ti, op_el_mul, octave_galois, octave_matrix, el_mul); INSTALL_BINOP_TI (ti, op_el_div, octave_galois, octave_matrix, el_div); INSTALL_BINOP_TI (ti, op_el_pow, octave_galois, octave_matrix, el_pow); INSTALL_BINOP_TI (ti, op_el_ldiv, octave_galois, octave_matrix, el_ldiv); INSTALL_BINOP_TI (ti, op_el_and, octave_galois, octave_matrix, el_and); INSTALL_BINOP_TI (ti, op_el_or, octave_galois, octave_matrix, el_or); INSTALL_CATOP_TI (ti, octave_galois, octave_matrix, gm_m); INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_galois, octave_matrix, assign); INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_galois, octave_matrix); } #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ communications-1.2.2/src/PaxHeaders.12771/ov-galois.h0000644000000000000000000000006213604150022017135 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/ov-galois.h0000644000175000017500000001215713604150022017045 0ustar00nirnir00000000000000//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 #ifdef HAVE_CONFIG_H #include "config.h" #endif #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 #if ! defined (OV_REP_TYPE) # define OV_REP_TYPE octave_base_value #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 OV_ISNUMERIC (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 OV_ISREAL (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, OCTAVE_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.2/src/PaxHeaders.12771/galois-def.h0000644000000000000000000000006213604150022017247 xustar0020 atime=1578160146 30 ctime=1578160213.541197341 communications-1.2.2/src/galois-def.h0000644000175000017500000003110013604150022017144 0ustar00nirnir00000000000000//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 #ifdef HAVE_CONFIG_H #include "config.h" #endif 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 \ OCTAVE__ERR_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 \ OCTAVE__ERR_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 \ OCTAVE__ERR_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)) \ OCTAVE__ERR_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.2/PaxHeaders.12771/inst0000644000000000000000000000013213604150040015173 xustar0030 mtime=1578160160.349401192 30 atime=1578160213.545197325 30 ctime=1578160213.541197341 communications-1.2.2/inst/0000755000175000017500000000000013604150040015154 5ustar00nirnir00000000000000communications-1.2.2/inst/PaxHeaders.12771/wgn.m0000644000000000000000000000007413604150022016226 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.545197325 communications-1.2.2/inst/wgn.m0000644000175000017500000001047113604150022016130 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/fiboenco.m0000644000000000000000000000007413604150022017217 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.545197325 communications-1.2.2/inst/fiboenco.m0000644000175000017500000000622313604150022017121 0ustar00nirnir00000000000000## 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, 1, "first")):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 (fiboenco (10), {[ 0 1 0 0 1 1]}) %!assert (fiboenco (11), {[ 0 0 1 0 1 1]}) %!assert (fiboenco (1:4), {[1 1], [0 1 1], [0 0 1 1], [1 0 1 1]}) %!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.2/inst/PaxHeaders.12771/minpol.m0000644000000000000000000000007413604150022016731 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.545197325 communications-1.2.2/inst/minpol.m0000644000175000017500000000452013604150022016631 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/huffmandeco.m0000644000000000000000000000007413604150022017712 xustar0030 atime=1578160160.425400902 30 ctime=1578160213.545197325 communications-1.2.2/inst/huffmandeco.m0000644000175000017500000000767613604150022017631 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/reedmullerenc.m0000644000000000000000000000007413604150022020261 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/reedmullerenc.m0000644000175000017500000000361213604150022020162 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/encode.m0000644000000000000000000000007413604150022016670 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/encode.m0000644000175000017500000002003313604150022016565 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/fibodeco.m0000644000000000000000000000007413604150022017205 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/fibodeco.m0000644000175000017500000000530413604150022017106 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/huffmanenco.m0000644000000000000000000000007413604150022017724 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/huffmanenco.m0000644000175000017500000000370113604150022017624 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/ademodce.m0000644000000000000000000000007413604150022017174 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/ademodce.m0000644000175000017500000001457413604150022017106 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/qfunc.m0000644000000000000000000000007413604150022016547 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/qfunc.m0000644000175000017500000000207713604150022016454 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/comms.m0000644000000000000000000000007413604150022016551 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/comms.m0000644000175000017500000005335213604150022016460 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/qamdemod.m0000644000000000000000000000007413604150022017222 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/qamdemod.m0000644000175000017500000000271413604150022017125 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/pammod.m0000644000000000000000000000007413604150022016710 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/pammod.m0000644000175000017500000000466613604150022016623 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/randdeintrlv.m0000644000000000000000000000007413604150022020127 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/randdeintrlv.m0000644000175000017500000000244513604150022020033 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/lz77enco.m0000644000000000000000000000007413604150022017103 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/lz77enco.m0000644000175000017500000000474213604150022017011 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/symerr.m0000644000000000000000000000007413604150022016754 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/symerr.m0000644000175000017500000001177713604150022016670 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/lloyds.m0000644000000000000000000000007413604150022016741 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/lloyds.m0000644000175000017500000001472313604150022016647 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/de2bi.m0000644000000000000000000000007413604150022016420 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/de2bi.m0000644000175000017500000000662013604150022016323 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/fmdemod.m0000644000000000000000000000007413604150022017046 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/fmdemod.m0000644000175000017500000000232413604150022016746 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/qfuncinv.m0000644000000000000000000000007413604150022017264 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/qfuncinv.m0000644000175000017500000000212313604150022017161 0ustar00nirnir00000000000000## 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 = sqrt(2)*erfcinv(2*x); endfunction %!assert (qfuncinv ([0 0.5 1]), [Inf 0 -Inf]) %% Test input validation %!error qfuncinv () %!error qfuncinv (1, 2) communications-1.2.2/inst/PaxHeaders.12771/dpcmdeco.m0000644000000000000000000000007413604150022017211 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/dpcmdeco.m0000644000175000017500000000327013604150022017112 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/rledeco.m0000644000000000000000000000007413604150022017050 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/rledeco.m0000644000175000017500000000310413604150022016745 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/poly2trellis.m0000644000000000000000000000007413604150022020077 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/poly2trellis.m0000644000175000017500000001564313604150022020007 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/rleenco.m0000644000000000000000000000007413604150022017062 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/rleenco.m0000644000175000017500000000326713604150022016771 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/genqammod.m0000644000000000000000000000007413604150022017403 xustar0030 atime=1578160160.429400886 30 ctime=1578160213.545197325 communications-1.2.2/inst/genqammod.m0000644000175000017500000000353413604150022017307 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/qaskenco.m0000644000000000000000000000007313604150022017236 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/qaskenco.m0000644000175000017500000001405413604150022017142 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/egolayenc.m0000644000000000000000000000007313604150022017400 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/egolayenc.m0000644000175000017500000000323413604150022017302 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/rsencof.m0000644000000000000000000000007313604150022017071 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/rsencof.m0000644000175000017500000000671613604150022017003 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/gftable.m0000644000000000000000000000007313604150022017036 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/gftable.m0000644000175000017500000000217013604150022016736 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/pskdemod.m0000644000000000000000000000007313604150022017240 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/pskdemod.m0000644000175000017500000000441613604150022017145 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/prbs_iterator.m0000644000000000000000000000007313604150022020311 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/prbs_iterator.m0000644000175000017500000001122313604150022020210 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/amdemod.m0000644000000000000000000000007313604150022017040 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/amdemod.m0000644000175000017500000000246313604150022016745 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/matintrlv.m0000644000000000000000000000007313604150022017452 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/matintrlv.m0000644000175000017500000000363013604150022017354 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/fmmod.m0000644000000000000000000000007313604150022016534 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/fmmod.m0000644000175000017500000000236713604150022016444 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/bchpoly.m0000644000000000000000000000007313604150022017072 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/bchpoly.m0000644000175000017500000002002313604150022016767 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/pamdemod.m0000644000000000000000000000007313604150022017220 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/pamdemod.m0000644000175000017500000000441213604150022017121 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/golombenco.m0000644000000000000000000000007313604150022017556 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/golombenco.m0000644000175000017500000000756513604150022017473 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/qammod.m0000644000000000000000000000007313604150022016710 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/qammod.m0000644000175000017500000000277413604150022016622 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/convenc.m0000644000000000000000000000007313604150022017065 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/convenc.m0000644000175000017500000000723513604150022016774 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/randintrlv.m0000644000000000000000000000007313604150022017615 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/randintrlv.m0000644000175000017500000000241513604150022017517 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/apkconst.m0000644000000000000000000000007313604150022017254 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/apkconst.m0000644000175000017500000001100013604150022017144 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/helscandeintrlv.m0000644000000000000000000000007313604150022020617 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/helscandeintrlv.m0000644000175000017500000000205113604150022020515 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/rsdecof.m0000644000000000000000000000007313604150022017057 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/rsdecof.m0000644000175000017500000000551413604150022016764 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/shannonfanodeco.m0000644000000000000000000000007313604150022020575 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/shannonfanodeco.m0000644000175000017500000001063013604150022020475 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/fibosplitstream.m0000644000000000000000000000007313604150022020641 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/fibosplitstream.m0000644000175000017500000000460713604150022020550 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/randerr.m0000644000000000000000000000007313604150022017067 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/randerr.m0000644000175000017500000000755313604150022017001 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/randint.m0000644000000000000000000000007313604150022017071 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/randint.m0000644000175000017500000000635613604150022017003 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/awgn.m0000644000000000000000000000007313604150022016366 xustar0029 atime=1578160160.43340087 30 ctime=1578160213.545197325 communications-1.2.2/inst/awgn.m0000644000175000017500000001031413604150022016265 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/rsgenpoly.m0000644000000000000000000000007413604150022017455 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/rsgenpoly.m0000644000175000017500000001133713604150022017361 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/shannonfanodict.m0000644000000000000000000000007413604150022020607 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/shannonfanodict.m0000644000175000017500000000631213604150022020510 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/prbs_generator.m0000644000000000000000000000007413604150022020447 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/prbs_generator.m0000644000175000017500000000526313604150022020354 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/golombdeco.m0000644000000000000000000000007413604150022017545 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/golombdeco.m0000644000175000017500000000555713604150022017460 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/bsc.m0000644000000000000000000000007413604150022016202 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/bsc.m0000644000175000017500000000331513604150022016103 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/istrellis.m0000644000000000000000000000007413604150022017445 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/istrellis.m0000644000175000017500000000774413604150022017360 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/gfweight.m0000644000000000000000000000007413604150022017237 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/gfweight.m0000644000175000017500000000554013604150022017142 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/modmap.m0000644000000000000000000000007413604150022016710 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/modmap.m0000644000175000017500000002473313604150022016620 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/lz77deco.m0000644000000000000000000000007413604150022017071 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/lz77deco.m0000644000175000017500000000416413604150022016775 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/decode.m0000644000000000000000000000007413604150022016656 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/decode.m0000644000175000017500000002541513604150022016564 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/shannonfanoenco.m0000644000000000000000000000007413604150022020610 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/shannonfanoenco.m0000644000175000017500000000372713604150022020520 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/ricedeco.m0000644000000000000000000000007413604150022017210 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/ricedeco.m0000644000175000017500000000464413604150022017117 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/dpcmenco.m0000644000000000000000000000007413604150022017223 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/dpcmenco.m0000644000175000017500000000551213604150022017125 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/scatterplot.m0000644000000000000000000000007413604150022017777 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/scatterplot.m0000644000175000017500000001157213604150022017704 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/hammgen.m0000644000000000000000000000007413604150022017047 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/hammgen.m0000644000175000017500000000546513604150022016760 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/helintrlv.m0000644000000000000000000000007413604150022017442 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/helintrlv.m0000644000175000017500000000437613604150022017353 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/huffmandict.m0000644000000000000000000000007413604150022017723 xustar0030 atime=1578160160.437400856 30 ctime=1578160213.545197325 communications-1.2.2/inst/huffmandict.m0000644000175000017500000001502413604150022017624 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/vec2mat.m0000644000000000000000000000007313604150022016773 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/vec2mat.m0000644000175000017500000000345013604150022016675 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/randsrc.m0000644000000000000000000000007313604150022017066 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/randsrc.m0000644000175000017500000000751213604150022016773 0ustar00nirnir00000000000000## 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 (double (a4(:))) <= double ("b")) %!assert (max (double (a4(:))) >= double ("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.2/inst/PaxHeaders.12771/compand.m0000644000000000000000000000007313604150022017053 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/compand.m0000644000175000017500000000722013604150022016754 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/qaskdeco.m0000644000000000000000000000007313604150022017224 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/qaskdeco.m0000644000175000017500000001705713604150022017136 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/eyediagram.m0000644000000000000000000000007313604150022017541 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/eyediagram.m0000644000175000017500000001404313604150022017443 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/egolaydec.m0000644000000000000000000000007313604150022017366 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/egolaydec.m0000644000175000017500000000655513604150022017301 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/reedmullerdec.m0000644000000000000000000000007313604150022020246 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/reedmullerdec.m0000644000175000017500000001607413604150022020156 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/matdeintrlv.m0000644000000000000000000000007313604150022017763 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/matdeintrlv.m0000644000175000017500000000236113604150022017665 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/deintrlv.m0000644000000000000000000000007313604150022017261 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/deintrlv.m0000644000175000017500000000333313604150022017163 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/riceenco.m0000644000000000000000000000007313604150022017221 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/riceenco.m0000644000175000017500000000671513604150022017132 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/pskmod.m0000644000000000000000000000007313604150022016727 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/pskmod.m0000644000175000017500000000467513604150022016643 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/biterr.m0000644000000000000000000000007313604150022016721 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/biterr.m0000644000175000017500000001330313604150022016621 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/amodce.m0000644000000000000000000000007313604150022016662 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/amodce.m0000644000175000017500000001341113604150022016562 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/reedmullergen.m0000644000000000000000000000007313604150022020264 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/reedmullergen.m0000644000175000017500000000451613604150022020172 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/egolaygen.m0000644000000000000000000000007313604150022017404 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/egolaygen.m0000644000175000017500000000335613604150022017313 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/bi2de.m0000644000000000000000000000007313604150022016417 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/bi2de.m0000644000175000017500000000544613604150022016330 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/gen2par.m0000644000000000000000000000007313604150022016770 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/gen2par.m0000644000175000017500000000343513604150022016675 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/cosets.m0000644000000000000000000000007313604150022016732 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/cosets.m0000644000175000017500000000321113604150022016627 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/helscanintrlv.m0000644000000000000000000000007313604150022020306 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/helscanintrlv.m0000644000175000017500000000377413604150022020221 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/intrlv.m0000644000000000000000000000007313604150022016750 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/intrlv.m0000644000175000017500000000316213604150022016652 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/oct2dec.m0000644000000000000000000000007313604150022016755 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/oct2dec.m0000644000175000017500000000341213604150022016655 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/systematize.m0000644000000000000000000000007313604150022020013 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/systematize.m0000644000175000017500000000630013604150022017712 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/prbs_sequence.m0000644000000000000000000000007313604150022020270 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/prbs_sequence.m0000644000175000017500000000567613604150022020206 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/quantiz.m0000644000000000000000000000007313604150022017125 xustar0029 atime=1578160160.44140084 30 ctime=1578160213.545197325 communications-1.2.2/inst/quantiz.m0000644000175000017500000000465613604150022017040 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/ammod.m0000644000000000000000000000007413604150022016530 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/ammod.m0000644000175000017500000000233713604150022016434 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/dpcmopt.m0000644000000000000000000000007413604150022017101 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/dpcmopt.m0000644000175000017500000000616713604150022017012 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/@galois0000644000000000000000000000013213604150040016551 xustar0030 mtime=1578160160.317401315 30 atime=1578160213.545197325 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/0000755000175000017500000000000013604150040016532 5ustar00nirnir00000000000000communications-1.2.2/inst/@galois/PaxHeaders.12771/sum.m0000644000000000000000000000007413604150022017615 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/sum.m0000644000175000017500000000202213604150022017510 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/prod.m0000644000000000000000000000007413604150022017755 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/prod.m0000644000175000017500000000203613604150022017655 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/fft.m0000644000000000000000000000007413604150022017570 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/fft.m0000644000175000017500000000312413604150022017467 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/dftmtx.m0000644000000000000000000000007413604150022020317 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/dftmtx.m0000644000175000017500000000422713604150022020223 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/convmtx.m0000644000000000000000000000007413604150022020507 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/convmtx.m0000644000175000017500000000317613604150022020415 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/log.m0000644000000000000000000000007413604150022017572 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/log.m0000644000175000017500000000173413604150022017476 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/conv.m0000644000000000000000000000007413604150022017756 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/conv.m0000644000175000017500000000470713604150022017665 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/isequal.m0000644000000000000000000000007413604150022020454 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/isequal.m0000644000175000017500000000213113604150022020350 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/inverse.m0000644000000000000000000000007413604150022020464 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/inverse.m0000644000175000017500000000167013604150022020367 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/sumsq.m0000644000000000000000000000007413604150022020161 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/sumsq.m0000644000175000017500000000226113604150022020061 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/inv.m0000644000000000000000000000007413604150022017605 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/inv.m0000644000175000017500000000217113604150022017505 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/rank.m0000644000000000000000000000007413604150022017744 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/rank.m0000644000175000017500000000176513604150022017654 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/exp.m0000644000000000000000000000007413604150022017605 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/exp.m0000644000175000017500000000173113604150022017506 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/lu.m0000644000000000000000000000007413604150022017431 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/lu.m0000644000175000017500000000356413604150022017340 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/det.m0000644000000000000000000000007413604150022017565 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/det.m0000644000175000017500000000171113604150022017464 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/ifft.m0000644000000000000000000000007413604150022017741 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/ifft.m0000644000175000017500000000316113604150022017641 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/diag.m0000644000000000000000000000007413604150022017715 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/diag.m0000644000175000017500000000275413604150022017624 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/deconv.m0000644000000000000000000000007413604150022020267 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/deconv.m0000644000175000017500000000463113604150022020172 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/roots.m0000644000000000000000000000007413604150022020157 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/roots.m0000644000175000017500000000352213604150022020060 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/filter.m0000644000000000000000000000007413604150022020276 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/filter.m0000644000175000017500000000511213604150022020174 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/sqrt.m0000644000000000000000000000007413604150022020002 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/sqrt.m0000644000175000017500000000175213604150022017706 0ustar00nirnir00000000000000## 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.2/inst/@galois/PaxHeaders.12771/reshape.m0000644000000000000000000000007413604150022020440 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/@galois/reshape.m0000644000175000017500000000346013604150022020342 0ustar00nirnir00000000000000## 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.2/inst/PaxHeaders.12771/demodmap.m0000644000000000000000000000007413604150022017221 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/inst/demodmap.m0000644000175000017500000002063513604150022017126 0ustar00nirnir00000000000000## 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.2/PaxHeaders.12771/COPYING0000644000000000000000000000006213604150022015330 xustar0020 atime=1578160146 30 ctime=1578160213.545197325 communications-1.2.2/COPYING0000644000175000017500000010451313604150022015236 0ustar00nirnir00000000000000 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.2/PaxHeaders.12771/DESCRIPTION0000644000000000000000000000006213604150022016003 xustar0020 atime=1578160146 30 ctime=1578160213.545197325 communications-1.2.2/DESCRIPTION0000644000175000017500000000056613604150022015714 0ustar00nirnir00000000000000Name: communications Version: 1.2.2 Date: 2019-12-22 Author: various authors Maintainer: Nir Krakauer Title: Communications Description: Digital Communications, Error Correcting Codes (Channel Code), Source Code functions, Modulation and Galois Fields Depends: octave (>= 4.4), signal (>= 1.1.3) Autoload: no License: GPLv3+ Url: http://octave.sf.net communications-1.2.2/PaxHeaders.12771/NEWS0000644000000000000000000000006213604150022014774 xustar0020 atime=1578160146 30 ctime=1578160213.545197325 communications-1.2.2/NEWS0000644000175000017500000000362413604150022014703 0ustar00nirnir00000000000000Summary of important user-visible changes for communications 1.2.2: ------------------------------------------------------------------ ** The communications package is now compatible with Octave 4.4 and 5. Summary 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. communications-1.2.2/PaxHeaders.12771/INDEX0000644000000000000000000000007413604150022015072 xustar0030 atime=1578160160.569400351 30 ctime=1578160213.545197325 communications-1.2.2/INDEX0000644000175000017500000000332613604150022014775 0ustar00nirnir00000000000000communications >> Communications Random Signals awgn biterr eyediagram randerr randint randsrc scatterplot symerr wgn bsc Source Coding 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 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 Modulations ademodce amodce ammod amdemod apkconst demodmap fmmod fmdemod genqammod genqamdemod modmap pamdemod pammod pskdemod pskmod qaskdeco qaskenco qammod qamdemod 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 Utility Functions comms bi2de de2bi oct2dec istrellis poly2trellis vec2mat qfunc qfuncinv communications-1.2.2/PaxHeaders.12771/doc0000644000000000000000000000013213604150123014765 xustar0030 mtime=1578160211.973203357 30 atime=1578160213.545197325 30 ctime=1578160213.545197325 communications-1.2.2/doc/0000755000175000017500000000000013604150123014746 5ustar00nirnir00000000000000communications-1.2.2/doc/PaxHeaders.12771/Makefile0000644000000000000000000000007413604150022016505 xustar0030 atime=1578160160.377401086 30 ctime=1578160213.545197325 communications-1.2.2/doc/Makefile0000644000175000017500000000374713604150022016417 0ustar00nirnir00000000000000DVIPS = 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.2/doc/PaxHeaders.12771/mkdoc.pl0000644000000000000000000000007313604150022016476 xustar0029 atime=1578160160.38940104 30 ctime=1578160213.545197325 communications-1.2.2/doc/mkdoc.pl0000755000175000017500000001240113604150022016377 0ustar00nirnir00000000000000#!/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.2/doc/PaxHeaders.12771/commsimages.m0000644000000000000000000000007413604150022017527 xustar0030 atime=1578160160.445400824 30 ctime=1578160213.545197325 communications-1.2.2/doc/commsimages.m0000644000175000017500000000533413604150022017433 0ustar00nirnir00000000000000## 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.2/doc/PaxHeaders.12771/comms.info0000644000000000000000000000013213604150124017036 xustar0030 mtime=1578160212.341201945 30 atime=1578160211.973203357 30 ctime=1578160213.545197325 communications-1.2.2/doc/comms.info0000644000175000017500000061352213604150124016753 0ustar00nirnir00000000000000This is comms.info, produced by makeinfo version 6.6 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 frequency of FC and a sample frequency of FS See also: ammod * 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 error one each symbol * comms:: Manual and test code for the Octave Communications toolbox. * compand:: Compresses and expanding the dynamic range of a signal using a mu-law or or A-law algorithm * conv:: Convolve two Galois vectors * convenc:: Encode the binary vector MSG with the convolutional encoder described by the trellis structure T * 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 Galois Field * 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:: Encode using differential pulse code modulation (DPCM) * dpcmopt:: Optimize the DPCM parameters and codebook * 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 Universal codes like Fibonacci codes have a useful synchronization property, only for 255 maximum value we have designed these routines. * fiboenco:: 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. * fibosplitstream:: 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 * filter:: Digital filtering of vectors in a Galois Field. * fmdemod:: Create the FM demodulation of the signal x with carrier frequency fs Where x is sample at frequency fs See also: ammod, amdemod, fmmod * 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 ... 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. * gf:: #endif * 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 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. * 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: deintrlv * inv:: Compute the inverse of the square matrix A. * inverse:: See inv * isequal:: Return true if all of X1, X2, ... are equal See also: isequalwithequalnans * 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 array * 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 NROWS-by-NCOLS See also: matintrlv * matintrlv:: Interleaved elements of DATA with a temporary matrix of size NROWS-by-NCOLS See also: matdeintrlv * 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 information sequence of integers in the range '[0 ... M-1]' PHI controls the initial phase and TYPE controls the constellation mapping. * pammod:: 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. * 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 into an information sequence of integers in the range '[0 ... M-1]'. * pskmod:: Modulates an information sequence of integers X in the range '[0 ... M-1]' onto a complex baseband phase shift keying modulated signal Y. * qamdemod:: Create the QAM demodulation of x with a size of alphabet m See also: qammod, pskmod, pskdemod * qammod:: Create the QAM modulation of x with a size of alphabet m See also: qamdemod, pskmod, pskdemod * 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: randintrlv, intrlv, deintrlv * 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: intrlv, deintrlv * randsrc:: Generate a matrix of random symbols. * rank:: Compute the rank of the Galois array A by counting the independent rows and columns * 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 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. * 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 polynomial over a Galois Field * 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 Dictionary is built from SYMBOL_PROBABILITIES using the Shannon-Fano scheme. * shannonfanoenco:: 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)'. * sqrt:: Compute the square root of X, element by element, in a Galois Field See also: exp * sum:: Sum of elements along dimension DIM of Galois array. * sumsq:: Sum of squares of elements along dimension DIM of Galois array If DIM is omitted, it defaults to 1 (column-wise sum of squares) * 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 arrangement and with the final column padded with the value D to the correct length. * 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 --------- #endif "-*- texinfo -*- \  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: ademodce83085 Node: amdemod85259 Node: ammod85561 Node: amodce85860 Node: apkconst87789 Node: awgn89527 Node: bchdeco90762 Node: bchenco92999 Node: bchpoly94626 Node: bi2de97847 Node: biterr98660 Node: bsc100654 Node: comms100897 Node: compand102440 Node: conv103709 Node: convenc104116 Node: convmtx105198 Node: cosets105934 Node: cyclgen106263 Node: cyclpoly107500 Node: de2bi108671 Node: decode109875 Node: deconv114591 Node: deintrlv115058 Node: demodmap115312 Node: det117810 Node: dftmtx118009 Node: diag118684 Node: dpcmdeco119434 Node: dpcmenco119951 Node: dpcmopt121156 Node: egolaydec122735 Node: egolayenc123959 Node: egolaygen124594 Node: encode125002 Node: exp128492 Node: eyediagram128711 Node: fft130330 Node: fibodeco130656 Node: fiboenco131666 Node: fibosplitstream132929 Node: filter133808 Node: fmdemod134983 Node: fmmod135294 Node: gen2par135596 Node: genqamdemod136159 Node: genqammod136539 Node: gf137232 Node: gftable137370 Node: gfweight137755 Node: golombdeco138707 Node: golombenco139797 Node: hammgen141773 Node: helscanintrlv142690 Node: huffmandeco142955 Node: huffmandict143994 Node: huffmanenco145707 Node: ifft146444 Node: intrlv146789 Node: inv147037 Node: inverse147409 Node: isequal147591 Node: isgalois147843 Node: isprimitive148083 Node: istrellis148414 Node: lloyds148872 Node: log150889 Node: lu151108 Node: lz77deco152118 Node: lz77enco152583 Node: matdeintrlv153009 Node: matintrlv153313 Node: minpol153615 Node: modmap153999 Node: oct2dec156748 Node: pamdemod157062 Node: pammod157918 Node: poly2trellis158697 Node: primpoly160635 Node: prod161907 Node: pskdemod162189 Node: pskmod163064 Node: qamdemod163862 Node: qammod164127 Node: qaskdeco164388 Node: qaskenco165703 Node: qfunc167496 Node: qfuncinv167698 Node: quantiz167916 Node: randdeintrlv168854 Node: randerr169150 Node: randint170269 Node: randintrlv171203 Node: randsrc171483 Node: rank172460 Node: reedmullerdec172712 Node: reedmullerenc174046 Node: reedmullergen174789 Node: reshape175781 Node: ricedeco176798 Node: riceenco177660 Node: rledeco179094 Node: rleenco179599 Node: roots180149 Node: rsdec180582 Node: rsdecof182777 Node: rsenc183733 Node: rsencof185782 Node: rsgenpoly186982 Node: scatterplot188742 Node: shannonfanodeco190321 Node: shannonfanodict191513 Node: shannonfanoenco192312 Node: sqrt193103 Node: sum193349 Node: sumsq193613 Node: symerr194017 Node: syndtable195712 Node: systematize196258 Node: vec2mat197134 Node: wgn197635  End Tag Table communications-1.2.2/doc/PaxHeaders.12771/mktexi.pl0000644000000000000000000000007313604150022016702 xustar0029 atime=1578160160.44940081 30 ctime=1578160213.545197325 communications-1.2.2/doc/mktexi.pl0000755000175000017500000003022613604150022016610 0ustar00nirnir00000000000000#!/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.2/doc/PaxHeaders.12771/comms.txi0000644000000000000000000000007413604150022016711 xustar0030 atime=1578160160.565400366 30 ctime=1578160213.545197325 communications-1.2.2/doc/comms.txi0000644000175000017500000023123713604150022016620 0ustar00nirnir00000000000000\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.2/doc/PaxHeaders.12771/comms.texi0000644000000000000000000000013213604150123017053 xustar0030 mtime=1578160211.381205627 30 atime=1578160211.577204876 30 ctime=1578160213.545197325 communications-1.2.2/doc/comms.texi0000644000175000017500000066167113604150123017000 0ustar00nirnir00000000000000\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 error one each symbol @end table @subsection Source Coding @table @asis @item compand Compresses and expanding the dynamic range of a signal using a mu-law or or A-law algorithm @item dpcmdeco Decode using differential pulse code modulation (DPCM) @item dpcmenco Encode using differential pulse code modulation (DPCM) @item dpcmopt Optimize the DPCM parameters and codebook @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 Dictionary is built from SYMBOL_PROBABILITIES using the Shannon-Fano scheme. @item shannonfanoenco 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)'. @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 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. @item fiboenco 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. @item fibodeco 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. @item fibosplitstream 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 @item golombenco 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. @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: deintrlv @item helscanintrlv NROWS-by-NCOLS See also: helscandeintrlv @item matintrlv Interleaved elements of DATA with a temporary matrix of size NROWS-by-NCOLS See also: matdeintrlv @item randintrlv Interleaves elements of DATA with a random permutation See also: intrlv, deintrlv @item deintrlv Restore elements of DATA according to ELEMENTS See also: intrlv @item matdeintrlv Restore elements of DATA with a temporary matrix of size NROWS-by-NCOLS See also: matintrlv @item randdeintrlv Restore elements of DATA with a random permutation See also: randintrlv, intrlv, deintrlv @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 described by the trellis structure T @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. @end table @subsection Modulations @table @asis @item ademodce Baseband demodulator for analog signals. @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 frequency of FC and a sample frequency of FS See also: ammod @item apkconst Plots a ASK/PSK signal constellation. @item demodmap Demapping of an analog signal to a digital signal. @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 fs Where x is sample at frequency fs See also: ammod, amdemod, fmmod @item genqammod 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. @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 information sequence of integers in the range '[0 ... M-1]' PHI controls the initial phase and TYPE controls the constellation mapping. @item pammod 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. @item pskdemod Demodulates a complex-baseband phase shift keying modulated signal into an information sequence of integers in the range '[0 ... M-1]'. @item pskmod Modulates an information sequence of integers X in the range '[0 ... M-1]' onto a complex baseband phase shift keying modulated signal Y. @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: qamdemod, pskmod, pskdemod @item qamdemod Create the QAM demodulation of x with a size of alphabet m See also: qammod, pskmod, pskdemod @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 Galois Field @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 #endif @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: isequalwithequalnans @item log Compute the natural logarithm for each element of X for a Galois array @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 See also: exp @item rank Compute the rank of the Galois array A by counting the independent rows and columns @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 polynomial over a Galois Field @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 DIM is omitted, it defaults to 1 (column-wise sum of squares) @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 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 arrangement and with the final column padded with the value D to the correct length. @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 frequency of FC and a sample frequency of FS See also: ammod * 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 error one each symbol * comms:: Manual and test code for the Octave Communications toolbox. * compand:: Compresses and expanding the dynamic range of a signal using a mu-law or or A-law algorithm * conv:: Convolve two Galois vectors * convenc:: Encode the binary vector MSG with the convolutional encoder described by the trellis structure T * 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 Galois Field * 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:: Encode using differential pulse code modulation (DPCM) * dpcmopt:: Optimize the DPCM parameters and codebook * 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 Universal codes like Fibonacci codes have a useful synchronization property, only for 255 maximum value we have designed these routines. * fiboenco:: 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. * fibosplitstream:: 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 * filter:: Digital filtering of vectors in a Galois Field. * fmdemod:: Create the FM demodulation of the signal x with carrier frequency fs Where x is sample at frequency fs See also: ammod, amdemod, fmmod * 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 ... 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. * gf:: #endif * 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 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. * 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: deintrlv * inv:: Compute the inverse of the square matrix A. * inverse:: See inv * isequal:: Return true if all of X1, X2, ... are equal See also: isequalwithequalnans * 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 array * 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 NROWS-by-NCOLS See also: matintrlv * matintrlv:: Interleaved elements of DATA with a temporary matrix of size NROWS-by-NCOLS See also: matdeintrlv * 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 information sequence of integers in the range '[0 ... M-1]' PHI controls the initial phase and TYPE controls the constellation mapping. * pammod:: 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. * 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 into an information sequence of integers in the range '[0 ... M-1]'. * pskmod:: Modulates an information sequence of integers X in the range '[0 ... M-1]' onto a complex baseband phase shift keying modulated signal Y. * qamdemod:: Create the QAM demodulation of x with a size of alphabet m See also: qammod, pskmod, pskdemod * qammod:: Create the QAM modulation of x with a size of alphabet m See also: qamdemod, pskmod, pskdemod * 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: randintrlv, intrlv, deintrlv * 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: intrlv, deintrlv * randsrc:: Generate a matrix of random symbols. * rank:: Compute the rank of the Galois array A by counting the independent rows and columns * 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 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. * 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 polynomial over a Galois Field * 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 Dictionary is built from SYMBOL_PROBABILITIES using the Shannon-Fano scheme. * shannonfanoenco:: 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)'. * sqrt:: Compute the square root of X, element by element, in a Galois Field See also: exp * sum:: Sum of elements along dimension DIM of Galois array. * sumsq:: Sum of squares of elements along dimension DIM of Galois array If DIM is omitted, it defaults to 1 (column-wise sum of squares) * 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 arrangement and with the final column padded with the value D to the correct length. * 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 #endif "-*- texinfo -*- \ @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.2/doc/PaxHeaders.12771/images.mk0000644000000000000000000000013213604150040016636 xustar0030 mtime=1578160160.385401054 30 atime=1578160160.385401054 30 ctime=1578160213.545197325 communications-1.2.2/doc/images.mk0000644000175000017500000000246113604150040016545 0ustar00nirnir00000000000000IMAGES = 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.2/doc/PaxHeaders.12771/images.sh0000644000000000000000000000007413604150022016646 xustar0030 atime=1578160160.377401086 30 ctime=1578160213.545197325 communications-1.2.2/doc/images.sh0000755000175000017500000000112413604150022016546 0ustar00nirnir00000000000000#!/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