./PaxHeaders/communications-1.2.6 0000644 0000000 0000000 00000000130 14426727003 013711 x ustar 00 30 mtime=1683729923.227701724
29 atime=1683729954.69955525
29 ctime=1683729954.69955525
communications-1.2.6/ 0000755 0001750 0001750 00000000000 14426727003 014217 5 ustar 00nir nir 0000000 0000000 communications-1.2.6/PaxHeaders/NEWS 0000644 0000000 0000000 00000000061 14426726573 014346 x ustar 00 20 atime=1683729787
29 ctime=1683729954.69955525
communications-1.2.6/NEWS 0000644 0001750 0001750 00000006267 14426726573 014744 0 ustar 00nir nir 0000000 0000000
Summary of important user-visible changes for communications (next release):
------------------------------------------------------------------
Summary of important user-visible changes for communications 1.2.6:
------------------------------------------------------------------
** Replaced operators deprecated as of Octave 7.
Summary of important user-visible changes for communications 1.2.5:
------------------------------------------------------------------
** The following functions are new:
ssbmod ssbdemod
** The following functions have improved Matlab compatibility and tests:
pskmod
qammod
Summary of important user-visible changes for communications 1.2.4:
------------------------------------------------------------------
** The communications package is now compatible with Octave 7 (bug #61566).
Summary of important user-visible changes for communications 1.2.3:
------------------------------------------------------------------
** The following functions are new:
berconfint bin2gray finddelay rcosfir
** The function `poly2trellis' now supports feedback connections.
** Fixed a bug in 'de2bi' that gave an error when only specifying
input decimal and MSB direction, and also improved Matlab
compatibility of input option handling.
Summary 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.6/PaxHeaders/COPYING 0000644 0000000 0000000 00000000061 14426726573 014702 x ustar 00 20 atime=1683729787
29 ctime=1683729954.69955525
communications-1.2.6/COPYING 0000644 0001750 0001750 00000104513 14426726573 015271 0 ustar 00nir nir 0000000 0000000 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.6/PaxHeaders/doc 0000644 0000000 0000000 00000000130 14426727041 014323 x ustar 00 30 mtime=1683729953.639560178
29 atime=1683729954.69955525
29 ctime=1683729954.69955525
communications-1.2.6/doc/ 0000755 0001750 0001750 00000000000 14426727041 014766 5 ustar 00nir nir 0000000 0000000 communications-1.2.6/doc/PaxHeaders/mkdoc.pl 0000644 0000000 0000000 00000000073 14426726573 016051 x ustar 00 30 atime=1683729923.275701501
29 ctime=1683729954.69955525
communications-1.2.6/doc/mkdoc.pl 0000755 0001750 0001750 00000012401 14426726573 016432 0 ustar 00nir nir 0000000 0000000 #!/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.6/doc/PaxHeaders/images.sh 0000644 0000000 0000000 00000000073 14426726573 016220 x ustar 00 30 atime=1683729923.267701538
29 ctime=1683729954.69955525
communications-1.2.6/doc/images.sh 0000755 0001750 0001750 00000001124 14426726573 016601 0 ustar 00nir nir 0000000 0000000 #!/bin/sh
images="awgn eyediagram scatterplot"
formats="eps pdf png"
script=commsimages.m
printf "IMAGES ="
for fmt in $formats; do
for img in $images; do
printf " $img.$fmt"
done
done
printf "\n"
for fmt in $formats; do
fmtupcase=`echo $fmt | awk '{print toupper($0)}'`
printf "IMAGES_$fmtupcase ="
for img in $images; do
printf " $img.$fmt"
done
printf "\n"
done
for fmt in $formats; do
for img in $images; do
printf "$img.$fmt: commsimages.m\n"
printf "\t\$(OCTAVE) --path=\$(CURDIR)/../inst -f -q -H --eval \"commsimages ('$img', '$fmt');\"\n"
done
done
communications-1.2.6/doc/PaxHeaders/comms.txi 0000644 0000000 0000000 00000000073 14426726573 016263 x ustar 00 30 atime=1683729923.343701184
29 ctime=1683729954.69955525
communications-1.2.6/doc/comms.txi 0000644 0001750 0001750 00000231237 14426726573 016653 0 ustar 00nir nir 0000000 0000000 \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.6/doc/PaxHeaders/comms.info 0000644 0000000 0000000 00000000131 14426727041 016374 x ustar 00 30 mtime=1683729953.919558876
30 atime=1683729953.639560178
29 ctime=1683729954.69955525
communications-1.2.6/doc/comms.info 0000644 0001750 0001750 00000633115 14426727041 016772 0 ustar 00nir nir 0000000 0000000 This is comms.info, produced by makeinfo version 6.8 from comms.texi.
File: comms.info, Node: Top, Next: Introduction, Up: (dir)
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:: Creates the AM demodulation of the signal S sampled at
frequency FS with carrier frequency FC
* ammod:: Creates the AM modulation of the amplitude signal X with
carrier frequency FC
* 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.
* berconfint:: Returns Bit Error Rate, BER, and confidence interval,
INTERVAL, for the number of errors R and number of
transmitted bits N with a confidence level of LEVEL.
* bi2de:: Convert bit matrix to a vector of integers
* bin2gray:: Creates a Gray encoded data Y with the same size as input X
* 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.
* finddelay:: Estimate the delay between times series X and time series Y
by correlating and finding the peak.
* fmdemod:: Creates the FM demodulation of the signal S sampled at
frequency FS with carrier frequency FC
* fmmod:: Creates the FM modulation S of the message signal M with
carrier frequency FC
* 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
using a given SYMORDER
* 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
* rcosfir:: Implements a cosine filter or root cosine filter impulse
response
* 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
* ssbdemod:: Creates the SSB demodulation of the signal S with carrier
frequency FC, sampling frequency FS initial phase PHI and a
standard 5th order low pass butterworth filter [b a] =
butter (5, fc .* 2 ./ fs) where b and a are numerator and
denominator respectively
* ssbmod:: Creates the SSB modulation of the amplitude signal X with
carrier frequency FC , sampling frequency FS initial phase
: PHI and specified band : BAND initial phase : PHI and
specified band : BAND are optional arguments and initial
phase : PHI will be considered 0 if not given specified
band : BAND by default is lower sideband, but upper
sideband can be specified by giving 'upper' as the fourth
argument
* 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)
Creates the AM demodulation of the signal S sampled at frequency FS
with carrier frequency FC
Inputs:
* S: AM modulated signal
* FC: carrier frequency
* FS: sampling frequency
Output:
* M: AM demodulation of the signal
Demo
demo amdemod
See also: ammod, fmmod, fmdemod
File: comms.info, Node: ammod, Next: amodce, Prev: amdemod, Up: Function Reference
9.1.3 ammod
-----------
-- Function File: Y = ammod (X, FC, FS)
Creates the AM modulation of the amplitude signal X with carrier
frequency FC
Inputs:
* X: amplitude message signal
* FC: carrier frequency
* FS: sampling frequency
Output:
Y: The AM modulation of X
Demo
demo ammod
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 (noisy, 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: berconfint, 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: berconfint, Next: bi2de, Prev: bchpoly, Up: Function Reference
9.1.10 berconfint
-----------------
-- Function File: BER = berconfint (R, N)
-- Function File: [BER, INTERVAL] = berconfint (R, N)
-- Function File: [BER, INTERVAL] = berconfint (R, N, LEVEL)
Returns Bit Error Rate, BER, and confidence interval, INTERVAL, for
the number of errors R and number of transmitted bits N with a
confidence level of LEVEL. By default LEVEL is 0.95
The confidence interval is the Wilson one (without continuity
correction) for a proportion. By contrast, Matlab appears to
return the Clopper–Pearson confidence interval
Reference: Robert G. Newcombe (1998), "Two‐sided confidence
intervals for the single proportion: comparison of seven methods",
Statistics in Medicine 17(8):857-872
File: comms.info, Node: bi2de, Next: bin2gray, Prev: berconfint, Up: Function Reference
9.1.11 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: bin2gray, Next: biterr, Prev: bi2de, Up: Function Reference
9.1.12 bin2gray
---------------
-- Function File: [Y, MAPPING] = bin2gray (X, TYPE, M)
Creates a Gray encoded data Y with the same size as input X
Input:
* X Binary matrix data
* TYPE: The modulation type choices available:'qam',
'pam','psk','dpsk', and 'fsk'
* M: The modualtion order must be a power of 2
Output:
* Y: The gray data of the X data
* MAPPING: This provides the gray labesfor the given modulation
Example
y = bin2gray ([0:3], 'qam', 16)
y =
0
1
3
2
Example with matrix
y = bin2gray ([0:3; 12:15], 'qam', 16)
y =
0 1 3 2
8 9 11 10
See also: qammod
File: comms.info, Node: biterr, Next: bsc, Prev: bin2gray, Up: Function Reference
9.1.13 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.14 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.15 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.16 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.17 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.18 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.19 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.20 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.21 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.22 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.23 de2bi
------------
-- Function File: B = de2bi (D)
-- Function File: B = de2bi (D, N)
-- Function File: B = de2bi (D, N, P)
-- Function File: B = de2bi (D, ..., 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'. (P must have a value of 2 or higher.)
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.24 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.25 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.26 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.27 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.28 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.29 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.30 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.31 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.32 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.33 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.34 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.35 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.36 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.37 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.38 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.39 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.40 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.41 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.42 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.43 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: finddelay, Prev: fibosplitstream, Up: Function Reference
9.1.44 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: finddelay, Next: fmdemod, Prev: filter, Up: Function Reference
9.1.45 finddelay
----------------
-- Function File: D = finddelay (X, Y)
Estimate the delay between times series X and time series Y by
correlating and finding the peak. The index of the peak
correlation is returned in D
Inputs:
X, Y: signals
Output:
D: The delay between the two signals
Example:
x = [0, 0, 1, 2, 3];
y = [1, 2, 3];
d = finddelay (x, y)
d = -2
See also: xcorr
File: comms.info, Node: fmdemod, Next: fmmod, Prev: finddelay, Up: Function Reference
9.1.46 fmdemod
--------------
-- Function File: M = fmdemod (S, FC, FS)
Creates the FM demodulation of the signal S sampled at frequency FS
with carrier frequency FC
Inputs:
* S: FM modulated signal
* FC: carrier frequency
* FS: sampling frequency
Output:
M: FM demodulation of the signal
See also: ammod, amdemod, fmmod
File: comms.info, Node: fmmod, Next: gen2par, Prev: fmdemod, Up: Function Reference
9.1.47 fmmod
------------
-- Function File: S = fmmod (M, FC, FS, FREQDEV)
Creates the FM modulation S of the message signal M with carrier
frequency FC
Inputs:
* M: sinusoidal message signal
* FC: carrier frequency
* FS: sampling frequency
* FREQDEV: maximum absolute frequency deviation, assuming M is
in [-1:1]
Output:
S: The FM modulation of M
Demo
demo fmmod
See also: ammod, fmdemod, amdemod
File: comms.info, Node: gen2par, Next: genqamdemod, Prev: fmmod, Up: Function Reference
9.1.48 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.49 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.50 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.51 gf
---------
#endif "-*- texinfo -*- \
File: comms.info, Node: gftable, Next: gfweight, Prev: gf, Up: Function Reference
9.1.52 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.53 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.54 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.55 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.56 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.57 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.58 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.59 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.60 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.61 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.62 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.63 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.64 inverse
--------------
-- Loadable Function: [X, RCOND] = inverse (A)
See inv
File: comms.info, Node: isequal, Next: isgalois, Prev: inverse, Up: Function Reference
9.1.65 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.66 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.67 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.68 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.69 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.70 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.71 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.72 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.73 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.74 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.75 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.76 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.77 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.78 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.79 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.80 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.81 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 optional argument F adds feedback
support 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 optional vector F is a 1-by-k vector of octal numbers
describing the feedback of each of the shift registers
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.82 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.83 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.84 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.85 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")
The output Y will be the same shape as the input X
See also: pskdemod
File: comms.info, Node: qamdemod, Next: qammod, Prev: pskmod, Up: Function Reference
9.1.86 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.87 qammod
-------------
-- Function File: qammod (X, M)
-- Function File: qammod (X, M, SYMORDER)
Create the QAM modulation of X with a size of alphabet M using a
given SYMORDER
X vector in the range 0 to M-1
M modulation order
SYMORDER 'bin', 'gray', user define array
M = 4;
sym = 0:M-1;
qammod(sym, M)
ans =
-1 + 1i
-1 - 1i
1 + 1i
1 - 1i
See also: qamdemod, pskmod, pskdemod
File: comms.info, Node: qaskdeco, Next: qaskenco, Prev: qammod, Up: Function Reference
9.1.88 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.89 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.90 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.91 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.92 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.93 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.94 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.95 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.96 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.97 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: rcosfir, Prev: randsrc, Up: Function Reference
9.1.98 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: rcosfir, Next: reedmullerdec, Prev: rank, Up: Function Reference
9.1.99 rcosfir
--------------
-- Function File: H, ST = rcosfir(R,NT,RATE,T,FILTERTYPE)
Implements a cosine filter or root cosine filter impulse response
R Roll-off factor
NT scalar vector of length 2 such as N = (nT(2)-nT(1))*rate+1
T symbol rate
FILTERTYPE 'normal' or 'sqrt'
H impulse response
ST sampling interval
Example:
h = rcosfir(0.2,[-3 3],4,1,'sqrt'); See also: filter, downsample,
rectfilt
File: comms.info, Node: reedmullerdec, Next: reedmullerenc, Prev: rcosfir, Up: Function Reference
9.1.100 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.101 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.102 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.103 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.104 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.105 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.106 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.107 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.108 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.109 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.110 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.111 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.112 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.113 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.114 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.115 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.116 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.117 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: ssbdemod, Prev: shannonfanoenco, Up: Function Reference
9.1.118 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: ssbdemod, Next: ssbmod, Prev: sqrt, Up: Function Reference
9.1.119 ssbdemod
----------------
-- Function File: M = ssbdemod (S, FC, FS)
-- Function File: M = ssbdemod (S, FC, FS, PHI)
Creates the SSB demodulation of the signal S with carrier frequency
FC, sampling frequency FS initial phase PHI and a standard 5th
order low pass butterworth filter [b a] = butter (5, fc .* 2 ./ fs)
where b and a are numerator and denominator respectively
The initial phase PHI is optional and will be considered 0 if not
given
references and equation for ssdebmod:
https://electronicscoach.com/single-sideband-modulation.html
https://www.ee-diary.com/2023/02/ssb-sc-am-signal-generation-in-matlab.html
Inputs:
* S: amplitude message signal
* FC: carrier frequency
* FS: sampling frequency
* PHI: initial phase
Output:
M: The SSB demodulation of S
Demo
demo ssbmod
See also: ssbmod,ammod,amdemod, fmmod, fmdemod
File: comms.info, Node: ssbmod, Next: sum, Prev: ssbdemod, Up: Function Reference
9.1.120 ssbmod
--------------
-- Function File: Y = ssbmod (X, FC, FS)
-- Function File: Y = ssbmod (X, FC, FS, PHI)
-- Function File: Y = ssbmod (X, FC, FS, PHI, BAND)
Creates the SSB modulation of the amplitude signal X with carrier
frequency FC , sampling frequency FS initial phase : PHI and
specified band : BAND initial phase : PHI and specified band : BAND
are optional arguments and initial phase : PHI will be considered 0
if not given specified band : BAND by default is lower sideband,
but upper sideband can be specified by giving 'upper' as the fourth
argument
references and equation for ssbmod:
https://electronicscoach.com/single-sideband-modulation.html
https://www.ee-diary.com/2023/02/ssb-sc-am-signal-generation-in-matlab.html
Inputs:
* X: amplitude message signal
* FC: carrier frequency
* FS: sampling frequency
* PHI: initial phase (defaults to 0)
* BAND: specified band (if upper)
Output:
Y: The SSB modulation of X
Demo
demo ssbmod
See also: ssbdemod,ammod,amdemod, fmmod, fmdemod
File: comms.info, Node: sum, Next: sumsq, Prev: ssbmod, Up: Function Reference
9.1.121 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.122 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.123 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.124 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.125 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.126 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.127 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: Introduction388
Node: Random Signals923
Node: Signal Creation1596
Node: Signal Analysis9791
Node: Source Coding13805
Node: Quantization14028
Node: PCM Coding16275
Node: Arithmetic Coding16626
Node: Dynamic Range Compression16876
Node: Block Coding18082
Node: Data Formats18637
Node: Binary Block Codes20830
Node: BCH Codes26409
Node: Reed-Solomon Codes29083
Node: Representation of Reed-Solomon Messages29336
Node: Creating and Decoding Messages31260
Node: Shortened Reed-Solomon Codes35268
Node: Convolutional Coding36430
Node: Trellis Structure36901
Node: Convolutional Encoding38704
Node: Modulations39974
Node: Special Filters40267
Node: Galois Fields40416
Node: Galois Field Basics40617
Node: Creating Galois Fields42736
Node: Primitive Polynomials44863
Node: Accessing Internal Fields47406
Node: Function Overloading49036
Node: Known Problems50743
Node: Manipulating Galois Fields52637
Node: Expressions manipulation and assignment53000
Node: Unary operations56392
Node: Arithmetic operations57146
Node: Comparison operations60342
Node: Polynomial manipulations61539
Node: Linear Algebra66614
Node: Signal Processing68670
Node: Function Reference71720
Node: ademodce84175
Node: amdemod86349
Node: ammod86860
Node: amodce87344
Node: apkconst89273
Node: awgn91011
Node: bchdeco92246
Node: bchenco94485
Node: bchpoly96112
Node: berconfint99338
Node: bi2de100201
Node: bin2gray101019
Node: biterr101903
Node: bsc103900
Node: comms104143
Node: compand105686
Node: conv106955
Node: convenc107362
Node: convmtx108444
Node: cosets109180
Node: cyclgen109509
Node: cyclpoly110746
Node: de2bi111917
Node: decode113160
Node: deconv117876
Node: deintrlv118343
Node: demodmap118597
Node: det121095
Node: dftmtx121294
Node: diag121969
Node: dpcmdeco122719
Node: dpcmenco123236
Node: dpcmopt124441
Node: egolaydec126020
Node: egolayenc127244
Node: egolaygen127879
Node: encode128287
Node: exp131777
Node: eyediagram131996
Node: fft133615
Node: fibodeco133941
Node: fiboenco134951
Node: fibosplitstream136214
Node: filter137093
Node: finddelay138270
Node: fmdemod138843
Node: fmmod139324
Node: gen2par139914
Node: genqamdemod140477
Node: genqammod140857
Node: gf141550
Node: gftable141688
Node: gfweight142073
Node: golombdeco143025
Node: golombenco144115
Node: hammgen146091
Node: helscanintrlv147008
Node: huffmandeco147273
Node: huffmandict148312
Node: huffmanenco150025
Node: ifft150762
Node: intrlv151107
Node: inv151355
Node: inverse151727
Node: isequal151909
Node: isgalois152161
Node: isprimitive152401
Node: istrellis152732
Node: lloyds153190
Node: log155207
Node: lu155426
Node: lz77deco156436
Node: lz77enco156901
Node: matdeintrlv157327
Node: matintrlv157631
Node: minpol157933
Node: modmap158317
Node: oct2dec161066
Node: pamdemod161380
Node: pammod162236
Node: poly2trellis163015
Node: primpoly165128
Node: prod166400
Node: pskdemod166682
Node: pskmod167557
Node: qamdemod168413
Node: qammod168678
Node: qaskdeco169281
Node: qaskenco170596
Node: qfunc172389
Node: qfuncinv172591
Node: quantiz172809
Node: randdeintrlv173747
Node: randerr174043
Node: randint175162
Node: randintrlv176096
Node: randsrc176376
Node: rank177353
Node: rcosfir177599
Node: reedmullerdec178159
Node: reedmullerenc179498
Node: reedmullergen180243
Node: reshape181237
Node: ricedeco182256
Node: riceenco183118
Node: rledeco184552
Node: rleenco185057
Node: roots185607
Node: rsdec186040
Node: rsdecof188235
Node: rsenc189191
Node: rsencof191240
Node: rsgenpoly192440
Node: scatterplot194200
Node: shannonfanodeco195779
Node: shannonfanodict196971
Node: shannonfanoenco197770
Node: sqrt198561
Node: ssbdemod198812
Node: ssbmod199868
Node: sum201106
Node: sumsq201372
Node: symerr201776
Node: syndtable203471
Node: systematize204017
Node: vec2mat204893
Node: wgn205394
End Tag Table
Local Variables:
coding: utf-8
End:
communications-1.2.6/doc/PaxHeaders/images.mk 0000644 0000000 0000000 00000000127 14426727003 016202 x ustar 00 29 mtime=1683729923.27170152
29 atime=1683729923.27170152
29 ctime=1683729954.69955525
communications-1.2.6/doc/images.mk 0000644 0001750 0001750 00000002461 14426727003 016565 0 ustar 00nir nir 0000000 0000000 IMAGES = 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.6/doc/PaxHeaders/mktexi.pl 0000644 0000000 0000000 00000000073 14426726573 016255 x ustar 00 30 atime=1683729923.315701314
29 ctime=1683729954.69955525
communications-1.2.6/doc/mktexi.pl 0000755 0001750 0001750 00000030226 14426726573 016643 0 ustar 00nir nir 0000000 0000000 #!/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.6/doc/PaxHeaders/commsimages.m 0000644 0000000 0000000 00000000073 14426726573 017101 x ustar 00 30 atime=1683729923.299701389
29 ctime=1683729954.69955525
communications-1.2.6/doc/commsimages.m 0000644 0001750 0001750 00000006127 14426726573 017467 0 ustar 00nir nir 0000000 0000000 ## 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 .
## .
## -*- texinfo -*-
## @deftypefn {Function File} {} commsimages (@var{nm}, @var{typ})
##
## Internal function for making demo plots.
##
## Inputs:
## @itemize
##
## @item
## @var{nm}: plot to generate;
## "awgn", "eyediagram", or "scatterplot"
##
## @item
## @var{typ}: output format;
## "png", "eps", or another available output device
##
## @end itemize
##
## @end deftypefn
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.6/doc/PaxHeaders/comms.texi 0000644 0000000 0000000 00000000131 14426727041 016412 x ustar 00 30 mtime=1683729953.427561163
30 atime=1683729953.591560401
29 ctime=1683729954.69955525
communications-1.2.6/doc/comms.texi 0000644 0001750 0001750 00000704163 14426727041 017012 0 ustar 00nir nir 0000000 0000000 \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
Creates the AM modulation of the amplitude signal X with carrier frequency FC
@item amdemod
Creates the AM demodulation of the signal S sampled at frequency FS with carrier frequency FC
@item apkconst
Plots a ASK/PSK signal constellation.
@item bin2gray
Creates a Gray encoded data Y with the same size as input X
@item demodmap
Demapping of an analog signal to a digital signal.
@item fmmod
Creates the FM modulation S of the message signal M with carrier frequency FC
@item fmdemod
Creates the FM demodulation of the signal S sampled at frequency FS with carrier frequency FC
@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 using a given SYMORDER
@item qamdemod
Create the QAM demodulation of x with a size of alphabet m See also: qammod, pskmod, pskdemod
@item ssbmod
Creates the SSB modulation of the amplitude signal X with carrier frequency FC , sampling frequency FS initial phase : PHI and specified band : BAND initial phase : PHI and specified band : BAND are optional arguments and initial phase : PHI will be considered 0 if not given specified band : BAND by default is lower sideband, but upper sideband can be specified by giving 'upper' as the fourth argument
@item ssbdemod
Creates the SSB demodulation of the signal S with carrier frequency FC, sampling frequency FS initial phase PHI and a standard 5th order low pass butterworth filter [b a] = butter (5, fc .* 2 ./ fs) where b and a are numerator and denominator respectively
@end table
@subsection Channel Filters
@table @asis
@item rcosfir
Implements a cosine filter or root cosine filter impulse response
@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
@subsection Measurement and Analysis
@table @asis
@item berconfint
Returns Bit Error Rate, BER, and confidence interval, INTERVAL, for the number of errors R and number of transmitted bits N with a confidence level of LEVEL.
@item finddelay
Estimate the delay between times series X and time series Y by correlating and finding the peak.
@end table
@end iftex
@section Functions Alphabetically
@menu
* ademodce:: Baseband demodulator for analog signals.
* amdemod:: Creates the AM demodulation of the signal S sampled at
frequency FS with carrier frequency FC
* ammod:: Creates the AM modulation of the amplitude signal X with
carrier frequency FC
* 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.
* berconfint:: Returns Bit Error Rate, BER, and confidence interval,
INTERVAL, for the number of errors R and number of
transmitted bits N with a confidence level of LEVEL.
* bi2de:: Convert bit matrix to a vector of integers
* bin2gray:: Creates a Gray encoded data Y with the same size as input X
* 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.
* finddelay:: Estimate the delay between times series X and time series Y
by correlating and finding the peak.
* fmdemod:: Creates the FM demodulation of the signal S sampled at
frequency FS with carrier frequency FC
* fmmod:: Creates the FM modulation S of the message signal M with
carrier frequency FC
* 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
using a given SYMORDER
* 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
* rcosfir:: Implements a cosine filter or root cosine filter impulse
response
* 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
* ssbdemod:: Creates the SSB demodulation of the signal S with carrier
frequency FC, sampling frequency FS initial phase PHI and a
standard 5th order low pass butterworth filter [b a] =
butter (5, fc .* 2 ./ fs) where b and a are numerator and
denominator respectively
* ssbmod:: Creates the SSB modulation of the amplitude signal X with
carrier frequency FC , sampling frequency FS initial phase
: PHI and specified band : BAND initial phase : PHI and
specified band : BAND are optional arguments and initial
phase : PHI will be considered 0 if not given specified
band : BAND by default is lower sideband, but upper
sideband can be specified by giving 'upper' as the fourth
argument
* 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})
Creates the AM demodulation of the signal @var{s}
sampled at frequency @var{fs} with carrier frequency @var{fc}
Inputs:
@itemize
@item
@var{s}: AM modulated signal
@item
@var{fc}: carrier frequency
@item
@var{fs}: sampling frequency
@end itemize
Output:
@itemize
@item
@var{m}: AM demodulation of the signal
@end itemize
Demo
@example
demo amdemod
@end example
See also: ammod, fmmod, fmdemod
@end deftypefn
@node ammod, amodce, amdemod, Function Reference
@subsection ammod
@deftypefn {Function File} {@var{y} =} ammod (@var{x}, @var{fc}, @var{fs})
Creates the AM modulation of the amplitude signal @var{x}
with carrier frequency @var{fc}
Inputs:
@itemize
@item
@var{x}: amplitude message signal
@item
@var{fc}: carrier frequency
@item
@var{fs}: sampling frequency
@end itemize
Output:
@itemize
@var{y}: The AM modulation of @var{x}
@end itemize
Demo
@example
demo ammod
@end example
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 (noisy, 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, berconfint, 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 berconfint, bi2de, bchpoly, Function Reference
@subsection berconfint
@deftypefn {Function File} {@var{ber} =} berconfint (@var{r}, @var{n})
@deftypefnx {Function File} {[@var{ber}, @var{interval}] =} berconfint (@var{r}, @var{n})
@deftypefnx {Function File} {[@var{ber}, @var{interval}] =} berconfint (@var{r}, @var{n}, @var{level})
Returns Bit Error Rate, @var{ber}, and confidence interval, @var{interval}, for
the number of errors @var{r} and number of transmitted bits @var{n} with a
confidence level of @var{level}. By default @var{level} is 0.95
The confidence interval is the Wilson one (without continuity correction) for a proportion. By contrast, Matlab appears to return the Clopper–Pearson confidence interval
Reference:
Robert G. Newcombe (1998), "Two‐sided confidence intervals for the single proportion: comparison of seven methods", Statistics in Medicine 17(8):857-872
@end deftypefn
@node bi2de, bin2gray, berconfint, 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 bin2gray, biterr, bi2de, Function Reference
@subsection bin2gray
@deftypefn {Function File} {[@var{y}, @var{mapping}] =} bin2gray (@var{x}, @var{type}, @var{M})
Creates a Gray encoded data @var{y} with the same size as input @var{x}
Input:
@itemize
@item @var{x} Binary matrix data
@item @var{type}: The modulation type
choices available:'qam', 'pam','psk','dpsk', and 'fsk'
@item @var{M}: The modualtion order must be a power of 2
@end itemize
Output:
@itemize
@item @var{y}: The gray data of the @var{x} data
@item @var{mapping}: This provides the gray labesfor the given modulation
@end itemize
Example
@example
y = bin2gray ([0:3], 'qam', 16)
y =
0
1
3
2
@end example
Example with matrix
@example
y = bin2gray ([0:3; 12:15], 'qam', 16)
y =
0 1 3 2
8 9 11 10
@end example
See also: qammod
@end deftypefn
@node biterr, bsc, bin2gray, 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}, @dots{}, @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'. (@var{p} must have a value of 2 or higher.)
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, finddelay, 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 finddelay, fmdemod, filter, Function Reference
@subsection finddelay
@deftypefn {Function File} {@var{d} =} finddelay (@var{x}, @var{y})
Estimate the delay between times series @var{x} and time series @var{y} by
correlating and finding the peak. The index of the peak correlation
is returned in @var{d}
Inputs:
@itemize
@var{x}, @var{y}: signals
@end itemize
Output:
@itemize
@var{d}: The delay between the two signals
@end itemize
Example:
@example
x = [0, 0, 1, 2, 3];
y = [1, 2, 3];
d = finddelay (x, y)
d = -2
@end example
See also: xcorr
@end deftypefn
@node fmdemod, fmmod, finddelay, Function Reference
@subsection fmdemod
@deftypefn {Function File} {@var{m} =} fmdemod (@var{s}, @var{fc}, @var{fs})
Creates the FM demodulation of the signal @var{s}
sampled at frequency @var{fs} with carrier frequency @var{fc}
Inputs:
@itemize
@item
@var{s}: FM modulated signal
@item
@var{fc}: carrier frequency
@item
@var{fs}: sampling frequency
@end itemize
Output:
@itemize
@var{m}: FM demodulation of the signal
@end itemize
See also: ammod, amdemod, fmmod
@end deftypefn
@node fmmod, gen2par, fmdemod, Function Reference
@subsection fmmod
@deftypefn {Function File} {@var{s} =} fmmod (@var{m}, @var{fc}, @var{fs}, @var{freqdev})
Creates the FM modulation @var{s} of the message signal @var{m} with carrier frequency @var{fc}
Inputs:
@itemize
@item
@var{m}: sinusoidal message signal
@item
@var{fc}: carrier frequency
@item
@var{fs}: sampling frequency
@item
@var{freqdev}: maximum absolute frequency deviation, assuming @var{m} is in [-1:1]
@end itemize
Output:
@itemize
@var{s}: The FM modulation of @var{m}
@end itemize
Demo
@example
demo fmmod
@end example
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 optional argument @var{f} adds feedback support
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 optional vector @var{f} is a 1-by-k vector of octal numbers describing
the feedback of each of the shift registers
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
The output @var{y} will be the same shape as the input @var{x}
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})
@deftypefnx {Function File} {} qammod (@var{x}, @var{M}, @var{symOrder})
Create the QAM modulation of @var{x} with a size of alphabet @var{M} using a given @var{symOrder}
@var{x} vector in the range 0 to M-1
@var{M} modulation order
@var{symOrder} 'bin', 'gray', user define array
@example
M = 4;
sym = 0:M-1;
qammod(sym, M)
ans =
-1 + 1i
-1 - 1i
1 + 1i
1 - 1i
@end example
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, rcosfir, 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 rcosfir, reedmullerdec, rank, Function Reference
@subsection rcosfir
@deftypefn {Function File} {@var{h}, @var{st} =} rcosfir(@var{R},@var{nT},@var{rate},@var{T},@var{filterType})
Implements a cosine filter or root cosine filter impulse response
@var{R} Roll-off factor
@var{nT} scalar vector of length 2 such as N = (nT(2)-nT(1))*rate+1
@var{T} symbol rate
@var{filterType} 'normal' or 'sqrt'
@var{h} impulse response
@var{st} sampling interval
Example:
h = rcosfir(0.2,[-3 3],4,1,'sqrt');
See also: filter, downsample, rectfilt
@end deftypefn
@node reedmullerdec, reedmullerenc, rcosfir, 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, ssbdemod, 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 ssbdemod, ssbmod, sqrt, Function Reference
@subsection ssbdemod
@deftypefn {Function File} {@var{m} =} ssbdemod (@var{s}, @var{fc}, @var{fs})
@deftypefnx {Function File} {@var{m} =} ssbdemod (@var{s}, @var{fc}, @var{fs}, @var{phi})
Creates the SSB demodulation of the signal @var{s}
with carrier frequency @var{fc}, sampling frequency @var{fs}
initial phase @var{phi} and a standard 5th order low pass butterworth filter
[b a] = butter (5, fc .* 2 ./ fs) where b and a are numerator and
denominator respectively
The initial phase @var{phi} is optional
and will be considered 0 if not given
references and equation for ssdebmod:
https://electronicscoach.com/single-sideband-modulation.html
https://www.ee-diary.com/2023/02/ssb-sc-am-signal-generation-in-matlab.html
Inputs:
@itemize
@item
@var{s}: amplitude message signal
@item
@var{fc}: carrier frequency
@item
@var{fs}: sampling frequency
@item
@var{phi}: initial phase
@end itemize
Output:
@itemize
@var{m}: The SSB demodulation of @var{s}
@end itemize
Demo
@example
demo ssbmod
@end example
See also: ssbmod,ammod,amdemod, fmmod, fmdemod
@end deftypefn
@node ssbmod, sum, ssbdemod, Function Reference
@subsection ssbmod
@deftypefn {Function File} {@var{y} =} ssbmod (@var{x}, @var{fc}, @var{fs})
@deftypefnx {Function File} {@var{y} =} ssbmod (@var{x}, @var{fc}, @var{fs}, @var{phi})
@deftypefnx {Function File} {@var{y} =} ssbmod (@var{x}, @var{fc}, @var{fs}, @var{phi}, @var{band})
Creates the SSB modulation of the amplitude signal @var{x}
with carrier frequency @var{fc} , sampling frequency @var{fs}
initial phase : @var{phi} and specified band : @var{band}
initial phase : @var{phi} and specified band : @var{band} are optional
arguments and initial phase : @var{phi} will be considered 0 if not given
specified band : @var{band} by default is lower sideband, but upper sideband
can be specified by giving 'upper' as the fourth argument
references and equation for ssbmod:
https://electronicscoach.com/single-sideband-modulation.html
https://www.ee-diary.com/2023/02/ssb-sc-am-signal-generation-in-matlab.html
Inputs:
@itemize
@item
@var{x}: amplitude message signal
@item
@var{fc}: carrier frequency
@item
@var{fs}: sampling frequency
@item
@var{phi}: initial phase (defaults to 0)
@item
@var{band}: specified band (if upper)
@end itemize
Output:
@itemize
@var{y}: The SSB modulation of @var{x}
@end itemize
Demo
@example
demo ssbmod
@end example
See also: ssbdemod,ammod,amdemod, fmmod, fmdemod
@end deftypefn
@node sum, sumsq, ssbmod, 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.6/doc/PaxHeaders/Makefile 0000644 0000000 0000000 00000000073 14426726573 016057 x ustar 00 30 atime=1683729923.263701557
29 ctime=1683729954.69955525
communications-1.2.6/doc/Makefile 0000644 0001750 0001750 00000003747 14426726573 016452 0 ustar 00nir nir 0000000 0000000 DVIPS = 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.6/PaxHeaders/src 0000644 0000000 0000000 00000000127 14426727042 014354 x ustar 00 29 mtime=1683729954.69955525
29 atime=1683729954.69955525
29 ctime=1683729954.69955525
communications-1.2.6/src/ 0000755 0001750 0001750 00000000000 14426727042 015011 5 ustar 00nir nir 0000000 0000000 communications-1.2.6/src/PaxHeaders/galois.cc 0000644 0000000 0000000 00000000073 14426726573 016226 x ustar 00 30 atime=1683729923.299701389
29 ctime=1683729954.69955525
communications-1.2.6/src/galois.cc 0000644 0001750 0001750 00000104167 14426726573 016617 0 ustar 00nir nir 0000000 0000000 //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.6/src/PaxHeaders/config.h.in 0000644 0000000 0000000 00000000131 14426727042 016447 x ustar 00 30 mtime=1683729954.695555269
30 atime=1683729954.695555269
29 ctime=1683729954.69955525
communications-1.2.6/src/config.h.in 0000644 0001750 0001750 00000007301 14426727042 017035 0 ustar 00nir nir 0000000 0000000 /* 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_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 if first catop function argument is const-qualified */
#undef HAVE_OCTAVE_FIRST_CATOP_ARG_CONST
/* 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_STDIO_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 all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
#include "oct-alt-includes.h"
communications-1.2.6/src/PaxHeaders/genqamdemod.cc 0000644 0000000 0000000 00000000073 14426726573 017231 x ustar 00 30 atime=1683729923.299701389
29 ctime=1683729954.69955525
communications-1.2.6/src/genqamdemod.cc 0000644 0001750 0001750 00000006350 14426726573 017615 0 ustar 00nir nir 0000000 0000000 //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 ());
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 ();
}
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.6/src/PaxHeaders/__errcore__.cc 0000644 0000000 0000000 00000000073 14426726573 017205 x ustar 00 30 atime=1683729923.299701389
29 ctime=1683729954.69955525
communications-1.2.6/src/__errcore__.cc 0000644 0001750 0001750 00000004501 14426726573 017565 0 ustar 00nir nir 0000000 0000000 //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
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<